ActivityManagerService.java revision f792e01606b988ab84190217529cca53da8db3f5
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 android.view.Display; 61import com.android.internal.R; 62import com.android.internal.annotations.GuardedBy; 63import com.android.internal.app.IAppOpsService; 64import com.android.internal.app.IVoiceInteractor; 65import com.android.internal.app.ProcessMap; 66import com.android.internal.app.ProcessStats; 67import com.android.internal.os.BackgroundThread; 68import com.android.internal.os.BatteryStatsImpl; 69import com.android.internal.os.ProcessCpuTracker; 70import com.android.internal.os.TransferPipe; 71import com.android.internal.os.Zygote; 72import com.android.internal.util.FastPrintWriter; 73import com.android.internal.util.FastXmlSerializer; 74import com.android.internal.util.MemInfoReader; 75import com.android.internal.util.Preconditions; 76import com.android.server.AppOpsService; 77import com.android.server.AttributeCache; 78import com.android.server.IntentResolver; 79import com.android.server.LocalServices; 80import com.android.server.ServiceThread; 81import com.android.server.SystemService; 82import com.android.server.SystemServiceManager; 83import com.android.server.Watchdog; 84import com.android.server.am.ActivityStack.ActivityState; 85import com.android.server.firewall.IntentFirewall; 86import com.android.server.pm.Installer; 87import com.android.server.pm.UserManagerService; 88import com.android.server.statusbar.StatusBarManagerInternal; 89import com.android.server.wm.AppTransition; 90import com.android.server.wm.WindowManagerService; 91import com.google.android.collect.Lists; 92import com.google.android.collect.Maps; 93 94import libcore.io.IoUtils; 95 96import org.xmlpull.v1.XmlPullParser; 97import org.xmlpull.v1.XmlPullParserException; 98import org.xmlpull.v1.XmlSerializer; 99 100import android.app.Activity; 101import android.app.ActivityManager; 102import android.app.ActivityManager.RunningTaskInfo; 103import android.app.ActivityManager.StackInfo; 104import android.app.ActivityManagerInternal; 105import android.app.ActivityManagerNative; 106import android.app.ActivityOptions; 107import android.app.ActivityThread; 108import android.app.AlertDialog; 109import android.app.AppGlobals; 110import android.app.ApplicationErrorReport; 111import android.app.Dialog; 112import android.app.IActivityController; 113import android.app.IApplicationThread; 114import android.app.IInstrumentationWatcher; 115import android.app.INotificationManager; 116import android.app.IProcessObserver; 117import android.app.IServiceConnection; 118import android.app.IStopUserCallback; 119import android.app.IUiAutomationConnection; 120import android.app.IUserSwitchObserver; 121import android.app.Instrumentation; 122import android.app.Notification; 123import android.app.NotificationManager; 124import android.app.PendingIntent; 125import android.app.backup.IBackupManager; 126import android.content.ActivityNotFoundException; 127import android.content.BroadcastReceiver; 128import android.content.ClipData; 129import android.content.ComponentCallbacks2; 130import android.content.ComponentName; 131import android.content.ContentProvider; 132import android.content.ContentResolver; 133import android.content.Context; 134import android.content.DialogInterface; 135import android.content.IContentProvider; 136import android.content.IIntentReceiver; 137import android.content.IIntentSender; 138import android.content.Intent; 139import android.content.IntentFilter; 140import android.content.IntentSender; 141import android.content.pm.ActivityInfo; 142import android.content.pm.ApplicationInfo; 143import android.content.pm.ConfigurationInfo; 144import android.content.pm.IPackageDataObserver; 145import android.content.pm.IPackageManager; 146import android.content.pm.InstrumentationInfo; 147import android.content.pm.PackageInfo; 148import android.content.pm.PackageManager; 149import android.content.pm.ParceledListSlice; 150import android.content.pm.UserInfo; 151import android.content.pm.PackageManager.NameNotFoundException; 152import android.content.pm.PathPermission; 153import android.content.pm.ProviderInfo; 154import android.content.pm.ResolveInfo; 155import android.content.pm.ServiceInfo; 156import android.content.res.CompatibilityInfo; 157import android.content.res.Configuration; 158import android.net.Proxy; 159import android.net.ProxyInfo; 160import android.net.Uri; 161import android.os.Binder; 162import android.os.Build; 163import android.os.Bundle; 164import android.os.Debug; 165import android.os.DropBoxManager; 166import android.os.Environment; 167import android.os.FactoryTest; 168import android.os.FileObserver; 169import android.os.FileUtils; 170import android.os.Handler; 171import android.os.IBinder; 172import android.os.IPermissionController; 173import android.os.IRemoteCallback; 174import android.os.IUserManager; 175import android.os.Looper; 176import android.os.Message; 177import android.os.Parcel; 178import android.os.ParcelFileDescriptor; 179import android.os.PowerManagerInternal; 180import android.os.Process; 181import android.os.RemoteCallbackList; 182import android.os.RemoteException; 183import android.os.SELinux; 184import android.os.ServiceManager; 185import android.os.StrictMode; 186import android.os.SystemClock; 187import android.os.SystemProperties; 188import android.os.UpdateLock; 189import android.os.UserHandle; 190import android.os.UserManager; 191import android.provider.Settings; 192import android.text.format.DateUtils; 193import android.text.format.Time; 194import android.util.AtomicFile; 195import android.util.EventLog; 196import android.util.Log; 197import android.util.Pair; 198import android.util.PrintWriterPrinter; 199import android.util.Slog; 200import android.util.SparseArray; 201import android.util.TimeUtils; 202import android.util.Xml; 203import android.view.Gravity; 204import android.view.LayoutInflater; 205import android.view.View; 206import android.view.WindowManager; 207 208import dalvik.system.VMRuntime; 209 210import java.io.BufferedInputStream; 211import java.io.BufferedOutputStream; 212import java.io.DataInputStream; 213import java.io.DataOutputStream; 214import java.io.File; 215import java.io.FileDescriptor; 216import java.io.FileInputStream; 217import java.io.FileNotFoundException; 218import java.io.FileOutputStream; 219import java.io.IOException; 220import java.io.InputStreamReader; 221import java.io.PrintWriter; 222import java.io.StringWriter; 223import java.lang.ref.WeakReference; 224import java.util.ArrayList; 225import java.util.Arrays; 226import java.util.Collections; 227import java.util.Comparator; 228import java.util.HashMap; 229import java.util.HashSet; 230import java.util.Iterator; 231import java.util.List; 232import java.util.Locale; 233import java.util.Map; 234import java.util.Set; 235import java.util.concurrent.atomic.AtomicBoolean; 236import java.util.concurrent.atomic.AtomicLong; 237 238public final class ActivityManagerService extends ActivityManagerNative 239 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 240 241 private static final String USER_DATA_DIR = "/data/user/"; 242 // File that stores last updated system version and called preboot receivers 243 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 244 245 static final String TAG = "ActivityManager"; 246 static final String TAG_MU = "ActivityManagerServiceMU"; 247 static final boolean DEBUG = false; 248 static final boolean localLOGV = DEBUG; 249 static final boolean DEBUG_BACKUP = localLOGV || false; 250 static final boolean DEBUG_BROADCAST = localLOGV || false; 251 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 253 static final boolean DEBUG_CLEANUP = localLOGV || false; 254 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 255 static final boolean DEBUG_FOCUS = false; 256 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 257 static final boolean DEBUG_MU = localLOGV || false; 258 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 259 static final boolean DEBUG_LRU = localLOGV || false; 260 static final boolean DEBUG_PAUSE = localLOGV || false; 261 static final boolean DEBUG_POWER = localLOGV || false; 262 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 263 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 264 static final boolean DEBUG_PROCESSES = localLOGV || false; 265 static final boolean DEBUG_PROVIDER = localLOGV || false; 266 static final boolean DEBUG_RESULTS = localLOGV || false; 267 static final boolean DEBUG_SERVICE = localLOGV || false; 268 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 269 static final boolean DEBUG_STACK = localLOGV || false; 270 static final boolean DEBUG_SWITCH = localLOGV || false; 271 static final boolean DEBUG_TASKS = localLOGV || false; 272 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 273 static final boolean DEBUG_TRANSITION = localLOGV || false; 274 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 275 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 276 static final boolean DEBUG_VISBILITY = localLOGV || false; 277 static final boolean DEBUG_PSS = localLOGV || false; 278 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 279 static final boolean DEBUG_RECENTS = localLOGV || false; 280 static final boolean VALIDATE_TOKENS = false; 281 static final boolean SHOW_ACTIVITY_START_TIME = true; 282 283 // Control over CPU and battery monitoring. 284 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 285 static final boolean MONITOR_CPU_USAGE = true; 286 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 287 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 288 static final boolean MONITOR_THREAD_CPU_USAGE = false; 289 290 // The flags that are set for all calls we make to the package manager. 291 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 292 293 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 294 295 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 296 297 // Maximum number recent bitmaps to keep in memory. 298 static final int MAX_RECENT_BITMAPS = 3; 299 300 // Amount of time after a call to stopAppSwitches() during which we will 301 // prevent further untrusted switches from happening. 302 static final long APP_SWITCH_DELAY_TIME = 5*1000; 303 304 // How long we wait for a launched process to attach to the activity manager 305 // before we decide it's never going to come up for real. 306 static final int PROC_START_TIMEOUT = 10*1000; 307 308 // How long we wait for a launched process to attach to the activity manager 309 // before we decide it's never going to come up for real, when the process was 310 // started with a wrapper for instrumentation (such as Valgrind) because it 311 // could take much longer than usual. 312 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 313 314 // How long to wait after going idle before forcing apps to GC. 315 static final int GC_TIMEOUT = 5*1000; 316 317 // The minimum amount of time between successive GC requests for a process. 318 static final int GC_MIN_INTERVAL = 60*1000; 319 320 // The minimum amount of time between successive PSS requests for a process. 321 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 322 323 // The minimum amount of time between successive PSS requests for a process 324 // when the request is due to the memory state being lowered. 325 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 326 327 // The rate at which we check for apps using excessive power -- 15 mins. 328 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 329 330 // The minimum sample duration we will allow before deciding we have 331 // enough data on wake locks to start killing things. 332 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 333 334 // The minimum sample duration we will allow before deciding we have 335 // enough data on CPU usage to start killing things. 336 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 337 338 // How long we allow a receiver to run before giving up on it. 339 static final int BROADCAST_FG_TIMEOUT = 10*1000; 340 static final int BROADCAST_BG_TIMEOUT = 60*1000; 341 342 // How long we wait until we timeout on key dispatching. 343 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 344 345 // How long we wait until we timeout on key dispatching during instrumentation. 346 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 347 348 // Amount of time we wait for observers to handle a user switch before 349 // giving up on them and unfreezing the screen. 350 static final int USER_SWITCH_TIMEOUT = 2*1000; 351 352 // Maximum number of users we allow to be running at a time. 353 static final int MAX_RUNNING_USERS = 3; 354 355 // How long to wait in getAssistContextExtras for the activity and foreground services 356 // to respond with the result. 357 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 358 359 // Maximum number of persisted Uri grants a package is allowed 360 static final int MAX_PERSISTED_URI_GRANTS = 128; 361 362 static final int MY_PID = Process.myPid(); 363 364 static final String[] EMPTY_STRING_ARRAY = new String[0]; 365 366 // How many bytes to write into the dropbox log before truncating 367 static final int DROPBOX_MAX_SIZE = 256 * 1024; 368 369 // Access modes for handleIncomingUser. 370 static final int ALLOW_NON_FULL = 0; 371 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 372 static final int ALLOW_FULL_ONLY = 2; 373 374 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 375 376 // Delay in notifying task stack change listeners (in millis) 377 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 378 379 /** All system services */ 380 SystemServiceManager mSystemServiceManager; 381 382 private Installer mInstaller; 383 384 /** Run all ActivityStacks through this */ 385 ActivityStackSupervisor mStackSupervisor; 386 387 /** Task stack change listeners. */ 388 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 389 new RemoteCallbackList<ITaskStackListener>(); 390 391 public IntentFirewall mIntentFirewall; 392 393 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 394 // default actuion automatically. Important for devices without direct input 395 // devices. 396 private boolean mShowDialogs = true; 397 398 BroadcastQueue mFgBroadcastQueue; 399 BroadcastQueue mBgBroadcastQueue; 400 // Convenient for easy iteration over the queues. Foreground is first 401 // so that dispatch of foreground broadcasts gets precedence. 402 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 403 404 BroadcastQueue broadcastQueueForIntent(Intent intent) { 405 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 406 if (DEBUG_BACKGROUND_BROADCAST) { 407 Slog.i(TAG, "Broadcast intent " + intent + " on " 408 + (isFg ? "foreground" : "background") 409 + " queue"); 410 } 411 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 412 } 413 414 /** 415 * Activity we have told the window manager to have key focus. 416 */ 417 ActivityRecord mFocusedActivity = null; 418 419 /** 420 * List of intents that were used to start the most recent tasks. 421 */ 422 ArrayList<TaskRecord> mRecentTasks; 423 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 424 425 /** 426 * For addAppTask: cached of the last activity component that was added. 427 */ 428 ComponentName mLastAddedTaskComponent; 429 430 /** 431 * For addAppTask: cached of the last activity uid that was added. 432 */ 433 int mLastAddedTaskUid; 434 435 /** 436 * For addAppTask: cached of the last ActivityInfo that was added. 437 */ 438 ActivityInfo mLastAddedTaskActivity; 439 440 public class PendingAssistExtras extends Binder implements Runnable { 441 public final ActivityRecord activity; 442 public final Bundle extras; 443 public final Intent intent; 444 public final String hint; 445 public final int userHandle; 446 public boolean haveResult = false; 447 public Bundle result = null; 448 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 449 String _hint, int _userHandle) { 450 activity = _activity; 451 extras = _extras; 452 intent = _intent; 453 hint = _hint; 454 userHandle = _userHandle; 455 } 456 @Override 457 public void run() { 458 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 459 synchronized (this) { 460 haveResult = true; 461 notifyAll(); 462 } 463 } 464 } 465 466 final ArrayList<PendingAssistExtras> mPendingAssistExtras 467 = new ArrayList<PendingAssistExtras>(); 468 469 /** 470 * Process management. 471 */ 472 final ProcessList mProcessList = new ProcessList(); 473 474 /** 475 * All of the applications we currently have running organized by name. 476 * The keys are strings of the application package name (as 477 * returned by the package manager), and the keys are ApplicationRecord 478 * objects. 479 */ 480 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 481 482 /** 483 * Tracking long-term execution of processes to look for abuse and other 484 * bad app behavior. 485 */ 486 final ProcessStatsService mProcessStats; 487 488 /** 489 * The currently running isolated processes. 490 */ 491 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 492 493 /** 494 * Counter for assigning isolated process uids, to avoid frequently reusing the 495 * same ones. 496 */ 497 int mNextIsolatedProcessUid = 0; 498 499 /** 500 * The currently running heavy-weight process, if any. 501 */ 502 ProcessRecord mHeavyWeightProcess = null; 503 504 /** 505 * The last time that various processes have crashed. 506 */ 507 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 508 509 /** 510 * Information about a process that is currently marked as bad. 511 */ 512 static final class BadProcessInfo { 513 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 514 this.time = time; 515 this.shortMsg = shortMsg; 516 this.longMsg = longMsg; 517 this.stack = stack; 518 } 519 520 final long time; 521 final String shortMsg; 522 final String longMsg; 523 final String stack; 524 } 525 526 /** 527 * Set of applications that we consider to be bad, and will reject 528 * incoming broadcasts from (which the user has no control over). 529 * Processes are added to this set when they have crashed twice within 530 * a minimum amount of time; they are removed from it when they are 531 * later restarted (hopefully due to some user action). The value is the 532 * time it was added to the list. 533 */ 534 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 535 536 /** 537 * All of the processes we currently have running organized by pid. 538 * The keys are the pid running the application. 539 * 540 * <p>NOTE: This object is protected by its own lock, NOT the global 541 * activity manager lock! 542 */ 543 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 544 545 /** 546 * All of the processes that have been forced to be foreground. The key 547 * is the pid of the caller who requested it (we hold a death 548 * link on it). 549 */ 550 abstract class ForegroundToken implements IBinder.DeathRecipient { 551 int pid; 552 IBinder token; 553 } 554 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 555 556 /** 557 * List of records for processes that someone had tried to start before the 558 * system was ready. We don't start them at that point, but ensure they 559 * are started by the time booting is complete. 560 */ 561 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 562 563 /** 564 * List of persistent applications that are in the process 565 * of being started. 566 */ 567 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * Processes that are being forcibly torn down. 571 */ 572 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 573 574 /** 575 * List of running applications, sorted by recent usage. 576 * The first entry in the list is the least recently used. 577 */ 578 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Where in mLruProcesses that the processes hosting activities start. 582 */ 583 int mLruProcessActivityStart = 0; 584 585 /** 586 * Where in mLruProcesses that the processes hosting services start. 587 * This is after (lower index) than mLruProcessesActivityStart. 588 */ 589 int mLruProcessServiceStart = 0; 590 591 /** 592 * List of processes that should gc as soon as things are idle. 593 */ 594 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Processes we want to collect PSS data from. 598 */ 599 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 600 601 /** 602 * Last time we requested PSS data of all processes. 603 */ 604 long mLastFullPssTime = SystemClock.uptimeMillis(); 605 606 /** 607 * If set, the next time we collect PSS data we should do a full collection 608 * with data from native processes and the kernel. 609 */ 610 boolean mFullPssPending = false; 611 612 /** 613 * This is the process holding what we currently consider to be 614 * the "home" activity. 615 */ 616 ProcessRecord mHomeProcess; 617 618 /** 619 * This is the process holding the activity the user last visited that 620 * is in a different process from the one they are currently in. 621 */ 622 ProcessRecord mPreviousProcess; 623 624 /** 625 * The time at which the previous process was last visible. 626 */ 627 long mPreviousProcessVisibleTime; 628 629 /** 630 * Which uses have been started, so are allowed to run code. 631 */ 632 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 633 634 /** 635 * LRU list of history of current users. Most recently current is at the end. 636 */ 637 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 638 639 /** 640 * Constant array of the users that are currently started. 641 */ 642 int[] mStartedUserArray = new int[] { 0 }; 643 644 /** 645 * Registered observers of the user switching mechanics. 646 */ 647 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 648 = new RemoteCallbackList<IUserSwitchObserver>(); 649 650 /** 651 * Currently active user switch. 652 */ 653 Object mCurUserSwitchCallback; 654 655 /** 656 * Packages that the user has asked to have run in screen size 657 * compatibility mode instead of filling the screen. 658 */ 659 final CompatModePackages mCompatModePackages; 660 661 /** 662 * Set of IntentSenderRecord objects that are currently active. 663 */ 664 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 665 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 666 667 /** 668 * Fingerprints (hashCode()) of stack traces that we've 669 * already logged DropBox entries for. Guarded by itself. If 670 * something (rogue user app) forces this over 671 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 672 */ 673 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 674 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 675 676 /** 677 * Strict Mode background batched logging state. 678 * 679 * The string buffer is guarded by itself, and its lock is also 680 * used to determine if another batched write is already 681 * in-flight. 682 */ 683 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 684 685 /** 686 * Keeps track of all IIntentReceivers that have been registered for 687 * broadcasts. Hash keys are the receiver IBinder, hash value is 688 * a ReceiverList. 689 */ 690 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 691 new HashMap<IBinder, ReceiverList>(); 692 693 /** 694 * Resolver for broadcast intents to registered receivers. 695 * Holds BroadcastFilter (subclass of IntentFilter). 696 */ 697 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 698 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 699 @Override 700 protected boolean allowFilterResult( 701 BroadcastFilter filter, List<BroadcastFilter> dest) { 702 IBinder target = filter.receiverList.receiver.asBinder(); 703 for (int i=dest.size()-1; i>=0; i--) { 704 if (dest.get(i).receiverList.receiver.asBinder() == target) { 705 return false; 706 } 707 } 708 return true; 709 } 710 711 @Override 712 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 713 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 714 || userId == filter.owningUserId) { 715 return super.newResult(filter, match, userId); 716 } 717 return null; 718 } 719 720 @Override 721 protected BroadcastFilter[] newArray(int size) { 722 return new BroadcastFilter[size]; 723 } 724 725 @Override 726 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 727 return packageName.equals(filter.packageName); 728 } 729 }; 730 731 /** 732 * State of all active sticky broadcasts per user. Keys are the action of the 733 * sticky Intent, values are an ArrayList of all broadcasted intents with 734 * that action (which should usually be one). The SparseArray is keyed 735 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 736 * for stickies that are sent to all users. 737 */ 738 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 739 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 740 741 final ActiveServices mServices; 742 743 final static class Association { 744 final int mSourceUid; 745 final String mSourceProcess; 746 final int mTargetUid; 747 final ComponentName mTargetComponent; 748 final String mTargetProcess; 749 750 int mCount; 751 long mTime; 752 753 int mNesting; 754 long mStartTime; 755 756 Association(int sourceUid, String sourceProcess, int targetUid, 757 ComponentName targetComponent, String targetProcess) { 758 mSourceUid = sourceUid; 759 mSourceProcess = sourceProcess; 760 mTargetUid = targetUid; 761 mTargetComponent = targetComponent; 762 mTargetProcess = targetProcess; 763 } 764 } 765 766 /** 767 * When service association tracking is enabled, this is all of the associations we 768 * have seen. Mapping is target uid -> target component -> source uid -> source process name 769 * -> association data. 770 */ 771 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 772 mAssociations = new SparseArray<>(); 773 boolean mTrackingAssociations; 774 775 /** 776 * Backup/restore process management 777 */ 778 String mBackupAppName = null; 779 BackupRecord mBackupTarget = null; 780 781 final ProviderMap mProviderMap; 782 783 /** 784 * List of content providers who have clients waiting for them. The 785 * application is currently being launched and the provider will be 786 * removed from this list once it is published. 787 */ 788 final ArrayList<ContentProviderRecord> mLaunchingProviders 789 = new ArrayList<ContentProviderRecord>(); 790 791 /** 792 * File storing persisted {@link #mGrantedUriPermissions}. 793 */ 794 private final AtomicFile mGrantFile; 795 796 /** XML constants used in {@link #mGrantFile} */ 797 private static final String TAG_URI_GRANTS = "uri-grants"; 798 private static final String TAG_URI_GRANT = "uri-grant"; 799 private static final String ATTR_USER_HANDLE = "userHandle"; 800 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 801 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 802 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 803 private static final String ATTR_TARGET_PKG = "targetPkg"; 804 private static final String ATTR_URI = "uri"; 805 private static final String ATTR_MODE_FLAGS = "modeFlags"; 806 private static final String ATTR_CREATED_TIME = "createdTime"; 807 private static final String ATTR_PREFIX = "prefix"; 808 809 /** 810 * Global set of specific {@link Uri} permissions that have been granted. 811 * This optimized lookup structure maps from {@link UriPermission#targetUid} 812 * to {@link UriPermission#uri} to {@link UriPermission}. 813 */ 814 @GuardedBy("this") 815 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 816 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 817 818 public static class GrantUri { 819 public final int sourceUserId; 820 public final Uri uri; 821 public boolean prefix; 822 823 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 824 this.sourceUserId = sourceUserId; 825 this.uri = uri; 826 this.prefix = prefix; 827 } 828 829 @Override 830 public int hashCode() { 831 int hashCode = 1; 832 hashCode = 31 * hashCode + sourceUserId; 833 hashCode = 31 * hashCode + uri.hashCode(); 834 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 835 return hashCode; 836 } 837 838 @Override 839 public boolean equals(Object o) { 840 if (o instanceof GrantUri) { 841 GrantUri other = (GrantUri) o; 842 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 843 && prefix == other.prefix; 844 } 845 return false; 846 } 847 848 @Override 849 public String toString() { 850 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 851 if (prefix) result += " [prefix]"; 852 return result; 853 } 854 855 public String toSafeString() { 856 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 857 if (prefix) result += " [prefix]"; 858 return result; 859 } 860 861 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 862 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 863 ContentProvider.getUriWithoutUserId(uri), false); 864 } 865 } 866 867 CoreSettingsObserver mCoreSettingsObserver; 868 869 /** 870 * Thread-local storage used to carry caller permissions over through 871 * indirect content-provider access. 872 */ 873 private class Identity { 874 public final IBinder token; 875 public final int pid; 876 public final int uid; 877 878 Identity(IBinder _token, int _pid, int _uid) { 879 token = _token; 880 pid = _pid; 881 uid = _uid; 882 } 883 } 884 885 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 886 887 /** 888 * All information we have collected about the runtime performance of 889 * any user id that can impact battery performance. 890 */ 891 final BatteryStatsService mBatteryStatsService; 892 893 /** 894 * Information about component usage 895 */ 896 UsageStatsManagerInternal mUsageStatsService; 897 898 /** 899 * Information about and control over application operations 900 */ 901 final AppOpsService mAppOpsService; 902 903 /** 904 * Save recent tasks information across reboots. 905 */ 906 final TaskPersister mTaskPersister; 907 908 /** 909 * Current configuration information. HistoryRecord objects are given 910 * a reference to this object to indicate which configuration they are 911 * currently running in, so this object must be kept immutable. 912 */ 913 Configuration mConfiguration = new Configuration(); 914 915 /** 916 * Current sequencing integer of the configuration, for skipping old 917 * configurations. 918 */ 919 int mConfigurationSeq = 0; 920 921 /** 922 * Hardware-reported OpenGLES version. 923 */ 924 final int GL_ES_VERSION; 925 926 /** 927 * List of initialization arguments to pass to all processes when binding applications to them. 928 * For example, references to the commonly used services. 929 */ 930 HashMap<String, IBinder> mAppBindArgs; 931 932 /** 933 * Temporary to avoid allocations. Protected by main lock. 934 */ 935 final StringBuilder mStringBuilder = new StringBuilder(256); 936 937 /** 938 * Used to control how we initialize the service. 939 */ 940 ComponentName mTopComponent; 941 String mTopAction = Intent.ACTION_MAIN; 942 String mTopData; 943 boolean mProcessesReady = false; 944 boolean mSystemReady = false; 945 boolean mBooting = false; 946 boolean mCallFinishBooting = false; 947 boolean mBootAnimationComplete = false; 948 boolean mWaitingUpdate = false; 949 boolean mDidUpdate = false; 950 boolean mOnBattery = false; 951 boolean mLaunchWarningShown = false; 952 953 Context mContext; 954 955 int mFactoryTest; 956 957 boolean mCheckedForSetup; 958 959 /** 960 * The time at which we will allow normal application switches again, 961 * after a call to {@link #stopAppSwitches()}. 962 */ 963 long mAppSwitchesAllowedTime; 964 965 /** 966 * This is set to true after the first switch after mAppSwitchesAllowedTime 967 * is set; any switches after that will clear the time. 968 */ 969 boolean mDidAppSwitch; 970 971 /** 972 * Last time (in realtime) at which we checked for power usage. 973 */ 974 long mLastPowerCheckRealtime; 975 976 /** 977 * Last time (in uptime) at which we checked for power usage. 978 */ 979 long mLastPowerCheckUptime; 980 981 /** 982 * Set while we are wanting to sleep, to prevent any 983 * activities from being started/resumed. 984 */ 985 private boolean mSleeping = false; 986 987 /** 988 * Set while we are running a voice interaction. This overrides 989 * sleeping while it is active. 990 */ 991 private boolean mRunningVoice = false; 992 993 /** 994 * State of external calls telling us if the device is awake or asleep. 995 */ 996 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 997 998 static final int LOCK_SCREEN_HIDDEN = 0; 999 static final int LOCK_SCREEN_LEAVING = 1; 1000 static final int LOCK_SCREEN_SHOWN = 2; 1001 /** 1002 * State of external call telling us if the lock screen is shown. 1003 */ 1004 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 1005 1006 /** 1007 * Set if we are shutting down the system, similar to sleeping. 1008 */ 1009 boolean mShuttingDown = false; 1010 1011 /** 1012 * Current sequence id for oom_adj computation traversal. 1013 */ 1014 int mAdjSeq = 0; 1015 1016 /** 1017 * Current sequence id for process LRU updating. 1018 */ 1019 int mLruSeq = 0; 1020 1021 /** 1022 * Keep track of the non-cached/empty process we last found, to help 1023 * determine how to distribute cached/empty processes next time. 1024 */ 1025 int mNumNonCachedProcs = 0; 1026 1027 /** 1028 * Keep track of the number of cached hidden procs, to balance oom adj 1029 * distribution between those and empty procs. 1030 */ 1031 int mNumCachedHiddenProcs = 0; 1032 1033 /** 1034 * Keep track of the number of service processes we last found, to 1035 * determine on the next iteration which should be B services. 1036 */ 1037 int mNumServiceProcs = 0; 1038 int mNewNumAServiceProcs = 0; 1039 int mNewNumServiceProcs = 0; 1040 1041 /** 1042 * Allow the current computed overall memory level of the system to go down? 1043 * This is set to false when we are killing processes for reasons other than 1044 * memory management, so that the now smaller process list will not be taken as 1045 * an indication that memory is tighter. 1046 */ 1047 boolean mAllowLowerMemLevel = false; 1048 1049 /** 1050 * The last computed memory level, for holding when we are in a state that 1051 * processes are going away for other reasons. 1052 */ 1053 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1054 1055 /** 1056 * The last total number of process we have, to determine if changes actually look 1057 * like a shrinking number of process due to lower RAM. 1058 */ 1059 int mLastNumProcesses; 1060 1061 /** 1062 * The uptime of the last time we performed idle maintenance. 1063 */ 1064 long mLastIdleTime = SystemClock.uptimeMillis(); 1065 1066 /** 1067 * Total time spent with RAM that has been added in the past since the last idle time. 1068 */ 1069 long mLowRamTimeSinceLastIdle = 0; 1070 1071 /** 1072 * If RAM is currently low, when that horrible situation started. 1073 */ 1074 long mLowRamStartTime = 0; 1075 1076 /** 1077 * For reporting to battery stats the current top application. 1078 */ 1079 private String mCurResumedPackage = null; 1080 private int mCurResumedUid = -1; 1081 1082 /** 1083 * For reporting to battery stats the apps currently running foreground 1084 * service. The ProcessMap is package/uid tuples; each of these contain 1085 * an array of the currently foreground processes. 1086 */ 1087 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1088 = new ProcessMap<ArrayList<ProcessRecord>>(); 1089 1090 /** 1091 * This is set if we had to do a delayed dexopt of an app before launching 1092 * it, to increase the ANR timeouts in that case. 1093 */ 1094 boolean mDidDexOpt; 1095 1096 /** 1097 * Set if the systemServer made a call to enterSafeMode. 1098 */ 1099 boolean mSafeMode; 1100 1101 /** 1102 * If true, we are running under a test environment so will sample PSS from processes 1103 * much more rapidly to try to collect better data when the tests are rapidly 1104 * running through apps. 1105 */ 1106 boolean mTestPssMode = false; 1107 1108 String mDebugApp = null; 1109 boolean mWaitForDebugger = false; 1110 boolean mDebugTransient = false; 1111 String mOrigDebugApp = null; 1112 boolean mOrigWaitForDebugger = false; 1113 boolean mAlwaysFinishActivities = false; 1114 IActivityController mController = null; 1115 String mProfileApp = null; 1116 ProcessRecord mProfileProc = null; 1117 String mProfileFile; 1118 ParcelFileDescriptor mProfileFd; 1119 int mSamplingInterval = 0; 1120 boolean mAutoStopProfiler = false; 1121 int mProfileType = 0; 1122 String mOpenGlTraceApp = null; 1123 1124 final long[] mTmpLong = new long[1]; 1125 1126 static class ProcessChangeItem { 1127 static final int CHANGE_ACTIVITIES = 1<<0; 1128 static final int CHANGE_PROCESS_STATE = 1<<1; 1129 int changes; 1130 int uid; 1131 int pid; 1132 int processState; 1133 boolean foregroundActivities; 1134 } 1135 1136 final RemoteCallbackList<IProcessObserver> mProcessObservers 1137 = new RemoteCallbackList<IProcessObserver>(); 1138 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1139 1140 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1141 = new ArrayList<ProcessChangeItem>(); 1142 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1143 = new ArrayList<ProcessChangeItem>(); 1144 1145 /** 1146 * Runtime CPU use collection thread. This object's lock is used to 1147 * perform synchronization with the thread (notifying it to run). 1148 */ 1149 final Thread mProcessCpuThread; 1150 1151 /** 1152 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1153 * Must acquire this object's lock when accessing it. 1154 * NOTE: this lock will be held while doing long operations (trawling 1155 * through all processes in /proc), so it should never be acquired by 1156 * any critical paths such as when holding the main activity manager lock. 1157 */ 1158 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1159 MONITOR_THREAD_CPU_USAGE); 1160 final AtomicLong mLastCpuTime = new AtomicLong(0); 1161 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1162 1163 long mLastWriteTime = 0; 1164 1165 /** 1166 * Used to retain an update lock when the foreground activity is in 1167 * immersive mode. 1168 */ 1169 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1170 1171 /** 1172 * Set to true after the system has finished booting. 1173 */ 1174 boolean mBooted = false; 1175 1176 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1177 int mProcessLimitOverride = -1; 1178 1179 WindowManagerService mWindowManager; 1180 1181 final ActivityThread mSystemThread; 1182 1183 // Holds the current foreground user's id 1184 int mCurrentUserId = 0; 1185 // Holds the target user's id during a user switch 1186 int mTargetUserId = UserHandle.USER_NULL; 1187 // If there are multiple profiles for the current user, their ids are here 1188 // Currently only the primary user can have managed profiles 1189 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1190 1191 /** 1192 * Mapping from each known user ID to the profile group ID it is associated with. 1193 */ 1194 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1195 1196 private UserManagerService mUserManager; 1197 1198 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1199 final ProcessRecord mApp; 1200 final int mPid; 1201 final IApplicationThread mAppThread; 1202 1203 AppDeathRecipient(ProcessRecord app, int pid, 1204 IApplicationThread thread) { 1205 if (localLOGV) Slog.v( 1206 TAG, "New death recipient " + this 1207 + " for thread " + thread.asBinder()); 1208 mApp = app; 1209 mPid = pid; 1210 mAppThread = thread; 1211 } 1212 1213 @Override 1214 public void binderDied() { 1215 if (localLOGV) Slog.v( 1216 TAG, "Death received in " + this 1217 + " for thread " + mAppThread.asBinder()); 1218 synchronized(ActivityManagerService.this) { 1219 appDiedLocked(mApp, mPid, mAppThread); 1220 } 1221 } 1222 } 1223 1224 static final int SHOW_ERROR_MSG = 1; 1225 static final int SHOW_NOT_RESPONDING_MSG = 2; 1226 static final int SHOW_FACTORY_ERROR_MSG = 3; 1227 static final int UPDATE_CONFIGURATION_MSG = 4; 1228 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1229 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1230 static final int SERVICE_TIMEOUT_MSG = 12; 1231 static final int UPDATE_TIME_ZONE = 13; 1232 static final int SHOW_UID_ERROR_MSG = 14; 1233 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1234 static final int PROC_START_TIMEOUT_MSG = 20; 1235 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1236 static final int KILL_APPLICATION_MSG = 22; 1237 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1238 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1239 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1240 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1241 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1242 static final int CLEAR_DNS_CACHE_MSG = 28; 1243 static final int UPDATE_HTTP_PROXY_MSG = 29; 1244 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1245 static final int DISPATCH_PROCESSES_CHANGED = 31; 1246 static final int DISPATCH_PROCESS_DIED = 32; 1247 static final int REPORT_MEM_USAGE_MSG = 33; 1248 static final int REPORT_USER_SWITCH_MSG = 34; 1249 static final int CONTINUE_USER_SWITCH_MSG = 35; 1250 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1251 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1252 static final int PERSIST_URI_GRANTS_MSG = 38; 1253 static final int REQUEST_ALL_PSS_MSG = 39; 1254 static final int START_PROFILES_MSG = 40; 1255 static final int UPDATE_TIME = 41; 1256 static final int SYSTEM_USER_START_MSG = 42; 1257 static final int SYSTEM_USER_CURRENT_MSG = 43; 1258 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1259 static final int FINISH_BOOTING_MSG = 45; 1260 static final int START_USER_SWITCH_MSG = 46; 1261 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1262 static final int DISMISS_DIALOG_MSG = 48; 1263 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1264 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50; 1265 1266 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1267 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1268 static final int FIRST_COMPAT_MODE_MSG = 300; 1269 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1270 1271 CompatModeDialog mCompatModeDialog; 1272 long mLastMemUsageReportTime = 0; 1273 1274 /** 1275 * Flag whether the current user is a "monkey", i.e. whether 1276 * the UI is driven by a UI automation tool. 1277 */ 1278 private boolean mUserIsMonkey; 1279 1280 /** Flag whether the device has a Recents UI */ 1281 boolean mHasRecents; 1282 1283 /** The dimensions of the thumbnails in the Recents UI. */ 1284 int mThumbnailWidth; 1285 int mThumbnailHeight; 1286 1287 final ServiceThread mHandlerThread; 1288 final MainHandler mHandler; 1289 1290 final class MainHandler extends Handler { 1291 public MainHandler(Looper looper) { 1292 super(looper, null, true); 1293 } 1294 1295 @Override 1296 public void handleMessage(Message msg) { 1297 switch (msg.what) { 1298 case SHOW_ERROR_MSG: { 1299 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1300 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1301 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1302 synchronized (ActivityManagerService.this) { 1303 ProcessRecord proc = (ProcessRecord)data.get("app"); 1304 AppErrorResult res = (AppErrorResult) data.get("result"); 1305 if (proc != null && proc.crashDialog != null) { 1306 Slog.e(TAG, "App already has crash dialog: " + proc); 1307 if (res != null) { 1308 res.set(0); 1309 } 1310 return; 1311 } 1312 boolean isBackground = (UserHandle.getAppId(proc.uid) 1313 >= Process.FIRST_APPLICATION_UID 1314 && proc.pid != MY_PID); 1315 for (int userId : mCurrentProfileIds) { 1316 isBackground &= (proc.userId != userId); 1317 } 1318 if (isBackground && !showBackground) { 1319 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1320 if (res != null) { 1321 res.set(0); 1322 } 1323 return; 1324 } 1325 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1326 Dialog d = new AppErrorDialog(mContext, 1327 ActivityManagerService.this, res, proc); 1328 d.show(); 1329 proc.crashDialog = d; 1330 } else { 1331 // The device is asleep, so just pretend that the user 1332 // saw a crash dialog and hit "force quit". 1333 if (res != null) { 1334 res.set(0); 1335 } 1336 } 1337 } 1338 1339 ensureBootCompleted(); 1340 } break; 1341 case SHOW_NOT_RESPONDING_MSG: { 1342 synchronized (ActivityManagerService.this) { 1343 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1344 ProcessRecord proc = (ProcessRecord)data.get("app"); 1345 if (proc != null && proc.anrDialog != null) { 1346 Slog.e(TAG, "App already has anr dialog: " + proc); 1347 return; 1348 } 1349 1350 Intent intent = new Intent("android.intent.action.ANR"); 1351 if (!mProcessesReady) { 1352 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1353 | Intent.FLAG_RECEIVER_FOREGROUND); 1354 } 1355 broadcastIntentLocked(null, null, intent, 1356 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1357 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1358 1359 if (mShowDialogs) { 1360 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1361 mContext, proc, (ActivityRecord)data.get("activity"), 1362 msg.arg1 != 0); 1363 d.show(); 1364 proc.anrDialog = d; 1365 } else { 1366 // Just kill the app if there is no dialog to be shown. 1367 killAppAtUsersRequest(proc, null); 1368 } 1369 } 1370 1371 ensureBootCompleted(); 1372 } break; 1373 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1374 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1375 synchronized (ActivityManagerService.this) { 1376 ProcessRecord proc = (ProcessRecord) data.get("app"); 1377 if (proc == null) { 1378 Slog.e(TAG, "App not found when showing strict mode dialog."); 1379 break; 1380 } 1381 if (proc.crashDialog != null) { 1382 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1383 return; 1384 } 1385 AppErrorResult res = (AppErrorResult) data.get("result"); 1386 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1387 Dialog d = new StrictModeViolationDialog(mContext, 1388 ActivityManagerService.this, res, proc); 1389 d.show(); 1390 proc.crashDialog = d; 1391 } else { 1392 // The device is asleep, so just pretend that the user 1393 // saw a crash dialog and hit "force quit". 1394 res.set(0); 1395 } 1396 } 1397 ensureBootCompleted(); 1398 } break; 1399 case SHOW_FACTORY_ERROR_MSG: { 1400 Dialog d = new FactoryErrorDialog( 1401 mContext, msg.getData().getCharSequence("msg")); 1402 d.show(); 1403 ensureBootCompleted(); 1404 } break; 1405 case UPDATE_CONFIGURATION_MSG: { 1406 final ContentResolver resolver = mContext.getContentResolver(); 1407 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1408 } break; 1409 case GC_BACKGROUND_PROCESSES_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 performAppGcsIfAppropriateLocked(); 1412 } 1413 } break; 1414 case WAIT_FOR_DEBUGGER_MSG: { 1415 synchronized (ActivityManagerService.this) { 1416 ProcessRecord app = (ProcessRecord)msg.obj; 1417 if (msg.arg1 != 0) { 1418 if (!app.waitedForDebugger) { 1419 Dialog d = new AppWaitingForDebuggerDialog( 1420 ActivityManagerService.this, 1421 mContext, app); 1422 app.waitDialog = d; 1423 app.waitedForDebugger = true; 1424 d.show(); 1425 } 1426 } else { 1427 if (app.waitDialog != null) { 1428 app.waitDialog.dismiss(); 1429 app.waitDialog = null; 1430 } 1431 } 1432 } 1433 } break; 1434 case SERVICE_TIMEOUT_MSG: { 1435 if (mDidDexOpt) { 1436 mDidDexOpt = false; 1437 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1438 nmsg.obj = msg.obj; 1439 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1440 return; 1441 } 1442 mServices.serviceTimeout((ProcessRecord)msg.obj); 1443 } break; 1444 case UPDATE_TIME_ZONE: { 1445 synchronized (ActivityManagerService.this) { 1446 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1447 ProcessRecord r = mLruProcesses.get(i); 1448 if (r.thread != null) { 1449 try { 1450 r.thread.updateTimeZone(); 1451 } catch (RemoteException ex) { 1452 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1453 } 1454 } 1455 } 1456 } 1457 } break; 1458 case CLEAR_DNS_CACHE_MSG: { 1459 synchronized (ActivityManagerService.this) { 1460 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1461 ProcessRecord r = mLruProcesses.get(i); 1462 if (r.thread != null) { 1463 try { 1464 r.thread.clearDnsCache(); 1465 } catch (RemoteException ex) { 1466 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1467 } 1468 } 1469 } 1470 } 1471 } break; 1472 case UPDATE_HTTP_PROXY_MSG: { 1473 ProxyInfo proxy = (ProxyInfo)msg.obj; 1474 String host = ""; 1475 String port = ""; 1476 String exclList = ""; 1477 Uri pacFileUrl = Uri.EMPTY; 1478 if (proxy != null) { 1479 host = proxy.getHost(); 1480 port = Integer.toString(proxy.getPort()); 1481 exclList = proxy.getExclusionListAsString(); 1482 pacFileUrl = proxy.getPacFileUrl(); 1483 } 1484 synchronized (ActivityManagerService.this) { 1485 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1486 ProcessRecord r = mLruProcesses.get(i); 1487 if (r.thread != null) { 1488 try { 1489 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1490 } catch (RemoteException ex) { 1491 Slog.w(TAG, "Failed to update http proxy for: " + 1492 r.info.processName); 1493 } 1494 } 1495 } 1496 } 1497 } break; 1498 case SHOW_UID_ERROR_MSG: { 1499 if (mShowDialogs) { 1500 AlertDialog d = new BaseErrorDialog(mContext); 1501 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1502 d.setCancelable(false); 1503 d.setTitle(mContext.getText(R.string.android_system_label)); 1504 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1505 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1506 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1507 d.show(); 1508 } 1509 } break; 1510 case SHOW_FINGERPRINT_ERROR_MSG: { 1511 if (mShowDialogs) { 1512 AlertDialog d = new BaseErrorDialog(mContext); 1513 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1514 d.setCancelable(false); 1515 d.setTitle(mContext.getText(R.string.android_system_label)); 1516 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1517 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1518 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1519 d.show(); 1520 } 1521 } break; 1522 case PROC_START_TIMEOUT_MSG: { 1523 if (mDidDexOpt) { 1524 mDidDexOpt = false; 1525 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1526 nmsg.obj = msg.obj; 1527 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1528 return; 1529 } 1530 ProcessRecord app = (ProcessRecord)msg.obj; 1531 synchronized (ActivityManagerService.this) { 1532 processStartTimedOutLocked(app); 1533 } 1534 } break; 1535 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1536 synchronized (ActivityManagerService.this) { 1537 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1538 } 1539 } break; 1540 case KILL_APPLICATION_MSG: { 1541 synchronized (ActivityManagerService.this) { 1542 int appid = msg.arg1; 1543 boolean restart = (msg.arg2 == 1); 1544 Bundle bundle = (Bundle)msg.obj; 1545 String pkg = bundle.getString("pkg"); 1546 String reason = bundle.getString("reason"); 1547 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1548 false, UserHandle.USER_ALL, reason); 1549 } 1550 } break; 1551 case FINALIZE_PENDING_INTENT_MSG: { 1552 ((PendingIntentRecord)msg.obj).completeFinalize(); 1553 } break; 1554 case POST_HEAVY_NOTIFICATION_MSG: { 1555 INotificationManager inm = NotificationManager.getService(); 1556 if (inm == null) { 1557 return; 1558 } 1559 1560 ActivityRecord root = (ActivityRecord)msg.obj; 1561 ProcessRecord process = root.app; 1562 if (process == null) { 1563 return; 1564 } 1565 1566 try { 1567 Context context = mContext.createPackageContext(process.info.packageName, 0); 1568 String text = mContext.getString(R.string.heavy_weight_notification, 1569 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1570 Notification notification = new Notification(); 1571 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1572 notification.when = 0; 1573 notification.flags = Notification.FLAG_ONGOING_EVENT; 1574 notification.tickerText = text; 1575 notification.defaults = 0; // please be quiet 1576 notification.sound = null; 1577 notification.vibrate = null; 1578 notification.color = mContext.getResources().getColor( 1579 com.android.internal.R.color.system_notification_accent_color); 1580 notification.setLatestEventInfo(context, text, 1581 mContext.getText(R.string.heavy_weight_notification_detail), 1582 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1583 PendingIntent.FLAG_CANCEL_CURRENT, null, 1584 new UserHandle(root.userId))); 1585 1586 try { 1587 int[] outId = new int[1]; 1588 inm.enqueueNotificationWithTag("android", "android", null, 1589 R.string.heavy_weight_notification, 1590 notification, outId, root.userId); 1591 } catch (RuntimeException e) { 1592 Slog.w(ActivityManagerService.TAG, 1593 "Error showing notification for heavy-weight app", e); 1594 } catch (RemoteException e) { 1595 } 1596 } catch (NameNotFoundException e) { 1597 Slog.w(TAG, "Unable to create context for heavy notification", e); 1598 } 1599 } break; 1600 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1601 INotificationManager inm = NotificationManager.getService(); 1602 if (inm == null) { 1603 return; 1604 } 1605 try { 1606 inm.cancelNotificationWithTag("android", null, 1607 R.string.heavy_weight_notification, msg.arg1); 1608 } catch (RuntimeException e) { 1609 Slog.w(ActivityManagerService.TAG, 1610 "Error canceling notification for service", e); 1611 } catch (RemoteException e) { 1612 } 1613 } break; 1614 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1615 synchronized (ActivityManagerService.this) { 1616 checkExcessivePowerUsageLocked(true); 1617 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1618 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1619 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1620 } 1621 } break; 1622 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1623 synchronized (ActivityManagerService.this) { 1624 ActivityRecord ar = (ActivityRecord)msg.obj; 1625 if (mCompatModeDialog != null) { 1626 if (mCompatModeDialog.mAppInfo.packageName.equals( 1627 ar.info.applicationInfo.packageName)) { 1628 return; 1629 } 1630 mCompatModeDialog.dismiss(); 1631 mCompatModeDialog = null; 1632 } 1633 if (ar != null && false) { 1634 if (mCompatModePackages.getPackageAskCompatModeLocked( 1635 ar.packageName)) { 1636 int mode = mCompatModePackages.computeCompatModeLocked( 1637 ar.info.applicationInfo); 1638 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1639 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1640 mCompatModeDialog = new CompatModeDialog( 1641 ActivityManagerService.this, mContext, 1642 ar.info.applicationInfo); 1643 mCompatModeDialog.show(); 1644 } 1645 } 1646 } 1647 } 1648 break; 1649 } 1650 case DISPATCH_PROCESSES_CHANGED: { 1651 dispatchProcessesChanged(); 1652 break; 1653 } 1654 case DISPATCH_PROCESS_DIED: { 1655 final int pid = msg.arg1; 1656 final int uid = msg.arg2; 1657 dispatchProcessDied(pid, uid); 1658 break; 1659 } 1660 case REPORT_MEM_USAGE_MSG: { 1661 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1662 Thread thread = new Thread() { 1663 @Override public void run() { 1664 reportMemUsage(memInfos); 1665 } 1666 }; 1667 thread.start(); 1668 break; 1669 } 1670 case START_USER_SWITCH_MSG: { 1671 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1672 break; 1673 } 1674 case REPORT_USER_SWITCH_MSG: { 1675 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1676 break; 1677 } 1678 case CONTINUE_USER_SWITCH_MSG: { 1679 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1680 break; 1681 } 1682 case USER_SWITCH_TIMEOUT_MSG: { 1683 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1684 break; 1685 } 1686 case IMMERSIVE_MODE_LOCK_MSG: { 1687 final boolean nextState = (msg.arg1 != 0); 1688 if (mUpdateLock.isHeld() != nextState) { 1689 if (DEBUG_IMMERSIVE) { 1690 final ActivityRecord r = (ActivityRecord) msg.obj; 1691 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1692 } 1693 if (nextState) { 1694 mUpdateLock.acquire(); 1695 } else { 1696 mUpdateLock.release(); 1697 } 1698 } 1699 break; 1700 } 1701 case PERSIST_URI_GRANTS_MSG: { 1702 writeGrantedUriPermissions(); 1703 break; 1704 } 1705 case REQUEST_ALL_PSS_MSG: { 1706 synchronized (ActivityManagerService.this) { 1707 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1708 } 1709 break; 1710 } 1711 case START_PROFILES_MSG: { 1712 synchronized (ActivityManagerService.this) { 1713 startProfilesLocked(); 1714 } 1715 break; 1716 } 1717 case UPDATE_TIME: { 1718 synchronized (ActivityManagerService.this) { 1719 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1720 ProcessRecord r = mLruProcesses.get(i); 1721 if (r.thread != null) { 1722 try { 1723 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1724 } catch (RemoteException ex) { 1725 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1726 } 1727 } 1728 } 1729 } 1730 break; 1731 } 1732 case SYSTEM_USER_START_MSG: { 1733 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1734 Integer.toString(msg.arg1), msg.arg1); 1735 mSystemServiceManager.startUser(msg.arg1); 1736 break; 1737 } 1738 case SYSTEM_USER_CURRENT_MSG: { 1739 mBatteryStatsService.noteEvent( 1740 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1741 Integer.toString(msg.arg2), msg.arg2); 1742 mBatteryStatsService.noteEvent( 1743 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1744 Integer.toString(msg.arg1), msg.arg1); 1745 mSystemServiceManager.switchUser(msg.arg1); 1746 break; 1747 } 1748 case ENTER_ANIMATION_COMPLETE_MSG: { 1749 synchronized (ActivityManagerService.this) { 1750 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1751 if (r != null && r.app != null && r.app.thread != null) { 1752 try { 1753 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1754 } catch (RemoteException e) { 1755 } 1756 } 1757 } 1758 break; 1759 } 1760 case FINISH_BOOTING_MSG: { 1761 if (msg.arg1 != 0) { 1762 finishBooting(); 1763 } 1764 if (msg.arg2 != 0) { 1765 enableScreenAfterBoot(); 1766 } 1767 break; 1768 } 1769 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1770 try { 1771 Locale l = (Locale) msg.obj; 1772 IBinder service = ServiceManager.getService("mount"); 1773 IMountService mountService = IMountService.Stub.asInterface(service); 1774 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1775 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1776 } catch (RemoteException e) { 1777 Log.e(TAG, "Error storing locale for decryption UI", e); 1778 } 1779 break; 1780 } 1781 case DISMISS_DIALOG_MSG: { 1782 final Dialog d = (Dialog) msg.obj; 1783 d.dismiss(); 1784 break; 1785 } 1786 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1787 synchronized (ActivityManagerService.this) { 1788 int i = mTaskStackListeners.beginBroadcast(); 1789 while (i > 0) { 1790 i--; 1791 try { 1792 // Make a one-way callback to the listener 1793 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1794 } catch (RemoteException e){ 1795 // Handled by the RemoteCallbackList 1796 } 1797 } 1798 mTaskStackListeners.finishBroadcast(); 1799 } 1800 break; 1801 } 1802 case NOTIFY_CLEARTEXT_NETWORK_MSG: { 1803 final int uid = msg.arg1; 1804 final byte[] firstPacket = (byte[]) msg.obj; 1805 1806 synchronized (mPidsSelfLocked) { 1807 for (int i = 0; i < mPidsSelfLocked.size(); i++) { 1808 final ProcessRecord p = mPidsSelfLocked.valueAt(i); 1809 if (p.uid == uid) { 1810 try { 1811 p.thread.notifyCleartextNetwork(firstPacket); 1812 } catch (RemoteException ignored) { 1813 } 1814 } 1815 } 1816 } 1817 break; 1818 } 1819 } 1820 } 1821 }; 1822 1823 static final int COLLECT_PSS_BG_MSG = 1; 1824 1825 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1826 @Override 1827 public void handleMessage(Message msg) { 1828 switch (msg.what) { 1829 case COLLECT_PSS_BG_MSG: { 1830 long start = SystemClock.uptimeMillis(); 1831 MemInfoReader memInfo = null; 1832 synchronized (ActivityManagerService.this) { 1833 if (mFullPssPending) { 1834 mFullPssPending = false; 1835 memInfo = new MemInfoReader(); 1836 } 1837 } 1838 if (memInfo != null) { 1839 updateCpuStatsNow(); 1840 long nativeTotalPss = 0; 1841 synchronized (mProcessCpuTracker) { 1842 final int N = mProcessCpuTracker.countStats(); 1843 for (int j=0; j<N; j++) { 1844 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1845 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1846 // This is definitely an application process; skip it. 1847 continue; 1848 } 1849 synchronized (mPidsSelfLocked) { 1850 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1851 // This is one of our own processes; skip it. 1852 continue; 1853 } 1854 } 1855 nativeTotalPss += Debug.getPss(st.pid, null, null); 1856 } 1857 } 1858 memInfo.readMemInfo(); 1859 synchronized (ActivityManagerService.this) { 1860 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1861 + (SystemClock.uptimeMillis()-start) + "ms"); 1862 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1863 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1864 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1865 } 1866 } 1867 1868 int num = 0; 1869 long[] tmp = new long[1]; 1870 do { 1871 ProcessRecord proc; 1872 int procState; 1873 int pid; 1874 long lastPssTime; 1875 synchronized (ActivityManagerService.this) { 1876 if (mPendingPssProcesses.size() <= 0) { 1877 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1878 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1879 mPendingPssProcesses.clear(); 1880 return; 1881 } 1882 proc = mPendingPssProcesses.remove(0); 1883 procState = proc.pssProcState; 1884 lastPssTime = proc.lastPssTime; 1885 if (proc.thread != null && procState == proc.setProcState 1886 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1887 < SystemClock.uptimeMillis()) { 1888 pid = proc.pid; 1889 } else { 1890 proc = null; 1891 pid = 0; 1892 } 1893 } 1894 if (proc != null) { 1895 long pss = Debug.getPss(pid, tmp, null); 1896 synchronized (ActivityManagerService.this) { 1897 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1898 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1899 num++; 1900 recordPssSample(proc, procState, pss, tmp[0], 1901 SystemClock.uptimeMillis()); 1902 } 1903 } 1904 } 1905 } while (true); 1906 } 1907 } 1908 } 1909 }; 1910 1911 public void setSystemProcess() { 1912 try { 1913 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1914 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1915 ServiceManager.addService("meminfo", new MemBinder(this)); 1916 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1917 ServiceManager.addService("dbinfo", new DbBinder(this)); 1918 if (MONITOR_CPU_USAGE) { 1919 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1920 } 1921 ServiceManager.addService("permission", new PermissionController(this)); 1922 1923 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1924 "android", STOCK_PM_FLAGS); 1925 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1926 1927 synchronized (this) { 1928 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1929 app.persistent = true; 1930 app.pid = MY_PID; 1931 app.maxAdj = ProcessList.SYSTEM_ADJ; 1932 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1933 mProcessNames.put(app.processName, app.uid, app); 1934 synchronized (mPidsSelfLocked) { 1935 mPidsSelfLocked.put(app.pid, app); 1936 } 1937 updateLruProcessLocked(app, false, null); 1938 updateOomAdjLocked(); 1939 } 1940 } catch (PackageManager.NameNotFoundException e) { 1941 throw new RuntimeException( 1942 "Unable to find android system package", e); 1943 } 1944 } 1945 1946 public void setWindowManager(WindowManagerService wm) { 1947 mWindowManager = wm; 1948 mStackSupervisor.setWindowManager(wm); 1949 } 1950 1951 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1952 mUsageStatsService = usageStatsManager; 1953 } 1954 1955 public void startObservingNativeCrashes() { 1956 final NativeCrashListener ncl = new NativeCrashListener(this); 1957 ncl.start(); 1958 } 1959 1960 public IAppOpsService getAppOpsService() { 1961 return mAppOpsService; 1962 } 1963 1964 static class MemBinder extends Binder { 1965 ActivityManagerService mActivityManagerService; 1966 MemBinder(ActivityManagerService activityManagerService) { 1967 mActivityManagerService = activityManagerService; 1968 } 1969 1970 @Override 1971 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1972 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1973 != PackageManager.PERMISSION_GRANTED) { 1974 pw.println("Permission Denial: can't dump meminfo from from pid=" 1975 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1976 + " without permission " + android.Manifest.permission.DUMP); 1977 return; 1978 } 1979 1980 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1981 } 1982 } 1983 1984 static class GraphicsBinder extends Binder { 1985 ActivityManagerService mActivityManagerService; 1986 GraphicsBinder(ActivityManagerService activityManagerService) { 1987 mActivityManagerService = activityManagerService; 1988 } 1989 1990 @Override 1991 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1992 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1993 != PackageManager.PERMISSION_GRANTED) { 1994 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1995 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1996 + " without permission " + android.Manifest.permission.DUMP); 1997 return; 1998 } 1999 2000 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2001 } 2002 } 2003 2004 static class DbBinder extends Binder { 2005 ActivityManagerService mActivityManagerService; 2006 DbBinder(ActivityManagerService activityManagerService) { 2007 mActivityManagerService = activityManagerService; 2008 } 2009 2010 @Override 2011 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2012 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2013 != PackageManager.PERMISSION_GRANTED) { 2014 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2015 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2016 + " without permission " + android.Manifest.permission.DUMP); 2017 return; 2018 } 2019 2020 mActivityManagerService.dumpDbInfo(fd, pw, args); 2021 } 2022 } 2023 2024 static class CpuBinder extends Binder { 2025 ActivityManagerService mActivityManagerService; 2026 CpuBinder(ActivityManagerService activityManagerService) { 2027 mActivityManagerService = activityManagerService; 2028 } 2029 2030 @Override 2031 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2032 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2033 != PackageManager.PERMISSION_GRANTED) { 2034 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2035 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2036 + " without permission " + android.Manifest.permission.DUMP); 2037 return; 2038 } 2039 2040 synchronized (mActivityManagerService.mProcessCpuTracker) { 2041 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2042 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2043 SystemClock.uptimeMillis())); 2044 } 2045 } 2046 } 2047 2048 public static final class Lifecycle extends SystemService { 2049 private final ActivityManagerService mService; 2050 2051 public Lifecycle(Context context) { 2052 super(context); 2053 mService = new ActivityManagerService(context); 2054 } 2055 2056 @Override 2057 public void onStart() { 2058 mService.start(); 2059 } 2060 2061 public ActivityManagerService getService() { 2062 return mService; 2063 } 2064 } 2065 2066 // Note: This method is invoked on the main thread but may need to attach various 2067 // handlers to other threads. So take care to be explicit about the looper. 2068 public ActivityManagerService(Context systemContext) { 2069 mContext = systemContext; 2070 mFactoryTest = FactoryTest.getMode(); 2071 mSystemThread = ActivityThread.currentActivityThread(); 2072 2073 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2074 2075 mHandlerThread = new ServiceThread(TAG, 2076 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2077 mHandlerThread.start(); 2078 mHandler = new MainHandler(mHandlerThread.getLooper()); 2079 2080 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2081 "foreground", BROADCAST_FG_TIMEOUT, false); 2082 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2083 "background", BROADCAST_BG_TIMEOUT, true); 2084 mBroadcastQueues[0] = mFgBroadcastQueue; 2085 mBroadcastQueues[1] = mBgBroadcastQueue; 2086 2087 mServices = new ActiveServices(this); 2088 mProviderMap = new ProviderMap(this); 2089 2090 // TODO: Move creation of battery stats service outside of activity manager service. 2091 File dataDir = Environment.getDataDirectory(); 2092 File systemDir = new File(dataDir, "system"); 2093 systemDir.mkdirs(); 2094 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2095 mBatteryStatsService.getActiveStatistics().readLocked(); 2096 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2097 mOnBattery = DEBUG_POWER ? true 2098 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2099 mBatteryStatsService.getActiveStatistics().setCallback(this); 2100 2101 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2102 2103 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2104 2105 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2106 2107 // User 0 is the first and only user that runs at boot. 2108 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2109 mUserLru.add(Integer.valueOf(0)); 2110 updateStartedUserArrayLocked(); 2111 2112 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2113 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2114 2115 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2116 2117 mConfiguration.setToDefaults(); 2118 mConfiguration.locale = Locale.getDefault(); 2119 2120 mConfigurationSeq = mConfiguration.seq = 1; 2121 mProcessCpuTracker.init(); 2122 2123 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2124 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2125 mStackSupervisor = new ActivityStackSupervisor(this); 2126 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2127 2128 mProcessCpuThread = new Thread("CpuTracker") { 2129 @Override 2130 public void run() { 2131 while (true) { 2132 try { 2133 try { 2134 synchronized(this) { 2135 final long now = SystemClock.uptimeMillis(); 2136 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2137 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2138 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2139 // + ", write delay=" + nextWriteDelay); 2140 if (nextWriteDelay < nextCpuDelay) { 2141 nextCpuDelay = nextWriteDelay; 2142 } 2143 if (nextCpuDelay > 0) { 2144 mProcessCpuMutexFree.set(true); 2145 this.wait(nextCpuDelay); 2146 } 2147 } 2148 } catch (InterruptedException e) { 2149 } 2150 updateCpuStatsNow(); 2151 } catch (Exception e) { 2152 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2153 } 2154 } 2155 } 2156 }; 2157 2158 Watchdog.getInstance().addMonitor(this); 2159 Watchdog.getInstance().addThread(mHandler); 2160 } 2161 2162 public void setSystemServiceManager(SystemServiceManager mgr) { 2163 mSystemServiceManager = mgr; 2164 } 2165 2166 public void setInstaller(Installer installer) { 2167 mInstaller = installer; 2168 } 2169 2170 private void start() { 2171 Process.removeAllProcessGroups(); 2172 mProcessCpuThread.start(); 2173 2174 mBatteryStatsService.publish(mContext); 2175 mAppOpsService.publish(mContext); 2176 Slog.d("AppOps", "AppOpsService published"); 2177 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2178 } 2179 2180 public void initPowerManagement() { 2181 mStackSupervisor.initPowerManagement(); 2182 mBatteryStatsService.initPowerManagement(); 2183 } 2184 2185 @Override 2186 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2187 throws RemoteException { 2188 if (code == SYSPROPS_TRANSACTION) { 2189 // We need to tell all apps about the system property change. 2190 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2191 synchronized(this) { 2192 final int NP = mProcessNames.getMap().size(); 2193 for (int ip=0; ip<NP; ip++) { 2194 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2195 final int NA = apps.size(); 2196 for (int ia=0; ia<NA; ia++) { 2197 ProcessRecord app = apps.valueAt(ia); 2198 if (app.thread != null) { 2199 procs.add(app.thread.asBinder()); 2200 } 2201 } 2202 } 2203 } 2204 2205 int N = procs.size(); 2206 for (int i=0; i<N; i++) { 2207 Parcel data2 = Parcel.obtain(); 2208 try { 2209 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2210 } catch (RemoteException e) { 2211 } 2212 data2.recycle(); 2213 } 2214 } 2215 try { 2216 return super.onTransact(code, data, reply, flags); 2217 } catch (RuntimeException e) { 2218 // The activity manager only throws security exceptions, so let's 2219 // log all others. 2220 if (!(e instanceof SecurityException)) { 2221 Slog.wtf(TAG, "Activity Manager Crash", e); 2222 } 2223 throw e; 2224 } 2225 } 2226 2227 void updateCpuStats() { 2228 final long now = SystemClock.uptimeMillis(); 2229 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2230 return; 2231 } 2232 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2233 synchronized (mProcessCpuThread) { 2234 mProcessCpuThread.notify(); 2235 } 2236 } 2237 } 2238 2239 void updateCpuStatsNow() { 2240 synchronized (mProcessCpuTracker) { 2241 mProcessCpuMutexFree.set(false); 2242 final long now = SystemClock.uptimeMillis(); 2243 boolean haveNewCpuStats = false; 2244 2245 if (MONITOR_CPU_USAGE && 2246 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2247 mLastCpuTime.set(now); 2248 haveNewCpuStats = true; 2249 mProcessCpuTracker.update(); 2250 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2251 //Slog.i(TAG, "Total CPU usage: " 2252 // + mProcessCpu.getTotalCpuPercent() + "%"); 2253 2254 // Slog the cpu usage if the property is set. 2255 if ("true".equals(SystemProperties.get("events.cpu"))) { 2256 int user = mProcessCpuTracker.getLastUserTime(); 2257 int system = mProcessCpuTracker.getLastSystemTime(); 2258 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2259 int irq = mProcessCpuTracker.getLastIrqTime(); 2260 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2261 int idle = mProcessCpuTracker.getLastIdleTime(); 2262 2263 int total = user + system + iowait + irq + softIrq + idle; 2264 if (total == 0) total = 1; 2265 2266 EventLog.writeEvent(EventLogTags.CPU, 2267 ((user+system+iowait+irq+softIrq) * 100) / total, 2268 (user * 100) / total, 2269 (system * 100) / total, 2270 (iowait * 100) / total, 2271 (irq * 100) / total, 2272 (softIrq * 100) / total); 2273 } 2274 } 2275 2276 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2277 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2278 synchronized(bstats) { 2279 synchronized(mPidsSelfLocked) { 2280 if (haveNewCpuStats) { 2281 if (mOnBattery) { 2282 int perc = bstats.startAddingCpuLocked(); 2283 int totalUTime = 0; 2284 int totalSTime = 0; 2285 final int N = mProcessCpuTracker.countStats(); 2286 for (int i=0; i<N; i++) { 2287 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2288 if (!st.working) { 2289 continue; 2290 } 2291 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2292 int otherUTime = (st.rel_utime*perc)/100; 2293 int otherSTime = (st.rel_stime*perc)/100; 2294 totalUTime += otherUTime; 2295 totalSTime += otherSTime; 2296 if (pr != null) { 2297 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2298 if (ps == null || !ps.isActive()) { 2299 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2300 pr.info.uid, pr.processName); 2301 } 2302 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2303 st.rel_stime-otherSTime); 2304 ps.addSpeedStepTimes(cpuSpeedTimes); 2305 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2306 } else { 2307 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2308 if (ps == null || !ps.isActive()) { 2309 st.batteryStats = ps = bstats.getProcessStatsLocked( 2310 bstats.mapUid(st.uid), st.name); 2311 } 2312 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2313 st.rel_stime-otherSTime); 2314 ps.addSpeedStepTimes(cpuSpeedTimes); 2315 } 2316 } 2317 bstats.finishAddingCpuLocked(perc, totalUTime, 2318 totalSTime, cpuSpeedTimes); 2319 } 2320 } 2321 } 2322 2323 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2324 mLastWriteTime = now; 2325 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2326 } 2327 } 2328 } 2329 } 2330 2331 @Override 2332 public void batteryNeedsCpuUpdate() { 2333 updateCpuStatsNow(); 2334 } 2335 2336 @Override 2337 public void batteryPowerChanged(boolean onBattery) { 2338 // When plugging in, update the CPU stats first before changing 2339 // the plug state. 2340 updateCpuStatsNow(); 2341 synchronized (this) { 2342 synchronized(mPidsSelfLocked) { 2343 mOnBattery = DEBUG_POWER ? true : onBattery; 2344 } 2345 } 2346 } 2347 2348 /** 2349 * Initialize the application bind args. These are passed to each 2350 * process when the bindApplication() IPC is sent to the process. They're 2351 * lazily setup to make sure the services are running when they're asked for. 2352 */ 2353 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2354 if (mAppBindArgs == null) { 2355 mAppBindArgs = new HashMap<>(); 2356 2357 // Isolated processes won't get this optimization, so that we don't 2358 // violate the rules about which services they have access to. 2359 if (!isolated) { 2360 // Setup the application init args 2361 mAppBindArgs.put("package", ServiceManager.getService("package")); 2362 mAppBindArgs.put("window", ServiceManager.getService("window")); 2363 mAppBindArgs.put(Context.ALARM_SERVICE, 2364 ServiceManager.getService(Context.ALARM_SERVICE)); 2365 } 2366 } 2367 return mAppBindArgs; 2368 } 2369 2370 final void setFocusedActivityLocked(ActivityRecord r, String reason) { 2371 if (mFocusedActivity != r) { 2372 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2373 mFocusedActivity = r; 2374 if (r.task != null && r.task.voiceInteractor != null) { 2375 startRunningVoiceLocked(); 2376 } else { 2377 finishRunningVoiceLocked(); 2378 } 2379 mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity"); 2380 if (r != null) { 2381 mWindowManager.setFocusedApp(r.appToken, true); 2382 } 2383 applyUpdateLockStateLocked(r); 2384 } 2385 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId, 2386 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName); 2387 } 2388 2389 final void clearFocusedActivity(ActivityRecord r) { 2390 if (mFocusedActivity == r) { 2391 mFocusedActivity = null; 2392 } 2393 } 2394 2395 @Override 2396 public void setFocusedStack(int stackId) { 2397 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2398 synchronized (ActivityManagerService.this) { 2399 ActivityStack stack = mStackSupervisor.getStack(stackId); 2400 if (stack != null) { 2401 ActivityRecord r = stack.topRunningActivityLocked(null); 2402 if (r != null) { 2403 setFocusedActivityLocked(r, "setFocusedStack"); 2404 } 2405 } 2406 } 2407 } 2408 2409 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2410 @Override 2411 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2412 synchronized (ActivityManagerService.this) { 2413 if (listener != null) { 2414 mTaskStackListeners.register(listener); 2415 } 2416 } 2417 } 2418 2419 @Override 2420 public void notifyActivityDrawn(IBinder token) { 2421 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2422 synchronized (this) { 2423 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2424 if (r != null) { 2425 r.task.stack.notifyActivityDrawnLocked(r); 2426 } 2427 } 2428 } 2429 2430 final void applyUpdateLockStateLocked(ActivityRecord r) { 2431 // Modifications to the UpdateLock state are done on our handler, outside 2432 // the activity manager's locks. The new state is determined based on the 2433 // state *now* of the relevant activity record. The object is passed to 2434 // the handler solely for logging detail, not to be consulted/modified. 2435 final boolean nextState = r != null && r.immersive; 2436 mHandler.sendMessage( 2437 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2438 } 2439 2440 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2441 Message msg = Message.obtain(); 2442 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2443 msg.obj = r.task.askedCompatMode ? null : r; 2444 mHandler.sendMessage(msg); 2445 } 2446 2447 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2448 String what, Object obj, ProcessRecord srcApp) { 2449 app.lastActivityTime = now; 2450 2451 if (app.activities.size() > 0) { 2452 // Don't want to touch dependent processes that are hosting activities. 2453 return index; 2454 } 2455 2456 int lrui = mLruProcesses.lastIndexOf(app); 2457 if (lrui < 0) { 2458 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2459 + what + " " + obj + " from " + srcApp); 2460 return index; 2461 } 2462 2463 if (lrui >= index) { 2464 // Don't want to cause this to move dependent processes *back* in the 2465 // list as if they were less frequently used. 2466 return index; 2467 } 2468 2469 if (lrui >= mLruProcessActivityStart) { 2470 // Don't want to touch dependent processes that are hosting activities. 2471 return index; 2472 } 2473 2474 mLruProcesses.remove(lrui); 2475 if (index > 0) { 2476 index--; 2477 } 2478 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2479 + " in LRU list: " + app); 2480 mLruProcesses.add(index, app); 2481 return index; 2482 } 2483 2484 final void removeLruProcessLocked(ProcessRecord app) { 2485 int lrui = mLruProcesses.lastIndexOf(app); 2486 if (lrui >= 0) { 2487 if (!app.killed) { 2488 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2489 Process.killProcessQuiet(app.pid); 2490 Process.killProcessGroup(app.info.uid, app.pid); 2491 } 2492 if (lrui <= mLruProcessActivityStart) { 2493 mLruProcessActivityStart--; 2494 } 2495 if (lrui <= mLruProcessServiceStart) { 2496 mLruProcessServiceStart--; 2497 } 2498 mLruProcesses.remove(lrui); 2499 } 2500 } 2501 2502 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2503 ProcessRecord client) { 2504 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2505 || app.treatLikeActivity; 2506 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2507 if (!activityChange && hasActivity) { 2508 // The process has activities, so we are only allowing activity-based adjustments 2509 // to move it. It should be kept in the front of the list with other 2510 // processes that have activities, and we don't want those to change their 2511 // order except due to activity operations. 2512 return; 2513 } 2514 2515 mLruSeq++; 2516 final long now = SystemClock.uptimeMillis(); 2517 app.lastActivityTime = now; 2518 2519 // First a quick reject: if the app is already at the position we will 2520 // put it, then there is nothing to do. 2521 if (hasActivity) { 2522 final int N = mLruProcesses.size(); 2523 if (N > 0 && mLruProcesses.get(N-1) == app) { 2524 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2525 return; 2526 } 2527 } else { 2528 if (mLruProcessServiceStart > 0 2529 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2530 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2531 return; 2532 } 2533 } 2534 2535 int lrui = mLruProcesses.lastIndexOf(app); 2536 2537 if (app.persistent && lrui >= 0) { 2538 // We don't care about the position of persistent processes, as long as 2539 // they are in the list. 2540 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2541 return; 2542 } 2543 2544 /* In progress: compute new position first, so we can avoid doing work 2545 if the process is not actually going to move. Not yet working. 2546 int addIndex; 2547 int nextIndex; 2548 boolean inActivity = false, inService = false; 2549 if (hasActivity) { 2550 // Process has activities, put it at the very tipsy-top. 2551 addIndex = mLruProcesses.size(); 2552 nextIndex = mLruProcessServiceStart; 2553 inActivity = true; 2554 } else if (hasService) { 2555 // Process has services, put it at the top of the service list. 2556 addIndex = mLruProcessActivityStart; 2557 nextIndex = mLruProcessServiceStart; 2558 inActivity = true; 2559 inService = true; 2560 } else { 2561 // Process not otherwise of interest, it goes to the top of the non-service area. 2562 addIndex = mLruProcessServiceStart; 2563 if (client != null) { 2564 int clientIndex = mLruProcesses.lastIndexOf(client); 2565 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2566 + app); 2567 if (clientIndex >= 0 && addIndex > clientIndex) { 2568 addIndex = clientIndex; 2569 } 2570 } 2571 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2572 } 2573 2574 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2575 + mLruProcessActivityStart + "): " + app); 2576 */ 2577 2578 if (lrui >= 0) { 2579 if (lrui < mLruProcessActivityStart) { 2580 mLruProcessActivityStart--; 2581 } 2582 if (lrui < mLruProcessServiceStart) { 2583 mLruProcessServiceStart--; 2584 } 2585 /* 2586 if (addIndex > lrui) { 2587 addIndex--; 2588 } 2589 if (nextIndex > lrui) { 2590 nextIndex--; 2591 } 2592 */ 2593 mLruProcesses.remove(lrui); 2594 } 2595 2596 /* 2597 mLruProcesses.add(addIndex, app); 2598 if (inActivity) { 2599 mLruProcessActivityStart++; 2600 } 2601 if (inService) { 2602 mLruProcessActivityStart++; 2603 } 2604 */ 2605 2606 int nextIndex; 2607 if (hasActivity) { 2608 final int N = mLruProcesses.size(); 2609 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2610 // Process doesn't have activities, but has clients with 2611 // activities... move it up, but one below the top (the top 2612 // should always have a real activity). 2613 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2614 mLruProcesses.add(N-1, app); 2615 // To keep it from spamming the LRU list (by making a bunch of clients), 2616 // we will push down any other entries owned by the app. 2617 final int uid = app.info.uid; 2618 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2619 ProcessRecord subProc = mLruProcesses.get(i); 2620 if (subProc.info.uid == uid) { 2621 // We want to push this one down the list. If the process after 2622 // it is for the same uid, however, don't do so, because we don't 2623 // want them internally to be re-ordered. 2624 if (mLruProcesses.get(i-1).info.uid != uid) { 2625 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2626 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2627 ProcessRecord tmp = mLruProcesses.get(i); 2628 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2629 mLruProcesses.set(i-1, tmp); 2630 i--; 2631 } 2632 } else { 2633 // A gap, we can stop here. 2634 break; 2635 } 2636 } 2637 } else { 2638 // Process has activities, put it at the very tipsy-top. 2639 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2640 mLruProcesses.add(app); 2641 } 2642 nextIndex = mLruProcessServiceStart; 2643 } else if (hasService) { 2644 // Process has services, put it at the top of the service list. 2645 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2646 mLruProcesses.add(mLruProcessActivityStart, app); 2647 nextIndex = mLruProcessServiceStart; 2648 mLruProcessActivityStart++; 2649 } else { 2650 // Process not otherwise of interest, it goes to the top of the non-service area. 2651 int index = mLruProcessServiceStart; 2652 if (client != null) { 2653 // If there is a client, don't allow the process to be moved up higher 2654 // in the list than that client. 2655 int clientIndex = mLruProcesses.lastIndexOf(client); 2656 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2657 + " when updating " + app); 2658 if (clientIndex <= lrui) { 2659 // Don't allow the client index restriction to push it down farther in the 2660 // list than it already is. 2661 clientIndex = lrui; 2662 } 2663 if (clientIndex >= 0 && index > clientIndex) { 2664 index = clientIndex; 2665 } 2666 } 2667 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2668 mLruProcesses.add(index, app); 2669 nextIndex = index-1; 2670 mLruProcessActivityStart++; 2671 mLruProcessServiceStart++; 2672 } 2673 2674 // If the app is currently using a content provider or service, 2675 // bump those processes as well. 2676 for (int j=app.connections.size()-1; j>=0; j--) { 2677 ConnectionRecord cr = app.connections.valueAt(j); 2678 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2679 && cr.binding.service.app != null 2680 && cr.binding.service.app.lruSeq != mLruSeq 2681 && !cr.binding.service.app.persistent) { 2682 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2683 "service connection", cr, app); 2684 } 2685 } 2686 for (int j=app.conProviders.size()-1; j>=0; j--) { 2687 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2688 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2689 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2690 "provider reference", cpr, app); 2691 } 2692 } 2693 } 2694 2695 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2696 if (uid == Process.SYSTEM_UID) { 2697 // The system gets to run in any process. If there are multiple 2698 // processes with the same uid, just pick the first (this 2699 // should never happen). 2700 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2701 if (procs == null) return null; 2702 final int N = procs.size(); 2703 for (int i = 0; i < N; i++) { 2704 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2705 } 2706 } 2707 ProcessRecord proc = mProcessNames.get(processName, uid); 2708 if (false && proc != null && !keepIfLarge 2709 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2710 && proc.lastCachedPss >= 4000) { 2711 // Turn this condition on to cause killing to happen regularly, for testing. 2712 if (proc.baseProcessTracker != null) { 2713 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2714 } 2715 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2716 } else if (proc != null && !keepIfLarge 2717 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2718 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2719 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2720 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2721 if (proc.baseProcessTracker != null) { 2722 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2723 } 2724 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2725 } 2726 } 2727 return proc; 2728 } 2729 2730 void ensurePackageDexOpt(String packageName) { 2731 IPackageManager pm = AppGlobals.getPackageManager(); 2732 try { 2733 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2734 mDidDexOpt = true; 2735 } 2736 } catch (RemoteException e) { 2737 } 2738 } 2739 2740 boolean isNextTransitionForward() { 2741 int transit = mWindowManager.getPendingAppTransition(); 2742 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2743 || transit == AppTransition.TRANSIT_TASK_OPEN 2744 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2745 } 2746 2747 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2748 String processName, String abiOverride, int uid, Runnable crashHandler) { 2749 synchronized(this) { 2750 ApplicationInfo info = new ApplicationInfo(); 2751 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2752 // For isolated processes, the former contains the parent's uid and the latter the 2753 // actual uid of the isolated process. 2754 // In the special case introduced by this method (which is, starting an isolated 2755 // process directly from the SystemServer without an actual parent app process) the 2756 // closest thing to a parent's uid is SYSTEM_UID. 2757 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2758 // the |isolated| logic in the ProcessRecord constructor. 2759 info.uid = Process.SYSTEM_UID; 2760 info.processName = processName; 2761 info.className = entryPoint; 2762 info.packageName = "android"; 2763 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2764 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2765 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2766 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2767 crashHandler); 2768 return proc != null ? proc.pid : 0; 2769 } 2770 } 2771 2772 final ProcessRecord startProcessLocked(String processName, 2773 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2774 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2775 boolean isolated, boolean keepIfLarge) { 2776 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2777 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2778 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2779 null /* crashHandler */); 2780 } 2781 2782 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2783 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2784 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2785 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2786 long startTime = SystemClock.elapsedRealtime(); 2787 ProcessRecord app; 2788 if (!isolated) { 2789 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2790 checkTime(startTime, "startProcess: after getProcessRecord"); 2791 } else { 2792 // If this is an isolated process, it can't re-use an existing process. 2793 app = null; 2794 } 2795 // We don't have to do anything more if: 2796 // (1) There is an existing application record; and 2797 // (2) The caller doesn't think it is dead, OR there is no thread 2798 // object attached to it so we know it couldn't have crashed; and 2799 // (3) There is a pid assigned to it, so it is either starting or 2800 // already running. 2801 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2802 + " app=" + app + " knownToBeDead=" + knownToBeDead 2803 + " thread=" + (app != null ? app.thread : null) 2804 + " pid=" + (app != null ? app.pid : -1)); 2805 if (app != null && app.pid > 0) { 2806 if (!knownToBeDead || app.thread == null) { 2807 // We already have the app running, or are waiting for it to 2808 // come up (we have a pid but not yet its thread), so keep it. 2809 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2810 // If this is a new package in the process, add the package to the list 2811 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2812 checkTime(startTime, "startProcess: done, added package to proc"); 2813 return app; 2814 } 2815 2816 // An application record is attached to a previous process, 2817 // clean it up now. 2818 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2819 checkTime(startTime, "startProcess: bad proc running, killing"); 2820 Process.killProcessGroup(app.info.uid, app.pid); 2821 handleAppDiedLocked(app, true, true); 2822 checkTime(startTime, "startProcess: done killing old proc"); 2823 } 2824 2825 String hostingNameStr = hostingName != null 2826 ? hostingName.flattenToShortString() : null; 2827 2828 if (!isolated) { 2829 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2830 // If we are in the background, then check to see if this process 2831 // is bad. If so, we will just silently fail. 2832 if (mBadProcesses.get(info.processName, info.uid) != null) { 2833 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2834 + "/" + info.processName); 2835 return null; 2836 } 2837 } else { 2838 // When the user is explicitly starting a process, then clear its 2839 // crash count so that we won't make it bad until they see at 2840 // least one crash dialog again, and make the process good again 2841 // if it had been bad. 2842 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2843 + "/" + info.processName); 2844 mProcessCrashTimes.remove(info.processName, info.uid); 2845 if (mBadProcesses.get(info.processName, info.uid) != null) { 2846 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2847 UserHandle.getUserId(info.uid), info.uid, 2848 info.processName); 2849 mBadProcesses.remove(info.processName, info.uid); 2850 if (app != null) { 2851 app.bad = false; 2852 } 2853 } 2854 } 2855 } 2856 2857 if (app == null) { 2858 checkTime(startTime, "startProcess: creating new process record"); 2859 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2860 if (app == null) { 2861 Slog.w(TAG, "Failed making new process record for " 2862 + processName + "/" + info.uid + " isolated=" + isolated); 2863 return null; 2864 } 2865 app.crashHandler = crashHandler; 2866 mProcessNames.put(processName, app.uid, app); 2867 if (isolated) { 2868 mIsolatedProcesses.put(app.uid, app); 2869 } 2870 checkTime(startTime, "startProcess: done creating new process record"); 2871 } else { 2872 // If this is a new package in the process, add the package to the list 2873 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2874 checkTime(startTime, "startProcess: added package to existing proc"); 2875 } 2876 2877 // If the system is not ready yet, then hold off on starting this 2878 // process until it is. 2879 if (!mProcessesReady 2880 && !isAllowedWhileBooting(info) 2881 && !allowWhileBooting) { 2882 if (!mProcessesOnHold.contains(app)) { 2883 mProcessesOnHold.add(app); 2884 } 2885 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2886 checkTime(startTime, "startProcess: returning with proc on hold"); 2887 return app; 2888 } 2889 2890 checkTime(startTime, "startProcess: stepping in to startProcess"); 2891 startProcessLocked( 2892 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2893 checkTime(startTime, "startProcess: done starting proc!"); 2894 return (app.pid != 0) ? app : null; 2895 } 2896 2897 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2898 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2899 } 2900 2901 private final void startProcessLocked(ProcessRecord app, 2902 String hostingType, String hostingNameStr) { 2903 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2904 null /* entryPoint */, null /* entryPointArgs */); 2905 } 2906 2907 private final void startProcessLocked(ProcessRecord app, String hostingType, 2908 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2909 long startTime = SystemClock.elapsedRealtime(); 2910 if (app.pid > 0 && app.pid != MY_PID) { 2911 checkTime(startTime, "startProcess: removing from pids map"); 2912 synchronized (mPidsSelfLocked) { 2913 mPidsSelfLocked.remove(app.pid); 2914 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2915 } 2916 checkTime(startTime, "startProcess: done removing from pids map"); 2917 app.setPid(0); 2918 } 2919 2920 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2921 "startProcessLocked removing on hold: " + app); 2922 mProcessesOnHold.remove(app); 2923 2924 checkTime(startTime, "startProcess: starting to update cpu stats"); 2925 updateCpuStats(); 2926 checkTime(startTime, "startProcess: done updating cpu stats"); 2927 2928 try { 2929 int uid = app.uid; 2930 2931 int[] gids = null; 2932 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2933 if (!app.isolated) { 2934 int[] permGids = null; 2935 try { 2936 checkTime(startTime, "startProcess: getting gids from package manager"); 2937 final PackageManager pm = mContext.getPackageManager(); 2938 permGids = pm.getPackageGids(app.info.packageName); 2939 2940 if (Environment.isExternalStorageEmulated()) { 2941 checkTime(startTime, "startProcess: checking external storage perm"); 2942 if (pm.checkPermission( 2943 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2944 app.info.packageName) == PERMISSION_GRANTED) { 2945 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2946 } else { 2947 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2948 } 2949 } 2950 } catch (PackageManager.NameNotFoundException e) { 2951 Slog.w(TAG, "Unable to retrieve gids", e); 2952 } 2953 2954 /* 2955 * Add shared application and profile GIDs so applications can share some 2956 * resources like shared libraries and access user-wide resources 2957 */ 2958 if (permGids == null) { 2959 gids = new int[2]; 2960 } else { 2961 gids = new int[permGids.length + 2]; 2962 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2963 } 2964 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2965 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2966 } 2967 checkTime(startTime, "startProcess: building args"); 2968 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2969 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2970 && mTopComponent != null 2971 && app.processName.equals(mTopComponent.getPackageName())) { 2972 uid = 0; 2973 } 2974 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2975 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2976 uid = 0; 2977 } 2978 } 2979 int debugFlags = 0; 2980 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2981 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2982 // Also turn on CheckJNI for debuggable apps. It's quite 2983 // awkward to turn on otherwise. 2984 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2985 } 2986 // Run the app in safe mode if its manifest requests so or the 2987 // system is booted in safe mode. 2988 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2989 mSafeMode == true) { 2990 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2991 } 2992 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2993 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2994 } 2995 String jitDebugProperty = SystemProperties.get("debug.usejit"); 2996 if ("true".equals(jitDebugProperty)) { 2997 debugFlags |= Zygote.DEBUG_ENABLE_JIT; 2998 } else if (!"false".equals(jitDebugProperty)) { 2999 // If we didn't force disable by setting false, defer to the dalvik vm options. 3000 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) { 3001 debugFlags |= Zygote.DEBUG_ENABLE_JIT; 3002 } 3003 } 3004 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3005 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3006 } 3007 if ("1".equals(SystemProperties.get("debug.assert"))) { 3008 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3009 } 3010 3011 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3012 if (requiredAbi == null) { 3013 requiredAbi = Build.SUPPORTED_ABIS[0]; 3014 } 3015 3016 String instructionSet = null; 3017 if (app.info.primaryCpuAbi != null) { 3018 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3019 } 3020 3021 app.gids = gids; 3022 app.requiredAbi = requiredAbi; 3023 app.instructionSet = instructionSet; 3024 3025 // Start the process. It will either succeed and return a result containing 3026 // the PID of the new process, or else throw a RuntimeException. 3027 boolean isActivityProcess = (entryPoint == null); 3028 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3029 checkTime(startTime, "startProcess: asking zygote to start proc"); 3030 Process.ProcessStartResult startResult = Process.start(entryPoint, 3031 app.processName, uid, uid, gids, debugFlags, mountExternal, 3032 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3033 app.info.dataDir, entryPointArgs); 3034 checkTime(startTime, "startProcess: returned from zygote!"); 3035 3036 if (app.isolated) { 3037 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3038 } 3039 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3040 checkTime(startTime, "startProcess: done updating battery stats"); 3041 3042 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3043 UserHandle.getUserId(uid), startResult.pid, uid, 3044 app.processName, hostingType, 3045 hostingNameStr != null ? hostingNameStr : ""); 3046 3047 if (app.persistent) { 3048 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3049 } 3050 3051 checkTime(startTime, "startProcess: building log message"); 3052 StringBuilder buf = mStringBuilder; 3053 buf.setLength(0); 3054 buf.append("Start proc "); 3055 buf.append(startResult.pid); 3056 buf.append(':'); 3057 buf.append(app.processName); 3058 buf.append('/'); 3059 UserHandle.formatUid(buf, uid); 3060 if (!isActivityProcess) { 3061 buf.append(" ["); 3062 buf.append(entryPoint); 3063 buf.append("]"); 3064 } 3065 buf.append(" for "); 3066 buf.append(hostingType); 3067 if (hostingNameStr != null) { 3068 buf.append(" "); 3069 buf.append(hostingNameStr); 3070 } 3071 Slog.i(TAG, buf.toString()); 3072 app.setPid(startResult.pid); 3073 app.usingWrapper = startResult.usingWrapper; 3074 app.removed = false; 3075 app.killed = false; 3076 app.killedByAm = false; 3077 checkTime(startTime, "startProcess: starting to update pids map"); 3078 synchronized (mPidsSelfLocked) { 3079 this.mPidsSelfLocked.put(startResult.pid, app); 3080 if (isActivityProcess) { 3081 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3082 msg.obj = app; 3083 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3084 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3085 } 3086 } 3087 checkTime(startTime, "startProcess: done updating pids map"); 3088 } catch (RuntimeException e) { 3089 // XXX do better error recovery. 3090 app.setPid(0); 3091 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3092 if (app.isolated) { 3093 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3094 } 3095 Slog.e(TAG, "Failure starting process " + app.processName, e); 3096 } 3097 } 3098 3099 void updateUsageStats(ActivityRecord component, boolean resumed) { 3100 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3101 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3102 if (resumed) { 3103 if (mUsageStatsService != null) { 3104 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3105 UsageEvents.Event.MOVE_TO_FOREGROUND); 3106 } 3107 synchronized (stats) { 3108 stats.noteActivityResumedLocked(component.app.uid); 3109 } 3110 } else { 3111 if (mUsageStatsService != null) { 3112 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3113 UsageEvents.Event.MOVE_TO_BACKGROUND); 3114 } 3115 synchronized (stats) { 3116 stats.noteActivityPausedLocked(component.app.uid); 3117 } 3118 } 3119 } 3120 3121 Intent getHomeIntent() { 3122 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3123 intent.setComponent(mTopComponent); 3124 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3125 intent.addCategory(Intent.CATEGORY_HOME); 3126 } 3127 return intent; 3128 } 3129 3130 boolean startHomeActivityLocked(int userId, String reason) { 3131 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3132 && mTopAction == null) { 3133 // We are running in factory test mode, but unable to find 3134 // the factory test app, so just sit around displaying the 3135 // error message and don't try to start anything. 3136 return false; 3137 } 3138 Intent intent = getHomeIntent(); 3139 ActivityInfo aInfo = 3140 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3141 if (aInfo != null) { 3142 intent.setComponent(new ComponentName( 3143 aInfo.applicationInfo.packageName, aInfo.name)); 3144 // Don't do this if the home app is currently being 3145 // instrumented. 3146 aInfo = new ActivityInfo(aInfo); 3147 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3148 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3149 aInfo.applicationInfo.uid, true); 3150 if (app == null || app.instrumentationClass == null) { 3151 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3152 mStackSupervisor.startHomeActivity(intent, aInfo, reason); 3153 } 3154 } 3155 3156 return true; 3157 } 3158 3159 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3160 ActivityInfo ai = null; 3161 ComponentName comp = intent.getComponent(); 3162 try { 3163 if (comp != null) { 3164 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3165 } else { 3166 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3167 intent, 3168 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3169 flags, userId); 3170 3171 if (info != null) { 3172 ai = info.activityInfo; 3173 } 3174 } 3175 } catch (RemoteException e) { 3176 // ignore 3177 } 3178 3179 return ai; 3180 } 3181 3182 /** 3183 * Starts the "new version setup screen" if appropriate. 3184 */ 3185 void startSetupActivityLocked() { 3186 // Only do this once per boot. 3187 if (mCheckedForSetup) { 3188 return; 3189 } 3190 3191 // We will show this screen if the current one is a different 3192 // version than the last one shown, and we are not running in 3193 // low-level factory test mode. 3194 final ContentResolver resolver = mContext.getContentResolver(); 3195 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3196 Settings.Global.getInt(resolver, 3197 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3198 mCheckedForSetup = true; 3199 3200 // See if we should be showing the platform update setup UI. 3201 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3202 List<ResolveInfo> ris = mContext.getPackageManager() 3203 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3204 3205 // We don't allow third party apps to replace this. 3206 ResolveInfo ri = null; 3207 for (int i=0; ris != null && i<ris.size(); i++) { 3208 if ((ris.get(i).activityInfo.applicationInfo.flags 3209 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3210 ri = ris.get(i); 3211 break; 3212 } 3213 } 3214 3215 if (ri != null) { 3216 String vers = ri.activityInfo.metaData != null 3217 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3218 : null; 3219 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3220 vers = ri.activityInfo.applicationInfo.metaData.getString( 3221 Intent.METADATA_SETUP_VERSION); 3222 } 3223 String lastVers = Settings.Secure.getString( 3224 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3225 if (vers != null && !vers.equals(lastVers)) { 3226 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3227 intent.setComponent(new ComponentName( 3228 ri.activityInfo.packageName, ri.activityInfo.name)); 3229 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3230 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3231 null); 3232 } 3233 } 3234 } 3235 } 3236 3237 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3238 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3239 } 3240 3241 void enforceNotIsolatedCaller(String caller) { 3242 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3243 throw new SecurityException("Isolated process not allowed to call " + caller); 3244 } 3245 } 3246 3247 void enforceShellRestriction(String restriction, int userHandle) { 3248 if (Binder.getCallingUid() == Process.SHELL_UID) { 3249 if (userHandle < 0 3250 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3251 throw new SecurityException("Shell does not have permission to access user " 3252 + userHandle); 3253 } 3254 } 3255 } 3256 3257 @Override 3258 public int getFrontActivityScreenCompatMode() { 3259 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3260 synchronized (this) { 3261 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3262 } 3263 } 3264 3265 @Override 3266 public void setFrontActivityScreenCompatMode(int mode) { 3267 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3268 "setFrontActivityScreenCompatMode"); 3269 synchronized (this) { 3270 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3271 } 3272 } 3273 3274 @Override 3275 public int getPackageScreenCompatMode(String packageName) { 3276 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3277 synchronized (this) { 3278 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3279 } 3280 } 3281 3282 @Override 3283 public void setPackageScreenCompatMode(String packageName, int mode) { 3284 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3285 "setPackageScreenCompatMode"); 3286 synchronized (this) { 3287 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3288 } 3289 } 3290 3291 @Override 3292 public boolean getPackageAskScreenCompat(String packageName) { 3293 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3294 synchronized (this) { 3295 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3296 } 3297 } 3298 3299 @Override 3300 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3301 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3302 "setPackageAskScreenCompat"); 3303 synchronized (this) { 3304 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3305 } 3306 } 3307 3308 private void dispatchProcessesChanged() { 3309 int N; 3310 synchronized (this) { 3311 N = mPendingProcessChanges.size(); 3312 if (mActiveProcessChanges.length < N) { 3313 mActiveProcessChanges = new ProcessChangeItem[N]; 3314 } 3315 mPendingProcessChanges.toArray(mActiveProcessChanges); 3316 mAvailProcessChanges.addAll(mPendingProcessChanges); 3317 mPendingProcessChanges.clear(); 3318 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3319 } 3320 3321 int i = mProcessObservers.beginBroadcast(); 3322 while (i > 0) { 3323 i--; 3324 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3325 if (observer != null) { 3326 try { 3327 for (int j=0; j<N; j++) { 3328 ProcessChangeItem item = mActiveProcessChanges[j]; 3329 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3330 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3331 + item.pid + " uid=" + item.uid + ": " 3332 + item.foregroundActivities); 3333 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3334 item.foregroundActivities); 3335 } 3336 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3337 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3338 + item.pid + " uid=" + item.uid + ": " + item.processState); 3339 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3340 } 3341 } 3342 } catch (RemoteException e) { 3343 } 3344 } 3345 } 3346 mProcessObservers.finishBroadcast(); 3347 } 3348 3349 private void dispatchProcessDied(int pid, int uid) { 3350 int i = mProcessObservers.beginBroadcast(); 3351 while (i > 0) { 3352 i--; 3353 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3354 if (observer != null) { 3355 try { 3356 observer.onProcessDied(pid, uid); 3357 } catch (RemoteException e) { 3358 } 3359 } 3360 } 3361 mProcessObservers.finishBroadcast(); 3362 } 3363 3364 @Override 3365 public final int startActivity(IApplicationThread caller, String callingPackage, 3366 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3367 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3368 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3369 resultWho, requestCode, startFlags, profilerInfo, options, 3370 UserHandle.getCallingUserId()); 3371 } 3372 3373 @Override 3374 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3375 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3376 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3377 enforceNotIsolatedCaller("startActivity"); 3378 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3379 false, ALLOW_FULL_ONLY, "startActivity", null); 3380 // TODO: Switch to user app stacks here. 3381 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3382 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3383 profilerInfo, null, null, options, userId, null, null); 3384 } 3385 3386 @Override 3387 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3388 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3389 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3390 3391 // This is very dangerous -- it allows you to perform a start activity (including 3392 // permission grants) as any app that may launch one of your own activities. So 3393 // we will only allow this to be done from activities that are part of the core framework, 3394 // and then only when they are running as the system. 3395 final ActivityRecord sourceRecord; 3396 final int targetUid; 3397 final String targetPackage; 3398 synchronized (this) { 3399 if (resultTo == null) { 3400 throw new SecurityException("Must be called from an activity"); 3401 } 3402 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3403 if (sourceRecord == null) { 3404 throw new SecurityException("Called with bad activity token: " + resultTo); 3405 } 3406 if (!sourceRecord.info.packageName.equals("android")) { 3407 throw new SecurityException( 3408 "Must be called from an activity that is declared in the android package"); 3409 } 3410 if (sourceRecord.app == null) { 3411 throw new SecurityException("Called without a process attached to activity"); 3412 } 3413 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3414 // This is still okay, as long as this activity is running under the 3415 // uid of the original calling activity. 3416 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3417 throw new SecurityException( 3418 "Calling activity in uid " + sourceRecord.app.uid 3419 + " must be system uid or original calling uid " 3420 + sourceRecord.launchedFromUid); 3421 } 3422 } 3423 targetUid = sourceRecord.launchedFromUid; 3424 targetPackage = sourceRecord.launchedFromPackage; 3425 } 3426 3427 if (userId == UserHandle.USER_NULL) { 3428 userId = UserHandle.getUserId(sourceRecord.app.uid); 3429 } 3430 3431 // TODO: Switch to user app stacks here. 3432 try { 3433 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3434 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3435 null, null, options, userId, null, null); 3436 return ret; 3437 } catch (SecurityException e) { 3438 // XXX need to figure out how to propagate to original app. 3439 // A SecurityException here is generally actually a fault of the original 3440 // calling activity (such as a fairly granting permissions), so propagate it 3441 // back to them. 3442 /* 3443 StringBuilder msg = new StringBuilder(); 3444 msg.append("While launching"); 3445 msg.append(intent.toString()); 3446 msg.append(": "); 3447 msg.append(e.getMessage()); 3448 */ 3449 throw e; 3450 } 3451 } 3452 3453 @Override 3454 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3455 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3456 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3457 enforceNotIsolatedCaller("startActivityAndWait"); 3458 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3459 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3460 WaitResult res = new WaitResult(); 3461 // TODO: Switch to user app stacks here. 3462 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3463 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3464 options, userId, null, null); 3465 return res; 3466 } 3467 3468 @Override 3469 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3470 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3471 int startFlags, Configuration config, Bundle options, int userId) { 3472 enforceNotIsolatedCaller("startActivityWithConfig"); 3473 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3474 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3475 // TODO: Switch to user app stacks here. 3476 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3477 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3478 null, null, config, options, userId, null, null); 3479 return ret; 3480 } 3481 3482 @Override 3483 public int startActivityIntentSender(IApplicationThread caller, 3484 IntentSender intent, Intent fillInIntent, String resolvedType, 3485 IBinder resultTo, String resultWho, int requestCode, 3486 int flagsMask, int flagsValues, Bundle options) { 3487 enforceNotIsolatedCaller("startActivityIntentSender"); 3488 // Refuse possible leaked file descriptors 3489 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3490 throw new IllegalArgumentException("File descriptors passed in Intent"); 3491 } 3492 3493 IIntentSender sender = intent.getTarget(); 3494 if (!(sender instanceof PendingIntentRecord)) { 3495 throw new IllegalArgumentException("Bad PendingIntent object"); 3496 } 3497 3498 PendingIntentRecord pir = (PendingIntentRecord)sender; 3499 3500 synchronized (this) { 3501 // If this is coming from the currently resumed activity, it is 3502 // effectively saying that app switches are allowed at this point. 3503 final ActivityStack stack = getFocusedStack(); 3504 if (stack.mResumedActivity != null && 3505 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3506 mAppSwitchesAllowedTime = 0; 3507 } 3508 } 3509 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3510 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3511 return ret; 3512 } 3513 3514 @Override 3515 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3516 Intent intent, String resolvedType, IVoiceInteractionSession session, 3517 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3518 Bundle options, int userId) { 3519 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3520 != PackageManager.PERMISSION_GRANTED) { 3521 String msg = "Permission Denial: startVoiceActivity() from pid=" 3522 + Binder.getCallingPid() 3523 + ", uid=" + Binder.getCallingUid() 3524 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3525 Slog.w(TAG, msg); 3526 throw new SecurityException(msg); 3527 } 3528 if (session == null || interactor == null) { 3529 throw new NullPointerException("null session or interactor"); 3530 } 3531 userId = handleIncomingUser(callingPid, callingUid, userId, 3532 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3533 // TODO: Switch to user app stacks here. 3534 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3535 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3536 null, options, userId, null, null); 3537 } 3538 3539 @Override 3540 public boolean startNextMatchingActivity(IBinder callingActivity, 3541 Intent intent, Bundle options) { 3542 // Refuse possible leaked file descriptors 3543 if (intent != null && intent.hasFileDescriptors() == true) { 3544 throw new IllegalArgumentException("File descriptors passed in Intent"); 3545 } 3546 3547 synchronized (this) { 3548 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3549 if (r == null) { 3550 ActivityOptions.abort(options); 3551 return false; 3552 } 3553 if (r.app == null || r.app.thread == null) { 3554 // The caller is not running... d'oh! 3555 ActivityOptions.abort(options); 3556 return false; 3557 } 3558 intent = new Intent(intent); 3559 // The caller is not allowed to change the data. 3560 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3561 // And we are resetting to find the next component... 3562 intent.setComponent(null); 3563 3564 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3565 3566 ActivityInfo aInfo = null; 3567 try { 3568 List<ResolveInfo> resolves = 3569 AppGlobals.getPackageManager().queryIntentActivities( 3570 intent, r.resolvedType, 3571 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3572 UserHandle.getCallingUserId()); 3573 3574 // Look for the original activity in the list... 3575 final int N = resolves != null ? resolves.size() : 0; 3576 for (int i=0; i<N; i++) { 3577 ResolveInfo rInfo = resolves.get(i); 3578 if (rInfo.activityInfo.packageName.equals(r.packageName) 3579 && rInfo.activityInfo.name.equals(r.info.name)) { 3580 // We found the current one... the next matching is 3581 // after it. 3582 i++; 3583 if (i<N) { 3584 aInfo = resolves.get(i).activityInfo; 3585 } 3586 if (debug) { 3587 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3588 + "/" + r.info.name); 3589 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3590 + "/" + aInfo.name); 3591 } 3592 break; 3593 } 3594 } 3595 } catch (RemoteException e) { 3596 } 3597 3598 if (aInfo == null) { 3599 // Nobody who is next! 3600 ActivityOptions.abort(options); 3601 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3602 return false; 3603 } 3604 3605 intent.setComponent(new ComponentName( 3606 aInfo.applicationInfo.packageName, aInfo.name)); 3607 intent.setFlags(intent.getFlags()&~( 3608 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3609 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3610 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3611 Intent.FLAG_ACTIVITY_NEW_TASK)); 3612 3613 // Okay now we need to start the new activity, replacing the 3614 // currently running activity. This is a little tricky because 3615 // we want to start the new one as if the current one is finished, 3616 // but not finish the current one first so that there is no flicker. 3617 // And thus... 3618 final boolean wasFinishing = r.finishing; 3619 r.finishing = true; 3620 3621 // Propagate reply information over to the new activity. 3622 final ActivityRecord resultTo = r.resultTo; 3623 final String resultWho = r.resultWho; 3624 final int requestCode = r.requestCode; 3625 r.resultTo = null; 3626 if (resultTo != null) { 3627 resultTo.removeResultsLocked(r, resultWho, requestCode); 3628 } 3629 3630 final long origId = Binder.clearCallingIdentity(); 3631 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3632 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3633 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3634 -1, r.launchedFromUid, 0, options, false, null, null, null); 3635 Binder.restoreCallingIdentity(origId); 3636 3637 r.finishing = wasFinishing; 3638 if (res != ActivityManager.START_SUCCESS) { 3639 return false; 3640 } 3641 return true; 3642 } 3643 } 3644 3645 @Override 3646 public final int startActivityFromRecents(int taskId, Bundle options) { 3647 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3648 String msg = "Permission Denial: startActivityFromRecents called without " + 3649 START_TASKS_FROM_RECENTS; 3650 Slog.w(TAG, msg); 3651 throw new SecurityException(msg); 3652 } 3653 return startActivityFromRecentsInner(taskId, options); 3654 } 3655 3656 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3657 final TaskRecord task; 3658 final int callingUid; 3659 final String callingPackage; 3660 final Intent intent; 3661 final int userId; 3662 synchronized (this) { 3663 task = recentTaskForIdLocked(taskId); 3664 if (task == null) { 3665 throw new IllegalArgumentException("Task " + taskId + " not found."); 3666 } 3667 if (task.getRootActivity() != null) { 3668 moveTaskToFrontLocked(task.taskId, 0, null); 3669 return ActivityManager.START_TASK_TO_FRONT; 3670 } 3671 callingUid = task.mCallingUid; 3672 callingPackage = task.mCallingPackage; 3673 intent = task.intent; 3674 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3675 userId = task.userId; 3676 } 3677 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3678 options, userId, null, task); 3679 } 3680 3681 final int startActivityInPackage(int uid, String callingPackage, 3682 Intent intent, String resolvedType, IBinder resultTo, 3683 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3684 IActivityContainer container, TaskRecord inTask) { 3685 3686 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3687 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3688 3689 // TODO: Switch to user app stacks here. 3690 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3691 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3692 null, null, null, options, userId, container, inTask); 3693 return ret; 3694 } 3695 3696 @Override 3697 public final int startActivities(IApplicationThread caller, String callingPackage, 3698 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3699 int userId) { 3700 enforceNotIsolatedCaller("startActivities"); 3701 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3702 false, ALLOW_FULL_ONLY, "startActivity", null); 3703 // TODO: Switch to user app stacks here. 3704 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3705 resolvedTypes, resultTo, options, userId); 3706 return ret; 3707 } 3708 3709 final int startActivitiesInPackage(int uid, String callingPackage, 3710 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3711 Bundle options, int userId) { 3712 3713 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3714 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3715 // TODO: Switch to user app stacks here. 3716 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3717 resultTo, options, userId); 3718 return ret; 3719 } 3720 3721 //explicitly remove thd old information in mRecentTasks when removing existing user. 3722 private void removeRecentTasksForUserLocked(int userId) { 3723 if(userId <= 0) { 3724 Slog.i(TAG, "Can't remove recent task on user " + userId); 3725 return; 3726 } 3727 3728 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3729 TaskRecord tr = mRecentTasks.get(i); 3730 if (tr.userId == userId) { 3731 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3732 + " when finishing user" + userId); 3733 mRecentTasks.remove(i); 3734 tr.removedFromRecents(); 3735 } 3736 } 3737 3738 // Remove tasks from persistent storage. 3739 notifyTaskPersisterLocked(null, true); 3740 } 3741 3742 // Sort by taskId 3743 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3744 @Override 3745 public int compare(TaskRecord lhs, TaskRecord rhs) { 3746 return rhs.taskId - lhs.taskId; 3747 } 3748 }; 3749 3750 // Extract the affiliates of the chain containing mRecentTasks[start]. 3751 private int processNextAffiliateChainLocked(int start) { 3752 final TaskRecord startTask = mRecentTasks.get(start); 3753 final int affiliateId = startTask.mAffiliatedTaskId; 3754 3755 // Quick identification of isolated tasks. I.e. those not launched behind. 3756 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3757 startTask.mNextAffiliate == null) { 3758 // There is still a slim chance that there are other tasks that point to this task 3759 // and that the chain is so messed up that this task no longer points to them but 3760 // the gain of this optimization outweighs the risk. 3761 startTask.inRecents = true; 3762 return start + 1; 3763 } 3764 3765 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3766 mTmpRecents.clear(); 3767 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3768 final TaskRecord task = mRecentTasks.get(i); 3769 if (task.mAffiliatedTaskId == affiliateId) { 3770 mRecentTasks.remove(i); 3771 mTmpRecents.add(task); 3772 } 3773 } 3774 3775 // Sort them all by taskId. That is the order they were create in and that order will 3776 // always be correct. 3777 Collections.sort(mTmpRecents, mTaskRecordComparator); 3778 3779 // Go through and fix up the linked list. 3780 // The first one is the end of the chain and has no next. 3781 final TaskRecord first = mTmpRecents.get(0); 3782 first.inRecents = true; 3783 if (first.mNextAffiliate != null) { 3784 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3785 first.setNextAffiliate(null); 3786 notifyTaskPersisterLocked(first, false); 3787 } 3788 // Everything in the middle is doubly linked from next to prev. 3789 final int tmpSize = mTmpRecents.size(); 3790 for (int i = 0; i < tmpSize - 1; ++i) { 3791 final TaskRecord next = mTmpRecents.get(i); 3792 final TaskRecord prev = mTmpRecents.get(i + 1); 3793 if (next.mPrevAffiliate != prev) { 3794 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3795 " setting prev=" + prev); 3796 next.setPrevAffiliate(prev); 3797 notifyTaskPersisterLocked(next, false); 3798 } 3799 if (prev.mNextAffiliate != next) { 3800 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3801 " setting next=" + next); 3802 prev.setNextAffiliate(next); 3803 notifyTaskPersisterLocked(prev, false); 3804 } 3805 prev.inRecents = true; 3806 } 3807 // The last one is the beginning of the list and has no prev. 3808 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3809 if (last.mPrevAffiliate != null) { 3810 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3811 last.setPrevAffiliate(null); 3812 notifyTaskPersisterLocked(last, false); 3813 } 3814 3815 // Insert the group back into mRecentTasks at start. 3816 mRecentTasks.addAll(start, mTmpRecents); 3817 3818 // Let the caller know where we left off. 3819 return start + tmpSize; 3820 } 3821 3822 /** 3823 * Update the recent tasks lists: make sure tasks should still be here (their 3824 * applications / activities still exist), update their availability, fixup ordering 3825 * of affiliations. 3826 */ 3827 void cleanupRecentTasksLocked(int userId) { 3828 if (mRecentTasks == null) { 3829 // Happens when called from the packagemanager broadcast before boot. 3830 return; 3831 } 3832 3833 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3834 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3835 final IPackageManager pm = AppGlobals.getPackageManager(); 3836 final ActivityInfo dummyAct = new ActivityInfo(); 3837 final ApplicationInfo dummyApp = new ApplicationInfo(); 3838 3839 int N = mRecentTasks.size(); 3840 3841 int[] users = userId == UserHandle.USER_ALL 3842 ? getUsersLocked() : new int[] { userId }; 3843 for (int user : users) { 3844 for (int i = 0; i < N; i++) { 3845 TaskRecord task = mRecentTasks.get(i); 3846 if (task.userId != user) { 3847 // Only look at tasks for the user ID of interest. 3848 continue; 3849 } 3850 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3851 // This situation is broken, and we should just get rid of it now. 3852 mRecentTasks.remove(i); 3853 task.removedFromRecents(); 3854 i--; 3855 N--; 3856 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3857 continue; 3858 } 3859 // Check whether this activity is currently available. 3860 if (task.realActivity != null) { 3861 ActivityInfo ai = availActCache.get(task.realActivity); 3862 if (ai == null) { 3863 try { 3864 ai = pm.getActivityInfo(task.realActivity, 3865 PackageManager.GET_UNINSTALLED_PACKAGES 3866 | PackageManager.GET_DISABLED_COMPONENTS, user); 3867 } catch (RemoteException e) { 3868 // Will never happen. 3869 continue; 3870 } 3871 if (ai == null) { 3872 ai = dummyAct; 3873 } 3874 availActCache.put(task.realActivity, ai); 3875 } 3876 if (ai == dummyAct) { 3877 // This could be either because the activity no longer exists, or the 3878 // app is temporarily gone. For the former we want to remove the recents 3879 // entry; for the latter we want to mark it as unavailable. 3880 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3881 if (app == null) { 3882 try { 3883 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3884 PackageManager.GET_UNINSTALLED_PACKAGES 3885 | PackageManager.GET_DISABLED_COMPONENTS, user); 3886 } catch (RemoteException e) { 3887 // Will never happen. 3888 continue; 3889 } 3890 if (app == null) { 3891 app = dummyApp; 3892 } 3893 availAppCache.put(task.realActivity.getPackageName(), app); 3894 } 3895 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3896 // Doesn't exist any more! Good-bye. 3897 mRecentTasks.remove(i); 3898 task.removedFromRecents(); 3899 i--; 3900 N--; 3901 Slog.w(TAG, "Removing no longer valid recent: " + task); 3902 continue; 3903 } else { 3904 // Otherwise just not available for now. 3905 if (task.isAvailable) { 3906 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3907 + task); 3908 } 3909 task.isAvailable = false; 3910 } 3911 } else { 3912 if (!ai.enabled || !ai.applicationInfo.enabled 3913 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3914 if (task.isAvailable) { 3915 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3916 + task + " (enabled=" + ai.enabled + "/" 3917 + ai.applicationInfo.enabled + " flags=" 3918 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3919 } 3920 task.isAvailable = false; 3921 } else { 3922 if (!task.isAvailable) { 3923 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3924 + task); 3925 } 3926 task.isAvailable = true; 3927 } 3928 } 3929 } 3930 } 3931 } 3932 3933 // Verify the affiliate chain for each task. 3934 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3935 } 3936 3937 mTmpRecents.clear(); 3938 // mRecentTasks is now in sorted, affiliated order. 3939 } 3940 3941 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3942 int N = mRecentTasks.size(); 3943 TaskRecord top = task; 3944 int topIndex = taskIndex; 3945 while (top.mNextAffiliate != null && topIndex > 0) { 3946 top = top.mNextAffiliate; 3947 topIndex--; 3948 } 3949 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3950 + topIndex + " from intial " + taskIndex); 3951 // Find the end of the chain, doing a sanity check along the way. 3952 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3953 int endIndex = topIndex; 3954 TaskRecord prev = top; 3955 while (endIndex < N) { 3956 TaskRecord cur = mRecentTasks.get(endIndex); 3957 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3958 + endIndex + " " + cur); 3959 if (cur == top) { 3960 // Verify start of the chain. 3961 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3962 Slog.wtf(TAG, "Bad chain @" + endIndex 3963 + ": first task has next affiliate: " + prev); 3964 sane = false; 3965 break; 3966 } 3967 } else { 3968 // Verify middle of the chain's next points back to the one before. 3969 if (cur.mNextAffiliate != prev 3970 || cur.mNextAffiliateTaskId != prev.taskId) { 3971 Slog.wtf(TAG, "Bad chain @" + endIndex 3972 + ": middle task " + cur + " @" + endIndex 3973 + " has bad next affiliate " 3974 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3975 + ", expected " + prev); 3976 sane = false; 3977 break; 3978 } 3979 } 3980 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3981 // Chain ends here. 3982 if (cur.mPrevAffiliate != null) { 3983 Slog.wtf(TAG, "Bad chain @" + endIndex 3984 + ": last task " + cur + " has previous affiliate " 3985 + cur.mPrevAffiliate); 3986 sane = false; 3987 } 3988 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3989 break; 3990 } else { 3991 // Verify middle of the chain's prev points to a valid item. 3992 if (cur.mPrevAffiliate == null) { 3993 Slog.wtf(TAG, "Bad chain @" + endIndex 3994 + ": task " + cur + " has previous affiliate " 3995 + cur.mPrevAffiliate + " but should be id " 3996 + cur.mPrevAffiliate); 3997 sane = false; 3998 break; 3999 } 4000 } 4001 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4002 Slog.wtf(TAG, "Bad chain @" + endIndex 4003 + ": task " + cur + " has affiliated id " 4004 + cur.mAffiliatedTaskId + " but should be " 4005 + task.mAffiliatedTaskId); 4006 sane = false; 4007 break; 4008 } 4009 prev = cur; 4010 endIndex++; 4011 if (endIndex >= N) { 4012 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4013 + ": last task " + prev); 4014 sane = false; 4015 break; 4016 } 4017 } 4018 if (sane) { 4019 if (endIndex < taskIndex) { 4020 Slog.wtf(TAG, "Bad chain @" + endIndex 4021 + ": did not extend to task " + task + " @" + taskIndex); 4022 sane = false; 4023 } 4024 } 4025 if (sane) { 4026 // All looks good, we can just move all of the affiliated tasks 4027 // to the top. 4028 for (int i=topIndex; i<=endIndex; i++) { 4029 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4030 + " from " + i + " to " + (i-topIndex)); 4031 TaskRecord cur = mRecentTasks.remove(i); 4032 mRecentTasks.add(i-topIndex, cur); 4033 } 4034 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4035 + " to " + endIndex); 4036 return true; 4037 } 4038 4039 // Whoops, couldn't do it. 4040 return false; 4041 } 4042 4043 final void addRecentTaskLocked(TaskRecord task) { 4044 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4045 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4046 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4047 4048 int N = mRecentTasks.size(); 4049 // Quick case: check if the top-most recent task is the same. 4050 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4051 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4052 return; 4053 } 4054 // Another quick case: check if this is part of a set of affiliated 4055 // tasks that are at the top. 4056 if (isAffiliated && N > 0 && task.inRecents 4057 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4058 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4059 + " at top when adding " + task); 4060 return; 4061 } 4062 // Another quick case: never add voice sessions. 4063 if (task.voiceSession != null) { 4064 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4065 return; 4066 } 4067 4068 boolean needAffiliationFix = false; 4069 4070 // Slightly less quick case: the task is already in recents, so all we need 4071 // to do is move it. 4072 if (task.inRecents) { 4073 int taskIndex = mRecentTasks.indexOf(task); 4074 if (taskIndex >= 0) { 4075 if (!isAffiliated) { 4076 // Simple case: this is not an affiliated task, so we just move it to the front. 4077 mRecentTasks.remove(taskIndex); 4078 mRecentTasks.add(0, task); 4079 notifyTaskPersisterLocked(task, false); 4080 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4081 + " from " + taskIndex); 4082 return; 4083 } else { 4084 // More complicated: need to keep all affiliated tasks together. 4085 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4086 // All went well. 4087 return; 4088 } 4089 4090 // Uh oh... something bad in the affiliation chain, try to rebuild 4091 // everything and then go through our general path of adding a new task. 4092 needAffiliationFix = true; 4093 } 4094 } else { 4095 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4096 needAffiliationFix = true; 4097 } 4098 } 4099 4100 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4101 trimRecentsForTaskLocked(task, true); 4102 4103 N = mRecentTasks.size(); 4104 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4105 final TaskRecord tr = mRecentTasks.remove(N - 1); 4106 tr.removedFromRecents(); 4107 N--; 4108 } 4109 task.inRecents = true; 4110 if (!isAffiliated || needAffiliationFix) { 4111 // If this is a simple non-affiliated task, or we had some failure trying to 4112 // handle it as part of an affilated task, then just place it at the top. 4113 mRecentTasks.add(0, task); 4114 } else if (isAffiliated) { 4115 // If this is a new affiliated task, then move all of the affiliated tasks 4116 // to the front and insert this new one. 4117 TaskRecord other = task.mNextAffiliate; 4118 if (other == null) { 4119 other = task.mPrevAffiliate; 4120 } 4121 if (other != null) { 4122 int otherIndex = mRecentTasks.indexOf(other); 4123 if (otherIndex >= 0) { 4124 // Insert new task at appropriate location. 4125 int taskIndex; 4126 if (other == task.mNextAffiliate) { 4127 // We found the index of our next affiliation, which is who is 4128 // before us in the list, so add after that point. 4129 taskIndex = otherIndex+1; 4130 } else { 4131 // We found the index of our previous affiliation, which is who is 4132 // after us in the list, so add at their position. 4133 taskIndex = otherIndex; 4134 } 4135 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4136 + taskIndex + ": " + task); 4137 mRecentTasks.add(taskIndex, task); 4138 4139 // Now move everything to the front. 4140 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4141 // All went well. 4142 return; 4143 } 4144 4145 // Uh oh... something bad in the affiliation chain, try to rebuild 4146 // everything and then go through our general path of adding a new task. 4147 needAffiliationFix = true; 4148 } else { 4149 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4150 + other); 4151 needAffiliationFix = true; 4152 } 4153 } else { 4154 if (DEBUG_RECENTS) Slog.d(TAG, 4155 "addRecent: adding affiliated task without next/prev:" + task); 4156 needAffiliationFix = true; 4157 } 4158 } 4159 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4160 4161 if (needAffiliationFix) { 4162 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4163 cleanupRecentTasksLocked(task.userId); 4164 } 4165 } 4166 4167 /** 4168 * If needed, remove oldest existing entries in recents that are for the same kind 4169 * of task as the given one. 4170 */ 4171 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4172 int N = mRecentTasks.size(); 4173 final Intent intent = task.intent; 4174 final boolean document = intent != null && intent.isDocument(); 4175 4176 int maxRecents = task.maxRecents - 1; 4177 for (int i=0; i<N; i++) { 4178 final TaskRecord tr = mRecentTasks.get(i); 4179 if (task != tr) { 4180 if (task.userId != tr.userId) { 4181 continue; 4182 } 4183 if (i > MAX_RECENT_BITMAPS) { 4184 tr.freeLastThumbnail(); 4185 } 4186 final Intent trIntent = tr.intent; 4187 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4188 (intent == null || !intent.filterEquals(trIntent))) { 4189 continue; 4190 } 4191 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4192 if (document && trIsDocument) { 4193 // These are the same document activity (not necessarily the same doc). 4194 if (maxRecents > 0) { 4195 --maxRecents; 4196 continue; 4197 } 4198 // Hit the maximum number of documents for this task. Fall through 4199 // and remove this document from recents. 4200 } else if (document || trIsDocument) { 4201 // Only one of these is a document. Not the droid we're looking for. 4202 continue; 4203 } 4204 } 4205 4206 if (!doTrim) { 4207 // If the caller is not actually asking for a trim, just tell them we reached 4208 // a point where the trim would happen. 4209 return i; 4210 } 4211 4212 // Either task and tr are the same or, their affinities match or their intents match 4213 // and neither of them is a document, or they are documents using the same activity 4214 // and their maxRecents has been reached. 4215 tr.disposeThumbnail(); 4216 mRecentTasks.remove(i); 4217 if (task != tr) { 4218 tr.removedFromRecents(); 4219 } 4220 i--; 4221 N--; 4222 if (task.intent == null) { 4223 // If the new recent task we are adding is not fully 4224 // specified, then replace it with the existing recent task. 4225 task = tr; 4226 } 4227 notifyTaskPersisterLocked(tr, false); 4228 } 4229 4230 return -1; 4231 } 4232 4233 @Override 4234 public void reportActivityFullyDrawn(IBinder token) { 4235 synchronized (this) { 4236 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4237 if (r == null) { 4238 return; 4239 } 4240 r.reportFullyDrawnLocked(); 4241 } 4242 } 4243 4244 @Override 4245 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4246 synchronized (this) { 4247 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4248 if (r == null) { 4249 return; 4250 } 4251 final long origId = Binder.clearCallingIdentity(); 4252 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4253 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4254 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4255 if (config != null) { 4256 r.frozenBeforeDestroy = true; 4257 if (!updateConfigurationLocked(config, r, false, false)) { 4258 mStackSupervisor.resumeTopActivitiesLocked(); 4259 } 4260 } 4261 Binder.restoreCallingIdentity(origId); 4262 } 4263 } 4264 4265 @Override 4266 public int getRequestedOrientation(IBinder token) { 4267 synchronized (this) { 4268 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4269 if (r == null) { 4270 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4271 } 4272 return mWindowManager.getAppOrientation(r.appToken); 4273 } 4274 } 4275 4276 /** 4277 * This is the internal entry point for handling Activity.finish(). 4278 * 4279 * @param token The Binder token referencing the Activity we want to finish. 4280 * @param resultCode Result code, if any, from this Activity. 4281 * @param resultData Result data (Intent), if any, from this Activity. 4282 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4283 * the root Activity in the task. 4284 * 4285 * @return Returns true if the activity successfully finished, or false if it is still running. 4286 */ 4287 @Override 4288 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4289 boolean finishTask) { 4290 // Refuse possible leaked file descriptors 4291 if (resultData != null && resultData.hasFileDescriptors() == true) { 4292 throw new IllegalArgumentException("File descriptors passed in Intent"); 4293 } 4294 4295 synchronized(this) { 4296 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4297 if (r == null) { 4298 return true; 4299 } 4300 // Keep track of the root activity of the task before we finish it 4301 TaskRecord tr = r.task; 4302 ActivityRecord rootR = tr.getRootActivity(); 4303 if (rootR == null) { 4304 Slog.w(TAG, "Finishing task with all activities already finished"); 4305 } 4306 // Do not allow task to finish in Lock Task mode. 4307 if (tr == mStackSupervisor.mLockTaskModeTask) { 4308 if (rootR == r) { 4309 Slog.i(TAG, "Not finishing task in lock task mode"); 4310 mStackSupervisor.showLockTaskToast(); 4311 return false; 4312 } 4313 } 4314 if (mController != null) { 4315 // Find the first activity that is not finishing. 4316 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4317 if (next != null) { 4318 // ask watcher if this is allowed 4319 boolean resumeOK = true; 4320 try { 4321 resumeOK = mController.activityResuming(next.packageName); 4322 } catch (RemoteException e) { 4323 mController = null; 4324 Watchdog.getInstance().setActivityController(null); 4325 } 4326 4327 if (!resumeOK) { 4328 Slog.i(TAG, "Not finishing activity because controller resumed"); 4329 return false; 4330 } 4331 } 4332 } 4333 final long origId = Binder.clearCallingIdentity(); 4334 try { 4335 boolean res; 4336 if (finishTask && r == rootR) { 4337 // If requested, remove the task that is associated to this activity only if it 4338 // was the root activity in the task. The result code and data is ignored 4339 // because we don't support returning them across task boundaries. 4340 res = removeTaskByIdLocked(tr.taskId, false); 4341 if (!res) { 4342 Slog.i(TAG, "Removing task failed to finish activity"); 4343 } 4344 } else { 4345 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4346 resultData, "app-request", true); 4347 if (!res) { 4348 Slog.i(TAG, "Failed to finish by app-request"); 4349 } 4350 } 4351 return res; 4352 } finally { 4353 Binder.restoreCallingIdentity(origId); 4354 } 4355 } 4356 } 4357 4358 @Override 4359 public final void finishHeavyWeightApp() { 4360 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4361 != PackageManager.PERMISSION_GRANTED) { 4362 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4363 + Binder.getCallingPid() 4364 + ", uid=" + Binder.getCallingUid() 4365 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4366 Slog.w(TAG, msg); 4367 throw new SecurityException(msg); 4368 } 4369 4370 synchronized(this) { 4371 if (mHeavyWeightProcess == null) { 4372 return; 4373 } 4374 4375 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4376 mHeavyWeightProcess.activities); 4377 for (int i=0; i<activities.size(); i++) { 4378 ActivityRecord r = activities.get(i); 4379 if (!r.finishing) { 4380 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4381 null, "finish-heavy", true); 4382 } 4383 } 4384 4385 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4386 mHeavyWeightProcess.userId, 0)); 4387 mHeavyWeightProcess = null; 4388 } 4389 } 4390 4391 @Override 4392 public void crashApplication(int uid, int initialPid, String packageName, 4393 String message) { 4394 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4395 != PackageManager.PERMISSION_GRANTED) { 4396 String msg = "Permission Denial: crashApplication() from pid=" 4397 + Binder.getCallingPid() 4398 + ", uid=" + Binder.getCallingUid() 4399 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4400 Slog.w(TAG, msg); 4401 throw new SecurityException(msg); 4402 } 4403 4404 synchronized(this) { 4405 ProcessRecord proc = null; 4406 4407 // Figure out which process to kill. We don't trust that initialPid 4408 // still has any relation to current pids, so must scan through the 4409 // list. 4410 synchronized (mPidsSelfLocked) { 4411 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4412 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4413 if (p.uid != uid) { 4414 continue; 4415 } 4416 if (p.pid == initialPid) { 4417 proc = p; 4418 break; 4419 } 4420 if (p.pkgList.containsKey(packageName)) { 4421 proc = p; 4422 } 4423 } 4424 } 4425 4426 if (proc == null) { 4427 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4428 + " initialPid=" + initialPid 4429 + " packageName=" + packageName); 4430 return; 4431 } 4432 4433 if (proc.thread != null) { 4434 if (proc.pid == Process.myPid()) { 4435 Log.w(TAG, "crashApplication: trying to crash self!"); 4436 return; 4437 } 4438 long ident = Binder.clearCallingIdentity(); 4439 try { 4440 proc.thread.scheduleCrash(message); 4441 } catch (RemoteException e) { 4442 } 4443 Binder.restoreCallingIdentity(ident); 4444 } 4445 } 4446 } 4447 4448 @Override 4449 public final void finishSubActivity(IBinder token, String resultWho, 4450 int requestCode) { 4451 synchronized(this) { 4452 final long origId = Binder.clearCallingIdentity(); 4453 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4454 if (r != null) { 4455 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4456 } 4457 Binder.restoreCallingIdentity(origId); 4458 } 4459 } 4460 4461 @Override 4462 public boolean finishActivityAffinity(IBinder token) { 4463 synchronized(this) { 4464 final long origId = Binder.clearCallingIdentity(); 4465 try { 4466 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4467 4468 ActivityRecord rootR = r.task.getRootActivity(); 4469 // Do not allow task to finish in Lock Task mode. 4470 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4471 if (rootR == r) { 4472 mStackSupervisor.showLockTaskToast(); 4473 return false; 4474 } 4475 } 4476 boolean res = false; 4477 if (r != null) { 4478 res = r.task.stack.finishActivityAffinityLocked(r); 4479 } 4480 return res; 4481 } finally { 4482 Binder.restoreCallingIdentity(origId); 4483 } 4484 } 4485 } 4486 4487 @Override 4488 public void finishVoiceTask(IVoiceInteractionSession session) { 4489 synchronized(this) { 4490 final long origId = Binder.clearCallingIdentity(); 4491 try { 4492 mStackSupervisor.finishVoiceTask(session); 4493 } finally { 4494 Binder.restoreCallingIdentity(origId); 4495 } 4496 } 4497 4498 } 4499 4500 @Override 4501 public boolean releaseActivityInstance(IBinder token) { 4502 synchronized(this) { 4503 final long origId = Binder.clearCallingIdentity(); 4504 try { 4505 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4506 if (r.task == null || r.task.stack == null) { 4507 return false; 4508 } 4509 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4510 } finally { 4511 Binder.restoreCallingIdentity(origId); 4512 } 4513 } 4514 } 4515 4516 @Override 4517 public void releaseSomeActivities(IApplicationThread appInt) { 4518 synchronized(this) { 4519 final long origId = Binder.clearCallingIdentity(); 4520 try { 4521 ProcessRecord app = getRecordForAppLocked(appInt); 4522 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4523 } finally { 4524 Binder.restoreCallingIdentity(origId); 4525 } 4526 } 4527 } 4528 4529 @Override 4530 public boolean willActivityBeVisible(IBinder token) { 4531 synchronized(this) { 4532 ActivityStack stack = ActivityRecord.getStackLocked(token); 4533 if (stack != null) { 4534 return stack.willActivityBeVisibleLocked(token); 4535 } 4536 return false; 4537 } 4538 } 4539 4540 @Override 4541 public void overridePendingTransition(IBinder token, String packageName, 4542 int enterAnim, int exitAnim) { 4543 synchronized(this) { 4544 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4545 if (self == null) { 4546 return; 4547 } 4548 4549 final long origId = Binder.clearCallingIdentity(); 4550 4551 if (self.state == ActivityState.RESUMED 4552 || self.state == ActivityState.PAUSING) { 4553 mWindowManager.overridePendingAppTransition(packageName, 4554 enterAnim, exitAnim, null); 4555 } 4556 4557 Binder.restoreCallingIdentity(origId); 4558 } 4559 } 4560 4561 /** 4562 * Main function for removing an existing process from the activity manager 4563 * as a result of that process going away. Clears out all connections 4564 * to the process. 4565 */ 4566 private final void handleAppDiedLocked(ProcessRecord app, 4567 boolean restarting, boolean allowRestart) { 4568 int pid = app.pid; 4569 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4570 if (!kept && !restarting) { 4571 removeLruProcessLocked(app); 4572 if (pid > 0) { 4573 ProcessList.remove(pid); 4574 } 4575 } 4576 4577 if (mProfileProc == app) { 4578 clearProfilerLocked(); 4579 } 4580 4581 // Remove this application's activities from active lists. 4582 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4583 4584 app.activities.clear(); 4585 4586 if (app.instrumentationClass != null) { 4587 Slog.w(TAG, "Crash of app " + app.processName 4588 + " running instrumentation " + app.instrumentationClass); 4589 Bundle info = new Bundle(); 4590 info.putString("shortMsg", "Process crashed."); 4591 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4592 } 4593 4594 if (!restarting) { 4595 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4596 // If there was nothing to resume, and we are not already 4597 // restarting this process, but there is a visible activity that 4598 // is hosted by the process... then make sure all visible 4599 // activities are running, taking care of restarting this 4600 // process. 4601 if (hasVisibleActivities) { 4602 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4603 } 4604 } 4605 } 4606 } 4607 4608 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4609 IBinder threadBinder = thread.asBinder(); 4610 // Find the application record. 4611 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4612 ProcessRecord rec = mLruProcesses.get(i); 4613 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4614 return i; 4615 } 4616 } 4617 return -1; 4618 } 4619 4620 final ProcessRecord getRecordForAppLocked( 4621 IApplicationThread thread) { 4622 if (thread == null) { 4623 return null; 4624 } 4625 4626 int appIndex = getLRURecordIndexForAppLocked(thread); 4627 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4628 } 4629 4630 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4631 // If there are no longer any background processes running, 4632 // and the app that died was not running instrumentation, 4633 // then tell everyone we are now low on memory. 4634 boolean haveBg = false; 4635 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4636 ProcessRecord rec = mLruProcesses.get(i); 4637 if (rec.thread != null 4638 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4639 haveBg = true; 4640 break; 4641 } 4642 } 4643 4644 if (!haveBg) { 4645 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4646 if (doReport) { 4647 long now = SystemClock.uptimeMillis(); 4648 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4649 doReport = false; 4650 } else { 4651 mLastMemUsageReportTime = now; 4652 } 4653 } 4654 final ArrayList<ProcessMemInfo> memInfos 4655 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4656 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4657 long now = SystemClock.uptimeMillis(); 4658 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4659 ProcessRecord rec = mLruProcesses.get(i); 4660 if (rec == dyingProc || rec.thread == null) { 4661 continue; 4662 } 4663 if (doReport) { 4664 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4665 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4666 } 4667 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4668 // The low memory report is overriding any current 4669 // state for a GC request. Make sure to do 4670 // heavy/important/visible/foreground processes first. 4671 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4672 rec.lastRequestedGc = 0; 4673 } else { 4674 rec.lastRequestedGc = rec.lastLowMemory; 4675 } 4676 rec.reportLowMemory = true; 4677 rec.lastLowMemory = now; 4678 mProcessesToGc.remove(rec); 4679 addProcessToGcListLocked(rec); 4680 } 4681 } 4682 if (doReport) { 4683 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4684 mHandler.sendMessage(msg); 4685 } 4686 scheduleAppGcsLocked(); 4687 } 4688 } 4689 4690 final void appDiedLocked(ProcessRecord app) { 4691 appDiedLocked(app, app.pid, app.thread); 4692 } 4693 4694 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4695 // First check if this ProcessRecord is actually active for the pid. 4696 synchronized (mPidsSelfLocked) { 4697 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4698 if (curProc != app) { 4699 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4700 return; 4701 } 4702 } 4703 4704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4705 synchronized (stats) { 4706 stats.noteProcessDiedLocked(app.info.uid, pid); 4707 } 4708 4709 if (!app.killed) { 4710 Process.killProcessQuiet(pid); 4711 Process.killProcessGroup(app.info.uid, pid); 4712 app.killed = true; 4713 } 4714 4715 // Clean up already done if the process has been re-started. 4716 if (app.pid == pid && app.thread != null && 4717 app.thread.asBinder() == thread.asBinder()) { 4718 boolean doLowMem = app.instrumentationClass == null; 4719 boolean doOomAdj = doLowMem; 4720 if (!app.killedByAm) { 4721 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4722 + ") has died"); 4723 mAllowLowerMemLevel = true; 4724 } else { 4725 // Note that we always want to do oom adj to update our state with the 4726 // new number of procs. 4727 mAllowLowerMemLevel = false; 4728 doLowMem = false; 4729 } 4730 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4731 if (DEBUG_CLEANUP) Slog.v( 4732 TAG, "Dying app: " + app + ", pid: " + pid 4733 + ", thread: " + thread.asBinder()); 4734 handleAppDiedLocked(app, false, true); 4735 4736 if (doOomAdj) { 4737 updateOomAdjLocked(); 4738 } 4739 if (doLowMem) { 4740 doLowMemReportIfNeededLocked(app); 4741 } 4742 } else if (app.pid != pid) { 4743 // A new process has already been started. 4744 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4745 + ") has died and restarted (pid " + app.pid + ")."); 4746 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4747 } else if (DEBUG_PROCESSES) { 4748 Slog.d(TAG, "Received spurious death notification for thread " 4749 + thread.asBinder()); 4750 } 4751 } 4752 4753 /** 4754 * If a stack trace dump file is configured, dump process stack traces. 4755 * @param clearTraces causes the dump file to be erased prior to the new 4756 * traces being written, if true; when false, the new traces will be 4757 * appended to any existing file content. 4758 * @param firstPids of dalvik VM processes to dump stack traces for first 4759 * @param lastPids of dalvik VM processes to dump stack traces for last 4760 * @param nativeProcs optional list of native process names to dump stack crawls 4761 * @return file containing stack traces, or null if no dump file is configured 4762 */ 4763 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4764 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4765 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4766 if (tracesPath == null || tracesPath.length() == 0) { 4767 return null; 4768 } 4769 4770 File tracesFile = new File(tracesPath); 4771 try { 4772 File tracesDir = tracesFile.getParentFile(); 4773 if (!tracesDir.exists()) { 4774 tracesDir.mkdirs(); 4775 if (!SELinux.restorecon(tracesDir)) { 4776 return null; 4777 } 4778 } 4779 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4780 4781 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4782 tracesFile.createNewFile(); 4783 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4784 } catch (IOException e) { 4785 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4786 return null; 4787 } 4788 4789 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4790 return tracesFile; 4791 } 4792 4793 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4794 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4795 // Use a FileObserver to detect when traces finish writing. 4796 // The order of traces is considered important to maintain for legibility. 4797 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4798 @Override 4799 public synchronized void onEvent(int event, String path) { notify(); } 4800 }; 4801 4802 try { 4803 observer.startWatching(); 4804 4805 // First collect all of the stacks of the most important pids. 4806 if (firstPids != null) { 4807 try { 4808 int num = firstPids.size(); 4809 for (int i = 0; i < num; i++) { 4810 synchronized (observer) { 4811 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4812 observer.wait(200); // Wait for write-close, give up after 200msec 4813 } 4814 } 4815 } catch (InterruptedException e) { 4816 Slog.wtf(TAG, e); 4817 } 4818 } 4819 4820 // Next collect the stacks of the native pids 4821 if (nativeProcs != null) { 4822 int[] pids = Process.getPidsForCommands(nativeProcs); 4823 if (pids != null) { 4824 for (int pid : pids) { 4825 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4826 } 4827 } 4828 } 4829 4830 // Lastly, measure CPU usage. 4831 if (processCpuTracker != null) { 4832 processCpuTracker.init(); 4833 System.gc(); 4834 processCpuTracker.update(); 4835 try { 4836 synchronized (processCpuTracker) { 4837 processCpuTracker.wait(500); // measure over 1/2 second. 4838 } 4839 } catch (InterruptedException e) { 4840 } 4841 processCpuTracker.update(); 4842 4843 // We'll take the stack crawls of just the top apps using CPU. 4844 final int N = processCpuTracker.countWorkingStats(); 4845 int numProcs = 0; 4846 for (int i=0; i<N && numProcs<5; i++) { 4847 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4848 if (lastPids.indexOfKey(stats.pid) >= 0) { 4849 numProcs++; 4850 try { 4851 synchronized (observer) { 4852 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4853 observer.wait(200); // Wait for write-close, give up after 200msec 4854 } 4855 } catch (InterruptedException e) { 4856 Slog.wtf(TAG, e); 4857 } 4858 4859 } 4860 } 4861 } 4862 } finally { 4863 observer.stopWatching(); 4864 } 4865 } 4866 4867 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4868 if (true || IS_USER_BUILD) { 4869 return; 4870 } 4871 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4872 if (tracesPath == null || tracesPath.length() == 0) { 4873 return; 4874 } 4875 4876 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4877 StrictMode.allowThreadDiskWrites(); 4878 try { 4879 final File tracesFile = new File(tracesPath); 4880 final File tracesDir = tracesFile.getParentFile(); 4881 final File tracesTmp = new File(tracesDir, "__tmp__"); 4882 try { 4883 if (!tracesDir.exists()) { 4884 tracesDir.mkdirs(); 4885 if (!SELinux.restorecon(tracesDir.getPath())) { 4886 return; 4887 } 4888 } 4889 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4890 4891 if (tracesFile.exists()) { 4892 tracesTmp.delete(); 4893 tracesFile.renameTo(tracesTmp); 4894 } 4895 StringBuilder sb = new StringBuilder(); 4896 Time tobj = new Time(); 4897 tobj.set(System.currentTimeMillis()); 4898 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4899 sb.append(": "); 4900 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4901 sb.append(" since "); 4902 sb.append(msg); 4903 FileOutputStream fos = new FileOutputStream(tracesFile); 4904 fos.write(sb.toString().getBytes()); 4905 if (app == null) { 4906 fos.write("\n*** No application process!".getBytes()); 4907 } 4908 fos.close(); 4909 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4910 } catch (IOException e) { 4911 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4912 return; 4913 } 4914 4915 if (app != null) { 4916 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4917 firstPids.add(app.pid); 4918 dumpStackTraces(tracesPath, firstPids, null, null, null); 4919 } 4920 4921 File lastTracesFile = null; 4922 File curTracesFile = null; 4923 for (int i=9; i>=0; i--) { 4924 String name = String.format(Locale.US, "slow%02d.txt", i); 4925 curTracesFile = new File(tracesDir, name); 4926 if (curTracesFile.exists()) { 4927 if (lastTracesFile != null) { 4928 curTracesFile.renameTo(lastTracesFile); 4929 } else { 4930 curTracesFile.delete(); 4931 } 4932 } 4933 lastTracesFile = curTracesFile; 4934 } 4935 tracesFile.renameTo(curTracesFile); 4936 if (tracesTmp.exists()) { 4937 tracesTmp.renameTo(tracesFile); 4938 } 4939 } finally { 4940 StrictMode.setThreadPolicy(oldPolicy); 4941 } 4942 } 4943 4944 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4945 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4946 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4947 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4948 4949 if (mController != null) { 4950 try { 4951 // 0 == continue, -1 = kill process immediately 4952 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4953 if (res < 0 && app.pid != MY_PID) { 4954 app.kill("anr", true); 4955 } 4956 } catch (RemoteException e) { 4957 mController = null; 4958 Watchdog.getInstance().setActivityController(null); 4959 } 4960 } 4961 4962 long anrTime = SystemClock.uptimeMillis(); 4963 if (MONITOR_CPU_USAGE) { 4964 updateCpuStatsNow(); 4965 } 4966 4967 synchronized (this) { 4968 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4969 if (mShuttingDown) { 4970 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4971 return; 4972 } else if (app.notResponding) { 4973 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4974 return; 4975 } else if (app.crashing) { 4976 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4977 return; 4978 } 4979 4980 // In case we come through here for the same app before completing 4981 // this one, mark as anring now so we will bail out. 4982 app.notResponding = true; 4983 4984 // Log the ANR to the event log. 4985 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4986 app.processName, app.info.flags, annotation); 4987 4988 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4989 firstPids.add(app.pid); 4990 4991 int parentPid = app.pid; 4992 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4993 if (parentPid != app.pid) firstPids.add(parentPid); 4994 4995 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4996 4997 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4998 ProcessRecord r = mLruProcesses.get(i); 4999 if (r != null && r.thread != null) { 5000 int pid = r.pid; 5001 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5002 if (r.persistent) { 5003 firstPids.add(pid); 5004 } else { 5005 lastPids.put(pid, Boolean.TRUE); 5006 } 5007 } 5008 } 5009 } 5010 } 5011 5012 // Log the ANR to the main log. 5013 StringBuilder info = new StringBuilder(); 5014 info.setLength(0); 5015 info.append("ANR in ").append(app.processName); 5016 if (activity != null && activity.shortComponentName != null) { 5017 info.append(" (").append(activity.shortComponentName).append(")"); 5018 } 5019 info.append("\n"); 5020 info.append("PID: ").append(app.pid).append("\n"); 5021 if (annotation != null) { 5022 info.append("Reason: ").append(annotation).append("\n"); 5023 } 5024 if (parent != null && parent != activity) { 5025 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5026 } 5027 5028 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5029 5030 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5031 NATIVE_STACKS_OF_INTEREST); 5032 5033 String cpuInfo = null; 5034 if (MONITOR_CPU_USAGE) { 5035 updateCpuStatsNow(); 5036 synchronized (mProcessCpuTracker) { 5037 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5038 } 5039 info.append(processCpuTracker.printCurrentLoad()); 5040 info.append(cpuInfo); 5041 } 5042 5043 info.append(processCpuTracker.printCurrentState(anrTime)); 5044 5045 Slog.e(TAG, info.toString()); 5046 if (tracesFile == null) { 5047 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5048 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5049 } 5050 5051 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5052 cpuInfo, tracesFile, null); 5053 5054 if (mController != null) { 5055 try { 5056 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5057 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5058 if (res != 0) { 5059 if (res < 0 && app.pid != MY_PID) { 5060 app.kill("anr", true); 5061 } else { 5062 synchronized (this) { 5063 mServices.scheduleServiceTimeoutLocked(app); 5064 } 5065 } 5066 return; 5067 } 5068 } catch (RemoteException e) { 5069 mController = null; 5070 Watchdog.getInstance().setActivityController(null); 5071 } 5072 } 5073 5074 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5075 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5076 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5077 5078 synchronized (this) { 5079 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5080 5081 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5082 app.kill("bg anr", true); 5083 return; 5084 } 5085 5086 // Set the app's notResponding state, and look up the errorReportReceiver 5087 makeAppNotRespondingLocked(app, 5088 activity != null ? activity.shortComponentName : null, 5089 annotation != null ? "ANR " + annotation : "ANR", 5090 info.toString()); 5091 5092 // Bring up the infamous App Not Responding dialog 5093 Message msg = Message.obtain(); 5094 HashMap<String, Object> map = new HashMap<String, Object>(); 5095 msg.what = SHOW_NOT_RESPONDING_MSG; 5096 msg.obj = map; 5097 msg.arg1 = aboveSystem ? 1 : 0; 5098 map.put("app", app); 5099 if (activity != null) { 5100 map.put("activity", activity); 5101 } 5102 5103 mHandler.sendMessage(msg); 5104 } 5105 } 5106 5107 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5108 if (!mLaunchWarningShown) { 5109 mLaunchWarningShown = true; 5110 mHandler.post(new Runnable() { 5111 @Override 5112 public void run() { 5113 synchronized (ActivityManagerService.this) { 5114 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5115 d.show(); 5116 mHandler.postDelayed(new Runnable() { 5117 @Override 5118 public void run() { 5119 synchronized (ActivityManagerService.this) { 5120 d.dismiss(); 5121 mLaunchWarningShown = false; 5122 } 5123 } 5124 }, 4000); 5125 } 5126 } 5127 }); 5128 } 5129 } 5130 5131 @Override 5132 public boolean clearApplicationUserData(final String packageName, 5133 final IPackageDataObserver observer, int userId) { 5134 enforceNotIsolatedCaller("clearApplicationUserData"); 5135 int uid = Binder.getCallingUid(); 5136 int pid = Binder.getCallingPid(); 5137 userId = handleIncomingUser(pid, uid, 5138 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5139 long callingId = Binder.clearCallingIdentity(); 5140 try { 5141 IPackageManager pm = AppGlobals.getPackageManager(); 5142 int pkgUid = -1; 5143 synchronized(this) { 5144 try { 5145 pkgUid = pm.getPackageUid(packageName, userId); 5146 } catch (RemoteException e) { 5147 } 5148 if (pkgUid == -1) { 5149 Slog.w(TAG, "Invalid packageName: " + packageName); 5150 if (observer != null) { 5151 try { 5152 observer.onRemoveCompleted(packageName, false); 5153 } catch (RemoteException e) { 5154 Slog.i(TAG, "Observer no longer exists."); 5155 } 5156 } 5157 return false; 5158 } 5159 if (uid == pkgUid || checkComponentPermission( 5160 android.Manifest.permission.CLEAR_APP_USER_DATA, 5161 pid, uid, -1, true) 5162 == PackageManager.PERMISSION_GRANTED) { 5163 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5164 } else { 5165 throw new SecurityException("PID " + pid + " does not have permission " 5166 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5167 + " of package " + packageName); 5168 } 5169 5170 // Remove all tasks match the cleared application package and user 5171 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5172 final TaskRecord tr = mRecentTasks.get(i); 5173 final String taskPackageName = 5174 tr.getBaseIntent().getComponent().getPackageName(); 5175 if (tr.userId != userId) continue; 5176 if (!taskPackageName.equals(packageName)) continue; 5177 removeTaskByIdLocked(tr.taskId, false); 5178 } 5179 } 5180 5181 try { 5182 // Clear application user data 5183 pm.clearApplicationUserData(packageName, observer, userId); 5184 5185 synchronized(this) { 5186 // Remove all permissions granted from/to this package 5187 removeUriPermissionsForPackageLocked(packageName, userId, true); 5188 } 5189 5190 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5191 Uri.fromParts("package", packageName, null)); 5192 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5193 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5194 null, null, 0, null, null, null, false, false, userId); 5195 } catch (RemoteException e) { 5196 } 5197 } finally { 5198 Binder.restoreCallingIdentity(callingId); 5199 } 5200 return true; 5201 } 5202 5203 @Override 5204 public void killBackgroundProcesses(final String packageName, int userId) { 5205 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5206 != PackageManager.PERMISSION_GRANTED && 5207 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5208 != PackageManager.PERMISSION_GRANTED) { 5209 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5210 + Binder.getCallingPid() 5211 + ", uid=" + Binder.getCallingUid() 5212 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5213 Slog.w(TAG, msg); 5214 throw new SecurityException(msg); 5215 } 5216 5217 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5218 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5219 long callingId = Binder.clearCallingIdentity(); 5220 try { 5221 IPackageManager pm = AppGlobals.getPackageManager(); 5222 synchronized(this) { 5223 int appId = -1; 5224 try { 5225 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5226 } catch (RemoteException e) { 5227 } 5228 if (appId == -1) { 5229 Slog.w(TAG, "Invalid packageName: " + packageName); 5230 return; 5231 } 5232 killPackageProcessesLocked(packageName, appId, userId, 5233 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5234 } 5235 } finally { 5236 Binder.restoreCallingIdentity(callingId); 5237 } 5238 } 5239 5240 @Override 5241 public void killAllBackgroundProcesses() { 5242 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5243 != PackageManager.PERMISSION_GRANTED) { 5244 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5245 + Binder.getCallingPid() 5246 + ", uid=" + Binder.getCallingUid() 5247 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5248 Slog.w(TAG, msg); 5249 throw new SecurityException(msg); 5250 } 5251 5252 long callingId = Binder.clearCallingIdentity(); 5253 try { 5254 synchronized(this) { 5255 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5256 final int NP = mProcessNames.getMap().size(); 5257 for (int ip=0; ip<NP; ip++) { 5258 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5259 final int NA = apps.size(); 5260 for (int ia=0; ia<NA; ia++) { 5261 ProcessRecord app = apps.valueAt(ia); 5262 if (app.persistent) { 5263 // we don't kill persistent processes 5264 continue; 5265 } 5266 if (app.removed) { 5267 procs.add(app); 5268 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5269 app.removed = true; 5270 procs.add(app); 5271 } 5272 } 5273 } 5274 5275 int N = procs.size(); 5276 for (int i=0; i<N; i++) { 5277 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5278 } 5279 mAllowLowerMemLevel = true; 5280 updateOomAdjLocked(); 5281 doLowMemReportIfNeededLocked(null); 5282 } 5283 } finally { 5284 Binder.restoreCallingIdentity(callingId); 5285 } 5286 } 5287 5288 @Override 5289 public void forceStopPackage(final String packageName, int userId) { 5290 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5291 != PackageManager.PERMISSION_GRANTED) { 5292 String msg = "Permission Denial: forceStopPackage() from pid=" 5293 + Binder.getCallingPid() 5294 + ", uid=" + Binder.getCallingUid() 5295 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5296 Slog.w(TAG, msg); 5297 throw new SecurityException(msg); 5298 } 5299 final int callingPid = Binder.getCallingPid(); 5300 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5301 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5302 long callingId = Binder.clearCallingIdentity(); 5303 try { 5304 IPackageManager pm = AppGlobals.getPackageManager(); 5305 synchronized(this) { 5306 int[] users = userId == UserHandle.USER_ALL 5307 ? getUsersLocked() : new int[] { userId }; 5308 for (int user : users) { 5309 int pkgUid = -1; 5310 try { 5311 pkgUid = pm.getPackageUid(packageName, user); 5312 } catch (RemoteException e) { 5313 } 5314 if (pkgUid == -1) { 5315 Slog.w(TAG, "Invalid packageName: " + packageName); 5316 continue; 5317 } 5318 try { 5319 pm.setPackageStoppedState(packageName, true, user); 5320 } catch (RemoteException e) { 5321 } catch (IllegalArgumentException e) { 5322 Slog.w(TAG, "Failed trying to unstop package " 5323 + packageName + ": " + e); 5324 } 5325 if (isUserRunningLocked(user, false)) { 5326 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5327 } 5328 } 5329 } 5330 } finally { 5331 Binder.restoreCallingIdentity(callingId); 5332 } 5333 } 5334 5335 @Override 5336 public void addPackageDependency(String packageName) { 5337 synchronized (this) { 5338 int callingPid = Binder.getCallingPid(); 5339 if (callingPid == Process.myPid()) { 5340 // Yeah, um, no. 5341 return; 5342 } 5343 ProcessRecord proc; 5344 synchronized (mPidsSelfLocked) { 5345 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5346 } 5347 if (proc != null) { 5348 if (proc.pkgDeps == null) { 5349 proc.pkgDeps = new ArraySet<String>(1); 5350 } 5351 proc.pkgDeps.add(packageName); 5352 } 5353 } 5354 } 5355 5356 /* 5357 * The pkg name and app id have to be specified. 5358 */ 5359 @Override 5360 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5361 if (pkg == null) { 5362 return; 5363 } 5364 // Make sure the uid is valid. 5365 if (appid < 0) { 5366 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5367 return; 5368 } 5369 int callerUid = Binder.getCallingUid(); 5370 // Only the system server can kill an application 5371 if (callerUid == Process.SYSTEM_UID) { 5372 // Post an aysnc message to kill the application 5373 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5374 msg.arg1 = appid; 5375 msg.arg2 = 0; 5376 Bundle bundle = new Bundle(); 5377 bundle.putString("pkg", pkg); 5378 bundle.putString("reason", reason); 5379 msg.obj = bundle; 5380 mHandler.sendMessage(msg); 5381 } else { 5382 throw new SecurityException(callerUid + " cannot kill pkg: " + 5383 pkg); 5384 } 5385 } 5386 5387 @Override 5388 public void closeSystemDialogs(String reason) { 5389 enforceNotIsolatedCaller("closeSystemDialogs"); 5390 5391 final int pid = Binder.getCallingPid(); 5392 final int uid = Binder.getCallingUid(); 5393 final long origId = Binder.clearCallingIdentity(); 5394 try { 5395 synchronized (this) { 5396 // Only allow this from foreground processes, so that background 5397 // applications can't abuse it to prevent system UI from being shown. 5398 if (uid >= Process.FIRST_APPLICATION_UID) { 5399 ProcessRecord proc; 5400 synchronized (mPidsSelfLocked) { 5401 proc = mPidsSelfLocked.get(pid); 5402 } 5403 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5404 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5405 + " from background process " + proc); 5406 return; 5407 } 5408 } 5409 closeSystemDialogsLocked(reason); 5410 } 5411 } finally { 5412 Binder.restoreCallingIdentity(origId); 5413 } 5414 } 5415 5416 void closeSystemDialogsLocked(String reason) { 5417 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5419 | Intent.FLAG_RECEIVER_FOREGROUND); 5420 if (reason != null) { 5421 intent.putExtra("reason", reason); 5422 } 5423 mWindowManager.closeSystemDialogs(reason); 5424 5425 mStackSupervisor.closeSystemDialogsLocked(); 5426 5427 broadcastIntentLocked(null, null, intent, null, 5428 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5429 Process.SYSTEM_UID, UserHandle.USER_ALL); 5430 } 5431 5432 @Override 5433 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5434 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5435 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5436 for (int i=pids.length-1; i>=0; i--) { 5437 ProcessRecord proc; 5438 int oomAdj; 5439 synchronized (this) { 5440 synchronized (mPidsSelfLocked) { 5441 proc = mPidsSelfLocked.get(pids[i]); 5442 oomAdj = proc != null ? proc.setAdj : 0; 5443 } 5444 } 5445 infos[i] = new Debug.MemoryInfo(); 5446 Debug.getMemoryInfo(pids[i], infos[i]); 5447 if (proc != null) { 5448 synchronized (this) { 5449 if (proc.thread != null && proc.setAdj == oomAdj) { 5450 // Record this for posterity if the process has been stable. 5451 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5452 infos[i].getTotalUss(), false, proc.pkgList); 5453 } 5454 } 5455 } 5456 } 5457 return infos; 5458 } 5459 5460 @Override 5461 public long[] getProcessPss(int[] pids) { 5462 enforceNotIsolatedCaller("getProcessPss"); 5463 long[] pss = new long[pids.length]; 5464 for (int i=pids.length-1; i>=0; i--) { 5465 ProcessRecord proc; 5466 int oomAdj; 5467 synchronized (this) { 5468 synchronized (mPidsSelfLocked) { 5469 proc = mPidsSelfLocked.get(pids[i]); 5470 oomAdj = proc != null ? proc.setAdj : 0; 5471 } 5472 } 5473 long[] tmpUss = new long[1]; 5474 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5475 if (proc != null) { 5476 synchronized (this) { 5477 if (proc.thread != null && proc.setAdj == oomAdj) { 5478 // Record this for posterity if the process has been stable. 5479 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5480 } 5481 } 5482 } 5483 } 5484 return pss; 5485 } 5486 5487 @Override 5488 public void killApplicationProcess(String processName, int uid) { 5489 if (processName == null) { 5490 return; 5491 } 5492 5493 int callerUid = Binder.getCallingUid(); 5494 // Only the system server can kill an application 5495 if (callerUid == Process.SYSTEM_UID) { 5496 synchronized (this) { 5497 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5498 if (app != null && app.thread != null) { 5499 try { 5500 app.thread.scheduleSuicide(); 5501 } catch (RemoteException e) { 5502 // If the other end already died, then our work here is done. 5503 } 5504 } else { 5505 Slog.w(TAG, "Process/uid not found attempting kill of " 5506 + processName + " / " + uid); 5507 } 5508 } 5509 } else { 5510 throw new SecurityException(callerUid + " cannot kill app process: " + 5511 processName); 5512 } 5513 } 5514 5515 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5516 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5517 false, true, false, false, UserHandle.getUserId(uid), reason); 5518 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5519 Uri.fromParts("package", packageName, null)); 5520 if (!mProcessesReady) { 5521 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5522 | Intent.FLAG_RECEIVER_FOREGROUND); 5523 } 5524 intent.putExtra(Intent.EXTRA_UID, uid); 5525 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5526 broadcastIntentLocked(null, null, intent, 5527 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5528 false, false, 5529 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5530 } 5531 5532 private void forceStopUserLocked(int userId, String reason) { 5533 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5534 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5535 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5536 | Intent.FLAG_RECEIVER_FOREGROUND); 5537 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5538 broadcastIntentLocked(null, null, intent, 5539 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5540 false, false, 5541 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5542 } 5543 5544 private final boolean killPackageProcessesLocked(String packageName, int appId, 5545 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5546 boolean doit, boolean evenPersistent, String reason) { 5547 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5548 5549 // Remove all processes this package may have touched: all with the 5550 // same UID (except for the system or root user), and all whose name 5551 // matches the package name. 5552 final int NP = mProcessNames.getMap().size(); 5553 for (int ip=0; ip<NP; ip++) { 5554 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5555 final int NA = apps.size(); 5556 for (int ia=0; ia<NA; ia++) { 5557 ProcessRecord app = apps.valueAt(ia); 5558 if (app.persistent && !evenPersistent) { 5559 // we don't kill persistent processes 5560 continue; 5561 } 5562 if (app.removed) { 5563 if (doit) { 5564 procs.add(app); 5565 } 5566 continue; 5567 } 5568 5569 // Skip process if it doesn't meet our oom adj requirement. 5570 if (app.setAdj < minOomAdj) { 5571 continue; 5572 } 5573 5574 // If no package is specified, we call all processes under the 5575 // give user id. 5576 if (packageName == null) { 5577 if (app.userId != userId) { 5578 continue; 5579 } 5580 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5581 continue; 5582 } 5583 // Package has been specified, we want to hit all processes 5584 // that match it. We need to qualify this by the processes 5585 // that are running under the specified app and user ID. 5586 } else { 5587 final boolean isDep = app.pkgDeps != null 5588 && app.pkgDeps.contains(packageName); 5589 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5590 continue; 5591 } 5592 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5593 continue; 5594 } 5595 if (!app.pkgList.containsKey(packageName) && !isDep) { 5596 continue; 5597 } 5598 } 5599 5600 // Process has passed all conditions, kill it! 5601 if (!doit) { 5602 return true; 5603 } 5604 app.removed = true; 5605 procs.add(app); 5606 } 5607 } 5608 5609 int N = procs.size(); 5610 for (int i=0; i<N; i++) { 5611 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5612 } 5613 updateOomAdjLocked(); 5614 return N > 0; 5615 } 5616 5617 private final boolean forceStopPackageLocked(String name, int appId, 5618 boolean callerWillRestart, boolean purgeCache, boolean doit, 5619 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5620 int i; 5621 int N; 5622 5623 if (userId == UserHandle.USER_ALL && name == null) { 5624 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5625 } 5626 5627 if (appId < 0 && name != null) { 5628 try { 5629 appId = UserHandle.getAppId( 5630 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5631 } catch (RemoteException e) { 5632 } 5633 } 5634 5635 if (doit) { 5636 if (name != null) { 5637 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5638 + " user=" + userId + ": " + reason); 5639 } else { 5640 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5641 } 5642 5643 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5644 for (int ip=pmap.size()-1; ip>=0; ip--) { 5645 SparseArray<Long> ba = pmap.valueAt(ip); 5646 for (i=ba.size()-1; i>=0; i--) { 5647 boolean remove = false; 5648 final int entUid = ba.keyAt(i); 5649 if (name != null) { 5650 if (userId == UserHandle.USER_ALL) { 5651 if (UserHandle.getAppId(entUid) == appId) { 5652 remove = true; 5653 } 5654 } else { 5655 if (entUid == UserHandle.getUid(userId, appId)) { 5656 remove = true; 5657 } 5658 } 5659 } else if (UserHandle.getUserId(entUid) == userId) { 5660 remove = true; 5661 } 5662 if (remove) { 5663 ba.removeAt(i); 5664 } 5665 } 5666 if (ba.size() == 0) { 5667 pmap.removeAt(ip); 5668 } 5669 } 5670 } 5671 5672 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5673 -100, callerWillRestart, true, doit, evenPersistent, 5674 name == null ? ("stop user " + userId) : ("stop " + name)); 5675 5676 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5677 if (!doit) { 5678 return true; 5679 } 5680 didSomething = true; 5681 } 5682 5683 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5684 if (!doit) { 5685 return true; 5686 } 5687 didSomething = true; 5688 } 5689 5690 if (name == null) { 5691 // Remove all sticky broadcasts from this user. 5692 mStickyBroadcasts.remove(userId); 5693 } 5694 5695 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5696 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5697 userId, providers)) { 5698 if (!doit) { 5699 return true; 5700 } 5701 didSomething = true; 5702 } 5703 N = providers.size(); 5704 for (i=0; i<N; i++) { 5705 removeDyingProviderLocked(null, providers.get(i), true); 5706 } 5707 5708 // Remove transient permissions granted from/to this package/user 5709 removeUriPermissionsForPackageLocked(name, userId, false); 5710 5711 if (name == null || uninstalling) { 5712 // Remove pending intents. For now we only do this when force 5713 // stopping users, because we have some problems when doing this 5714 // for packages -- app widgets are not currently cleaned up for 5715 // such packages, so they can be left with bad pending intents. 5716 if (mIntentSenderRecords.size() > 0) { 5717 Iterator<WeakReference<PendingIntentRecord>> it 5718 = mIntentSenderRecords.values().iterator(); 5719 while (it.hasNext()) { 5720 WeakReference<PendingIntentRecord> wpir = it.next(); 5721 if (wpir == null) { 5722 it.remove(); 5723 continue; 5724 } 5725 PendingIntentRecord pir = wpir.get(); 5726 if (pir == null) { 5727 it.remove(); 5728 continue; 5729 } 5730 if (name == null) { 5731 // Stopping user, remove all objects for the user. 5732 if (pir.key.userId != userId) { 5733 // Not the same user, skip it. 5734 continue; 5735 } 5736 } else { 5737 if (UserHandle.getAppId(pir.uid) != appId) { 5738 // Different app id, skip it. 5739 continue; 5740 } 5741 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5742 // Different user, skip it. 5743 continue; 5744 } 5745 if (!pir.key.packageName.equals(name)) { 5746 // Different package, skip it. 5747 continue; 5748 } 5749 } 5750 if (!doit) { 5751 return true; 5752 } 5753 didSomething = true; 5754 it.remove(); 5755 pir.canceled = true; 5756 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5757 pir.key.activity.pendingResults.remove(pir.ref); 5758 } 5759 } 5760 } 5761 } 5762 5763 if (doit) { 5764 if (purgeCache && name != null) { 5765 AttributeCache ac = AttributeCache.instance(); 5766 if (ac != null) { 5767 ac.removePackage(name); 5768 } 5769 } 5770 if (mBooted) { 5771 mStackSupervisor.resumeTopActivitiesLocked(); 5772 mStackSupervisor.scheduleIdleLocked(); 5773 } 5774 } 5775 5776 return didSomething; 5777 } 5778 5779 private final boolean removeProcessLocked(ProcessRecord app, 5780 boolean callerWillRestart, boolean allowRestart, String reason) { 5781 final String name = app.processName; 5782 final int uid = app.uid; 5783 if (DEBUG_PROCESSES) Slog.d( 5784 TAG, "Force removing proc " + app.toShortString() + " (" + name 5785 + "/" + uid + ")"); 5786 5787 mProcessNames.remove(name, uid); 5788 mIsolatedProcesses.remove(app.uid); 5789 if (mHeavyWeightProcess == app) { 5790 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5791 mHeavyWeightProcess.userId, 0)); 5792 mHeavyWeightProcess = null; 5793 } 5794 boolean needRestart = false; 5795 if (app.pid > 0 && app.pid != MY_PID) { 5796 int pid = app.pid; 5797 synchronized (mPidsSelfLocked) { 5798 mPidsSelfLocked.remove(pid); 5799 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5800 } 5801 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5802 if (app.isolated) { 5803 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5804 } 5805 app.kill(reason, true); 5806 handleAppDiedLocked(app, true, allowRestart); 5807 removeLruProcessLocked(app); 5808 5809 if (app.persistent && !app.isolated) { 5810 if (!callerWillRestart) { 5811 addAppLocked(app.info, false, null /* ABI override */); 5812 } else { 5813 needRestart = true; 5814 } 5815 } 5816 } else { 5817 mRemovedProcesses.add(app); 5818 } 5819 5820 return needRestart; 5821 } 5822 5823 private final void processStartTimedOutLocked(ProcessRecord app) { 5824 final int pid = app.pid; 5825 boolean gone = false; 5826 synchronized (mPidsSelfLocked) { 5827 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5828 if (knownApp != null && knownApp.thread == null) { 5829 mPidsSelfLocked.remove(pid); 5830 gone = true; 5831 } 5832 } 5833 5834 if (gone) { 5835 Slog.w(TAG, "Process " + app + " failed to attach"); 5836 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5837 pid, app.uid, app.processName); 5838 mProcessNames.remove(app.processName, app.uid); 5839 mIsolatedProcesses.remove(app.uid); 5840 if (mHeavyWeightProcess == app) { 5841 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5842 mHeavyWeightProcess.userId, 0)); 5843 mHeavyWeightProcess = null; 5844 } 5845 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5846 if (app.isolated) { 5847 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5848 } 5849 // Take care of any launching providers waiting for this process. 5850 checkAppInLaunchingProvidersLocked(app, true); 5851 // Take care of any services that are waiting for the process. 5852 mServices.processStartTimedOutLocked(app); 5853 app.kill("start timeout", true); 5854 removeLruProcessLocked(app); 5855 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5856 Slog.w(TAG, "Unattached app died before backup, skipping"); 5857 try { 5858 IBackupManager bm = IBackupManager.Stub.asInterface( 5859 ServiceManager.getService(Context.BACKUP_SERVICE)); 5860 bm.agentDisconnected(app.info.packageName); 5861 } catch (RemoteException e) { 5862 // Can't happen; the backup manager is local 5863 } 5864 } 5865 if (isPendingBroadcastProcessLocked(pid)) { 5866 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5867 skipPendingBroadcastLocked(pid); 5868 } 5869 } else { 5870 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5871 } 5872 } 5873 5874 private final boolean attachApplicationLocked(IApplicationThread thread, 5875 int pid) { 5876 5877 // Find the application record that is being attached... either via 5878 // the pid if we are running in multiple processes, or just pull the 5879 // next app record if we are emulating process with anonymous threads. 5880 ProcessRecord app; 5881 if (pid != MY_PID && pid >= 0) { 5882 synchronized (mPidsSelfLocked) { 5883 app = mPidsSelfLocked.get(pid); 5884 } 5885 } else { 5886 app = null; 5887 } 5888 5889 if (app == null) { 5890 Slog.w(TAG, "No pending application record for pid " + pid 5891 + " (IApplicationThread " + thread + "); dropping process"); 5892 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5893 if (pid > 0 && pid != MY_PID) { 5894 Process.killProcessQuiet(pid); 5895 //TODO: Process.killProcessGroup(app.info.uid, pid); 5896 } else { 5897 try { 5898 thread.scheduleExit(); 5899 } catch (Exception e) { 5900 // Ignore exceptions. 5901 } 5902 } 5903 return false; 5904 } 5905 5906 // If this application record is still attached to a previous 5907 // process, clean it up now. 5908 if (app.thread != null) { 5909 handleAppDiedLocked(app, true, true); 5910 } 5911 5912 // Tell the process all about itself. 5913 5914 if (localLOGV) Slog.v( 5915 TAG, "Binding process pid " + pid + " to record " + app); 5916 5917 final String processName = app.processName; 5918 try { 5919 AppDeathRecipient adr = new AppDeathRecipient( 5920 app, pid, thread); 5921 thread.asBinder().linkToDeath(adr, 0); 5922 app.deathRecipient = adr; 5923 } catch (RemoteException e) { 5924 app.resetPackageList(mProcessStats); 5925 startProcessLocked(app, "link fail", processName); 5926 return false; 5927 } 5928 5929 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5930 5931 app.makeActive(thread, mProcessStats); 5932 app.curAdj = app.setAdj = -100; 5933 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5934 app.forcingToForeground = null; 5935 updateProcessForegroundLocked(app, false, false); 5936 app.hasShownUi = false; 5937 app.debugging = false; 5938 app.cached = false; 5939 app.killedByAm = false; 5940 5941 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5942 5943 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5944 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5945 5946 if (!normalMode) { 5947 Slog.i(TAG, "Launching preboot mode app: " + app); 5948 } 5949 5950 if (localLOGV) Slog.v( 5951 TAG, "New app record " + app 5952 + " thread=" + thread.asBinder() + " pid=" + pid); 5953 try { 5954 int testMode = IApplicationThread.DEBUG_OFF; 5955 if (mDebugApp != null && mDebugApp.equals(processName)) { 5956 testMode = mWaitForDebugger 5957 ? IApplicationThread.DEBUG_WAIT 5958 : IApplicationThread.DEBUG_ON; 5959 app.debugging = true; 5960 if (mDebugTransient) { 5961 mDebugApp = mOrigDebugApp; 5962 mWaitForDebugger = mOrigWaitForDebugger; 5963 } 5964 } 5965 String profileFile = app.instrumentationProfileFile; 5966 ParcelFileDescriptor profileFd = null; 5967 int samplingInterval = 0; 5968 boolean profileAutoStop = false; 5969 if (mProfileApp != null && mProfileApp.equals(processName)) { 5970 mProfileProc = app; 5971 profileFile = mProfileFile; 5972 profileFd = mProfileFd; 5973 samplingInterval = mSamplingInterval; 5974 profileAutoStop = mAutoStopProfiler; 5975 } 5976 boolean enableOpenGlTrace = false; 5977 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5978 enableOpenGlTrace = true; 5979 mOpenGlTraceApp = null; 5980 } 5981 5982 // If the app is being launched for restore or full backup, set it up specially 5983 boolean isRestrictedBackupMode = false; 5984 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5985 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5986 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5987 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5988 } 5989 5990 ensurePackageDexOpt(app.instrumentationInfo != null 5991 ? app.instrumentationInfo.packageName 5992 : app.info.packageName); 5993 if (app.instrumentationClass != null) { 5994 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5995 } 5996 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5997 + processName + " with config " + mConfiguration); 5998 ApplicationInfo appInfo = app.instrumentationInfo != null 5999 ? app.instrumentationInfo : app.info; 6000 app.compat = compatibilityInfoForPackageLocked(appInfo); 6001 if (profileFd != null) { 6002 profileFd = profileFd.dup(); 6003 } 6004 ProfilerInfo profilerInfo = profileFile == null ? null 6005 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6006 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6007 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6008 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6009 isRestrictedBackupMode || !normalMode, app.persistent, 6010 new Configuration(mConfiguration), app.compat, 6011 getCommonServicesLocked(app.isolated), 6012 mCoreSettingsObserver.getCoreSettingsLocked()); 6013 updateLruProcessLocked(app, false, null); 6014 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6015 } catch (Exception e) { 6016 // todo: Yikes! What should we do? For now we will try to 6017 // start another process, but that could easily get us in 6018 // an infinite loop of restarting processes... 6019 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6020 6021 app.resetPackageList(mProcessStats); 6022 app.unlinkDeathRecipient(); 6023 startProcessLocked(app, "bind fail", processName); 6024 return false; 6025 } 6026 6027 // Remove this record from the list of starting applications. 6028 mPersistentStartingProcesses.remove(app); 6029 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6030 "Attach application locked removing on hold: " + app); 6031 mProcessesOnHold.remove(app); 6032 6033 boolean badApp = false; 6034 boolean didSomething = false; 6035 6036 // See if the top visible activity is waiting to run in this process... 6037 if (normalMode) { 6038 try { 6039 if (mStackSupervisor.attachApplicationLocked(app)) { 6040 didSomething = true; 6041 } 6042 } catch (Exception e) { 6043 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6044 badApp = true; 6045 } 6046 } 6047 6048 // Find any services that should be running in this process... 6049 if (!badApp) { 6050 try { 6051 didSomething |= mServices.attachApplicationLocked(app, processName); 6052 } catch (Exception e) { 6053 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6054 badApp = true; 6055 } 6056 } 6057 6058 // Check if a next-broadcast receiver is in this process... 6059 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6060 try { 6061 didSomething |= sendPendingBroadcastsLocked(app); 6062 } catch (Exception e) { 6063 // If the app died trying to launch the receiver we declare it 'bad' 6064 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6065 badApp = true; 6066 } 6067 } 6068 6069 // Check whether the next backup agent is in this process... 6070 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6071 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6072 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6073 try { 6074 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6075 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6076 mBackupTarget.backupMode); 6077 } catch (Exception e) { 6078 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6079 badApp = true; 6080 } 6081 } 6082 6083 if (badApp) { 6084 app.kill("error during init", true); 6085 handleAppDiedLocked(app, false, true); 6086 return false; 6087 } 6088 6089 if (!didSomething) { 6090 updateOomAdjLocked(); 6091 } 6092 6093 return true; 6094 } 6095 6096 @Override 6097 public final void attachApplication(IApplicationThread thread) { 6098 synchronized (this) { 6099 int callingPid = Binder.getCallingPid(); 6100 final long origId = Binder.clearCallingIdentity(); 6101 attachApplicationLocked(thread, callingPid); 6102 Binder.restoreCallingIdentity(origId); 6103 } 6104 } 6105 6106 @Override 6107 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6108 final long origId = Binder.clearCallingIdentity(); 6109 synchronized (this) { 6110 ActivityStack stack = ActivityRecord.getStackLocked(token); 6111 if (stack != null) { 6112 ActivityRecord r = 6113 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6114 if (stopProfiling) { 6115 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6116 try { 6117 mProfileFd.close(); 6118 } catch (IOException e) { 6119 } 6120 clearProfilerLocked(); 6121 } 6122 } 6123 } 6124 } 6125 Binder.restoreCallingIdentity(origId); 6126 } 6127 6128 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6129 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6130 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6131 } 6132 6133 void enableScreenAfterBoot() { 6134 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6135 SystemClock.uptimeMillis()); 6136 mWindowManager.enableScreenAfterBoot(); 6137 6138 synchronized (this) { 6139 updateEventDispatchingLocked(); 6140 } 6141 } 6142 6143 @Override 6144 public void showBootMessage(final CharSequence msg, final boolean always) { 6145 enforceNotIsolatedCaller("showBootMessage"); 6146 mWindowManager.showBootMessage(msg, always); 6147 } 6148 6149 @Override 6150 public void keyguardWaitingForActivityDrawn() { 6151 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6152 final long token = Binder.clearCallingIdentity(); 6153 try { 6154 synchronized (this) { 6155 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6156 mWindowManager.keyguardWaitingForActivityDrawn(); 6157 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6158 mLockScreenShown = LOCK_SCREEN_LEAVING; 6159 updateSleepIfNeededLocked(); 6160 } 6161 } 6162 } finally { 6163 Binder.restoreCallingIdentity(token); 6164 } 6165 } 6166 6167 final void finishBooting() { 6168 synchronized (this) { 6169 if (!mBootAnimationComplete) { 6170 mCallFinishBooting = true; 6171 return; 6172 } 6173 mCallFinishBooting = false; 6174 } 6175 6176 ArraySet<String> completedIsas = new ArraySet<String>(); 6177 for (String abi : Build.SUPPORTED_ABIS) { 6178 Process.establishZygoteConnectionForAbi(abi); 6179 final String instructionSet = VMRuntime.getInstructionSet(abi); 6180 if (!completedIsas.contains(instructionSet)) { 6181 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6182 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6183 } 6184 completedIsas.add(instructionSet); 6185 } 6186 } 6187 6188 IntentFilter pkgFilter = new IntentFilter(); 6189 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6190 pkgFilter.addDataScheme("package"); 6191 mContext.registerReceiver(new BroadcastReceiver() { 6192 @Override 6193 public void onReceive(Context context, Intent intent) { 6194 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6195 if (pkgs != null) { 6196 for (String pkg : pkgs) { 6197 synchronized (ActivityManagerService.this) { 6198 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6199 0, "finished booting")) { 6200 setResultCode(Activity.RESULT_OK); 6201 return; 6202 } 6203 } 6204 } 6205 } 6206 } 6207 }, pkgFilter); 6208 6209 // Let system services know. 6210 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6211 6212 synchronized (this) { 6213 // Ensure that any processes we had put on hold are now started 6214 // up. 6215 final int NP = mProcessesOnHold.size(); 6216 if (NP > 0) { 6217 ArrayList<ProcessRecord> procs = 6218 new ArrayList<ProcessRecord>(mProcessesOnHold); 6219 for (int ip=0; ip<NP; ip++) { 6220 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6221 + procs.get(ip)); 6222 startProcessLocked(procs.get(ip), "on-hold", null); 6223 } 6224 } 6225 6226 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6227 // Start looking for apps that are abusing wake locks. 6228 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6229 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6230 // Tell anyone interested that we are done booting! 6231 SystemProperties.set("sys.boot_completed", "1"); 6232 6233 // And trigger dev.bootcomplete if we are not showing encryption progress 6234 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6235 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6236 SystemProperties.set("dev.bootcomplete", "1"); 6237 } 6238 for (int i=0; i<mStartedUsers.size(); i++) { 6239 UserStartedState uss = mStartedUsers.valueAt(i); 6240 if (uss.mState == UserStartedState.STATE_BOOTING) { 6241 uss.mState = UserStartedState.STATE_RUNNING; 6242 final int userId = mStartedUsers.keyAt(i); 6243 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6244 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6245 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6246 broadcastIntentLocked(null, null, intent, null, 6247 new IIntentReceiver.Stub() { 6248 @Override 6249 public void performReceive(Intent intent, int resultCode, 6250 String data, Bundle extras, boolean ordered, 6251 boolean sticky, int sendingUser) { 6252 synchronized (ActivityManagerService.this) { 6253 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6254 true, false); 6255 } 6256 } 6257 }, 6258 0, null, null, 6259 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6260 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6261 userId); 6262 } 6263 } 6264 scheduleStartProfilesLocked(); 6265 } 6266 } 6267 } 6268 6269 @Override 6270 public void bootAnimationComplete() { 6271 final boolean callFinishBooting; 6272 synchronized (this) { 6273 callFinishBooting = mCallFinishBooting; 6274 mBootAnimationComplete = true; 6275 } 6276 if (callFinishBooting) { 6277 finishBooting(); 6278 } 6279 } 6280 6281 @Override 6282 public void systemBackupRestored() { 6283 synchronized (this) { 6284 if (mSystemReady) { 6285 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6286 } else { 6287 Slog.w(TAG, "System backup restored before system is ready"); 6288 } 6289 } 6290 } 6291 6292 final void ensureBootCompleted() { 6293 boolean booting; 6294 boolean enableScreen; 6295 synchronized (this) { 6296 booting = mBooting; 6297 mBooting = false; 6298 enableScreen = !mBooted; 6299 mBooted = true; 6300 } 6301 6302 if (booting) { 6303 finishBooting(); 6304 } 6305 6306 if (enableScreen) { 6307 enableScreenAfterBoot(); 6308 } 6309 } 6310 6311 @Override 6312 public final void activityResumed(IBinder token) { 6313 final long origId = Binder.clearCallingIdentity(); 6314 synchronized(this) { 6315 ActivityStack stack = ActivityRecord.getStackLocked(token); 6316 if (stack != null) { 6317 ActivityRecord.activityResumedLocked(token); 6318 } 6319 } 6320 Binder.restoreCallingIdentity(origId); 6321 } 6322 6323 @Override 6324 public final void activityPaused(IBinder token) { 6325 final long origId = Binder.clearCallingIdentity(); 6326 synchronized(this) { 6327 ActivityStack stack = ActivityRecord.getStackLocked(token); 6328 if (stack != null) { 6329 stack.activityPausedLocked(token, false); 6330 } 6331 } 6332 Binder.restoreCallingIdentity(origId); 6333 } 6334 6335 @Override 6336 public final void activityStopped(IBinder token, Bundle icicle, 6337 PersistableBundle persistentState, CharSequence description) { 6338 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6339 6340 // Refuse possible leaked file descriptors 6341 if (icicle != null && icicle.hasFileDescriptors()) { 6342 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6343 } 6344 6345 final long origId = Binder.clearCallingIdentity(); 6346 6347 synchronized (this) { 6348 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6349 if (r != null) { 6350 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6351 } 6352 } 6353 6354 trimApplications(); 6355 6356 Binder.restoreCallingIdentity(origId); 6357 } 6358 6359 @Override 6360 public final void activityDestroyed(IBinder token) { 6361 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6362 synchronized (this) { 6363 ActivityStack stack = ActivityRecord.getStackLocked(token); 6364 if (stack != null) { 6365 stack.activityDestroyedLocked(token, "activityDestroyed"); 6366 } 6367 } 6368 } 6369 6370 @Override 6371 public final void backgroundResourcesReleased(IBinder token) { 6372 final long origId = Binder.clearCallingIdentity(); 6373 try { 6374 synchronized (this) { 6375 ActivityStack stack = ActivityRecord.getStackLocked(token); 6376 if (stack != null) { 6377 stack.backgroundResourcesReleased(); 6378 } 6379 } 6380 } finally { 6381 Binder.restoreCallingIdentity(origId); 6382 } 6383 } 6384 6385 @Override 6386 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6387 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6388 } 6389 6390 @Override 6391 public final void notifyEnterAnimationComplete(IBinder token) { 6392 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6393 } 6394 6395 @Override 6396 public String getCallingPackage(IBinder token) { 6397 synchronized (this) { 6398 ActivityRecord r = getCallingRecordLocked(token); 6399 return r != null ? r.info.packageName : null; 6400 } 6401 } 6402 6403 @Override 6404 public ComponentName getCallingActivity(IBinder token) { 6405 synchronized (this) { 6406 ActivityRecord r = getCallingRecordLocked(token); 6407 return r != null ? r.intent.getComponent() : null; 6408 } 6409 } 6410 6411 private ActivityRecord getCallingRecordLocked(IBinder token) { 6412 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6413 if (r == null) { 6414 return null; 6415 } 6416 return r.resultTo; 6417 } 6418 6419 @Override 6420 public ComponentName getActivityClassForToken(IBinder token) { 6421 synchronized(this) { 6422 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6423 if (r == null) { 6424 return null; 6425 } 6426 return r.intent.getComponent(); 6427 } 6428 } 6429 6430 @Override 6431 public String getPackageForToken(IBinder token) { 6432 synchronized(this) { 6433 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6434 if (r == null) { 6435 return null; 6436 } 6437 return r.packageName; 6438 } 6439 } 6440 6441 @Override 6442 public IIntentSender getIntentSender(int type, 6443 String packageName, IBinder token, String resultWho, 6444 int requestCode, Intent[] intents, String[] resolvedTypes, 6445 int flags, Bundle options, int userId) { 6446 enforceNotIsolatedCaller("getIntentSender"); 6447 // Refuse possible leaked file descriptors 6448 if (intents != null) { 6449 if (intents.length < 1) { 6450 throw new IllegalArgumentException("Intents array length must be >= 1"); 6451 } 6452 for (int i=0; i<intents.length; i++) { 6453 Intent intent = intents[i]; 6454 if (intent != null) { 6455 if (intent.hasFileDescriptors()) { 6456 throw new IllegalArgumentException("File descriptors passed in Intent"); 6457 } 6458 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6459 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6460 throw new IllegalArgumentException( 6461 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6462 } 6463 intents[i] = new Intent(intent); 6464 } 6465 } 6466 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6467 throw new IllegalArgumentException( 6468 "Intent array length does not match resolvedTypes length"); 6469 } 6470 } 6471 if (options != null) { 6472 if (options.hasFileDescriptors()) { 6473 throw new IllegalArgumentException("File descriptors passed in options"); 6474 } 6475 } 6476 6477 synchronized(this) { 6478 int callingUid = Binder.getCallingUid(); 6479 int origUserId = userId; 6480 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6481 type == ActivityManager.INTENT_SENDER_BROADCAST, 6482 ALLOW_NON_FULL, "getIntentSender", null); 6483 if (origUserId == UserHandle.USER_CURRENT) { 6484 // We don't want to evaluate this until the pending intent is 6485 // actually executed. However, we do want to always do the 6486 // security checking for it above. 6487 userId = UserHandle.USER_CURRENT; 6488 } 6489 try { 6490 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6491 int uid = AppGlobals.getPackageManager() 6492 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6493 if (!UserHandle.isSameApp(callingUid, uid)) { 6494 String msg = "Permission Denial: getIntentSender() from pid=" 6495 + Binder.getCallingPid() 6496 + ", uid=" + Binder.getCallingUid() 6497 + ", (need uid=" + uid + ")" 6498 + " is not allowed to send as package " + packageName; 6499 Slog.w(TAG, msg); 6500 throw new SecurityException(msg); 6501 } 6502 } 6503 6504 return getIntentSenderLocked(type, packageName, callingUid, userId, 6505 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6506 6507 } catch (RemoteException e) { 6508 throw new SecurityException(e); 6509 } 6510 } 6511 } 6512 6513 IIntentSender getIntentSenderLocked(int type, String packageName, 6514 int callingUid, int userId, IBinder token, String resultWho, 6515 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6516 Bundle options) { 6517 if (DEBUG_MU) 6518 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6519 ActivityRecord activity = null; 6520 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6521 activity = ActivityRecord.isInStackLocked(token); 6522 if (activity == null) { 6523 return null; 6524 } 6525 if (activity.finishing) { 6526 return null; 6527 } 6528 } 6529 6530 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6531 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6532 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6533 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6534 |PendingIntent.FLAG_UPDATE_CURRENT); 6535 6536 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6537 type, packageName, activity, resultWho, 6538 requestCode, intents, resolvedTypes, flags, options, userId); 6539 WeakReference<PendingIntentRecord> ref; 6540 ref = mIntentSenderRecords.get(key); 6541 PendingIntentRecord rec = ref != null ? ref.get() : null; 6542 if (rec != null) { 6543 if (!cancelCurrent) { 6544 if (updateCurrent) { 6545 if (rec.key.requestIntent != null) { 6546 rec.key.requestIntent.replaceExtras(intents != null ? 6547 intents[intents.length - 1] : null); 6548 } 6549 if (intents != null) { 6550 intents[intents.length-1] = rec.key.requestIntent; 6551 rec.key.allIntents = intents; 6552 rec.key.allResolvedTypes = resolvedTypes; 6553 } else { 6554 rec.key.allIntents = null; 6555 rec.key.allResolvedTypes = null; 6556 } 6557 } 6558 return rec; 6559 } 6560 rec.canceled = true; 6561 mIntentSenderRecords.remove(key); 6562 } 6563 if (noCreate) { 6564 return rec; 6565 } 6566 rec = new PendingIntentRecord(this, key, callingUid); 6567 mIntentSenderRecords.put(key, rec.ref); 6568 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6569 if (activity.pendingResults == null) { 6570 activity.pendingResults 6571 = new HashSet<WeakReference<PendingIntentRecord>>(); 6572 } 6573 activity.pendingResults.add(rec.ref); 6574 } 6575 return rec; 6576 } 6577 6578 @Override 6579 public void cancelIntentSender(IIntentSender sender) { 6580 if (!(sender instanceof PendingIntentRecord)) { 6581 return; 6582 } 6583 synchronized(this) { 6584 PendingIntentRecord rec = (PendingIntentRecord)sender; 6585 try { 6586 int uid = AppGlobals.getPackageManager() 6587 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6588 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6589 String msg = "Permission Denial: cancelIntentSender() from pid=" 6590 + Binder.getCallingPid() 6591 + ", uid=" + Binder.getCallingUid() 6592 + " is not allowed to cancel packges " 6593 + rec.key.packageName; 6594 Slog.w(TAG, msg); 6595 throw new SecurityException(msg); 6596 } 6597 } catch (RemoteException e) { 6598 throw new SecurityException(e); 6599 } 6600 cancelIntentSenderLocked(rec, true); 6601 } 6602 } 6603 6604 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6605 rec.canceled = true; 6606 mIntentSenderRecords.remove(rec.key); 6607 if (cleanActivity && rec.key.activity != null) { 6608 rec.key.activity.pendingResults.remove(rec.ref); 6609 } 6610 } 6611 6612 @Override 6613 public String getPackageForIntentSender(IIntentSender pendingResult) { 6614 if (!(pendingResult instanceof PendingIntentRecord)) { 6615 return null; 6616 } 6617 try { 6618 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6619 return res.key.packageName; 6620 } catch (ClassCastException e) { 6621 } 6622 return null; 6623 } 6624 6625 @Override 6626 public int getUidForIntentSender(IIntentSender sender) { 6627 if (sender instanceof PendingIntentRecord) { 6628 try { 6629 PendingIntentRecord res = (PendingIntentRecord)sender; 6630 return res.uid; 6631 } catch (ClassCastException e) { 6632 } 6633 } 6634 return -1; 6635 } 6636 6637 @Override 6638 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6639 if (!(pendingResult instanceof PendingIntentRecord)) { 6640 return false; 6641 } 6642 try { 6643 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6644 if (res.key.allIntents == null) { 6645 return false; 6646 } 6647 for (int i=0; i<res.key.allIntents.length; i++) { 6648 Intent intent = res.key.allIntents[i]; 6649 if (intent.getPackage() != null && intent.getComponent() != null) { 6650 return false; 6651 } 6652 } 6653 return true; 6654 } catch (ClassCastException e) { 6655 } 6656 return false; 6657 } 6658 6659 @Override 6660 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6661 if (!(pendingResult instanceof PendingIntentRecord)) { 6662 return false; 6663 } 6664 try { 6665 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6666 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6667 return true; 6668 } 6669 return false; 6670 } catch (ClassCastException e) { 6671 } 6672 return false; 6673 } 6674 6675 @Override 6676 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6677 if (!(pendingResult instanceof PendingIntentRecord)) { 6678 return null; 6679 } 6680 try { 6681 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6682 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6683 } catch (ClassCastException e) { 6684 } 6685 return null; 6686 } 6687 6688 @Override 6689 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6690 if (!(pendingResult instanceof PendingIntentRecord)) { 6691 return null; 6692 } 6693 try { 6694 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6695 Intent intent = res.key.requestIntent; 6696 if (intent != null) { 6697 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6698 || res.lastTagPrefix.equals(prefix))) { 6699 return res.lastTag; 6700 } 6701 res.lastTagPrefix = prefix; 6702 StringBuilder sb = new StringBuilder(128); 6703 if (prefix != null) { 6704 sb.append(prefix); 6705 } 6706 if (intent.getAction() != null) { 6707 sb.append(intent.getAction()); 6708 } else if (intent.getComponent() != null) { 6709 intent.getComponent().appendShortString(sb); 6710 } else { 6711 sb.append("?"); 6712 } 6713 return res.lastTag = sb.toString(); 6714 } 6715 } catch (ClassCastException e) { 6716 } 6717 return null; 6718 } 6719 6720 @Override 6721 public void setProcessLimit(int max) { 6722 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6723 "setProcessLimit()"); 6724 synchronized (this) { 6725 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6726 mProcessLimitOverride = max; 6727 } 6728 trimApplications(); 6729 } 6730 6731 @Override 6732 public int getProcessLimit() { 6733 synchronized (this) { 6734 return mProcessLimitOverride; 6735 } 6736 } 6737 6738 void foregroundTokenDied(ForegroundToken token) { 6739 synchronized (ActivityManagerService.this) { 6740 synchronized (mPidsSelfLocked) { 6741 ForegroundToken cur 6742 = mForegroundProcesses.get(token.pid); 6743 if (cur != token) { 6744 return; 6745 } 6746 mForegroundProcesses.remove(token.pid); 6747 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6748 if (pr == null) { 6749 return; 6750 } 6751 pr.forcingToForeground = null; 6752 updateProcessForegroundLocked(pr, false, false); 6753 } 6754 updateOomAdjLocked(); 6755 } 6756 } 6757 6758 @Override 6759 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6760 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6761 "setProcessForeground()"); 6762 synchronized(this) { 6763 boolean changed = false; 6764 6765 synchronized (mPidsSelfLocked) { 6766 ProcessRecord pr = mPidsSelfLocked.get(pid); 6767 if (pr == null && isForeground) { 6768 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6769 return; 6770 } 6771 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6772 if (oldToken != null) { 6773 oldToken.token.unlinkToDeath(oldToken, 0); 6774 mForegroundProcesses.remove(pid); 6775 if (pr != null) { 6776 pr.forcingToForeground = null; 6777 } 6778 changed = true; 6779 } 6780 if (isForeground && token != null) { 6781 ForegroundToken newToken = new ForegroundToken() { 6782 @Override 6783 public void binderDied() { 6784 foregroundTokenDied(this); 6785 } 6786 }; 6787 newToken.pid = pid; 6788 newToken.token = token; 6789 try { 6790 token.linkToDeath(newToken, 0); 6791 mForegroundProcesses.put(pid, newToken); 6792 pr.forcingToForeground = token; 6793 changed = true; 6794 } catch (RemoteException e) { 6795 // If the process died while doing this, we will later 6796 // do the cleanup with the process death link. 6797 } 6798 } 6799 } 6800 6801 if (changed) { 6802 updateOomAdjLocked(); 6803 } 6804 } 6805 } 6806 6807 // ========================================================= 6808 // PERMISSIONS 6809 // ========================================================= 6810 6811 static class PermissionController extends IPermissionController.Stub { 6812 ActivityManagerService mActivityManagerService; 6813 PermissionController(ActivityManagerService activityManagerService) { 6814 mActivityManagerService = activityManagerService; 6815 } 6816 6817 @Override 6818 public boolean checkPermission(String permission, int pid, int uid) { 6819 return mActivityManagerService.checkPermission(permission, pid, 6820 uid) == PackageManager.PERMISSION_GRANTED; 6821 } 6822 } 6823 6824 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6825 @Override 6826 public int checkComponentPermission(String permission, int pid, int uid, 6827 int owningUid, boolean exported) { 6828 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6829 owningUid, exported); 6830 } 6831 6832 @Override 6833 public Object getAMSLock() { 6834 return ActivityManagerService.this; 6835 } 6836 } 6837 6838 /** 6839 * This can be called with or without the global lock held. 6840 */ 6841 int checkComponentPermission(String permission, int pid, int uid, 6842 int owningUid, boolean exported) { 6843 if (pid == MY_PID) { 6844 return PackageManager.PERMISSION_GRANTED; 6845 } 6846 return ActivityManager.checkComponentPermission(permission, uid, 6847 owningUid, exported); 6848 } 6849 6850 /** 6851 * As the only public entry point for permissions checking, this method 6852 * can enforce the semantic that requesting a check on a null global 6853 * permission is automatically denied. (Internally a null permission 6854 * string is used when calling {@link #checkComponentPermission} in cases 6855 * when only uid-based security is needed.) 6856 * 6857 * This can be called with or without the global lock held. 6858 */ 6859 @Override 6860 public int checkPermission(String permission, int pid, int uid) { 6861 if (permission == null) { 6862 return PackageManager.PERMISSION_DENIED; 6863 } 6864 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6865 } 6866 6867 @Override 6868 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6869 if (permission == null) { 6870 return PackageManager.PERMISSION_DENIED; 6871 } 6872 6873 // We might be performing an operation on behalf of an indirect binder 6874 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6875 // client identity accordingly before proceeding. 6876 Identity tlsIdentity = sCallerIdentity.get(); 6877 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6878 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6879 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6880 uid = tlsIdentity.uid; 6881 pid = tlsIdentity.pid; 6882 } 6883 6884 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6885 } 6886 6887 /** 6888 * Binder IPC calls go through the public entry point. 6889 * This can be called with or without the global lock held. 6890 */ 6891 int checkCallingPermission(String permission) { 6892 return checkPermission(permission, 6893 Binder.getCallingPid(), 6894 UserHandle.getAppId(Binder.getCallingUid())); 6895 } 6896 6897 /** 6898 * This can be called with or without the global lock held. 6899 */ 6900 void enforceCallingPermission(String permission, String func) { 6901 if (checkCallingPermission(permission) 6902 == PackageManager.PERMISSION_GRANTED) { 6903 return; 6904 } 6905 6906 String msg = "Permission Denial: " + func + " from pid=" 6907 + Binder.getCallingPid() 6908 + ", uid=" + Binder.getCallingUid() 6909 + " requires " + permission; 6910 Slog.w(TAG, msg); 6911 throw new SecurityException(msg); 6912 } 6913 6914 /** 6915 * Determine if UID is holding permissions required to access {@link Uri} in 6916 * the given {@link ProviderInfo}. Final permission checking is always done 6917 * in {@link ContentProvider}. 6918 */ 6919 private final boolean checkHoldingPermissionsLocked( 6920 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6921 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6922 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6923 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6924 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6925 != PERMISSION_GRANTED) { 6926 return false; 6927 } 6928 } 6929 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6930 } 6931 6932 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6933 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6934 if (pi.applicationInfo.uid == uid) { 6935 return true; 6936 } else if (!pi.exported) { 6937 return false; 6938 } 6939 6940 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6941 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6942 try { 6943 // check if target holds top-level <provider> permissions 6944 if (!readMet && pi.readPermission != null && considerUidPermissions 6945 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6946 readMet = true; 6947 } 6948 if (!writeMet && pi.writePermission != null && considerUidPermissions 6949 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6950 writeMet = true; 6951 } 6952 6953 // track if unprotected read/write is allowed; any denied 6954 // <path-permission> below removes this ability 6955 boolean allowDefaultRead = pi.readPermission == null; 6956 boolean allowDefaultWrite = pi.writePermission == null; 6957 6958 // check if target holds any <path-permission> that match uri 6959 final PathPermission[] pps = pi.pathPermissions; 6960 if (pps != null) { 6961 final String path = grantUri.uri.getPath(); 6962 int i = pps.length; 6963 while (i > 0 && (!readMet || !writeMet)) { 6964 i--; 6965 PathPermission pp = pps[i]; 6966 if (pp.match(path)) { 6967 if (!readMet) { 6968 final String pprperm = pp.getReadPermission(); 6969 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6970 + pprperm + " for " + pp.getPath() 6971 + ": match=" + pp.match(path) 6972 + " check=" + pm.checkUidPermission(pprperm, uid)); 6973 if (pprperm != null) { 6974 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6975 == PERMISSION_GRANTED) { 6976 readMet = true; 6977 } else { 6978 allowDefaultRead = false; 6979 } 6980 } 6981 } 6982 if (!writeMet) { 6983 final String ppwperm = pp.getWritePermission(); 6984 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6985 + ppwperm + " for " + pp.getPath() 6986 + ": match=" + pp.match(path) 6987 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6988 if (ppwperm != null) { 6989 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6990 == PERMISSION_GRANTED) { 6991 writeMet = true; 6992 } else { 6993 allowDefaultWrite = false; 6994 } 6995 } 6996 } 6997 } 6998 } 6999 } 7000 7001 // grant unprotected <provider> read/write, if not blocked by 7002 // <path-permission> above 7003 if (allowDefaultRead) readMet = true; 7004 if (allowDefaultWrite) writeMet = true; 7005 7006 } catch (RemoteException e) { 7007 return false; 7008 } 7009 7010 return readMet && writeMet; 7011 } 7012 7013 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7014 ProviderInfo pi = null; 7015 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7016 if (cpr != null) { 7017 pi = cpr.info; 7018 } else { 7019 try { 7020 pi = AppGlobals.getPackageManager().resolveContentProvider( 7021 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7022 } catch (RemoteException ex) { 7023 } 7024 } 7025 return pi; 7026 } 7027 7028 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7029 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7030 if (targetUris != null) { 7031 return targetUris.get(grantUri); 7032 } 7033 return null; 7034 } 7035 7036 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7037 String targetPkg, int targetUid, GrantUri grantUri) { 7038 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7039 if (targetUris == null) { 7040 targetUris = Maps.newArrayMap(); 7041 mGrantedUriPermissions.put(targetUid, targetUris); 7042 } 7043 7044 UriPermission perm = targetUris.get(grantUri); 7045 if (perm == null) { 7046 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7047 targetUris.put(grantUri, perm); 7048 } 7049 7050 return perm; 7051 } 7052 7053 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7054 final int modeFlags) { 7055 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7056 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7057 : UriPermission.STRENGTH_OWNED; 7058 7059 // Root gets to do everything. 7060 if (uid == 0) { 7061 return true; 7062 } 7063 7064 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7065 if (perms == null) return false; 7066 7067 // First look for exact match 7068 final UriPermission exactPerm = perms.get(grantUri); 7069 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7070 return true; 7071 } 7072 7073 // No exact match, look for prefixes 7074 final int N = perms.size(); 7075 for (int i = 0; i < N; i++) { 7076 final UriPermission perm = perms.valueAt(i); 7077 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7078 && perm.getStrength(modeFlags) >= minStrength) { 7079 return true; 7080 } 7081 } 7082 7083 return false; 7084 } 7085 7086 /** 7087 * @param uri This uri must NOT contain an embedded userId. 7088 * @param userId The userId in which the uri is to be resolved. 7089 */ 7090 @Override 7091 public int checkUriPermission(Uri uri, int pid, int uid, 7092 final int modeFlags, int userId, IBinder callerToken) { 7093 enforceNotIsolatedCaller("checkUriPermission"); 7094 7095 // Another redirected-binder-call permissions check as in 7096 // {@link checkPermissionWithToken}. 7097 Identity tlsIdentity = sCallerIdentity.get(); 7098 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7099 uid = tlsIdentity.uid; 7100 pid = tlsIdentity.pid; 7101 } 7102 7103 // Our own process gets to do everything. 7104 if (pid == MY_PID) { 7105 return PackageManager.PERMISSION_GRANTED; 7106 } 7107 synchronized (this) { 7108 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7109 ? PackageManager.PERMISSION_GRANTED 7110 : PackageManager.PERMISSION_DENIED; 7111 } 7112 } 7113 7114 /** 7115 * Check if the targetPkg can be granted permission to access uri by 7116 * the callingUid using the given modeFlags. Throws a security exception 7117 * if callingUid is not allowed to do this. Returns the uid of the target 7118 * if the URI permission grant should be performed; returns -1 if it is not 7119 * needed (for example targetPkg already has permission to access the URI). 7120 * If you already know the uid of the target, you can supply it in 7121 * lastTargetUid else set that to -1. 7122 */ 7123 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7124 final int modeFlags, int lastTargetUid) { 7125 if (!Intent.isAccessUriMode(modeFlags)) { 7126 return -1; 7127 } 7128 7129 if (targetPkg != null) { 7130 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7131 "Checking grant " + targetPkg + " permission to " + grantUri); 7132 } 7133 7134 final IPackageManager pm = AppGlobals.getPackageManager(); 7135 7136 // If this is not a content: uri, we can't do anything with it. 7137 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7138 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7139 "Can't grant URI permission for non-content URI: " + grantUri); 7140 return -1; 7141 } 7142 7143 final String authority = grantUri.uri.getAuthority(); 7144 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7145 if (pi == null) { 7146 Slog.w(TAG, "No content provider found for permission check: " + 7147 grantUri.uri.toSafeString()); 7148 return -1; 7149 } 7150 7151 int targetUid = lastTargetUid; 7152 if (targetUid < 0 && targetPkg != null) { 7153 try { 7154 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7155 if (targetUid < 0) { 7156 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7157 "Can't grant URI permission no uid for: " + targetPkg); 7158 return -1; 7159 } 7160 } catch (RemoteException ex) { 7161 return -1; 7162 } 7163 } 7164 7165 if (targetUid >= 0) { 7166 // First... does the target actually need this permission? 7167 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7168 // No need to grant the target this permission. 7169 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7170 "Target " + targetPkg + " already has full permission to " + grantUri); 7171 return -1; 7172 } 7173 } else { 7174 // First... there is no target package, so can anyone access it? 7175 boolean allowed = pi.exported; 7176 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7177 if (pi.readPermission != null) { 7178 allowed = false; 7179 } 7180 } 7181 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7182 if (pi.writePermission != null) { 7183 allowed = false; 7184 } 7185 } 7186 if (allowed) { 7187 return -1; 7188 } 7189 } 7190 7191 /* There is a special cross user grant if: 7192 * - The target is on another user. 7193 * - Apps on the current user can access the uri without any uid permissions. 7194 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7195 * grant uri permissions. 7196 */ 7197 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7198 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7199 modeFlags, false /*without considering the uid permissions*/); 7200 7201 // Second... is the provider allowing granting of URI permissions? 7202 if (!specialCrossUserGrant) { 7203 if (!pi.grantUriPermissions) { 7204 throw new SecurityException("Provider " + pi.packageName 7205 + "/" + pi.name 7206 + " does not allow granting of Uri permissions (uri " 7207 + grantUri + ")"); 7208 } 7209 if (pi.uriPermissionPatterns != null) { 7210 final int N = pi.uriPermissionPatterns.length; 7211 boolean allowed = false; 7212 for (int i=0; i<N; i++) { 7213 if (pi.uriPermissionPatterns[i] != null 7214 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7215 allowed = true; 7216 break; 7217 } 7218 } 7219 if (!allowed) { 7220 throw new SecurityException("Provider " + pi.packageName 7221 + "/" + pi.name 7222 + " does not allow granting of permission to path of Uri " 7223 + grantUri); 7224 } 7225 } 7226 } 7227 7228 // Third... does the caller itself have permission to access 7229 // this uri? 7230 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7231 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7232 // Require they hold a strong enough Uri permission 7233 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7234 throw new SecurityException("Uid " + callingUid 7235 + " does not have permission to uri " + grantUri); 7236 } 7237 } 7238 } 7239 return targetUid; 7240 } 7241 7242 /** 7243 * @param uri This uri must NOT contain an embedded userId. 7244 * @param userId The userId in which the uri is to be resolved. 7245 */ 7246 @Override 7247 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7248 final int modeFlags, int userId) { 7249 enforceNotIsolatedCaller("checkGrantUriPermission"); 7250 synchronized(this) { 7251 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7252 new GrantUri(userId, uri, false), modeFlags, -1); 7253 } 7254 } 7255 7256 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7257 final int modeFlags, UriPermissionOwner owner) { 7258 if (!Intent.isAccessUriMode(modeFlags)) { 7259 return; 7260 } 7261 7262 // So here we are: the caller has the assumed permission 7263 // to the uri, and the target doesn't. Let's now give this to 7264 // the target. 7265 7266 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7267 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7268 7269 final String authority = grantUri.uri.getAuthority(); 7270 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7271 if (pi == null) { 7272 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7273 return; 7274 } 7275 7276 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7277 grantUri.prefix = true; 7278 } 7279 final UriPermission perm = findOrCreateUriPermissionLocked( 7280 pi.packageName, targetPkg, targetUid, grantUri); 7281 perm.grantModes(modeFlags, owner); 7282 } 7283 7284 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7285 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7286 if (targetPkg == null) { 7287 throw new NullPointerException("targetPkg"); 7288 } 7289 int targetUid; 7290 final IPackageManager pm = AppGlobals.getPackageManager(); 7291 try { 7292 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7293 } catch (RemoteException ex) { 7294 return; 7295 } 7296 7297 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7298 targetUid); 7299 if (targetUid < 0) { 7300 return; 7301 } 7302 7303 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7304 owner); 7305 } 7306 7307 static class NeededUriGrants extends ArrayList<GrantUri> { 7308 final String targetPkg; 7309 final int targetUid; 7310 final int flags; 7311 7312 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7313 this.targetPkg = targetPkg; 7314 this.targetUid = targetUid; 7315 this.flags = flags; 7316 } 7317 } 7318 7319 /** 7320 * Like checkGrantUriPermissionLocked, but takes an Intent. 7321 */ 7322 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7323 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7324 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7325 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7326 + " clip=" + (intent != null ? intent.getClipData() : null) 7327 + " from " + intent + "; flags=0x" 7328 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7329 7330 if (targetPkg == null) { 7331 throw new NullPointerException("targetPkg"); 7332 } 7333 7334 if (intent == null) { 7335 return null; 7336 } 7337 Uri data = intent.getData(); 7338 ClipData clip = intent.getClipData(); 7339 if (data == null && clip == null) { 7340 return null; 7341 } 7342 // Default userId for uris in the intent (if they don't specify it themselves) 7343 int contentUserHint = intent.getContentUserHint(); 7344 if (contentUserHint == UserHandle.USER_CURRENT) { 7345 contentUserHint = UserHandle.getUserId(callingUid); 7346 } 7347 final IPackageManager pm = AppGlobals.getPackageManager(); 7348 int targetUid; 7349 if (needed != null) { 7350 targetUid = needed.targetUid; 7351 } else { 7352 try { 7353 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7354 } catch (RemoteException ex) { 7355 return null; 7356 } 7357 if (targetUid < 0) { 7358 if (DEBUG_URI_PERMISSION) { 7359 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7360 + " on user " + targetUserId); 7361 } 7362 return null; 7363 } 7364 } 7365 if (data != null) { 7366 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7367 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7368 targetUid); 7369 if (targetUid > 0) { 7370 if (needed == null) { 7371 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7372 } 7373 needed.add(grantUri); 7374 } 7375 } 7376 if (clip != null) { 7377 for (int i=0; i<clip.getItemCount(); i++) { 7378 Uri uri = clip.getItemAt(i).getUri(); 7379 if (uri != null) { 7380 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7381 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7382 targetUid); 7383 if (targetUid > 0) { 7384 if (needed == null) { 7385 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7386 } 7387 needed.add(grantUri); 7388 } 7389 } else { 7390 Intent clipIntent = clip.getItemAt(i).getIntent(); 7391 if (clipIntent != null) { 7392 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7393 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7394 if (newNeeded != null) { 7395 needed = newNeeded; 7396 } 7397 } 7398 } 7399 } 7400 } 7401 7402 return needed; 7403 } 7404 7405 /** 7406 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7407 */ 7408 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7409 UriPermissionOwner owner) { 7410 if (needed != null) { 7411 for (int i=0; i<needed.size(); i++) { 7412 GrantUri grantUri = needed.get(i); 7413 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7414 grantUri, needed.flags, owner); 7415 } 7416 } 7417 } 7418 7419 void grantUriPermissionFromIntentLocked(int callingUid, 7420 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7421 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7422 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7423 if (needed == null) { 7424 return; 7425 } 7426 7427 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7428 } 7429 7430 /** 7431 * @param uri This uri must NOT contain an embedded userId. 7432 * @param userId The userId in which the uri is to be resolved. 7433 */ 7434 @Override 7435 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7436 final int modeFlags, int userId) { 7437 enforceNotIsolatedCaller("grantUriPermission"); 7438 GrantUri grantUri = new GrantUri(userId, uri, false); 7439 synchronized(this) { 7440 final ProcessRecord r = getRecordForAppLocked(caller); 7441 if (r == null) { 7442 throw new SecurityException("Unable to find app for caller " 7443 + caller 7444 + " when granting permission to uri " + grantUri); 7445 } 7446 if (targetPkg == null) { 7447 throw new IllegalArgumentException("null target"); 7448 } 7449 if (grantUri == null) { 7450 throw new IllegalArgumentException("null uri"); 7451 } 7452 7453 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7454 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7455 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7456 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7457 7458 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7459 UserHandle.getUserId(r.uid)); 7460 } 7461 } 7462 7463 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7464 if (perm.modeFlags == 0) { 7465 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7466 perm.targetUid); 7467 if (perms != null) { 7468 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7469 "Removing " + perm.targetUid + " permission to " + perm.uri); 7470 7471 perms.remove(perm.uri); 7472 if (perms.isEmpty()) { 7473 mGrantedUriPermissions.remove(perm.targetUid); 7474 } 7475 } 7476 } 7477 } 7478 7479 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7480 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7481 7482 final IPackageManager pm = AppGlobals.getPackageManager(); 7483 final String authority = grantUri.uri.getAuthority(); 7484 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7485 if (pi == null) { 7486 Slog.w(TAG, "No content provider found for permission revoke: " 7487 + grantUri.toSafeString()); 7488 return; 7489 } 7490 7491 // Does the caller have this permission on the URI? 7492 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7493 // If they don't have direct access to the URI, then revoke any 7494 // ownerless URI permissions that have been granted to them. 7495 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7496 if (perms != null) { 7497 boolean persistChanged = false; 7498 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7499 final UriPermission perm = it.next(); 7500 if (perm.uri.sourceUserId == grantUri.sourceUserId 7501 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7502 if (DEBUG_URI_PERMISSION) 7503 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7504 " permission to " + perm.uri); 7505 persistChanged |= perm.revokeModes( 7506 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7507 if (perm.modeFlags == 0) { 7508 it.remove(); 7509 } 7510 } 7511 } 7512 if (perms.isEmpty()) { 7513 mGrantedUriPermissions.remove(callingUid); 7514 } 7515 if (persistChanged) { 7516 schedulePersistUriGrants(); 7517 } 7518 } 7519 return; 7520 } 7521 7522 boolean persistChanged = false; 7523 7524 // Go through all of the permissions and remove any that match. 7525 int N = mGrantedUriPermissions.size(); 7526 for (int i = 0; i < N; i++) { 7527 final int targetUid = mGrantedUriPermissions.keyAt(i); 7528 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7529 7530 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7531 final UriPermission perm = it.next(); 7532 if (perm.uri.sourceUserId == grantUri.sourceUserId 7533 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7534 if (DEBUG_URI_PERMISSION) 7535 Slog.v(TAG, 7536 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7537 persistChanged |= perm.revokeModes( 7538 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7539 if (perm.modeFlags == 0) { 7540 it.remove(); 7541 } 7542 } 7543 } 7544 7545 if (perms.isEmpty()) { 7546 mGrantedUriPermissions.remove(targetUid); 7547 N--; 7548 i--; 7549 } 7550 } 7551 7552 if (persistChanged) { 7553 schedulePersistUriGrants(); 7554 } 7555 } 7556 7557 /** 7558 * @param uri This uri must NOT contain an embedded userId. 7559 * @param userId The userId in which the uri is to be resolved. 7560 */ 7561 @Override 7562 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7563 int userId) { 7564 enforceNotIsolatedCaller("revokeUriPermission"); 7565 synchronized(this) { 7566 final ProcessRecord r = getRecordForAppLocked(caller); 7567 if (r == null) { 7568 throw new SecurityException("Unable to find app for caller " 7569 + caller 7570 + " when revoking permission to uri " + uri); 7571 } 7572 if (uri == null) { 7573 Slog.w(TAG, "revokeUriPermission: null uri"); 7574 return; 7575 } 7576 7577 if (!Intent.isAccessUriMode(modeFlags)) { 7578 return; 7579 } 7580 7581 final IPackageManager pm = AppGlobals.getPackageManager(); 7582 final String authority = uri.getAuthority(); 7583 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7584 if (pi == null) { 7585 Slog.w(TAG, "No content provider found for permission revoke: " 7586 + uri.toSafeString()); 7587 return; 7588 } 7589 7590 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7591 } 7592 } 7593 7594 /** 7595 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7596 * given package. 7597 * 7598 * @param packageName Package name to match, or {@code null} to apply to all 7599 * packages. 7600 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7601 * to all users. 7602 * @param persistable If persistable grants should be removed. 7603 */ 7604 private void removeUriPermissionsForPackageLocked( 7605 String packageName, int userHandle, boolean persistable) { 7606 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7607 throw new IllegalArgumentException("Must narrow by either package or user"); 7608 } 7609 7610 boolean persistChanged = false; 7611 7612 int N = mGrantedUriPermissions.size(); 7613 for (int i = 0; i < N; i++) { 7614 final int targetUid = mGrantedUriPermissions.keyAt(i); 7615 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7616 7617 // Only inspect grants matching user 7618 if (userHandle == UserHandle.USER_ALL 7619 || userHandle == UserHandle.getUserId(targetUid)) { 7620 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7621 final UriPermission perm = it.next(); 7622 7623 // Only inspect grants matching package 7624 if (packageName == null || perm.sourcePkg.equals(packageName) 7625 || perm.targetPkg.equals(packageName)) { 7626 persistChanged |= perm.revokeModes(persistable 7627 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7628 7629 // Only remove when no modes remain; any persisted grants 7630 // will keep this alive. 7631 if (perm.modeFlags == 0) { 7632 it.remove(); 7633 } 7634 } 7635 } 7636 7637 if (perms.isEmpty()) { 7638 mGrantedUriPermissions.remove(targetUid); 7639 N--; 7640 i--; 7641 } 7642 } 7643 } 7644 7645 if (persistChanged) { 7646 schedulePersistUriGrants(); 7647 } 7648 } 7649 7650 @Override 7651 public IBinder newUriPermissionOwner(String name) { 7652 enforceNotIsolatedCaller("newUriPermissionOwner"); 7653 synchronized(this) { 7654 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7655 return owner.getExternalTokenLocked(); 7656 } 7657 } 7658 7659 /** 7660 * @param uri This uri must NOT contain an embedded userId. 7661 * @param sourceUserId The userId in which the uri is to be resolved. 7662 * @param targetUserId The userId of the app that receives the grant. 7663 */ 7664 @Override 7665 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7666 final int modeFlags, int sourceUserId, int targetUserId) { 7667 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7668 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7669 synchronized(this) { 7670 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7671 if (owner == null) { 7672 throw new IllegalArgumentException("Unknown owner: " + token); 7673 } 7674 if (fromUid != Binder.getCallingUid()) { 7675 if (Binder.getCallingUid() != Process.myUid()) { 7676 // Only system code can grant URI permissions on behalf 7677 // of other users. 7678 throw new SecurityException("nice try"); 7679 } 7680 } 7681 if (targetPkg == null) { 7682 throw new IllegalArgumentException("null target"); 7683 } 7684 if (uri == null) { 7685 throw new IllegalArgumentException("null uri"); 7686 } 7687 7688 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7689 modeFlags, owner, targetUserId); 7690 } 7691 } 7692 7693 /** 7694 * @param uri This uri must NOT contain an embedded userId. 7695 * @param userId The userId in which the uri is to be resolved. 7696 */ 7697 @Override 7698 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7699 synchronized(this) { 7700 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7701 if (owner == null) { 7702 throw new IllegalArgumentException("Unknown owner: " + token); 7703 } 7704 7705 if (uri == null) { 7706 owner.removeUriPermissionsLocked(mode); 7707 } else { 7708 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7709 } 7710 } 7711 } 7712 7713 private void schedulePersistUriGrants() { 7714 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7715 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7716 10 * DateUtils.SECOND_IN_MILLIS); 7717 } 7718 } 7719 7720 private void writeGrantedUriPermissions() { 7721 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7722 7723 // Snapshot permissions so we can persist without lock 7724 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7725 synchronized (this) { 7726 final int size = mGrantedUriPermissions.size(); 7727 for (int i = 0; i < size; i++) { 7728 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7729 for (UriPermission perm : perms.values()) { 7730 if (perm.persistedModeFlags != 0) { 7731 persist.add(perm.snapshot()); 7732 } 7733 } 7734 } 7735 } 7736 7737 FileOutputStream fos = null; 7738 try { 7739 fos = mGrantFile.startWrite(); 7740 7741 XmlSerializer out = new FastXmlSerializer(); 7742 out.setOutput(fos, "utf-8"); 7743 out.startDocument(null, true); 7744 out.startTag(null, TAG_URI_GRANTS); 7745 for (UriPermission.Snapshot perm : persist) { 7746 out.startTag(null, TAG_URI_GRANT); 7747 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7748 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7749 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7750 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7751 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7752 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7753 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7754 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7755 out.endTag(null, TAG_URI_GRANT); 7756 } 7757 out.endTag(null, TAG_URI_GRANTS); 7758 out.endDocument(); 7759 7760 mGrantFile.finishWrite(fos); 7761 } catch (IOException e) { 7762 if (fos != null) { 7763 mGrantFile.failWrite(fos); 7764 } 7765 } 7766 } 7767 7768 private void readGrantedUriPermissionsLocked() { 7769 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7770 7771 final long now = System.currentTimeMillis(); 7772 7773 FileInputStream fis = null; 7774 try { 7775 fis = mGrantFile.openRead(); 7776 final XmlPullParser in = Xml.newPullParser(); 7777 in.setInput(fis, null); 7778 7779 int type; 7780 while ((type = in.next()) != END_DOCUMENT) { 7781 final String tag = in.getName(); 7782 if (type == START_TAG) { 7783 if (TAG_URI_GRANT.equals(tag)) { 7784 final int sourceUserId; 7785 final int targetUserId; 7786 final int userHandle = readIntAttribute(in, 7787 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7788 if (userHandle != UserHandle.USER_NULL) { 7789 // For backwards compatibility. 7790 sourceUserId = userHandle; 7791 targetUserId = userHandle; 7792 } else { 7793 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7794 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7795 } 7796 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7797 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7798 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7799 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7800 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7801 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7802 7803 // Sanity check that provider still belongs to source package 7804 final ProviderInfo pi = getProviderInfoLocked( 7805 uri.getAuthority(), sourceUserId); 7806 if (pi != null && sourcePkg.equals(pi.packageName)) { 7807 int targetUid = -1; 7808 try { 7809 targetUid = AppGlobals.getPackageManager() 7810 .getPackageUid(targetPkg, targetUserId); 7811 } catch (RemoteException e) { 7812 } 7813 if (targetUid != -1) { 7814 final UriPermission perm = findOrCreateUriPermissionLocked( 7815 sourcePkg, targetPkg, targetUid, 7816 new GrantUri(sourceUserId, uri, prefix)); 7817 perm.initPersistedModes(modeFlags, createdTime); 7818 } 7819 } else { 7820 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7821 + " but instead found " + pi); 7822 } 7823 } 7824 } 7825 } 7826 } catch (FileNotFoundException e) { 7827 // Missing grants is okay 7828 } catch (IOException e) { 7829 Slog.wtf(TAG, "Failed reading Uri grants", e); 7830 } catch (XmlPullParserException e) { 7831 Slog.wtf(TAG, "Failed reading Uri grants", e); 7832 } finally { 7833 IoUtils.closeQuietly(fis); 7834 } 7835 } 7836 7837 /** 7838 * @param uri This uri must NOT contain an embedded userId. 7839 * @param userId The userId in which the uri is to be resolved. 7840 */ 7841 @Override 7842 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7843 enforceNotIsolatedCaller("takePersistableUriPermission"); 7844 7845 Preconditions.checkFlagsArgument(modeFlags, 7846 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7847 7848 synchronized (this) { 7849 final int callingUid = Binder.getCallingUid(); 7850 boolean persistChanged = false; 7851 GrantUri grantUri = new GrantUri(userId, uri, 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 7858 final boolean exactValid = (exactPerm != null) 7859 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7860 final boolean prefixValid = (prefixPerm != null) 7861 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7862 7863 if (!(exactValid || prefixValid)) { 7864 throw new SecurityException("No persistable permission grants found for UID " 7865 + callingUid + " and Uri " + grantUri.toSafeString()); 7866 } 7867 7868 if (exactValid) { 7869 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7870 } 7871 if (prefixValid) { 7872 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7873 } 7874 7875 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7876 7877 if (persistChanged) { 7878 schedulePersistUriGrants(); 7879 } 7880 } 7881 } 7882 7883 /** 7884 * @param uri This uri must NOT contain an embedded userId. 7885 * @param userId The userId in which the uri is to be resolved. 7886 */ 7887 @Override 7888 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7889 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7890 7891 Preconditions.checkFlagsArgument(modeFlags, 7892 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7893 7894 synchronized (this) { 7895 final int callingUid = Binder.getCallingUid(); 7896 boolean persistChanged = false; 7897 7898 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7899 new GrantUri(userId, uri, false)); 7900 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7901 new GrantUri(userId, uri, true)); 7902 if (exactPerm == null && prefixPerm == null) { 7903 throw new SecurityException("No permission grants found for UID " + callingUid 7904 + " and Uri " + uri.toSafeString()); 7905 } 7906 7907 if (exactPerm != null) { 7908 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7909 removeUriPermissionIfNeededLocked(exactPerm); 7910 } 7911 if (prefixPerm != null) { 7912 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7913 removeUriPermissionIfNeededLocked(prefixPerm); 7914 } 7915 7916 if (persistChanged) { 7917 schedulePersistUriGrants(); 7918 } 7919 } 7920 } 7921 7922 /** 7923 * Prune any older {@link UriPermission} for the given UID until outstanding 7924 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7925 * 7926 * @return if any mutations occured that require persisting. 7927 */ 7928 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7929 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7930 if (perms == null) return false; 7931 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7932 7933 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7934 for (UriPermission perm : perms.values()) { 7935 if (perm.persistedModeFlags != 0) { 7936 persisted.add(perm); 7937 } 7938 } 7939 7940 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7941 if (trimCount <= 0) return false; 7942 7943 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7944 for (int i = 0; i < trimCount; i++) { 7945 final UriPermission perm = persisted.get(i); 7946 7947 if (DEBUG_URI_PERMISSION) { 7948 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7949 } 7950 7951 perm.releasePersistableModes(~0); 7952 removeUriPermissionIfNeededLocked(perm); 7953 } 7954 7955 return true; 7956 } 7957 7958 @Override 7959 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7960 String packageName, boolean incoming) { 7961 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7962 Preconditions.checkNotNull(packageName, "packageName"); 7963 7964 final int callingUid = Binder.getCallingUid(); 7965 final IPackageManager pm = AppGlobals.getPackageManager(); 7966 try { 7967 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7968 if (packageUid != callingUid) { 7969 throw new SecurityException( 7970 "Package " + packageName + " does not belong to calling UID " + callingUid); 7971 } 7972 } catch (RemoteException e) { 7973 throw new SecurityException("Failed to verify package name ownership"); 7974 } 7975 7976 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7977 synchronized (this) { 7978 if (incoming) { 7979 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7980 callingUid); 7981 if (perms == null) { 7982 Slog.w(TAG, "No permission grants found for " + packageName); 7983 } else { 7984 for (UriPermission perm : perms.values()) { 7985 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7986 result.add(perm.buildPersistedPublicApiObject()); 7987 } 7988 } 7989 } 7990 } else { 7991 final int size = mGrantedUriPermissions.size(); 7992 for (int i = 0; i < size; i++) { 7993 final ArrayMap<GrantUri, UriPermission> perms = 7994 mGrantedUriPermissions.valueAt(i); 7995 for (UriPermission perm : perms.values()) { 7996 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7997 result.add(perm.buildPersistedPublicApiObject()); 7998 } 7999 } 8000 } 8001 } 8002 } 8003 return new ParceledListSlice<android.content.UriPermission>(result); 8004 } 8005 8006 @Override 8007 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8008 synchronized (this) { 8009 ProcessRecord app = 8010 who != null ? getRecordForAppLocked(who) : null; 8011 if (app == null) return; 8012 8013 Message msg = Message.obtain(); 8014 msg.what = WAIT_FOR_DEBUGGER_MSG; 8015 msg.obj = app; 8016 msg.arg1 = waiting ? 1 : 0; 8017 mHandler.sendMessage(msg); 8018 } 8019 } 8020 8021 @Override 8022 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8023 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8024 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8025 outInfo.availMem = Process.getFreeMemory(); 8026 outInfo.totalMem = Process.getTotalMemory(); 8027 outInfo.threshold = homeAppMem; 8028 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8029 outInfo.hiddenAppThreshold = cachedAppMem; 8030 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8031 ProcessList.SERVICE_ADJ); 8032 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8033 ProcessList.VISIBLE_APP_ADJ); 8034 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8035 ProcessList.FOREGROUND_APP_ADJ); 8036 } 8037 8038 // ========================================================= 8039 // TASK MANAGEMENT 8040 // ========================================================= 8041 8042 @Override 8043 public List<IAppTask> getAppTasks(String callingPackage) { 8044 int callingUid = Binder.getCallingUid(); 8045 long ident = Binder.clearCallingIdentity(); 8046 8047 synchronized(this) { 8048 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8049 try { 8050 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8051 8052 final int N = mRecentTasks.size(); 8053 for (int i = 0; i < N; i++) { 8054 TaskRecord tr = mRecentTasks.get(i); 8055 // Skip tasks that do not match the caller. We don't need to verify 8056 // callingPackage, because we are also limiting to callingUid and know 8057 // that will limit to the correct security sandbox. 8058 if (tr.effectiveUid != callingUid) { 8059 continue; 8060 } 8061 Intent intent = tr.getBaseIntent(); 8062 if (intent == null || 8063 !callingPackage.equals(intent.getComponent().getPackageName())) { 8064 continue; 8065 } 8066 ActivityManager.RecentTaskInfo taskInfo = 8067 createRecentTaskInfoFromTaskRecord(tr); 8068 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8069 list.add(taskImpl); 8070 } 8071 } finally { 8072 Binder.restoreCallingIdentity(ident); 8073 } 8074 return list; 8075 } 8076 } 8077 8078 @Override 8079 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8080 final int callingUid = Binder.getCallingUid(); 8081 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8082 8083 synchronized(this) { 8084 if (localLOGV) Slog.v( 8085 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8086 8087 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8088 callingUid); 8089 8090 // TODO: Improve with MRU list from all ActivityStacks. 8091 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8092 } 8093 8094 return list; 8095 } 8096 8097 /** 8098 * Creates a new RecentTaskInfo from a TaskRecord. 8099 */ 8100 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8101 // Update the task description to reflect any changes in the task stack 8102 tr.updateTaskDescription(); 8103 8104 // Compose the recent task info 8105 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8106 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8107 rti.persistentId = tr.taskId; 8108 rti.baseIntent = new Intent(tr.getBaseIntent()); 8109 rti.origActivity = tr.origActivity; 8110 rti.description = tr.lastDescription; 8111 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8112 rti.userId = tr.userId; 8113 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8114 rti.firstActiveTime = tr.firstActiveTime; 8115 rti.lastActiveTime = tr.lastActiveTime; 8116 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8117 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8118 return rti; 8119 } 8120 8121 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8122 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8123 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8124 if (!allowed) { 8125 if (checkPermission(android.Manifest.permission.GET_TASKS, 8126 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8127 // Temporary compatibility: some existing apps on the system image may 8128 // still be requesting the old permission and not switched to the new 8129 // one; if so, we'll still allow them full access. This means we need 8130 // to see if they are holding the old permission and are a system app. 8131 try { 8132 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8133 allowed = true; 8134 Slog.w(TAG, caller + ": caller " + callingUid 8135 + " is using old GET_TASKS but privileged; allowing"); 8136 } 8137 } catch (RemoteException e) { 8138 } 8139 } 8140 } 8141 if (!allowed) { 8142 Slog.w(TAG, caller + ": caller " + callingUid 8143 + " does not hold GET_TASKS; limiting output"); 8144 } 8145 return allowed; 8146 } 8147 8148 @Override 8149 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8150 final int callingUid = Binder.getCallingUid(); 8151 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8152 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8153 8154 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8155 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8156 synchronized (this) { 8157 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8158 callingUid); 8159 final boolean detailed = checkCallingPermission( 8160 android.Manifest.permission.GET_DETAILED_TASKS) 8161 == PackageManager.PERMISSION_GRANTED; 8162 8163 final int N = mRecentTasks.size(); 8164 ArrayList<ActivityManager.RecentTaskInfo> res 8165 = new ArrayList<ActivityManager.RecentTaskInfo>( 8166 maxNum < N ? maxNum : N); 8167 8168 final Set<Integer> includedUsers; 8169 if (includeProfiles) { 8170 includedUsers = getProfileIdsLocked(userId); 8171 } else { 8172 includedUsers = new HashSet<Integer>(); 8173 } 8174 includedUsers.add(Integer.valueOf(userId)); 8175 8176 for (int i=0; i<N && maxNum > 0; i++) { 8177 TaskRecord tr = mRecentTasks.get(i); 8178 // Only add calling user or related users recent tasks 8179 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8180 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8181 continue; 8182 } 8183 8184 // Return the entry if desired by the caller. We always return 8185 // the first entry, because callers always expect this to be the 8186 // foreground app. We may filter others if the caller has 8187 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8188 // we should exclude the entry. 8189 8190 if (i == 0 8191 || withExcluded 8192 || (tr.intent == null) 8193 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8194 == 0)) { 8195 if (!allowed) { 8196 // If the caller doesn't have the GET_TASKS permission, then only 8197 // allow them to see a small subset of tasks -- their own and home. 8198 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8199 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8200 continue; 8201 } 8202 } 8203 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8204 if (tr.stack != null && tr.stack.isHomeStack()) { 8205 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8206 continue; 8207 } 8208 } 8209 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8210 // Don't include auto remove tasks that are finished or finishing. 8211 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8212 + tr); 8213 continue; 8214 } 8215 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8216 && !tr.isAvailable) { 8217 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8218 continue; 8219 } 8220 8221 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8222 if (!detailed) { 8223 rti.baseIntent.replaceExtras((Bundle)null); 8224 } 8225 8226 res.add(rti); 8227 maxNum--; 8228 } 8229 } 8230 return res; 8231 } 8232 } 8233 8234 TaskRecord recentTaskForIdLocked(int id) { 8235 final int N = mRecentTasks.size(); 8236 for (int i=0; i<N; i++) { 8237 TaskRecord tr = mRecentTasks.get(i); 8238 if (tr.taskId == id) { 8239 return tr; 8240 } 8241 } 8242 return null; 8243 } 8244 8245 @Override 8246 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8247 synchronized (this) { 8248 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8249 "getTaskThumbnail()"); 8250 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8251 if (tr != null) { 8252 return tr.getTaskThumbnailLocked(); 8253 } 8254 } 8255 return null; 8256 } 8257 8258 @Override 8259 public int addAppTask(IBinder activityToken, Intent intent, 8260 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8261 final int callingUid = Binder.getCallingUid(); 8262 final long callingIdent = Binder.clearCallingIdentity(); 8263 8264 try { 8265 synchronized (this) { 8266 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8267 if (r == null) { 8268 throw new IllegalArgumentException("Activity does not exist; token=" 8269 + activityToken); 8270 } 8271 ComponentName comp = intent.getComponent(); 8272 if (comp == null) { 8273 throw new IllegalArgumentException("Intent " + intent 8274 + " must specify explicit component"); 8275 } 8276 if (thumbnail.getWidth() != mThumbnailWidth 8277 || thumbnail.getHeight() != mThumbnailHeight) { 8278 throw new IllegalArgumentException("Bad thumbnail size: got " 8279 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8280 + mThumbnailWidth + "x" + mThumbnailHeight); 8281 } 8282 if (intent.getSelector() != null) { 8283 intent.setSelector(null); 8284 } 8285 if (intent.getSourceBounds() != null) { 8286 intent.setSourceBounds(null); 8287 } 8288 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8289 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8290 // The caller has added this as an auto-remove task... that makes no 8291 // sense, so turn off auto-remove. 8292 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8293 } 8294 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8295 // Must be a new task. 8296 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8297 } 8298 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8299 mLastAddedTaskActivity = null; 8300 } 8301 ActivityInfo ainfo = mLastAddedTaskActivity; 8302 if (ainfo == null) { 8303 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8304 comp, 0, UserHandle.getUserId(callingUid)); 8305 if (ainfo.applicationInfo.uid != callingUid) { 8306 throw new SecurityException( 8307 "Can't add task for another application: target uid=" 8308 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8309 } 8310 } 8311 8312 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8313 intent, description); 8314 8315 int trimIdx = trimRecentsForTaskLocked(task, false); 8316 if (trimIdx >= 0) { 8317 // If this would have caused a trim, then we'll abort because that 8318 // means it would be added at the end of the list but then just removed. 8319 return INVALID_TASK_ID; 8320 } 8321 8322 final int N = mRecentTasks.size(); 8323 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8324 final TaskRecord tr = mRecentTasks.remove(N - 1); 8325 tr.removedFromRecents(); 8326 } 8327 8328 task.inRecents = true; 8329 mRecentTasks.add(task); 8330 r.task.stack.addTask(task, false, false); 8331 8332 task.setLastThumbnail(thumbnail); 8333 task.freeLastThumbnail(); 8334 8335 return task.taskId; 8336 } 8337 } finally { 8338 Binder.restoreCallingIdentity(callingIdent); 8339 } 8340 } 8341 8342 @Override 8343 public Point getAppTaskThumbnailSize() { 8344 synchronized (this) { 8345 return new Point(mThumbnailWidth, mThumbnailHeight); 8346 } 8347 } 8348 8349 @Override 8350 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8351 synchronized (this) { 8352 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8353 if (r != null) { 8354 r.setTaskDescription(td); 8355 r.task.updateTaskDescription(); 8356 } 8357 } 8358 } 8359 8360 @Override 8361 public Bitmap getTaskDescriptionIcon(String filename) { 8362 if (!FileUtils.isValidExtFilename(filename) 8363 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8364 throw new IllegalArgumentException("Bad filename: " + filename); 8365 } 8366 return mTaskPersister.getTaskDescriptionIcon(filename); 8367 } 8368 8369 @Override 8370 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8371 throws RemoteException { 8372 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8373 opts.getCustomInPlaceResId() == 0) { 8374 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8375 "with valid animation"); 8376 } 8377 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8378 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8379 opts.getCustomInPlaceResId()); 8380 mWindowManager.executeAppTransition(); 8381 } 8382 8383 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8384 mRecentTasks.remove(tr); 8385 tr.removedFromRecents(); 8386 ComponentName component = tr.getBaseIntent().getComponent(); 8387 if (component == null) { 8388 Slog.w(TAG, "No component for base intent of task: " + tr); 8389 return; 8390 } 8391 8392 if (!killProcess) { 8393 return; 8394 } 8395 8396 // Determine if the process(es) for this task should be killed. 8397 final String pkg = component.getPackageName(); 8398 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8399 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8400 for (int i = 0; i < pmap.size(); i++) { 8401 8402 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8403 for (int j = 0; j < uids.size(); j++) { 8404 ProcessRecord proc = uids.valueAt(j); 8405 if (proc.userId != tr.userId) { 8406 // Don't kill process for a different user. 8407 continue; 8408 } 8409 if (proc == mHomeProcess) { 8410 // Don't kill the home process along with tasks from the same package. 8411 continue; 8412 } 8413 if (!proc.pkgList.containsKey(pkg)) { 8414 // Don't kill process that is not associated with this task. 8415 continue; 8416 } 8417 8418 for (int k = 0; k < proc.activities.size(); k++) { 8419 TaskRecord otherTask = proc.activities.get(k).task; 8420 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8421 // Don't kill process(es) that has an activity in a different task that is 8422 // also in recents. 8423 return; 8424 } 8425 } 8426 8427 // Add process to kill list. 8428 procsToKill.add(proc); 8429 } 8430 } 8431 8432 // Find any running services associated with this app and stop if needed. 8433 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8434 8435 // Kill the running processes. 8436 for (int i = 0; i < procsToKill.size(); i++) { 8437 ProcessRecord pr = procsToKill.get(i); 8438 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8439 pr.kill("remove task", true); 8440 } else { 8441 pr.waitingToKill = "remove task"; 8442 } 8443 } 8444 } 8445 8446 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8447 // Remove all tasks with activities in the specified package from the list of recent tasks 8448 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8449 TaskRecord tr = mRecentTasks.get(i); 8450 if (tr.userId != userId) continue; 8451 8452 ComponentName cn = tr.intent.getComponent(); 8453 if (cn != null && cn.getPackageName().equals(packageName)) { 8454 // If the package name matches, remove the task. 8455 removeTaskByIdLocked(tr.taskId, true); 8456 } 8457 } 8458 } 8459 8460 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8461 final IPackageManager pm = AppGlobals.getPackageManager(); 8462 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8463 8464 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8465 TaskRecord tr = mRecentTasks.get(i); 8466 if (tr.userId != userId) continue; 8467 8468 ComponentName cn = tr.intent.getComponent(); 8469 if (cn != null && cn.getPackageName().equals(packageName)) { 8470 // Skip if component still exists in the package. 8471 if (componentsKnownToExist.contains(cn)) continue; 8472 8473 try { 8474 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8475 if (info != null) { 8476 componentsKnownToExist.add(cn); 8477 } else { 8478 removeTaskByIdLocked(tr.taskId, false); 8479 } 8480 } catch (RemoteException e) { 8481 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8482 } 8483 } 8484 } 8485 } 8486 8487 /** 8488 * Removes the task with the specified task id. 8489 * 8490 * @param taskId Identifier of the task to be removed. 8491 * @param killProcess Kill any process associated with the task if possible. 8492 * @return Returns true if the given task was found and removed. 8493 */ 8494 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8495 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8496 if (tr != null) { 8497 tr.removeTaskActivitiesLocked(); 8498 cleanUpRemovedTaskLocked(tr, killProcess); 8499 if (tr.isPersistable) { 8500 notifyTaskPersisterLocked(null, true); 8501 } 8502 return true; 8503 } 8504 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8505 return false; 8506 } 8507 8508 @Override 8509 public boolean removeTask(int taskId) { 8510 synchronized (this) { 8511 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8512 "removeTask()"); 8513 long ident = Binder.clearCallingIdentity(); 8514 try { 8515 return removeTaskByIdLocked(taskId, true); 8516 } finally { 8517 Binder.restoreCallingIdentity(ident); 8518 } 8519 } 8520 } 8521 8522 /** 8523 * TODO: Add mController hook 8524 */ 8525 @Override 8526 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8527 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8528 "moveTaskToFront()"); 8529 8530 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8531 synchronized(this) { 8532 moveTaskToFrontLocked(taskId, flags, options); 8533 } 8534 } 8535 8536 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8537 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8538 Binder.getCallingUid(), -1, -1, "Task to front")) { 8539 ActivityOptions.abort(options); 8540 return; 8541 } 8542 final long origId = Binder.clearCallingIdentity(); 8543 try { 8544 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8545 if (task == null) { 8546 Slog.d(TAG, "Could not find task for id: "+ taskId); 8547 return; 8548 } 8549 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8550 mStackSupervisor.showLockTaskToast(); 8551 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8552 return; 8553 } 8554 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8555 if (prev != null && prev.isRecentsActivity()) { 8556 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8557 } 8558 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront"); 8559 } finally { 8560 Binder.restoreCallingIdentity(origId); 8561 } 8562 ActivityOptions.abort(options); 8563 } 8564 8565 @Override 8566 public void moveTaskToBack(int taskId) { 8567 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8568 "moveTaskToBack()"); 8569 8570 synchronized(this) { 8571 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8572 if (tr != null) { 8573 if (tr == mStackSupervisor.mLockTaskModeTask) { 8574 mStackSupervisor.showLockTaskToast(); 8575 return; 8576 } 8577 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8578 ActivityStack stack = tr.stack; 8579 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8580 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8581 Binder.getCallingUid(), -1, -1, "Task to back")) { 8582 return; 8583 } 8584 } 8585 final long origId = Binder.clearCallingIdentity(); 8586 try { 8587 stack.moveTaskToBackLocked(taskId); 8588 } finally { 8589 Binder.restoreCallingIdentity(origId); 8590 } 8591 } 8592 } 8593 } 8594 8595 /** 8596 * Moves an activity, and all of the other activities within the same task, to the bottom 8597 * of the history stack. The activity's order within the task is unchanged. 8598 * 8599 * @param token A reference to the activity we wish to move 8600 * @param nonRoot If false then this only works if the activity is the root 8601 * of a task; if true it will work for any activity in a task. 8602 * @return Returns true if the move completed, false if not. 8603 */ 8604 @Override 8605 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8606 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8607 synchronized(this) { 8608 final long origId = Binder.clearCallingIdentity(); 8609 try { 8610 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8611 if (taskId >= 0) { 8612 if ((mStackSupervisor.mLockTaskModeTask != null) 8613 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8614 mStackSupervisor.showLockTaskToast(); 8615 return false; 8616 } 8617 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 8618 } 8619 } finally { 8620 Binder.restoreCallingIdentity(origId); 8621 } 8622 } 8623 return false; 8624 } 8625 8626 @Override 8627 public void moveTaskBackwards(int task) { 8628 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8629 "moveTaskBackwards()"); 8630 8631 synchronized(this) { 8632 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8633 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8634 return; 8635 } 8636 final long origId = Binder.clearCallingIdentity(); 8637 moveTaskBackwardsLocked(task); 8638 Binder.restoreCallingIdentity(origId); 8639 } 8640 } 8641 8642 private final void moveTaskBackwardsLocked(int task) { 8643 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8644 } 8645 8646 @Override 8647 public IBinder getHomeActivityToken() throws RemoteException { 8648 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8649 "getHomeActivityToken()"); 8650 synchronized (this) { 8651 return mStackSupervisor.getHomeActivityToken(); 8652 } 8653 } 8654 8655 @Override 8656 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8657 IActivityContainerCallback callback) throws RemoteException { 8658 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8659 "createActivityContainer()"); 8660 synchronized (this) { 8661 if (parentActivityToken == null) { 8662 throw new IllegalArgumentException("parent token must not be null"); 8663 } 8664 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8665 if (r == null) { 8666 return null; 8667 } 8668 if (callback == null) { 8669 throw new IllegalArgumentException("callback must not be null"); 8670 } 8671 return mStackSupervisor.createActivityContainer(r, callback); 8672 } 8673 } 8674 8675 @Override 8676 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8677 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8678 "deleteActivityContainer()"); 8679 synchronized (this) { 8680 mStackSupervisor.deleteActivityContainer(container); 8681 } 8682 } 8683 8684 @Override 8685 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 8686 synchronized (this) { 8687 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8688 if (stack != null && stack.mActivityContainer.isAttachedLocked()) { 8689 return stack.mActivityContainer.getDisplayId(); 8690 } 8691 return Display.DEFAULT_DISPLAY; 8692 } 8693 } 8694 8695 @Override 8696 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8697 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8698 "moveTaskToStack()"); 8699 if (stackId == HOME_STACK_ID) { 8700 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8701 new RuntimeException("here").fillInStackTrace()); 8702 } 8703 synchronized (this) { 8704 long ident = Binder.clearCallingIdentity(); 8705 try { 8706 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8707 + stackId + " toTop=" + toTop); 8708 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop); 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 } 8714 8715 @Override 8716 public void resizeStack(int stackBoxId, Rect bounds) { 8717 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8718 "resizeStackBox()"); 8719 long ident = Binder.clearCallingIdentity(); 8720 try { 8721 mWindowManager.resizeStack(stackBoxId, bounds); 8722 } finally { 8723 Binder.restoreCallingIdentity(ident); 8724 } 8725 } 8726 8727 @Override 8728 public List<StackInfo> getAllStackInfos() { 8729 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8730 "getAllStackInfos()"); 8731 long ident = Binder.clearCallingIdentity(); 8732 try { 8733 synchronized (this) { 8734 return mStackSupervisor.getAllStackInfosLocked(); 8735 } 8736 } finally { 8737 Binder.restoreCallingIdentity(ident); 8738 } 8739 } 8740 8741 @Override 8742 public StackInfo getStackInfo(int stackId) { 8743 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8744 "getStackInfo()"); 8745 long ident = Binder.clearCallingIdentity(); 8746 try { 8747 synchronized (this) { 8748 return mStackSupervisor.getStackInfoLocked(stackId); 8749 } 8750 } finally { 8751 Binder.restoreCallingIdentity(ident); 8752 } 8753 } 8754 8755 @Override 8756 public boolean isInHomeStack(int taskId) { 8757 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8758 "getStackInfo()"); 8759 long ident = Binder.clearCallingIdentity(); 8760 try { 8761 synchronized (this) { 8762 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8763 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8764 } 8765 } finally { 8766 Binder.restoreCallingIdentity(ident); 8767 } 8768 } 8769 8770 @Override 8771 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8772 synchronized(this) { 8773 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8774 } 8775 } 8776 8777 private boolean isLockTaskAuthorized(String pkg) { 8778 final DevicePolicyManager dpm = (DevicePolicyManager) 8779 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8780 try { 8781 int uid = mContext.getPackageManager().getPackageUid(pkg, 8782 Binder.getCallingUserHandle().getIdentifier()); 8783 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8784 } catch (NameNotFoundException e) { 8785 return false; 8786 } 8787 } 8788 8789 void startLockTaskMode(TaskRecord task) { 8790 final String pkg; 8791 synchronized (this) { 8792 pkg = task.intent.getComponent().getPackageName(); 8793 } 8794 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8795 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8796 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8797 StatusBarManagerInternal.class); 8798 if (statusBarManager != null) { 8799 statusBarManager.showScreenPinningRequest(); 8800 } 8801 return; 8802 } 8803 long ident = Binder.clearCallingIdentity(); 8804 try { 8805 synchronized (this) { 8806 // Since we lost lock on task, make sure it is still there. 8807 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8808 if (task != null) { 8809 if (!isSystemInitiated 8810 && ((mStackSupervisor.getFocusedStack() == null) 8811 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8812 throw new IllegalArgumentException("Invalid task, not in foreground"); 8813 } 8814 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated, 8815 "startLockTask"); 8816 } 8817 } 8818 } finally { 8819 Binder.restoreCallingIdentity(ident); 8820 } 8821 } 8822 8823 @Override 8824 public void startLockTaskMode(int taskId) { 8825 final TaskRecord task; 8826 long ident = Binder.clearCallingIdentity(); 8827 try { 8828 synchronized (this) { 8829 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8830 } 8831 } finally { 8832 Binder.restoreCallingIdentity(ident); 8833 } 8834 if (task != null) { 8835 startLockTaskMode(task); 8836 } 8837 } 8838 8839 @Override 8840 public void startLockTaskMode(IBinder token) { 8841 final TaskRecord task; 8842 long ident = Binder.clearCallingIdentity(); 8843 try { 8844 synchronized (this) { 8845 final ActivityRecord r = ActivityRecord.forToken(token); 8846 if (r == null) { 8847 return; 8848 } 8849 task = r.task; 8850 } 8851 } finally { 8852 Binder.restoreCallingIdentity(ident); 8853 } 8854 if (task != null) { 8855 startLockTaskMode(task); 8856 } 8857 } 8858 8859 @Override 8860 public void startLockTaskModeOnCurrent() throws RemoteException { 8861 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8862 "startLockTaskModeOnCurrent"); 8863 long ident = Binder.clearCallingIdentity(); 8864 try { 8865 ActivityRecord r = null; 8866 synchronized (this) { 8867 r = mStackSupervisor.topRunningActivityLocked(); 8868 } 8869 startLockTaskMode(r.task); 8870 } finally { 8871 Binder.restoreCallingIdentity(ident); 8872 } 8873 } 8874 8875 @Override 8876 public void stopLockTaskMode() { 8877 // Verify that the user matches the package of the intent for the TaskRecord 8878 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8879 // and stopLockTaskMode. 8880 final int callingUid = Binder.getCallingUid(); 8881 if (callingUid != Process.SYSTEM_UID) { 8882 try { 8883 String pkg = 8884 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8885 int uid = mContext.getPackageManager().getPackageUid(pkg, 8886 Binder.getCallingUserHandle().getIdentifier()); 8887 if (uid != callingUid) { 8888 throw new SecurityException("Invalid uid, expected " + uid); 8889 } 8890 } catch (NameNotFoundException e) { 8891 Log.d(TAG, "stopLockTaskMode " + e); 8892 return; 8893 } 8894 } 8895 long ident = Binder.clearCallingIdentity(); 8896 try { 8897 Log.d(TAG, "stopLockTaskMode"); 8898 // Stop lock task 8899 synchronized (this) { 8900 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask"); 8901 } 8902 } finally { 8903 Binder.restoreCallingIdentity(ident); 8904 } 8905 } 8906 8907 @Override 8908 public void stopLockTaskModeOnCurrent() throws RemoteException { 8909 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8910 "stopLockTaskModeOnCurrent"); 8911 long ident = Binder.clearCallingIdentity(); 8912 try { 8913 stopLockTaskMode(); 8914 } finally { 8915 Binder.restoreCallingIdentity(ident); 8916 } 8917 } 8918 8919 @Override 8920 public boolean isInLockTaskMode() { 8921 synchronized (this) { 8922 return mStackSupervisor.isInLockTaskMode(); 8923 } 8924 } 8925 8926 // ========================================================= 8927 // CONTENT PROVIDERS 8928 // ========================================================= 8929 8930 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8931 List<ProviderInfo> providers = null; 8932 try { 8933 providers = AppGlobals.getPackageManager(). 8934 queryContentProviders(app.processName, app.uid, 8935 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8936 } catch (RemoteException ex) { 8937 } 8938 if (DEBUG_MU) 8939 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8940 int userId = app.userId; 8941 if (providers != null) { 8942 int N = providers.size(); 8943 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8944 for (int i=0; i<N; i++) { 8945 ProviderInfo cpi = 8946 (ProviderInfo)providers.get(i); 8947 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8948 cpi.name, cpi.flags); 8949 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8950 // This is a singleton provider, but a user besides the 8951 // default user is asking to initialize a process it runs 8952 // in... well, no, it doesn't actually run in this process, 8953 // it runs in the process of the default user. Get rid of it. 8954 providers.remove(i); 8955 N--; 8956 i--; 8957 continue; 8958 } 8959 8960 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8961 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8962 if (cpr == null) { 8963 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8964 mProviderMap.putProviderByClass(comp, cpr); 8965 } 8966 if (DEBUG_MU) 8967 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8968 app.pubProviders.put(cpi.name, cpr); 8969 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8970 // Don't add this if it is a platform component that is marked 8971 // to run in multiple processes, because this is actually 8972 // part of the framework so doesn't make sense to track as a 8973 // separate apk in the process. 8974 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8975 mProcessStats); 8976 } 8977 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8978 } 8979 } 8980 return providers; 8981 } 8982 8983 /** 8984 * Check if {@link ProcessRecord} has a possible chance at accessing the 8985 * given {@link ProviderInfo}. Final permission checking is always done 8986 * in {@link ContentProvider}. 8987 */ 8988 private final String checkContentProviderPermissionLocked( 8989 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8990 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8991 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8992 boolean checkedGrants = false; 8993 if (checkUser) { 8994 // Looking for cross-user grants before enforcing the typical cross-users permissions 8995 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8996 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8997 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8998 return null; 8999 } 9000 checkedGrants = true; 9001 } 9002 userId = handleIncomingUser(callingPid, callingUid, userId, 9003 false, ALLOW_NON_FULL, 9004 "checkContentProviderPermissionLocked " + cpi.authority, null); 9005 if (userId != tmpTargetUserId) { 9006 // When we actually went to determine the final targer user ID, this ended 9007 // up different than our initial check for the authority. This is because 9008 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9009 // SELF. So we need to re-check the grants again. 9010 checkedGrants = false; 9011 } 9012 } 9013 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9014 cpi.applicationInfo.uid, cpi.exported) 9015 == PackageManager.PERMISSION_GRANTED) { 9016 return null; 9017 } 9018 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9019 cpi.applicationInfo.uid, cpi.exported) 9020 == PackageManager.PERMISSION_GRANTED) { 9021 return null; 9022 } 9023 9024 PathPermission[] pps = cpi.pathPermissions; 9025 if (pps != null) { 9026 int i = pps.length; 9027 while (i > 0) { 9028 i--; 9029 PathPermission pp = pps[i]; 9030 String pprperm = pp.getReadPermission(); 9031 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9032 cpi.applicationInfo.uid, cpi.exported) 9033 == PackageManager.PERMISSION_GRANTED) { 9034 return null; 9035 } 9036 String ppwperm = pp.getWritePermission(); 9037 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9038 cpi.applicationInfo.uid, cpi.exported) 9039 == PackageManager.PERMISSION_GRANTED) { 9040 return null; 9041 } 9042 } 9043 } 9044 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9045 return null; 9046 } 9047 9048 String msg; 9049 if (!cpi.exported) { 9050 msg = "Permission Denial: opening provider " + cpi.name 9051 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9052 + ", uid=" + callingUid + ") that is not exported from uid " 9053 + cpi.applicationInfo.uid; 9054 } else { 9055 msg = "Permission Denial: opening provider " + cpi.name 9056 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9057 + ", uid=" + callingUid + ") requires " 9058 + cpi.readPermission + " or " + cpi.writePermission; 9059 } 9060 Slog.w(TAG, msg); 9061 return msg; 9062 } 9063 9064 /** 9065 * Returns if the ContentProvider has granted a uri to callingUid 9066 */ 9067 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9068 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9069 if (perms != null) { 9070 for (int i=perms.size()-1; i>=0; i--) { 9071 GrantUri grantUri = perms.keyAt(i); 9072 if (grantUri.sourceUserId == userId || !checkUser) { 9073 if (matchesProvider(grantUri.uri, cpi)) { 9074 return true; 9075 } 9076 } 9077 } 9078 } 9079 return false; 9080 } 9081 9082 /** 9083 * Returns true if the uri authority is one of the authorities specified in the provider. 9084 */ 9085 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9086 String uriAuth = uri.getAuthority(); 9087 String cpiAuth = cpi.authority; 9088 if (cpiAuth.indexOf(';') == -1) { 9089 return cpiAuth.equals(uriAuth); 9090 } 9091 String[] cpiAuths = cpiAuth.split(";"); 9092 int length = cpiAuths.length; 9093 for (int i = 0; i < length; i++) { 9094 if (cpiAuths[i].equals(uriAuth)) return true; 9095 } 9096 return false; 9097 } 9098 9099 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9100 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9101 if (r != null) { 9102 for (int i=0; i<r.conProviders.size(); i++) { 9103 ContentProviderConnection conn = r.conProviders.get(i); 9104 if (conn.provider == cpr) { 9105 if (DEBUG_PROVIDER) Slog.v(TAG, 9106 "Adding provider requested by " 9107 + r.processName + " from process " 9108 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9109 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9110 if (stable) { 9111 conn.stableCount++; 9112 conn.numStableIncs++; 9113 } else { 9114 conn.unstableCount++; 9115 conn.numUnstableIncs++; 9116 } 9117 return conn; 9118 } 9119 } 9120 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9121 if (stable) { 9122 conn.stableCount = 1; 9123 conn.numStableIncs = 1; 9124 } else { 9125 conn.unstableCount = 1; 9126 conn.numUnstableIncs = 1; 9127 } 9128 cpr.connections.add(conn); 9129 r.conProviders.add(conn); 9130 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9131 return conn; 9132 } 9133 cpr.addExternalProcessHandleLocked(externalProcessToken); 9134 return null; 9135 } 9136 9137 boolean decProviderCountLocked(ContentProviderConnection conn, 9138 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9139 if (conn != null) { 9140 cpr = conn.provider; 9141 if (DEBUG_PROVIDER) Slog.v(TAG, 9142 "Removing provider requested by " 9143 + conn.client.processName + " from process " 9144 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9145 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9146 if (stable) { 9147 conn.stableCount--; 9148 } else { 9149 conn.unstableCount--; 9150 } 9151 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9152 cpr.connections.remove(conn); 9153 conn.client.conProviders.remove(conn); 9154 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9155 return true; 9156 } 9157 return false; 9158 } 9159 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9160 return false; 9161 } 9162 9163 private void checkTime(long startTime, String where) { 9164 long now = SystemClock.elapsedRealtime(); 9165 if ((now-startTime) > 1000) { 9166 // If we are taking more than a second, log about it. 9167 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9168 } 9169 } 9170 9171 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9172 String name, IBinder token, boolean stable, int userId) { 9173 ContentProviderRecord cpr; 9174 ContentProviderConnection conn = null; 9175 ProviderInfo cpi = null; 9176 9177 synchronized(this) { 9178 long startTime = SystemClock.elapsedRealtime(); 9179 9180 ProcessRecord r = null; 9181 if (caller != null) { 9182 r = getRecordForAppLocked(caller); 9183 if (r == null) { 9184 throw new SecurityException( 9185 "Unable to find app for caller " + caller 9186 + " (pid=" + Binder.getCallingPid() 9187 + ") when getting content provider " + name); 9188 } 9189 } 9190 9191 boolean checkCrossUser = true; 9192 9193 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9194 9195 // First check if this content provider has been published... 9196 cpr = mProviderMap.getProviderByName(name, userId); 9197 // If that didn't work, check if it exists for user 0 and then 9198 // verify that it's a singleton provider before using it. 9199 if (cpr == null && userId != UserHandle.USER_OWNER) { 9200 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9201 if (cpr != null) { 9202 cpi = cpr.info; 9203 if (isSingleton(cpi.processName, cpi.applicationInfo, 9204 cpi.name, cpi.flags) 9205 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9206 userId = UserHandle.USER_OWNER; 9207 checkCrossUser = false; 9208 } else { 9209 cpr = null; 9210 cpi = null; 9211 } 9212 } 9213 } 9214 9215 boolean providerRunning = cpr != null; 9216 if (providerRunning) { 9217 cpi = cpr.info; 9218 String msg; 9219 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9220 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9221 != null) { 9222 throw new SecurityException(msg); 9223 } 9224 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9225 9226 if (r != null && cpr.canRunHere(r)) { 9227 // This provider has been published or is in the process 9228 // of being published... but it is also allowed to run 9229 // in the caller's process, so don't make a connection 9230 // and just let the caller instantiate its own instance. 9231 ContentProviderHolder holder = cpr.newHolder(null); 9232 // don't give caller the provider object, it needs 9233 // to make its own. 9234 holder.provider = null; 9235 return holder; 9236 } 9237 9238 final long origId = Binder.clearCallingIdentity(); 9239 9240 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9241 9242 // In this case the provider instance already exists, so we can 9243 // return it right away. 9244 conn = incProviderCountLocked(r, cpr, token, stable); 9245 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9246 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9247 // If this is a perceptible app accessing the provider, 9248 // make sure to count it as being accessed and thus 9249 // back up on the LRU list. This is good because 9250 // content providers are often expensive to start. 9251 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9252 updateLruProcessLocked(cpr.proc, false, null); 9253 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9254 } 9255 } 9256 9257 if (cpr.proc != null) { 9258 if (false) { 9259 if (cpr.name.flattenToShortString().equals( 9260 "com.android.providers.calendar/.CalendarProvider2")) { 9261 Slog.v(TAG, "****************** KILLING " 9262 + cpr.name.flattenToShortString()); 9263 Process.killProcess(cpr.proc.pid); 9264 } 9265 } 9266 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9267 boolean success = updateOomAdjLocked(cpr.proc); 9268 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9269 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9270 // NOTE: there is still a race here where a signal could be 9271 // pending on the process even though we managed to update its 9272 // adj level. Not sure what to do about this, but at least 9273 // the race is now smaller. 9274 if (!success) { 9275 // Uh oh... it looks like the provider's process 9276 // has been killed on us. We need to wait for a new 9277 // process to be started, and make sure its death 9278 // doesn't kill our process. 9279 Slog.i(TAG, 9280 "Existing provider " + cpr.name.flattenToShortString() 9281 + " is crashing; detaching " + r); 9282 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9283 checkTime(startTime, "getContentProviderImpl: before appDied"); 9284 appDiedLocked(cpr.proc); 9285 checkTime(startTime, "getContentProviderImpl: after appDied"); 9286 if (!lastRef) { 9287 // This wasn't the last ref our process had on 9288 // the provider... we have now been killed, bail. 9289 return null; 9290 } 9291 providerRunning = false; 9292 conn = null; 9293 } 9294 } 9295 9296 Binder.restoreCallingIdentity(origId); 9297 } 9298 9299 boolean singleton; 9300 if (!providerRunning) { 9301 try { 9302 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9303 cpi = AppGlobals.getPackageManager(). 9304 resolveContentProvider(name, 9305 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9306 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9307 } catch (RemoteException ex) { 9308 } 9309 if (cpi == null) { 9310 return null; 9311 } 9312 // If the provider is a singleton AND 9313 // (it's a call within the same user || the provider is a 9314 // privileged app) 9315 // Then allow connecting to the singleton provider 9316 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9317 cpi.name, cpi.flags) 9318 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9319 if (singleton) { 9320 userId = UserHandle.USER_OWNER; 9321 } 9322 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9323 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9324 9325 String msg; 9326 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9327 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9328 != null) { 9329 throw new SecurityException(msg); 9330 } 9331 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9332 9333 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9334 && !cpi.processName.equals("system")) { 9335 // If this content provider does not run in the system 9336 // process, and the system is not yet ready to run other 9337 // processes, then fail fast instead of hanging. 9338 throw new IllegalArgumentException( 9339 "Attempt to launch content provider before system ready"); 9340 } 9341 9342 // Make sure that the user who owns this provider is running. If not, 9343 // we don't want to allow it to run. 9344 if (!isUserRunningLocked(userId, false)) { 9345 Slog.w(TAG, "Unable to launch app " 9346 + cpi.applicationInfo.packageName + "/" 9347 + cpi.applicationInfo.uid + " for provider " 9348 + name + ": user " + userId + " is stopped"); 9349 return null; 9350 } 9351 9352 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9353 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9354 cpr = mProviderMap.getProviderByClass(comp, userId); 9355 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9356 final boolean firstClass = cpr == null; 9357 if (firstClass) { 9358 final long ident = Binder.clearCallingIdentity(); 9359 try { 9360 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9361 ApplicationInfo ai = 9362 AppGlobals.getPackageManager(). 9363 getApplicationInfo( 9364 cpi.applicationInfo.packageName, 9365 STOCK_PM_FLAGS, userId); 9366 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9367 if (ai == null) { 9368 Slog.w(TAG, "No package info for content provider " 9369 + cpi.name); 9370 return null; 9371 } 9372 ai = getAppInfoForUser(ai, userId); 9373 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9374 } catch (RemoteException ex) { 9375 // pm is in same process, this will never happen. 9376 } finally { 9377 Binder.restoreCallingIdentity(ident); 9378 } 9379 } 9380 9381 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9382 9383 if (r != null && cpr.canRunHere(r)) { 9384 // If this is a multiprocess provider, then just return its 9385 // info and allow the caller to instantiate it. Only do 9386 // this if the provider is the same user as the caller's 9387 // process, or can run as root (so can be in any process). 9388 return cpr.newHolder(null); 9389 } 9390 9391 if (DEBUG_PROVIDER) { 9392 RuntimeException e = new RuntimeException("here"); 9393 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9394 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9395 } 9396 9397 // This is single process, and our app is now connecting to it. 9398 // See if we are already in the process of launching this 9399 // provider. 9400 final int N = mLaunchingProviders.size(); 9401 int i; 9402 for (i=0; i<N; i++) { 9403 if (mLaunchingProviders.get(i) == cpr) { 9404 break; 9405 } 9406 } 9407 9408 // If the provider is not already being launched, then get it 9409 // started. 9410 if (i >= N) { 9411 final long origId = Binder.clearCallingIdentity(); 9412 9413 try { 9414 // Content provider is now in use, its package can't be stopped. 9415 try { 9416 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9417 AppGlobals.getPackageManager().setPackageStoppedState( 9418 cpr.appInfo.packageName, false, userId); 9419 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9420 } catch (RemoteException e) { 9421 } catch (IllegalArgumentException e) { 9422 Slog.w(TAG, "Failed trying to unstop package " 9423 + cpr.appInfo.packageName + ": " + e); 9424 } 9425 9426 // Use existing process if already started 9427 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9428 ProcessRecord proc = getProcessRecordLocked( 9429 cpi.processName, cpr.appInfo.uid, false); 9430 if (proc != null && proc.thread != null) { 9431 if (DEBUG_PROVIDER) { 9432 Slog.d(TAG, "Installing in existing process " + proc); 9433 } 9434 if (!proc.pubProviders.containsKey(cpi.name)) { 9435 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9436 proc.pubProviders.put(cpi.name, cpr); 9437 try { 9438 proc.thread.scheduleInstallProvider(cpi); 9439 } catch (RemoteException e) { 9440 } 9441 } 9442 } else { 9443 checkTime(startTime, "getContentProviderImpl: before start process"); 9444 proc = startProcessLocked(cpi.processName, 9445 cpr.appInfo, false, 0, "content provider", 9446 new ComponentName(cpi.applicationInfo.packageName, 9447 cpi.name), false, false, false); 9448 checkTime(startTime, "getContentProviderImpl: after start process"); 9449 if (proc == null) { 9450 Slog.w(TAG, "Unable to launch app " 9451 + cpi.applicationInfo.packageName + "/" 9452 + cpi.applicationInfo.uid + " for provider " 9453 + name + ": process is bad"); 9454 return null; 9455 } 9456 } 9457 cpr.launchingApp = proc; 9458 mLaunchingProviders.add(cpr); 9459 } finally { 9460 Binder.restoreCallingIdentity(origId); 9461 } 9462 } 9463 9464 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9465 9466 // Make sure the provider is published (the same provider class 9467 // may be published under multiple names). 9468 if (firstClass) { 9469 mProviderMap.putProviderByClass(comp, cpr); 9470 } 9471 9472 mProviderMap.putProviderByName(name, cpr); 9473 conn = incProviderCountLocked(r, cpr, token, stable); 9474 if (conn != null) { 9475 conn.waiting = true; 9476 } 9477 } 9478 checkTime(startTime, "getContentProviderImpl: done!"); 9479 } 9480 9481 // Wait for the provider to be published... 9482 synchronized (cpr) { 9483 while (cpr.provider == null) { 9484 if (cpr.launchingApp == null) { 9485 Slog.w(TAG, "Unable to launch app " 9486 + cpi.applicationInfo.packageName + "/" 9487 + cpi.applicationInfo.uid + " for provider " 9488 + name + ": launching app became null"); 9489 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9490 UserHandle.getUserId(cpi.applicationInfo.uid), 9491 cpi.applicationInfo.packageName, 9492 cpi.applicationInfo.uid, name); 9493 return null; 9494 } 9495 try { 9496 if (DEBUG_MU) { 9497 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9498 + cpr.launchingApp); 9499 } 9500 if (conn != null) { 9501 conn.waiting = true; 9502 } 9503 cpr.wait(); 9504 } catch (InterruptedException ex) { 9505 } finally { 9506 if (conn != null) { 9507 conn.waiting = false; 9508 } 9509 } 9510 } 9511 } 9512 return cpr != null ? cpr.newHolder(conn) : null; 9513 } 9514 9515 @Override 9516 public final ContentProviderHolder getContentProvider( 9517 IApplicationThread caller, String name, int userId, boolean stable) { 9518 enforceNotIsolatedCaller("getContentProvider"); 9519 if (caller == null) { 9520 String msg = "null IApplicationThread when getting content provider " 9521 + name; 9522 Slog.w(TAG, msg); 9523 throw new SecurityException(msg); 9524 } 9525 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9526 // with cross-user grant. 9527 return getContentProviderImpl(caller, name, null, stable, userId); 9528 } 9529 9530 public ContentProviderHolder getContentProviderExternal( 9531 String name, int userId, IBinder token) { 9532 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9533 "Do not have permission in call getContentProviderExternal()"); 9534 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9535 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9536 return getContentProviderExternalUnchecked(name, token, userId); 9537 } 9538 9539 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9540 IBinder token, int userId) { 9541 return getContentProviderImpl(null, name, token, true, userId); 9542 } 9543 9544 /** 9545 * Drop a content provider from a ProcessRecord's bookkeeping 9546 */ 9547 public void removeContentProvider(IBinder connection, boolean stable) { 9548 enforceNotIsolatedCaller("removeContentProvider"); 9549 long ident = Binder.clearCallingIdentity(); 9550 try { 9551 synchronized (this) { 9552 ContentProviderConnection conn; 9553 try { 9554 conn = (ContentProviderConnection)connection; 9555 } catch (ClassCastException e) { 9556 String msg ="removeContentProvider: " + connection 9557 + " not a ContentProviderConnection"; 9558 Slog.w(TAG, msg); 9559 throw new IllegalArgumentException(msg); 9560 } 9561 if (conn == null) { 9562 throw new NullPointerException("connection is null"); 9563 } 9564 if (decProviderCountLocked(conn, null, null, stable)) { 9565 updateOomAdjLocked(); 9566 } 9567 } 9568 } finally { 9569 Binder.restoreCallingIdentity(ident); 9570 } 9571 } 9572 9573 public void removeContentProviderExternal(String name, IBinder token) { 9574 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9575 "Do not have permission in call removeContentProviderExternal()"); 9576 int userId = UserHandle.getCallingUserId(); 9577 long ident = Binder.clearCallingIdentity(); 9578 try { 9579 removeContentProviderExternalUnchecked(name, token, userId); 9580 } finally { 9581 Binder.restoreCallingIdentity(ident); 9582 } 9583 } 9584 9585 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9586 synchronized (this) { 9587 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9588 if(cpr == null) { 9589 //remove from mProvidersByClass 9590 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9591 return; 9592 } 9593 9594 //update content provider record entry info 9595 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9596 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9597 if (localCpr.hasExternalProcessHandles()) { 9598 if (localCpr.removeExternalProcessHandleLocked(token)) { 9599 updateOomAdjLocked(); 9600 } else { 9601 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9602 + " with no external reference for token: " 9603 + token + "."); 9604 } 9605 } else { 9606 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9607 + " with no external references."); 9608 } 9609 } 9610 } 9611 9612 public final void publishContentProviders(IApplicationThread caller, 9613 List<ContentProviderHolder> providers) { 9614 if (providers == null) { 9615 return; 9616 } 9617 9618 enforceNotIsolatedCaller("publishContentProviders"); 9619 synchronized (this) { 9620 final ProcessRecord r = getRecordForAppLocked(caller); 9621 if (DEBUG_MU) 9622 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9623 if (r == null) { 9624 throw new SecurityException( 9625 "Unable to find app for caller " + caller 9626 + " (pid=" + Binder.getCallingPid() 9627 + ") when publishing content providers"); 9628 } 9629 9630 final long origId = Binder.clearCallingIdentity(); 9631 9632 final int N = providers.size(); 9633 for (int i=0; i<N; i++) { 9634 ContentProviderHolder src = providers.get(i); 9635 if (src == null || src.info == null || src.provider == null) { 9636 continue; 9637 } 9638 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9639 if (DEBUG_MU) 9640 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9641 if (dst != null) { 9642 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9643 mProviderMap.putProviderByClass(comp, dst); 9644 String names[] = dst.info.authority.split(";"); 9645 for (int j = 0; j < names.length; j++) { 9646 mProviderMap.putProviderByName(names[j], dst); 9647 } 9648 9649 int NL = mLaunchingProviders.size(); 9650 int j; 9651 for (j=0; j<NL; j++) { 9652 if (mLaunchingProviders.get(j) == dst) { 9653 mLaunchingProviders.remove(j); 9654 j--; 9655 NL--; 9656 } 9657 } 9658 synchronized (dst) { 9659 dst.provider = src.provider; 9660 dst.proc = r; 9661 dst.notifyAll(); 9662 } 9663 updateOomAdjLocked(r); 9664 } 9665 } 9666 9667 Binder.restoreCallingIdentity(origId); 9668 } 9669 } 9670 9671 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9672 ContentProviderConnection conn; 9673 try { 9674 conn = (ContentProviderConnection)connection; 9675 } catch (ClassCastException e) { 9676 String msg ="refContentProvider: " + connection 9677 + " not a ContentProviderConnection"; 9678 Slog.w(TAG, msg); 9679 throw new IllegalArgumentException(msg); 9680 } 9681 if (conn == null) { 9682 throw new NullPointerException("connection is null"); 9683 } 9684 9685 synchronized (this) { 9686 if (stable > 0) { 9687 conn.numStableIncs += stable; 9688 } 9689 stable = conn.stableCount + stable; 9690 if (stable < 0) { 9691 throw new IllegalStateException("stableCount < 0: " + stable); 9692 } 9693 9694 if (unstable > 0) { 9695 conn.numUnstableIncs += unstable; 9696 } 9697 unstable = conn.unstableCount + unstable; 9698 if (unstable < 0) { 9699 throw new IllegalStateException("unstableCount < 0: " + unstable); 9700 } 9701 9702 if ((stable+unstable) <= 0) { 9703 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9704 + stable + " unstable=" + unstable); 9705 } 9706 conn.stableCount = stable; 9707 conn.unstableCount = unstable; 9708 return !conn.dead; 9709 } 9710 } 9711 9712 public void unstableProviderDied(IBinder connection) { 9713 ContentProviderConnection conn; 9714 try { 9715 conn = (ContentProviderConnection)connection; 9716 } catch (ClassCastException e) { 9717 String msg ="refContentProvider: " + connection 9718 + " not a ContentProviderConnection"; 9719 Slog.w(TAG, msg); 9720 throw new IllegalArgumentException(msg); 9721 } 9722 if (conn == null) { 9723 throw new NullPointerException("connection is null"); 9724 } 9725 9726 // Safely retrieve the content provider associated with the connection. 9727 IContentProvider provider; 9728 synchronized (this) { 9729 provider = conn.provider.provider; 9730 } 9731 9732 if (provider == null) { 9733 // Um, yeah, we're way ahead of you. 9734 return; 9735 } 9736 9737 // Make sure the caller is being honest with us. 9738 if (provider.asBinder().pingBinder()) { 9739 // Er, no, still looks good to us. 9740 synchronized (this) { 9741 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9742 + " says " + conn + " died, but we don't agree"); 9743 return; 9744 } 9745 } 9746 9747 // Well look at that! It's dead! 9748 synchronized (this) { 9749 if (conn.provider.provider != provider) { 9750 // But something changed... good enough. 9751 return; 9752 } 9753 9754 ProcessRecord proc = conn.provider.proc; 9755 if (proc == null || proc.thread == null) { 9756 // Seems like the process is already cleaned up. 9757 return; 9758 } 9759 9760 // As far as we're concerned, this is just like receiving a 9761 // death notification... just a bit prematurely. 9762 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9763 + ") early provider death"); 9764 final long ident = Binder.clearCallingIdentity(); 9765 try { 9766 appDiedLocked(proc); 9767 } finally { 9768 Binder.restoreCallingIdentity(ident); 9769 } 9770 } 9771 } 9772 9773 @Override 9774 public void appNotRespondingViaProvider(IBinder connection) { 9775 enforceCallingPermission( 9776 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9777 9778 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9779 if (conn == null) { 9780 Slog.w(TAG, "ContentProviderConnection is null"); 9781 return; 9782 } 9783 9784 final ProcessRecord host = conn.provider.proc; 9785 if (host == null) { 9786 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9787 return; 9788 } 9789 9790 final long token = Binder.clearCallingIdentity(); 9791 try { 9792 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9793 } finally { 9794 Binder.restoreCallingIdentity(token); 9795 } 9796 } 9797 9798 public final void installSystemProviders() { 9799 List<ProviderInfo> providers; 9800 synchronized (this) { 9801 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9802 providers = generateApplicationProvidersLocked(app); 9803 if (providers != null) { 9804 for (int i=providers.size()-1; i>=0; i--) { 9805 ProviderInfo pi = (ProviderInfo)providers.get(i); 9806 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9807 Slog.w(TAG, "Not installing system proc provider " + pi.name 9808 + ": not system .apk"); 9809 providers.remove(i); 9810 } 9811 } 9812 } 9813 } 9814 if (providers != null) { 9815 mSystemThread.installSystemProviders(providers); 9816 } 9817 9818 mCoreSettingsObserver = new CoreSettingsObserver(this); 9819 9820 //mUsageStatsService.monitorPackages(); 9821 } 9822 9823 /** 9824 * Allows apps to retrieve the MIME type of a URI. 9825 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9826 * users, then it does not need permission to access the ContentProvider. 9827 * Either, it needs cross-user uri grants. 9828 * 9829 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9830 * 9831 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9832 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9833 */ 9834 public String getProviderMimeType(Uri uri, int userId) { 9835 enforceNotIsolatedCaller("getProviderMimeType"); 9836 final String name = uri.getAuthority(); 9837 int callingUid = Binder.getCallingUid(); 9838 int callingPid = Binder.getCallingPid(); 9839 long ident = 0; 9840 boolean clearedIdentity = false; 9841 userId = unsafeConvertIncomingUser(userId); 9842 if (canClearIdentity(callingPid, callingUid, userId)) { 9843 clearedIdentity = true; 9844 ident = Binder.clearCallingIdentity(); 9845 } 9846 ContentProviderHolder holder = null; 9847 try { 9848 holder = getContentProviderExternalUnchecked(name, null, userId); 9849 if (holder != null) { 9850 return holder.provider.getType(uri); 9851 } 9852 } catch (RemoteException e) { 9853 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9854 return null; 9855 } finally { 9856 // We need to clear the identity to call removeContentProviderExternalUnchecked 9857 if (!clearedIdentity) { 9858 ident = Binder.clearCallingIdentity(); 9859 } 9860 try { 9861 if (holder != null) { 9862 removeContentProviderExternalUnchecked(name, null, userId); 9863 } 9864 } finally { 9865 Binder.restoreCallingIdentity(ident); 9866 } 9867 } 9868 9869 return null; 9870 } 9871 9872 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9873 if (UserHandle.getUserId(callingUid) == userId) { 9874 return true; 9875 } 9876 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9877 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9878 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9879 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9880 return true; 9881 } 9882 return false; 9883 } 9884 9885 // ========================================================= 9886 // GLOBAL MANAGEMENT 9887 // ========================================================= 9888 9889 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9890 boolean isolated, int isolatedUid) { 9891 String proc = customProcess != null ? customProcess : info.processName; 9892 BatteryStatsImpl.Uid.Proc ps = null; 9893 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9894 int uid = info.uid; 9895 if (isolated) { 9896 if (isolatedUid == 0) { 9897 int userId = UserHandle.getUserId(uid); 9898 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9899 while (true) { 9900 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9901 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9902 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9903 } 9904 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9905 mNextIsolatedProcessUid++; 9906 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9907 // No process for this uid, use it. 9908 break; 9909 } 9910 stepsLeft--; 9911 if (stepsLeft <= 0) { 9912 return null; 9913 } 9914 } 9915 } else { 9916 // Special case for startIsolatedProcess (internal only), where 9917 // the uid of the isolated process is specified by the caller. 9918 uid = isolatedUid; 9919 } 9920 } 9921 return new ProcessRecord(stats, info, proc, uid); 9922 } 9923 9924 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9925 String abiOverride) { 9926 ProcessRecord app; 9927 if (!isolated) { 9928 app = getProcessRecordLocked(info.processName, info.uid, true); 9929 } else { 9930 app = null; 9931 } 9932 9933 if (app == null) { 9934 app = newProcessRecordLocked(info, null, isolated, 0); 9935 mProcessNames.put(info.processName, app.uid, app); 9936 if (isolated) { 9937 mIsolatedProcesses.put(app.uid, app); 9938 } 9939 updateLruProcessLocked(app, false, null); 9940 updateOomAdjLocked(); 9941 } 9942 9943 // This package really, really can not be stopped. 9944 try { 9945 AppGlobals.getPackageManager().setPackageStoppedState( 9946 info.packageName, false, UserHandle.getUserId(app.uid)); 9947 } catch (RemoteException e) { 9948 } catch (IllegalArgumentException e) { 9949 Slog.w(TAG, "Failed trying to unstop package " 9950 + info.packageName + ": " + e); 9951 } 9952 9953 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9954 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9955 app.persistent = true; 9956 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9957 } 9958 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9959 mPersistentStartingProcesses.add(app); 9960 startProcessLocked(app, "added application", app.processName, abiOverride, 9961 null /* entryPoint */, null /* entryPointArgs */); 9962 } 9963 9964 return app; 9965 } 9966 9967 public void unhandledBack() { 9968 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9969 "unhandledBack()"); 9970 9971 synchronized(this) { 9972 final long origId = Binder.clearCallingIdentity(); 9973 try { 9974 getFocusedStack().unhandledBackLocked(); 9975 } finally { 9976 Binder.restoreCallingIdentity(origId); 9977 } 9978 } 9979 } 9980 9981 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9982 enforceNotIsolatedCaller("openContentUri"); 9983 final int userId = UserHandle.getCallingUserId(); 9984 String name = uri.getAuthority(); 9985 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9986 ParcelFileDescriptor pfd = null; 9987 if (cph != null) { 9988 // We record the binder invoker's uid in thread-local storage before 9989 // going to the content provider to open the file. Later, in the code 9990 // that handles all permissions checks, we look for this uid and use 9991 // that rather than the Activity Manager's own uid. The effect is that 9992 // we do the check against the caller's permissions even though it looks 9993 // to the content provider like the Activity Manager itself is making 9994 // the request. 9995 Binder token = new Binder(); 9996 sCallerIdentity.set(new Identity( 9997 token, Binder.getCallingPid(), Binder.getCallingUid())); 9998 try { 9999 pfd = cph.provider.openFile(null, uri, "r", null, token); 10000 } catch (FileNotFoundException e) { 10001 // do nothing; pfd will be returned null 10002 } finally { 10003 // Ensure that whatever happens, we clean up the identity state 10004 sCallerIdentity.remove(); 10005 // Ensure we're done with the provider. 10006 removeContentProviderExternalUnchecked(name, null, userId); 10007 } 10008 } else { 10009 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10010 } 10011 return pfd; 10012 } 10013 10014 // Actually is sleeping or shutting down or whatever else in the future 10015 // is an inactive state. 10016 public boolean isSleepingOrShuttingDown() { 10017 return isSleeping() || mShuttingDown; 10018 } 10019 10020 public boolean isSleeping() { 10021 return mSleeping; 10022 } 10023 10024 void onWakefulnessChanged(int wakefulness) { 10025 synchronized(this) { 10026 mWakefulness = wakefulness; 10027 updateSleepIfNeededLocked(); 10028 } 10029 } 10030 10031 void finishRunningVoiceLocked() { 10032 if (mRunningVoice) { 10033 mRunningVoice = false; 10034 updateSleepIfNeededLocked(); 10035 } 10036 } 10037 10038 void updateSleepIfNeededLocked() { 10039 if (mSleeping && !shouldSleepLocked()) { 10040 mSleeping = false; 10041 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10042 } else if (!mSleeping && shouldSleepLocked()) { 10043 mSleeping = true; 10044 mStackSupervisor.goingToSleepLocked(); 10045 10046 // Initialize the wake times of all processes. 10047 checkExcessivePowerUsageLocked(false); 10048 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10049 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10050 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10051 } 10052 } 10053 10054 private boolean shouldSleepLocked() { 10055 // Resume applications while running a voice interactor. 10056 if (mRunningVoice) { 10057 return false; 10058 } 10059 10060 switch (mWakefulness) { 10061 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10062 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10063 // If we're interactive but applications are already paused then defer 10064 // resuming them until the lock screen is hidden. 10065 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10066 case PowerManagerInternal.WAKEFULNESS_DOZING: 10067 // If we're dozing then pause applications whenever the lock screen is shown. 10068 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10069 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10070 default: 10071 // If we're asleep then pause applications unconditionally. 10072 return true; 10073 } 10074 } 10075 10076 /** Pokes the task persister. */ 10077 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10078 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10079 // Never persist the home stack. 10080 return; 10081 } 10082 mTaskPersister.wakeup(task, flush); 10083 } 10084 10085 /** Notifies all listeners when the task stack has changed. */ 10086 void notifyTaskStackChangedLocked() { 10087 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10088 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10089 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10090 } 10091 10092 @Override 10093 public void notifyCleartextNetwork(int uid, byte[] firstPacket) { 10094 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); 10095 } 10096 10097 @Override 10098 public boolean shutdown(int timeout) { 10099 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10100 != PackageManager.PERMISSION_GRANTED) { 10101 throw new SecurityException("Requires permission " 10102 + android.Manifest.permission.SHUTDOWN); 10103 } 10104 10105 boolean timedout = false; 10106 10107 synchronized(this) { 10108 mShuttingDown = true; 10109 updateEventDispatchingLocked(); 10110 timedout = mStackSupervisor.shutdownLocked(timeout); 10111 } 10112 10113 mAppOpsService.shutdown(); 10114 if (mUsageStatsService != null) { 10115 mUsageStatsService.prepareShutdown(); 10116 } 10117 mBatteryStatsService.shutdown(); 10118 synchronized (this) { 10119 mProcessStats.shutdownLocked(); 10120 notifyTaskPersisterLocked(null, true); 10121 } 10122 10123 return timedout; 10124 } 10125 10126 public final void activitySlept(IBinder token) { 10127 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10128 10129 final long origId = Binder.clearCallingIdentity(); 10130 10131 synchronized (this) { 10132 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10133 if (r != null) { 10134 mStackSupervisor.activitySleptLocked(r); 10135 } 10136 } 10137 10138 Binder.restoreCallingIdentity(origId); 10139 } 10140 10141 private String lockScreenShownToString() { 10142 switch (mLockScreenShown) { 10143 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10144 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10145 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10146 default: return "Unknown=" + mLockScreenShown; 10147 } 10148 } 10149 10150 void logLockScreen(String msg) { 10151 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10152 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10153 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10154 + " mSleeping=" + mSleeping); 10155 } 10156 10157 void startRunningVoiceLocked() { 10158 if (!mRunningVoice) { 10159 mRunningVoice = true; 10160 updateSleepIfNeededLocked(); 10161 } 10162 } 10163 10164 private void updateEventDispatchingLocked() { 10165 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10166 } 10167 10168 public void setLockScreenShown(boolean shown) { 10169 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10170 != PackageManager.PERMISSION_GRANTED) { 10171 throw new SecurityException("Requires permission " 10172 + android.Manifest.permission.DEVICE_POWER); 10173 } 10174 10175 synchronized(this) { 10176 long ident = Binder.clearCallingIdentity(); 10177 try { 10178 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10179 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10180 updateSleepIfNeededLocked(); 10181 } finally { 10182 Binder.restoreCallingIdentity(ident); 10183 } 10184 } 10185 } 10186 10187 @Override 10188 public void stopAppSwitches() { 10189 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10190 != PackageManager.PERMISSION_GRANTED) { 10191 throw new SecurityException("Requires permission " 10192 + android.Manifest.permission.STOP_APP_SWITCHES); 10193 } 10194 10195 synchronized(this) { 10196 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10197 + APP_SWITCH_DELAY_TIME; 10198 mDidAppSwitch = false; 10199 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10200 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10201 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10202 } 10203 } 10204 10205 public void resumeAppSwitches() { 10206 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10207 != PackageManager.PERMISSION_GRANTED) { 10208 throw new SecurityException("Requires permission " 10209 + android.Manifest.permission.STOP_APP_SWITCHES); 10210 } 10211 10212 synchronized(this) { 10213 // Note that we don't execute any pending app switches... we will 10214 // let those wait until either the timeout, or the next start 10215 // activity request. 10216 mAppSwitchesAllowedTime = 0; 10217 } 10218 } 10219 10220 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10221 int callingPid, int callingUid, String name) { 10222 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10223 return true; 10224 } 10225 10226 int perm = checkComponentPermission( 10227 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10228 sourceUid, -1, true); 10229 if (perm == PackageManager.PERMISSION_GRANTED) { 10230 return true; 10231 } 10232 10233 // If the actual IPC caller is different from the logical source, then 10234 // also see if they are allowed to control app switches. 10235 if (callingUid != -1 && callingUid != sourceUid) { 10236 perm = checkComponentPermission( 10237 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10238 callingUid, -1, true); 10239 if (perm == PackageManager.PERMISSION_GRANTED) { 10240 return true; 10241 } 10242 } 10243 10244 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10245 return false; 10246 } 10247 10248 public void setDebugApp(String packageName, boolean waitForDebugger, 10249 boolean persistent) { 10250 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10251 "setDebugApp()"); 10252 10253 long ident = Binder.clearCallingIdentity(); 10254 try { 10255 // Note that this is not really thread safe if there are multiple 10256 // callers into it at the same time, but that's not a situation we 10257 // care about. 10258 if (persistent) { 10259 final ContentResolver resolver = mContext.getContentResolver(); 10260 Settings.Global.putString( 10261 resolver, Settings.Global.DEBUG_APP, 10262 packageName); 10263 Settings.Global.putInt( 10264 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10265 waitForDebugger ? 1 : 0); 10266 } 10267 10268 synchronized (this) { 10269 if (!persistent) { 10270 mOrigDebugApp = mDebugApp; 10271 mOrigWaitForDebugger = mWaitForDebugger; 10272 } 10273 mDebugApp = packageName; 10274 mWaitForDebugger = waitForDebugger; 10275 mDebugTransient = !persistent; 10276 if (packageName != null) { 10277 forceStopPackageLocked(packageName, -1, false, false, true, true, 10278 false, UserHandle.USER_ALL, "set debug app"); 10279 } 10280 } 10281 } finally { 10282 Binder.restoreCallingIdentity(ident); 10283 } 10284 } 10285 10286 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10287 synchronized (this) { 10288 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10289 if (!isDebuggable) { 10290 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10291 throw new SecurityException("Process not debuggable: " + app.packageName); 10292 } 10293 } 10294 10295 mOpenGlTraceApp = processName; 10296 } 10297 } 10298 10299 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10300 synchronized (this) { 10301 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10302 if (!isDebuggable) { 10303 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10304 throw new SecurityException("Process not debuggable: " + app.packageName); 10305 } 10306 } 10307 mProfileApp = processName; 10308 mProfileFile = profilerInfo.profileFile; 10309 if (mProfileFd != null) { 10310 try { 10311 mProfileFd.close(); 10312 } catch (IOException e) { 10313 } 10314 mProfileFd = null; 10315 } 10316 mProfileFd = profilerInfo.profileFd; 10317 mSamplingInterval = profilerInfo.samplingInterval; 10318 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10319 mProfileType = 0; 10320 } 10321 } 10322 10323 @Override 10324 public void setAlwaysFinish(boolean enabled) { 10325 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10326 "setAlwaysFinish()"); 10327 10328 Settings.Global.putInt( 10329 mContext.getContentResolver(), 10330 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10331 10332 synchronized (this) { 10333 mAlwaysFinishActivities = enabled; 10334 } 10335 } 10336 10337 @Override 10338 public void setActivityController(IActivityController controller) { 10339 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10340 "setActivityController()"); 10341 synchronized (this) { 10342 mController = controller; 10343 Watchdog.getInstance().setActivityController(controller); 10344 } 10345 } 10346 10347 @Override 10348 public void setUserIsMonkey(boolean userIsMonkey) { 10349 synchronized (this) { 10350 synchronized (mPidsSelfLocked) { 10351 final int callingPid = Binder.getCallingPid(); 10352 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10353 if (precessRecord == null) { 10354 throw new SecurityException("Unknown process: " + callingPid); 10355 } 10356 if (precessRecord.instrumentationUiAutomationConnection == null) { 10357 throw new SecurityException("Only an instrumentation process " 10358 + "with a UiAutomation can call setUserIsMonkey"); 10359 } 10360 } 10361 mUserIsMonkey = userIsMonkey; 10362 } 10363 } 10364 10365 @Override 10366 public boolean isUserAMonkey() { 10367 synchronized (this) { 10368 // If there is a controller also implies the user is a monkey. 10369 return (mUserIsMonkey || mController != null); 10370 } 10371 } 10372 10373 public void requestBugReport() { 10374 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10375 SystemProperties.set("ctl.start", "bugreport"); 10376 } 10377 10378 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10379 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10380 } 10381 10382 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10383 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10384 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10385 } 10386 return KEY_DISPATCHING_TIMEOUT; 10387 } 10388 10389 @Override 10390 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10391 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10392 != PackageManager.PERMISSION_GRANTED) { 10393 throw new SecurityException("Requires permission " 10394 + android.Manifest.permission.FILTER_EVENTS); 10395 } 10396 ProcessRecord proc; 10397 long timeout; 10398 synchronized (this) { 10399 synchronized (mPidsSelfLocked) { 10400 proc = mPidsSelfLocked.get(pid); 10401 } 10402 timeout = getInputDispatchingTimeoutLocked(proc); 10403 } 10404 10405 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10406 return -1; 10407 } 10408 10409 return timeout; 10410 } 10411 10412 /** 10413 * Handle input dispatching timeouts. 10414 * Returns whether input dispatching should be aborted or not. 10415 */ 10416 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10417 final ActivityRecord activity, final ActivityRecord parent, 10418 final boolean aboveSystem, String reason) { 10419 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10420 != PackageManager.PERMISSION_GRANTED) { 10421 throw new SecurityException("Requires permission " 10422 + android.Manifest.permission.FILTER_EVENTS); 10423 } 10424 10425 final String annotation; 10426 if (reason == null) { 10427 annotation = "Input dispatching timed out"; 10428 } else { 10429 annotation = "Input dispatching timed out (" + reason + ")"; 10430 } 10431 10432 if (proc != null) { 10433 synchronized (this) { 10434 if (proc.debugging) { 10435 return false; 10436 } 10437 10438 if (mDidDexOpt) { 10439 // Give more time since we were dexopting. 10440 mDidDexOpt = false; 10441 return false; 10442 } 10443 10444 if (proc.instrumentationClass != null) { 10445 Bundle info = new Bundle(); 10446 info.putString("shortMsg", "keyDispatchingTimedOut"); 10447 info.putString("longMsg", annotation); 10448 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10449 return true; 10450 } 10451 } 10452 mHandler.post(new Runnable() { 10453 @Override 10454 public void run() { 10455 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10456 } 10457 }); 10458 } 10459 10460 return true; 10461 } 10462 10463 public Bundle getAssistContextExtras(int requestType) { 10464 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10465 UserHandle.getCallingUserId()); 10466 if (pae == null) { 10467 return null; 10468 } 10469 synchronized (pae) { 10470 while (!pae.haveResult) { 10471 try { 10472 pae.wait(); 10473 } catch (InterruptedException e) { 10474 } 10475 } 10476 if (pae.result != null) { 10477 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10478 } 10479 } 10480 synchronized (this) { 10481 mPendingAssistExtras.remove(pae); 10482 mHandler.removeCallbacks(pae); 10483 } 10484 return pae.extras; 10485 } 10486 10487 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10488 int userHandle) { 10489 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10490 "getAssistContextExtras()"); 10491 PendingAssistExtras pae; 10492 Bundle extras = new Bundle(); 10493 synchronized (this) { 10494 ActivityRecord activity = getFocusedStack().mResumedActivity; 10495 if (activity == null) { 10496 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10497 return null; 10498 } 10499 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10500 if (activity.app == null || activity.app.thread == null) { 10501 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10502 return null; 10503 } 10504 if (activity.app.pid == Binder.getCallingPid()) { 10505 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10506 return null; 10507 } 10508 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10509 try { 10510 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10511 requestType); 10512 mPendingAssistExtras.add(pae); 10513 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10514 } catch (RemoteException e) { 10515 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10516 return null; 10517 } 10518 return pae; 10519 } 10520 } 10521 10522 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10523 PendingAssistExtras pae = (PendingAssistExtras)token; 10524 synchronized (pae) { 10525 pae.result = extras; 10526 pae.haveResult = true; 10527 pae.notifyAll(); 10528 if (pae.intent == null) { 10529 // Caller is just waiting for the result. 10530 return; 10531 } 10532 } 10533 10534 // We are now ready to launch the assist activity. 10535 synchronized (this) { 10536 boolean exists = mPendingAssistExtras.remove(pae); 10537 mHandler.removeCallbacks(pae); 10538 if (!exists) { 10539 // Timed out. 10540 return; 10541 } 10542 } 10543 pae.intent.replaceExtras(extras); 10544 if (pae.hint != null) { 10545 pae.intent.putExtra(pae.hint, true); 10546 } 10547 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10548 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10549 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10550 closeSystemDialogs("assist"); 10551 try { 10552 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10553 } catch (ActivityNotFoundException e) { 10554 Slog.w(TAG, "No activity to handle assist action.", e); 10555 } 10556 } 10557 10558 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10559 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10560 } 10561 10562 public void registerProcessObserver(IProcessObserver observer) { 10563 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10564 "registerProcessObserver()"); 10565 synchronized (this) { 10566 mProcessObservers.register(observer); 10567 } 10568 } 10569 10570 @Override 10571 public void unregisterProcessObserver(IProcessObserver observer) { 10572 synchronized (this) { 10573 mProcessObservers.unregister(observer); 10574 } 10575 } 10576 10577 @Override 10578 public boolean convertFromTranslucent(IBinder token) { 10579 final long origId = Binder.clearCallingIdentity(); 10580 try { 10581 synchronized (this) { 10582 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10583 if (r == null) { 10584 return false; 10585 } 10586 final boolean translucentChanged = r.changeWindowTranslucency(true); 10587 if (translucentChanged) { 10588 r.task.stack.releaseBackgroundResources(); 10589 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10590 } 10591 mWindowManager.setAppFullscreen(token, true); 10592 return translucentChanged; 10593 } 10594 } finally { 10595 Binder.restoreCallingIdentity(origId); 10596 } 10597 } 10598 10599 @Override 10600 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10601 final long origId = Binder.clearCallingIdentity(); 10602 try { 10603 synchronized (this) { 10604 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10605 if (r == null) { 10606 return false; 10607 } 10608 int index = r.task.mActivities.lastIndexOf(r); 10609 if (index > 0) { 10610 ActivityRecord under = r.task.mActivities.get(index - 1); 10611 under.returningOptions = options; 10612 } 10613 final boolean translucentChanged = r.changeWindowTranslucency(false); 10614 if (translucentChanged) { 10615 r.task.stack.convertToTranslucent(r); 10616 } 10617 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10618 mWindowManager.setAppFullscreen(token, false); 10619 return translucentChanged; 10620 } 10621 } finally { 10622 Binder.restoreCallingIdentity(origId); 10623 } 10624 } 10625 10626 @Override 10627 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10628 final long origId = Binder.clearCallingIdentity(); 10629 try { 10630 synchronized (this) { 10631 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10632 if (r != null) { 10633 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10634 } 10635 } 10636 return false; 10637 } finally { 10638 Binder.restoreCallingIdentity(origId); 10639 } 10640 } 10641 10642 @Override 10643 public boolean isBackgroundVisibleBehind(IBinder token) { 10644 final long origId = Binder.clearCallingIdentity(); 10645 try { 10646 synchronized (this) { 10647 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10648 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10649 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10650 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10651 return visible; 10652 } 10653 } finally { 10654 Binder.restoreCallingIdentity(origId); 10655 } 10656 } 10657 10658 @Override 10659 public ActivityOptions getActivityOptions(IBinder token) { 10660 final long origId = Binder.clearCallingIdentity(); 10661 try { 10662 synchronized (this) { 10663 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10664 if (r != null) { 10665 final ActivityOptions activityOptions = r.pendingOptions; 10666 r.pendingOptions = null; 10667 return activityOptions; 10668 } 10669 return null; 10670 } 10671 } finally { 10672 Binder.restoreCallingIdentity(origId); 10673 } 10674 } 10675 10676 @Override 10677 public void setImmersive(IBinder token, boolean immersive) { 10678 synchronized(this) { 10679 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10680 if (r == null) { 10681 throw new IllegalArgumentException(); 10682 } 10683 r.immersive = immersive; 10684 10685 // update associated state if we're frontmost 10686 if (r == mFocusedActivity) { 10687 if (DEBUG_IMMERSIVE) { 10688 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10689 } 10690 applyUpdateLockStateLocked(r); 10691 } 10692 } 10693 } 10694 10695 @Override 10696 public boolean isImmersive(IBinder token) { 10697 synchronized (this) { 10698 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10699 if (r == null) { 10700 throw new IllegalArgumentException(); 10701 } 10702 return r.immersive; 10703 } 10704 } 10705 10706 public boolean isTopActivityImmersive() { 10707 enforceNotIsolatedCaller("startActivity"); 10708 synchronized (this) { 10709 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10710 return (r != null) ? r.immersive : false; 10711 } 10712 } 10713 10714 @Override 10715 public boolean isTopOfTask(IBinder token) { 10716 synchronized (this) { 10717 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10718 if (r == null) { 10719 throw new IllegalArgumentException(); 10720 } 10721 return r.task.getTopActivity() == r; 10722 } 10723 } 10724 10725 public final void enterSafeMode() { 10726 synchronized(this) { 10727 // It only makes sense to do this before the system is ready 10728 // and started launching other packages. 10729 if (!mSystemReady) { 10730 try { 10731 AppGlobals.getPackageManager().enterSafeMode(); 10732 } catch (RemoteException e) { 10733 } 10734 } 10735 10736 mSafeMode = true; 10737 } 10738 } 10739 10740 public final void showSafeModeOverlay() { 10741 View v = LayoutInflater.from(mContext).inflate( 10742 com.android.internal.R.layout.safe_mode, null); 10743 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10744 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10745 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10746 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10747 lp.gravity = Gravity.BOTTOM | Gravity.START; 10748 lp.format = v.getBackground().getOpacity(); 10749 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10750 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10751 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10752 ((WindowManager)mContext.getSystemService( 10753 Context.WINDOW_SERVICE)).addView(v, lp); 10754 } 10755 10756 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10757 if (!(sender instanceof PendingIntentRecord)) { 10758 return; 10759 } 10760 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10761 synchronized (stats) { 10762 if (mBatteryStatsService.isOnBattery()) { 10763 mBatteryStatsService.enforceCallingPermission(); 10764 PendingIntentRecord rec = (PendingIntentRecord)sender; 10765 int MY_UID = Binder.getCallingUid(); 10766 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10767 BatteryStatsImpl.Uid.Pkg pkg = 10768 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10769 sourcePkg != null ? sourcePkg : rec.key.packageName); 10770 pkg.incWakeupsLocked(); 10771 } 10772 } 10773 } 10774 10775 public boolean killPids(int[] pids, String pReason, boolean secure) { 10776 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10777 throw new SecurityException("killPids only available to the system"); 10778 } 10779 String reason = (pReason == null) ? "Unknown" : pReason; 10780 // XXX Note: don't acquire main activity lock here, because the window 10781 // manager calls in with its locks held. 10782 10783 boolean killed = false; 10784 synchronized (mPidsSelfLocked) { 10785 int[] types = new int[pids.length]; 10786 int worstType = 0; 10787 for (int i=0; i<pids.length; i++) { 10788 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10789 if (proc != null) { 10790 int type = proc.setAdj; 10791 types[i] = type; 10792 if (type > worstType) { 10793 worstType = type; 10794 } 10795 } 10796 } 10797 10798 // If the worst oom_adj is somewhere in the cached proc LRU range, 10799 // then constrain it so we will kill all cached procs. 10800 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10801 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10802 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10803 } 10804 10805 // If this is not a secure call, don't let it kill processes that 10806 // are important. 10807 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10808 worstType = ProcessList.SERVICE_ADJ; 10809 } 10810 10811 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10812 for (int i=0; i<pids.length; i++) { 10813 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10814 if (proc == null) { 10815 continue; 10816 } 10817 int adj = proc.setAdj; 10818 if (adj >= worstType && !proc.killedByAm) { 10819 proc.kill(reason, true); 10820 killed = true; 10821 } 10822 } 10823 } 10824 return killed; 10825 } 10826 10827 @Override 10828 public void killUid(int uid, String reason) { 10829 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10830 throw new SecurityException("killUid only available to the system"); 10831 } 10832 synchronized (this) { 10833 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10834 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10835 reason != null ? reason : "kill uid"); 10836 } 10837 } 10838 10839 @Override 10840 public boolean killProcessesBelowForeground(String reason) { 10841 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10842 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10843 } 10844 10845 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10846 } 10847 10848 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10849 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10850 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10851 } 10852 10853 boolean killed = false; 10854 synchronized (mPidsSelfLocked) { 10855 final int size = mPidsSelfLocked.size(); 10856 for (int i = 0; i < size; i++) { 10857 final int pid = mPidsSelfLocked.keyAt(i); 10858 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10859 if (proc == null) continue; 10860 10861 final int adj = proc.setAdj; 10862 if (adj > belowAdj && !proc.killedByAm) { 10863 proc.kill(reason, true); 10864 killed = true; 10865 } 10866 } 10867 } 10868 return killed; 10869 } 10870 10871 @Override 10872 public void hang(final IBinder who, boolean allowRestart) { 10873 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10874 != PackageManager.PERMISSION_GRANTED) { 10875 throw new SecurityException("Requires permission " 10876 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10877 } 10878 10879 final IBinder.DeathRecipient death = new DeathRecipient() { 10880 @Override 10881 public void binderDied() { 10882 synchronized (this) { 10883 notifyAll(); 10884 } 10885 } 10886 }; 10887 10888 try { 10889 who.linkToDeath(death, 0); 10890 } catch (RemoteException e) { 10891 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10892 return; 10893 } 10894 10895 synchronized (this) { 10896 Watchdog.getInstance().setAllowRestart(allowRestart); 10897 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10898 synchronized (death) { 10899 while (who.isBinderAlive()) { 10900 try { 10901 death.wait(); 10902 } catch (InterruptedException e) { 10903 } 10904 } 10905 } 10906 Watchdog.getInstance().setAllowRestart(true); 10907 } 10908 } 10909 10910 @Override 10911 public void restart() { 10912 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10913 != PackageManager.PERMISSION_GRANTED) { 10914 throw new SecurityException("Requires permission " 10915 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10916 } 10917 10918 Log.i(TAG, "Sending shutdown broadcast..."); 10919 10920 BroadcastReceiver br = new BroadcastReceiver() { 10921 @Override public void onReceive(Context context, Intent intent) { 10922 // Now the broadcast is done, finish up the low-level shutdown. 10923 Log.i(TAG, "Shutting down activity manager..."); 10924 shutdown(10000); 10925 Log.i(TAG, "Shutdown complete, restarting!"); 10926 Process.killProcess(Process.myPid()); 10927 System.exit(10); 10928 } 10929 }; 10930 10931 // First send the high-level shut down broadcast. 10932 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10933 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10934 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10935 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10936 mContext.sendOrderedBroadcastAsUser(intent, 10937 UserHandle.ALL, null, br, mHandler, 0, null, null); 10938 */ 10939 br.onReceive(mContext, intent); 10940 } 10941 10942 private long getLowRamTimeSinceIdle(long now) { 10943 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10944 } 10945 10946 @Override 10947 public void performIdleMaintenance() { 10948 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10949 != PackageManager.PERMISSION_GRANTED) { 10950 throw new SecurityException("Requires permission " 10951 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10952 } 10953 10954 synchronized (this) { 10955 final long now = SystemClock.uptimeMillis(); 10956 final long timeSinceLastIdle = now - mLastIdleTime; 10957 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10958 mLastIdleTime = now; 10959 mLowRamTimeSinceLastIdle = 0; 10960 if (mLowRamStartTime != 0) { 10961 mLowRamStartTime = now; 10962 } 10963 10964 StringBuilder sb = new StringBuilder(128); 10965 sb.append("Idle maintenance over "); 10966 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10967 sb.append(" low RAM for "); 10968 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10969 Slog.i(TAG, sb.toString()); 10970 10971 // If at least 1/3 of our time since the last idle period has been spent 10972 // with RAM low, then we want to kill processes. 10973 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10974 10975 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10976 ProcessRecord proc = mLruProcesses.get(i); 10977 if (proc.notCachedSinceIdle) { 10978 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10979 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10980 if (doKilling && proc.initialIdlePss != 0 10981 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10982 sb = new StringBuilder(128); 10983 sb.append("Kill"); 10984 sb.append(proc.processName); 10985 sb.append(" in idle maint: pss="); 10986 sb.append(proc.lastPss); 10987 sb.append(", initialPss="); 10988 sb.append(proc.initialIdlePss); 10989 sb.append(", period="); 10990 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10991 sb.append(", lowRamPeriod="); 10992 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10993 Slog.wtfQuiet(TAG, sb.toString()); 10994 proc.kill("idle maint (pss " + proc.lastPss 10995 + " from " + proc.initialIdlePss + ")", true); 10996 } 10997 } 10998 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10999 proc.notCachedSinceIdle = true; 11000 proc.initialIdlePss = 0; 11001 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 11002 mTestPssMode, isSleeping(), now); 11003 } 11004 } 11005 11006 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 11007 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 11008 } 11009 } 11010 11011 private void retrieveSettings() { 11012 final ContentResolver resolver = mContext.getContentResolver(); 11013 String debugApp = Settings.Global.getString( 11014 resolver, Settings.Global.DEBUG_APP); 11015 boolean waitForDebugger = Settings.Global.getInt( 11016 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11017 boolean alwaysFinishActivities = Settings.Global.getInt( 11018 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11019 boolean forceRtl = Settings.Global.getInt( 11020 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11021 // Transfer any global setting for forcing RTL layout, into a System Property 11022 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11023 11024 Configuration configuration = new Configuration(); 11025 Settings.System.getConfiguration(resolver, configuration); 11026 if (forceRtl) { 11027 // This will take care of setting the correct layout direction flags 11028 configuration.setLayoutDirection(configuration.locale); 11029 } 11030 11031 synchronized (this) { 11032 mDebugApp = mOrigDebugApp = debugApp; 11033 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11034 mAlwaysFinishActivities = alwaysFinishActivities; 11035 // This happens before any activities are started, so we can 11036 // change mConfiguration in-place. 11037 updateConfigurationLocked(configuration, null, false, true); 11038 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11039 } 11040 } 11041 11042 /** Loads resources after the current configuration has been set. */ 11043 private void loadResourcesOnSystemReady() { 11044 final Resources res = mContext.getResources(); 11045 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11046 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11047 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11048 } 11049 11050 public boolean testIsSystemReady() { 11051 // no need to synchronize(this) just to read & return the value 11052 return mSystemReady; 11053 } 11054 11055 private static File getCalledPreBootReceiversFile() { 11056 File dataDir = Environment.getDataDirectory(); 11057 File systemDir = new File(dataDir, "system"); 11058 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11059 return fname; 11060 } 11061 11062 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11063 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11064 File file = getCalledPreBootReceiversFile(); 11065 FileInputStream fis = null; 11066 try { 11067 fis = new FileInputStream(file); 11068 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11069 int fvers = dis.readInt(); 11070 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11071 String vers = dis.readUTF(); 11072 String codename = dis.readUTF(); 11073 String build = dis.readUTF(); 11074 if (android.os.Build.VERSION.RELEASE.equals(vers) 11075 && android.os.Build.VERSION.CODENAME.equals(codename) 11076 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11077 int num = dis.readInt(); 11078 while (num > 0) { 11079 num--; 11080 String pkg = dis.readUTF(); 11081 String cls = dis.readUTF(); 11082 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11083 } 11084 } 11085 } 11086 } catch (FileNotFoundException e) { 11087 } catch (IOException e) { 11088 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11089 } finally { 11090 if (fis != null) { 11091 try { 11092 fis.close(); 11093 } catch (IOException e) { 11094 } 11095 } 11096 } 11097 return lastDoneReceivers; 11098 } 11099 11100 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11101 File file = getCalledPreBootReceiversFile(); 11102 FileOutputStream fos = null; 11103 DataOutputStream dos = null; 11104 try { 11105 fos = new FileOutputStream(file); 11106 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11107 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11108 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11109 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11110 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11111 dos.writeInt(list.size()); 11112 for (int i=0; i<list.size(); i++) { 11113 dos.writeUTF(list.get(i).getPackageName()); 11114 dos.writeUTF(list.get(i).getClassName()); 11115 } 11116 } catch (IOException e) { 11117 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11118 file.delete(); 11119 } finally { 11120 FileUtils.sync(fos); 11121 if (dos != null) { 11122 try { 11123 dos.close(); 11124 } catch (IOException e) { 11125 // TODO Auto-generated catch block 11126 e.printStackTrace(); 11127 } 11128 } 11129 } 11130 } 11131 11132 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11133 ArrayList<ComponentName> doneReceivers, int userId) { 11134 boolean waitingUpdate = false; 11135 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11136 List<ResolveInfo> ris = null; 11137 try { 11138 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11139 intent, null, 0, userId); 11140 } catch (RemoteException e) { 11141 } 11142 if (ris != null) { 11143 for (int i=ris.size()-1; i>=0; i--) { 11144 if ((ris.get(i).activityInfo.applicationInfo.flags 11145 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11146 ris.remove(i); 11147 } 11148 } 11149 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11150 11151 // For User 0, load the version number. When delivering to a new user, deliver 11152 // to all receivers. 11153 if (userId == UserHandle.USER_OWNER) { 11154 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11155 for (int i=0; i<ris.size(); i++) { 11156 ActivityInfo ai = ris.get(i).activityInfo; 11157 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11158 if (lastDoneReceivers.contains(comp)) { 11159 // We already did the pre boot receiver for this app with the current 11160 // platform version, so don't do it again... 11161 ris.remove(i); 11162 i--; 11163 // ...however, do keep it as one that has been done, so we don't 11164 // forget about it when rewriting the file of last done receivers. 11165 doneReceivers.add(comp); 11166 } 11167 } 11168 } 11169 11170 // If primary user, send broadcast to all available users, else just to userId 11171 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11172 : new int[] { userId }; 11173 for (int i = 0; i < ris.size(); i++) { 11174 ActivityInfo ai = ris.get(i).activityInfo; 11175 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11176 doneReceivers.add(comp); 11177 intent.setComponent(comp); 11178 for (int j=0; j<users.length; j++) { 11179 IIntentReceiver finisher = null; 11180 // On last receiver and user, set up a completion callback 11181 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11182 finisher = new IIntentReceiver.Stub() { 11183 public void performReceive(Intent intent, int resultCode, 11184 String data, Bundle extras, boolean ordered, 11185 boolean sticky, int sendingUser) { 11186 // The raw IIntentReceiver interface is called 11187 // with the AM lock held, so redispatch to 11188 // execute our code without the lock. 11189 mHandler.post(onFinishCallback); 11190 } 11191 }; 11192 } 11193 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11194 + " for user " + users[j]); 11195 broadcastIntentLocked(null, null, intent, null, finisher, 11196 0, null, null, null, AppOpsManager.OP_NONE, 11197 true, false, MY_PID, Process.SYSTEM_UID, 11198 users[j]); 11199 if (finisher != null) { 11200 waitingUpdate = true; 11201 } 11202 } 11203 } 11204 } 11205 11206 return waitingUpdate; 11207 } 11208 11209 public void systemReady(final Runnable goingCallback) { 11210 synchronized(this) { 11211 if (mSystemReady) { 11212 // If we're done calling all the receivers, run the next "boot phase" passed in 11213 // by the SystemServer 11214 if (goingCallback != null) { 11215 goingCallback.run(); 11216 } 11217 return; 11218 } 11219 11220 // Make sure we have the current profile info, since it is needed for 11221 // security checks. 11222 updateCurrentProfileIdsLocked(); 11223 11224 if (mRecentTasks == null) { 11225 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11226 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11227 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11228 mTaskPersister.startPersisting(); 11229 } 11230 11231 // Check to see if there are any update receivers to run. 11232 if (!mDidUpdate) { 11233 if (mWaitingUpdate) { 11234 return; 11235 } 11236 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11237 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11238 public void run() { 11239 synchronized (ActivityManagerService.this) { 11240 mDidUpdate = true; 11241 } 11242 writeLastDonePreBootReceivers(doneReceivers); 11243 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11244 false); 11245 systemReady(goingCallback); 11246 } 11247 }, doneReceivers, UserHandle.USER_OWNER); 11248 11249 if (mWaitingUpdate) { 11250 return; 11251 } 11252 mDidUpdate = true; 11253 } 11254 11255 mAppOpsService.systemReady(); 11256 mSystemReady = true; 11257 } 11258 11259 ArrayList<ProcessRecord> procsToKill = null; 11260 synchronized(mPidsSelfLocked) { 11261 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11262 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11263 if (!isAllowedWhileBooting(proc.info)){ 11264 if (procsToKill == null) { 11265 procsToKill = new ArrayList<ProcessRecord>(); 11266 } 11267 procsToKill.add(proc); 11268 } 11269 } 11270 } 11271 11272 synchronized(this) { 11273 if (procsToKill != null) { 11274 for (int i=procsToKill.size()-1; i>=0; i--) { 11275 ProcessRecord proc = procsToKill.get(i); 11276 Slog.i(TAG, "Removing system update proc: " + proc); 11277 removeProcessLocked(proc, true, false, "system update done"); 11278 } 11279 } 11280 11281 // Now that we have cleaned up any update processes, we 11282 // are ready to start launching real processes and know that 11283 // we won't trample on them any more. 11284 mProcessesReady = true; 11285 } 11286 11287 Slog.i(TAG, "System now ready"); 11288 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11289 SystemClock.uptimeMillis()); 11290 11291 synchronized(this) { 11292 // Make sure we have no pre-ready processes sitting around. 11293 11294 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11295 ResolveInfo ri = mContext.getPackageManager() 11296 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11297 STOCK_PM_FLAGS); 11298 CharSequence errorMsg = null; 11299 if (ri != null) { 11300 ActivityInfo ai = ri.activityInfo; 11301 ApplicationInfo app = ai.applicationInfo; 11302 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11303 mTopAction = Intent.ACTION_FACTORY_TEST; 11304 mTopData = null; 11305 mTopComponent = new ComponentName(app.packageName, 11306 ai.name); 11307 } else { 11308 errorMsg = mContext.getResources().getText( 11309 com.android.internal.R.string.factorytest_not_system); 11310 } 11311 } else { 11312 errorMsg = mContext.getResources().getText( 11313 com.android.internal.R.string.factorytest_no_action); 11314 } 11315 if (errorMsg != null) { 11316 mTopAction = null; 11317 mTopData = null; 11318 mTopComponent = null; 11319 Message msg = Message.obtain(); 11320 msg.what = SHOW_FACTORY_ERROR_MSG; 11321 msg.getData().putCharSequence("msg", errorMsg); 11322 mHandler.sendMessage(msg); 11323 } 11324 } 11325 } 11326 11327 retrieveSettings(); 11328 loadResourcesOnSystemReady(); 11329 11330 synchronized (this) { 11331 readGrantedUriPermissionsLocked(); 11332 } 11333 11334 if (goingCallback != null) goingCallback.run(); 11335 11336 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11337 Integer.toString(mCurrentUserId), mCurrentUserId); 11338 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11339 Integer.toString(mCurrentUserId), mCurrentUserId); 11340 mSystemServiceManager.startUser(mCurrentUserId); 11341 11342 synchronized (this) { 11343 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11344 try { 11345 List apps = AppGlobals.getPackageManager(). 11346 getPersistentApplications(STOCK_PM_FLAGS); 11347 if (apps != null) { 11348 int N = apps.size(); 11349 int i; 11350 for (i=0; i<N; i++) { 11351 ApplicationInfo info 11352 = (ApplicationInfo)apps.get(i); 11353 if (info != null && 11354 !info.packageName.equals("android")) { 11355 addAppLocked(info, false, null /* ABI override */); 11356 } 11357 } 11358 } 11359 } catch (RemoteException ex) { 11360 // pm is in same process, this will never happen. 11361 } 11362 } 11363 11364 // Start up initial activity. 11365 mBooting = true; 11366 startHomeActivityLocked(mCurrentUserId, "systemReady"); 11367 11368 try { 11369 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11370 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11371 + " data partition or your device will be unstable."); 11372 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11373 } 11374 } catch (RemoteException e) { 11375 } 11376 11377 if (!Build.isFingerprintConsistent()) { 11378 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11379 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11380 } 11381 11382 long ident = Binder.clearCallingIdentity(); 11383 try { 11384 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11385 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11386 | Intent.FLAG_RECEIVER_FOREGROUND); 11387 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11388 broadcastIntentLocked(null, null, intent, 11389 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11390 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11391 intent = new Intent(Intent.ACTION_USER_STARTING); 11392 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11393 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11394 broadcastIntentLocked(null, null, intent, 11395 null, new IIntentReceiver.Stub() { 11396 @Override 11397 public void performReceive(Intent intent, int resultCode, String data, 11398 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11399 throws RemoteException { 11400 } 11401 }, 0, null, null, 11402 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11403 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11404 } catch (Throwable t) { 11405 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11406 } finally { 11407 Binder.restoreCallingIdentity(ident); 11408 } 11409 mStackSupervisor.resumeTopActivitiesLocked(); 11410 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11411 } 11412 } 11413 11414 private boolean makeAppCrashingLocked(ProcessRecord app, 11415 String shortMsg, String longMsg, String stackTrace) { 11416 app.crashing = true; 11417 app.crashingReport = generateProcessError(app, 11418 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11419 startAppProblemLocked(app); 11420 app.stopFreezingAllLocked(); 11421 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11422 } 11423 11424 private void makeAppNotRespondingLocked(ProcessRecord app, 11425 String activity, String shortMsg, String longMsg) { 11426 app.notResponding = true; 11427 app.notRespondingReport = generateProcessError(app, 11428 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11429 activity, shortMsg, longMsg, null); 11430 startAppProblemLocked(app); 11431 app.stopFreezingAllLocked(); 11432 } 11433 11434 /** 11435 * Generate a process error record, suitable for attachment to a ProcessRecord. 11436 * 11437 * @param app The ProcessRecord in which the error occurred. 11438 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11439 * ActivityManager.AppErrorStateInfo 11440 * @param activity The activity associated with the crash, if known. 11441 * @param shortMsg Short message describing the crash. 11442 * @param longMsg Long message describing the crash. 11443 * @param stackTrace Full crash stack trace, may be null. 11444 * 11445 * @return Returns a fully-formed AppErrorStateInfo record. 11446 */ 11447 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11448 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11449 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11450 11451 report.condition = condition; 11452 report.processName = app.processName; 11453 report.pid = app.pid; 11454 report.uid = app.info.uid; 11455 report.tag = activity; 11456 report.shortMsg = shortMsg; 11457 report.longMsg = longMsg; 11458 report.stackTrace = stackTrace; 11459 11460 return report; 11461 } 11462 11463 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11464 synchronized (this) { 11465 app.crashing = false; 11466 app.crashingReport = null; 11467 app.notResponding = false; 11468 app.notRespondingReport = null; 11469 if (app.anrDialog == fromDialog) { 11470 app.anrDialog = null; 11471 } 11472 if (app.waitDialog == fromDialog) { 11473 app.waitDialog = null; 11474 } 11475 if (app.pid > 0 && app.pid != MY_PID) { 11476 handleAppCrashLocked(app, null, null, null); 11477 app.kill("user request after error", true); 11478 } 11479 } 11480 } 11481 11482 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11483 String stackTrace) { 11484 long now = SystemClock.uptimeMillis(); 11485 11486 Long crashTime; 11487 if (!app.isolated) { 11488 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11489 } else { 11490 crashTime = null; 11491 } 11492 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11493 // This process loses! 11494 Slog.w(TAG, "Process " + app.info.processName 11495 + " has crashed too many times: killing!"); 11496 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11497 app.userId, app.info.processName, app.uid); 11498 mStackSupervisor.handleAppCrashLocked(app); 11499 if (!app.persistent) { 11500 // We don't want to start this process again until the user 11501 // explicitly does so... but for persistent process, we really 11502 // need to keep it running. If a persistent process is actually 11503 // repeatedly crashing, then badness for everyone. 11504 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11505 app.info.processName); 11506 if (!app.isolated) { 11507 // XXX We don't have a way to mark isolated processes 11508 // as bad, since they don't have a peristent identity. 11509 mBadProcesses.put(app.info.processName, app.uid, 11510 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11511 mProcessCrashTimes.remove(app.info.processName, app.uid); 11512 } 11513 app.bad = true; 11514 app.removed = true; 11515 // Don't let services in this process be restarted and potentially 11516 // annoy the user repeatedly. Unless it is persistent, since those 11517 // processes run critical code. 11518 removeProcessLocked(app, false, false, "crash"); 11519 mStackSupervisor.resumeTopActivitiesLocked(); 11520 return false; 11521 } 11522 mStackSupervisor.resumeTopActivitiesLocked(); 11523 } else { 11524 mStackSupervisor.finishTopRunningActivityLocked(app); 11525 } 11526 11527 // Bump up the crash count of any services currently running in the proc. 11528 for (int i=app.services.size()-1; i>=0; i--) { 11529 // Any services running in the application need to be placed 11530 // back in the pending list. 11531 ServiceRecord sr = app.services.valueAt(i); 11532 sr.crashCount++; 11533 } 11534 11535 // If the crashing process is what we consider to be the "home process" and it has been 11536 // replaced by a third-party app, clear the package preferred activities from packages 11537 // with a home activity running in the process to prevent a repeatedly crashing app 11538 // from blocking the user to manually clear the list. 11539 final ArrayList<ActivityRecord> activities = app.activities; 11540 if (app == mHomeProcess && activities.size() > 0 11541 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11542 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11543 final ActivityRecord r = activities.get(activityNdx); 11544 if (r.isHomeActivity()) { 11545 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11546 try { 11547 ActivityThread.getPackageManager() 11548 .clearPackagePreferredActivities(r.packageName); 11549 } catch (RemoteException c) { 11550 // pm is in same process, this will never happen. 11551 } 11552 } 11553 } 11554 } 11555 11556 if (!app.isolated) { 11557 // XXX Can't keep track of crash times for isolated processes, 11558 // because they don't have a perisistent identity. 11559 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11560 } 11561 11562 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11563 return true; 11564 } 11565 11566 void startAppProblemLocked(ProcessRecord app) { 11567 // If this app is not running under the current user, then we 11568 // can't give it a report button because that would require 11569 // launching the report UI under a different user. 11570 app.errorReportReceiver = null; 11571 11572 for (int userId : mCurrentProfileIds) { 11573 if (app.userId == userId) { 11574 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11575 mContext, app.info.packageName, app.info.flags); 11576 } 11577 } 11578 skipCurrentReceiverLocked(app); 11579 } 11580 11581 void skipCurrentReceiverLocked(ProcessRecord app) { 11582 for (BroadcastQueue queue : mBroadcastQueues) { 11583 queue.skipCurrentReceiverLocked(app); 11584 } 11585 } 11586 11587 /** 11588 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11589 * The application process will exit immediately after this call returns. 11590 * @param app object of the crashing app, null for the system server 11591 * @param crashInfo describing the exception 11592 */ 11593 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11594 ProcessRecord r = findAppProcess(app, "Crash"); 11595 final String processName = app == null ? "system_server" 11596 : (r == null ? "unknown" : r.processName); 11597 11598 handleApplicationCrashInner("crash", r, processName, crashInfo); 11599 } 11600 11601 /* Native crash reporting uses this inner version because it needs to be somewhat 11602 * decoupled from the AM-managed cleanup lifecycle 11603 */ 11604 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11605 ApplicationErrorReport.CrashInfo crashInfo) { 11606 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11607 UserHandle.getUserId(Binder.getCallingUid()), processName, 11608 r == null ? -1 : r.info.flags, 11609 crashInfo.exceptionClassName, 11610 crashInfo.exceptionMessage, 11611 crashInfo.throwFileName, 11612 crashInfo.throwLineNumber); 11613 11614 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11615 11616 crashApplication(r, crashInfo); 11617 } 11618 11619 public void handleApplicationStrictModeViolation( 11620 IBinder app, 11621 int violationMask, 11622 StrictMode.ViolationInfo info) { 11623 ProcessRecord r = findAppProcess(app, "StrictMode"); 11624 if (r == null) { 11625 return; 11626 } 11627 11628 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11629 Integer stackFingerprint = info.hashCode(); 11630 boolean logIt = true; 11631 synchronized (mAlreadyLoggedViolatedStacks) { 11632 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11633 logIt = false; 11634 // TODO: sub-sample into EventLog for these, with 11635 // the info.durationMillis? Then we'd get 11636 // the relative pain numbers, without logging all 11637 // the stack traces repeatedly. We'd want to do 11638 // likewise in the client code, which also does 11639 // dup suppression, before the Binder call. 11640 } else { 11641 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11642 mAlreadyLoggedViolatedStacks.clear(); 11643 } 11644 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11645 } 11646 } 11647 if (logIt) { 11648 logStrictModeViolationToDropBox(r, info); 11649 } 11650 } 11651 11652 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11653 AppErrorResult result = new AppErrorResult(); 11654 synchronized (this) { 11655 final long origId = Binder.clearCallingIdentity(); 11656 11657 Message msg = Message.obtain(); 11658 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11659 HashMap<String, Object> data = new HashMap<String, Object>(); 11660 data.put("result", result); 11661 data.put("app", r); 11662 data.put("violationMask", violationMask); 11663 data.put("info", info); 11664 msg.obj = data; 11665 mHandler.sendMessage(msg); 11666 11667 Binder.restoreCallingIdentity(origId); 11668 } 11669 int res = result.get(); 11670 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11671 } 11672 } 11673 11674 // Depending on the policy in effect, there could be a bunch of 11675 // these in quick succession so we try to batch these together to 11676 // minimize disk writes, number of dropbox entries, and maximize 11677 // compression, by having more fewer, larger records. 11678 private void logStrictModeViolationToDropBox( 11679 ProcessRecord process, 11680 StrictMode.ViolationInfo info) { 11681 if (info == null) { 11682 return; 11683 } 11684 final boolean isSystemApp = process == null || 11685 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11686 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11687 final String processName = process == null ? "unknown" : process.processName; 11688 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11689 final DropBoxManager dbox = (DropBoxManager) 11690 mContext.getSystemService(Context.DROPBOX_SERVICE); 11691 11692 // Exit early if the dropbox isn't configured to accept this report type. 11693 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11694 11695 boolean bufferWasEmpty; 11696 boolean needsFlush; 11697 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11698 synchronized (sb) { 11699 bufferWasEmpty = sb.length() == 0; 11700 appendDropBoxProcessHeaders(process, processName, sb); 11701 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11702 sb.append("System-App: ").append(isSystemApp).append("\n"); 11703 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11704 if (info.violationNumThisLoop != 0) { 11705 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11706 } 11707 if (info.numAnimationsRunning != 0) { 11708 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11709 } 11710 if (info.broadcastIntentAction != null) { 11711 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11712 } 11713 if (info.durationMillis != -1) { 11714 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11715 } 11716 if (info.numInstances != -1) { 11717 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11718 } 11719 if (info.tags != null) { 11720 for (String tag : info.tags) { 11721 sb.append("Span-Tag: ").append(tag).append("\n"); 11722 } 11723 } 11724 sb.append("\n"); 11725 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11726 sb.append(info.crashInfo.stackTrace); 11727 sb.append("\n"); 11728 } 11729 if (info.message != null) { 11730 sb.append(info.message); 11731 sb.append("\n"); 11732 } 11733 11734 // Only buffer up to ~64k. Various logging bits truncate 11735 // things at 128k. 11736 needsFlush = (sb.length() > 64 * 1024); 11737 } 11738 11739 // Flush immediately if the buffer's grown too large, or this 11740 // is a non-system app. Non-system apps are isolated with a 11741 // different tag & policy and not batched. 11742 // 11743 // Batching is useful during internal testing with 11744 // StrictMode settings turned up high. Without batching, 11745 // thousands of separate files could be created on boot. 11746 if (!isSystemApp || needsFlush) { 11747 new Thread("Error dump: " + dropboxTag) { 11748 @Override 11749 public void run() { 11750 String report; 11751 synchronized (sb) { 11752 report = sb.toString(); 11753 sb.delete(0, sb.length()); 11754 sb.trimToSize(); 11755 } 11756 if (report.length() != 0) { 11757 dbox.addText(dropboxTag, report); 11758 } 11759 } 11760 }.start(); 11761 return; 11762 } 11763 11764 // System app batching: 11765 if (!bufferWasEmpty) { 11766 // An existing dropbox-writing thread is outstanding, so 11767 // we don't need to start it up. The existing thread will 11768 // catch the buffer appends we just did. 11769 return; 11770 } 11771 11772 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11773 // (After this point, we shouldn't access AMS internal data structures.) 11774 new Thread("Error dump: " + dropboxTag) { 11775 @Override 11776 public void run() { 11777 // 5 second sleep to let stacks arrive and be batched together 11778 try { 11779 Thread.sleep(5000); // 5 seconds 11780 } catch (InterruptedException e) {} 11781 11782 String errorReport; 11783 synchronized (mStrictModeBuffer) { 11784 errorReport = mStrictModeBuffer.toString(); 11785 if (errorReport.length() == 0) { 11786 return; 11787 } 11788 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11789 mStrictModeBuffer.trimToSize(); 11790 } 11791 dbox.addText(dropboxTag, errorReport); 11792 } 11793 }.start(); 11794 } 11795 11796 /** 11797 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11798 * @param app object of the crashing app, null for the system server 11799 * @param tag reported by the caller 11800 * @param system whether this wtf is coming from the system 11801 * @param crashInfo describing the context of the error 11802 * @return true if the process should exit immediately (WTF is fatal) 11803 */ 11804 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11805 final ApplicationErrorReport.CrashInfo crashInfo) { 11806 final int callingUid = Binder.getCallingUid(); 11807 final int callingPid = Binder.getCallingPid(); 11808 11809 if (system) { 11810 // If this is coming from the system, we could very well have low-level 11811 // system locks held, so we want to do this all asynchronously. And we 11812 // never want this to become fatal, so there is that too. 11813 mHandler.post(new Runnable() { 11814 @Override public void run() { 11815 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11816 } 11817 }); 11818 return false; 11819 } 11820 11821 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11822 crashInfo); 11823 11824 if (r != null && r.pid != Process.myPid() && 11825 Settings.Global.getInt(mContext.getContentResolver(), 11826 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11827 crashApplication(r, crashInfo); 11828 return true; 11829 } else { 11830 return false; 11831 } 11832 } 11833 11834 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11835 final ApplicationErrorReport.CrashInfo crashInfo) { 11836 final ProcessRecord r = findAppProcess(app, "WTF"); 11837 final String processName = app == null ? "system_server" 11838 : (r == null ? "unknown" : r.processName); 11839 11840 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11841 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11842 11843 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11844 11845 return r; 11846 } 11847 11848 /** 11849 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11850 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11851 */ 11852 private ProcessRecord findAppProcess(IBinder app, String reason) { 11853 if (app == null) { 11854 return null; 11855 } 11856 11857 synchronized (this) { 11858 final int NP = mProcessNames.getMap().size(); 11859 for (int ip=0; ip<NP; ip++) { 11860 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11861 final int NA = apps.size(); 11862 for (int ia=0; ia<NA; ia++) { 11863 ProcessRecord p = apps.valueAt(ia); 11864 if (p.thread != null && p.thread.asBinder() == app) { 11865 return p; 11866 } 11867 } 11868 } 11869 11870 Slog.w(TAG, "Can't find mystery application for " + reason 11871 + " from pid=" + Binder.getCallingPid() 11872 + " uid=" + Binder.getCallingUid() + ": " + app); 11873 return null; 11874 } 11875 } 11876 11877 /** 11878 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11879 * to append various headers to the dropbox log text. 11880 */ 11881 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11882 StringBuilder sb) { 11883 // Watchdog thread ends up invoking this function (with 11884 // a null ProcessRecord) to add the stack file to dropbox. 11885 // Do not acquire a lock on this (am) in such cases, as it 11886 // could cause a potential deadlock, if and when watchdog 11887 // is invoked due to unavailability of lock on am and it 11888 // would prevent watchdog from killing system_server. 11889 if (process == null) { 11890 sb.append("Process: ").append(processName).append("\n"); 11891 return; 11892 } 11893 // Note: ProcessRecord 'process' is guarded by the service 11894 // instance. (notably process.pkgList, which could otherwise change 11895 // concurrently during execution of this method) 11896 synchronized (this) { 11897 sb.append("Process: ").append(processName).append("\n"); 11898 int flags = process.info.flags; 11899 IPackageManager pm = AppGlobals.getPackageManager(); 11900 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11901 for (int ip=0; ip<process.pkgList.size(); ip++) { 11902 String pkg = process.pkgList.keyAt(ip); 11903 sb.append("Package: ").append(pkg); 11904 try { 11905 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11906 if (pi != null) { 11907 sb.append(" v").append(pi.versionCode); 11908 if (pi.versionName != null) { 11909 sb.append(" (").append(pi.versionName).append(")"); 11910 } 11911 } 11912 } catch (RemoteException e) { 11913 Slog.e(TAG, "Error getting package info: " + pkg, e); 11914 } 11915 sb.append("\n"); 11916 } 11917 } 11918 } 11919 11920 private static String processClass(ProcessRecord process) { 11921 if (process == null || process.pid == MY_PID) { 11922 return "system_server"; 11923 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11924 return "system_app"; 11925 } else { 11926 return "data_app"; 11927 } 11928 } 11929 11930 /** 11931 * Write a description of an error (crash, WTF, ANR) to the drop box. 11932 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11933 * @param process which caused the error, null means the system server 11934 * @param activity which triggered the error, null if unknown 11935 * @param parent activity related to the error, null if unknown 11936 * @param subject line related to the error, null if absent 11937 * @param report in long form describing the error, null if absent 11938 * @param logFile to include in the report, null if none 11939 * @param crashInfo giving an application stack trace, null if absent 11940 */ 11941 public void addErrorToDropBox(String eventType, 11942 ProcessRecord process, String processName, ActivityRecord activity, 11943 ActivityRecord parent, String subject, 11944 final String report, final File logFile, 11945 final ApplicationErrorReport.CrashInfo crashInfo) { 11946 // NOTE -- this must never acquire the ActivityManagerService lock, 11947 // otherwise the watchdog may be prevented from resetting the system. 11948 11949 final String dropboxTag = processClass(process) + "_" + eventType; 11950 final DropBoxManager dbox = (DropBoxManager) 11951 mContext.getSystemService(Context.DROPBOX_SERVICE); 11952 11953 // Exit early if the dropbox isn't configured to accept this report type. 11954 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11955 11956 final StringBuilder sb = new StringBuilder(1024); 11957 appendDropBoxProcessHeaders(process, processName, sb); 11958 if (activity != null) { 11959 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11960 } 11961 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11962 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11963 } 11964 if (parent != null && parent != activity) { 11965 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11966 } 11967 if (subject != null) { 11968 sb.append("Subject: ").append(subject).append("\n"); 11969 } 11970 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11971 if (Debug.isDebuggerConnected()) { 11972 sb.append("Debugger: Connected\n"); 11973 } 11974 sb.append("\n"); 11975 11976 // Do the rest in a worker thread to avoid blocking the caller on I/O 11977 // (After this point, we shouldn't access AMS internal data structures.) 11978 Thread worker = new Thread("Error dump: " + dropboxTag) { 11979 @Override 11980 public void run() { 11981 if (report != null) { 11982 sb.append(report); 11983 } 11984 if (logFile != null) { 11985 try { 11986 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11987 "\n\n[[TRUNCATED]]")); 11988 } catch (IOException e) { 11989 Slog.e(TAG, "Error reading " + logFile, e); 11990 } 11991 } 11992 if (crashInfo != null && crashInfo.stackTrace != null) { 11993 sb.append(crashInfo.stackTrace); 11994 } 11995 11996 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11997 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11998 if (lines > 0) { 11999 sb.append("\n"); 12000 12001 // Merge several logcat streams, and take the last N lines 12002 InputStreamReader input = null; 12003 try { 12004 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 12005 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 12006 "-b", "crash", 12007 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 12008 12009 try { logcat.getOutputStream().close(); } catch (IOException e) {} 12010 try { logcat.getErrorStream().close(); } catch (IOException e) {} 12011 input = new InputStreamReader(logcat.getInputStream()); 12012 12013 int num; 12014 char[] buf = new char[8192]; 12015 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 12016 } catch (IOException e) { 12017 Slog.e(TAG, "Error running logcat", e); 12018 } finally { 12019 if (input != null) try { input.close(); } catch (IOException e) {} 12020 } 12021 } 12022 12023 dbox.addText(dropboxTag, sb.toString()); 12024 } 12025 }; 12026 12027 if (process == null) { 12028 // If process is null, we are being called from some internal code 12029 // and may be about to die -- run this synchronously. 12030 worker.run(); 12031 } else { 12032 worker.start(); 12033 } 12034 } 12035 12036 /** 12037 * Bring up the "unexpected error" dialog box for a crashing app. 12038 * Deal with edge cases (intercepts from instrumented applications, 12039 * ActivityController, error intent receivers, that sort of thing). 12040 * @param r the application crashing 12041 * @param crashInfo describing the failure 12042 */ 12043 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12044 long timeMillis = System.currentTimeMillis(); 12045 String shortMsg = crashInfo.exceptionClassName; 12046 String longMsg = crashInfo.exceptionMessage; 12047 String stackTrace = crashInfo.stackTrace; 12048 if (shortMsg != null && longMsg != null) { 12049 longMsg = shortMsg + ": " + longMsg; 12050 } else if (shortMsg != null) { 12051 longMsg = shortMsg; 12052 } 12053 12054 AppErrorResult result = new AppErrorResult(); 12055 synchronized (this) { 12056 if (mController != null) { 12057 try { 12058 String name = r != null ? r.processName : null; 12059 int pid = r != null ? r.pid : Binder.getCallingPid(); 12060 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12061 if (!mController.appCrashed(name, pid, 12062 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12063 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12064 && "Native crash".equals(crashInfo.exceptionClassName)) { 12065 Slog.w(TAG, "Skip killing native crashed app " + name 12066 + "(" + pid + ") during testing"); 12067 } else { 12068 Slog.w(TAG, "Force-killing crashed app " + name 12069 + " at watcher's request"); 12070 if (r != null) { 12071 r.kill("crash", true); 12072 } else { 12073 // Huh. 12074 Process.killProcess(pid); 12075 Process.killProcessGroup(uid, pid); 12076 } 12077 } 12078 return; 12079 } 12080 } catch (RemoteException e) { 12081 mController = null; 12082 Watchdog.getInstance().setActivityController(null); 12083 } 12084 } 12085 12086 final long origId = Binder.clearCallingIdentity(); 12087 12088 // If this process is running instrumentation, finish it. 12089 if (r != null && r.instrumentationClass != null) { 12090 Slog.w(TAG, "Error in app " + r.processName 12091 + " running instrumentation " + r.instrumentationClass + ":"); 12092 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12093 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12094 Bundle info = new Bundle(); 12095 info.putString("shortMsg", shortMsg); 12096 info.putString("longMsg", longMsg); 12097 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12098 Binder.restoreCallingIdentity(origId); 12099 return; 12100 } 12101 12102 // Log crash in battery stats. 12103 if (r != null) { 12104 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12105 } 12106 12107 // If we can't identify the process or it's already exceeded its crash quota, 12108 // quit right away without showing a crash dialog. 12109 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12110 Binder.restoreCallingIdentity(origId); 12111 return; 12112 } 12113 12114 Message msg = Message.obtain(); 12115 msg.what = SHOW_ERROR_MSG; 12116 HashMap data = new HashMap(); 12117 data.put("result", result); 12118 data.put("app", r); 12119 msg.obj = data; 12120 mHandler.sendMessage(msg); 12121 12122 Binder.restoreCallingIdentity(origId); 12123 } 12124 12125 int res = result.get(); 12126 12127 Intent appErrorIntent = null; 12128 synchronized (this) { 12129 if (r != null && !r.isolated) { 12130 // XXX Can't keep track of crash time for isolated processes, 12131 // since they don't have a persistent identity. 12132 mProcessCrashTimes.put(r.info.processName, r.uid, 12133 SystemClock.uptimeMillis()); 12134 } 12135 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12136 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12137 } 12138 } 12139 12140 if (appErrorIntent != null) { 12141 try { 12142 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12143 } catch (ActivityNotFoundException e) { 12144 Slog.w(TAG, "bug report receiver dissappeared", e); 12145 } 12146 } 12147 } 12148 12149 Intent createAppErrorIntentLocked(ProcessRecord r, 12150 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12151 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12152 if (report == null) { 12153 return null; 12154 } 12155 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12156 result.setComponent(r.errorReportReceiver); 12157 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12158 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12159 return result; 12160 } 12161 12162 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12163 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12164 if (r.errorReportReceiver == null) { 12165 return null; 12166 } 12167 12168 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12169 return null; 12170 } 12171 12172 ApplicationErrorReport report = new ApplicationErrorReport(); 12173 report.packageName = r.info.packageName; 12174 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12175 report.processName = r.processName; 12176 report.time = timeMillis; 12177 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12178 12179 if (r.crashing || r.forceCrashReport) { 12180 report.type = ApplicationErrorReport.TYPE_CRASH; 12181 report.crashInfo = crashInfo; 12182 } else if (r.notResponding) { 12183 report.type = ApplicationErrorReport.TYPE_ANR; 12184 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12185 12186 report.anrInfo.activity = r.notRespondingReport.tag; 12187 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12188 report.anrInfo.info = r.notRespondingReport.longMsg; 12189 } 12190 12191 return report; 12192 } 12193 12194 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12195 enforceNotIsolatedCaller("getProcessesInErrorState"); 12196 // assume our apps are happy - lazy create the list 12197 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12198 12199 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12200 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12201 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12202 12203 synchronized (this) { 12204 12205 // iterate across all processes 12206 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12207 ProcessRecord app = mLruProcesses.get(i); 12208 if (!allUsers && app.userId != userId) { 12209 continue; 12210 } 12211 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12212 // This one's in trouble, so we'll generate a report for it 12213 // crashes are higher priority (in case there's a crash *and* an anr) 12214 ActivityManager.ProcessErrorStateInfo report = null; 12215 if (app.crashing) { 12216 report = app.crashingReport; 12217 } else if (app.notResponding) { 12218 report = app.notRespondingReport; 12219 } 12220 12221 if (report != null) { 12222 if (errList == null) { 12223 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12224 } 12225 errList.add(report); 12226 } else { 12227 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12228 " crashing = " + app.crashing + 12229 " notResponding = " + app.notResponding); 12230 } 12231 } 12232 } 12233 } 12234 12235 return errList; 12236 } 12237 12238 static int procStateToImportance(int procState, int memAdj, 12239 ActivityManager.RunningAppProcessInfo currApp) { 12240 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12241 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12242 currApp.lru = memAdj; 12243 } else { 12244 currApp.lru = 0; 12245 } 12246 return imp; 12247 } 12248 12249 private void fillInProcMemInfo(ProcessRecord app, 12250 ActivityManager.RunningAppProcessInfo outInfo) { 12251 outInfo.pid = app.pid; 12252 outInfo.uid = app.info.uid; 12253 if (mHeavyWeightProcess == app) { 12254 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12255 } 12256 if (app.persistent) { 12257 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12258 } 12259 if (app.activities.size() > 0) { 12260 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12261 } 12262 outInfo.lastTrimLevel = app.trimMemoryLevel; 12263 int adj = app.curAdj; 12264 int procState = app.curProcState; 12265 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12266 outInfo.importanceReasonCode = app.adjTypeCode; 12267 outInfo.processState = app.curProcState; 12268 } 12269 12270 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12271 enforceNotIsolatedCaller("getRunningAppProcesses"); 12272 // Lazy instantiation of list 12273 List<ActivityManager.RunningAppProcessInfo> runList = null; 12274 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12275 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12276 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12277 synchronized (this) { 12278 // Iterate across all processes 12279 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12280 ProcessRecord app = mLruProcesses.get(i); 12281 if (!allUsers && app.userId != userId) { 12282 continue; 12283 } 12284 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12285 // Generate process state info for running application 12286 ActivityManager.RunningAppProcessInfo currApp = 12287 new ActivityManager.RunningAppProcessInfo(app.processName, 12288 app.pid, app.getPackageList()); 12289 fillInProcMemInfo(app, currApp); 12290 if (app.adjSource instanceof ProcessRecord) { 12291 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12292 currApp.importanceReasonImportance = 12293 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12294 app.adjSourceProcState); 12295 } else if (app.adjSource instanceof ActivityRecord) { 12296 ActivityRecord r = (ActivityRecord)app.adjSource; 12297 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12298 } 12299 if (app.adjTarget instanceof ComponentName) { 12300 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12301 } 12302 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12303 // + " lru=" + currApp.lru); 12304 if (runList == null) { 12305 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12306 } 12307 runList.add(currApp); 12308 } 12309 } 12310 } 12311 return runList; 12312 } 12313 12314 public List<ApplicationInfo> getRunningExternalApplications() { 12315 enforceNotIsolatedCaller("getRunningExternalApplications"); 12316 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12317 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12318 if (runningApps != null && runningApps.size() > 0) { 12319 Set<String> extList = new HashSet<String>(); 12320 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12321 if (app.pkgList != null) { 12322 for (String pkg : app.pkgList) { 12323 extList.add(pkg); 12324 } 12325 } 12326 } 12327 IPackageManager pm = AppGlobals.getPackageManager(); 12328 for (String pkg : extList) { 12329 try { 12330 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12331 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12332 retList.add(info); 12333 } 12334 } catch (RemoteException e) { 12335 } 12336 } 12337 } 12338 return retList; 12339 } 12340 12341 @Override 12342 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12343 enforceNotIsolatedCaller("getMyMemoryState"); 12344 synchronized (this) { 12345 ProcessRecord proc; 12346 synchronized (mPidsSelfLocked) { 12347 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12348 } 12349 fillInProcMemInfo(proc, outInfo); 12350 } 12351 } 12352 12353 @Override 12354 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12355 if (checkCallingPermission(android.Manifest.permission.DUMP) 12356 != PackageManager.PERMISSION_GRANTED) { 12357 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12358 + Binder.getCallingPid() 12359 + ", uid=" + Binder.getCallingUid() 12360 + " without permission " 12361 + android.Manifest.permission.DUMP); 12362 return; 12363 } 12364 12365 boolean dumpAll = false; 12366 boolean dumpClient = false; 12367 String dumpPackage = null; 12368 12369 int opti = 0; 12370 while (opti < args.length) { 12371 String opt = args[opti]; 12372 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12373 break; 12374 } 12375 opti++; 12376 if ("-a".equals(opt)) { 12377 dumpAll = true; 12378 } else if ("-c".equals(opt)) { 12379 dumpClient = true; 12380 } else if ("-p".equals(opt)) { 12381 if (opti < args.length) { 12382 dumpPackage = args[opti]; 12383 opti++; 12384 } else { 12385 pw.println("Error: -p option requires package argument"); 12386 return; 12387 } 12388 dumpClient = true; 12389 } else if ("-h".equals(opt)) { 12390 pw.println("Activity manager dump options:"); 12391 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12392 pw.println(" cmd may be one of:"); 12393 pw.println(" a[ctivities]: activity stack state"); 12394 pw.println(" r[recents]: recent activities state"); 12395 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12396 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12397 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12398 pw.println(" o[om]: out of memory management"); 12399 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12400 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12401 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12402 pw.println(" as[sociations]: tracked app associations"); 12403 pw.println(" service [COMP_SPEC]: service client-side state"); 12404 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12405 pw.println(" all: dump all activities"); 12406 pw.println(" top: dump the top activity"); 12407 pw.println(" write: write all pending state to storage"); 12408 pw.println(" track-associations: enable association tracking"); 12409 pw.println(" untrack-associations: disable and clear association tracking"); 12410 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12411 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12412 pw.println(" a partial substring in a component name, a"); 12413 pw.println(" hex object identifier."); 12414 pw.println(" -a: include all available server state."); 12415 pw.println(" -c: include client state."); 12416 pw.println(" -p: limit output to given package."); 12417 return; 12418 } else { 12419 pw.println("Unknown argument: " + opt + "; use -h for help"); 12420 } 12421 } 12422 12423 long origId = Binder.clearCallingIdentity(); 12424 boolean more = false; 12425 // Is the caller requesting to dump a particular piece of data? 12426 if (opti < args.length) { 12427 String cmd = args[opti]; 12428 opti++; 12429 if ("activities".equals(cmd) || "a".equals(cmd)) { 12430 synchronized (this) { 12431 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12432 } 12433 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12434 synchronized (this) { 12435 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12436 } 12437 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12438 String[] newArgs; 12439 String name; 12440 if (opti >= args.length) { 12441 name = null; 12442 newArgs = EMPTY_STRING_ARRAY; 12443 } else { 12444 dumpPackage = args[opti]; 12445 opti++; 12446 newArgs = new String[args.length - opti]; 12447 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12448 args.length - opti); 12449 } 12450 synchronized (this) { 12451 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12452 } 12453 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12454 String[] newArgs; 12455 String name; 12456 if (opti >= args.length) { 12457 name = null; 12458 newArgs = EMPTY_STRING_ARRAY; 12459 } else { 12460 dumpPackage = args[opti]; 12461 opti++; 12462 newArgs = new String[args.length - opti]; 12463 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12464 args.length - opti); 12465 } 12466 synchronized (this) { 12467 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12468 } 12469 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12470 String[] newArgs; 12471 String name; 12472 if (opti >= args.length) { 12473 name = null; 12474 newArgs = EMPTY_STRING_ARRAY; 12475 } else { 12476 dumpPackage = args[opti]; 12477 opti++; 12478 newArgs = new String[args.length - opti]; 12479 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12480 args.length - opti); 12481 } 12482 synchronized (this) { 12483 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12484 } 12485 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12486 synchronized (this) { 12487 dumpOomLocked(fd, pw, args, opti, true); 12488 } 12489 } else if ("provider".equals(cmd)) { 12490 String[] newArgs; 12491 String name; 12492 if (opti >= args.length) { 12493 name = null; 12494 newArgs = EMPTY_STRING_ARRAY; 12495 } else { 12496 name = args[opti]; 12497 opti++; 12498 newArgs = new String[args.length - opti]; 12499 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12500 } 12501 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12502 pw.println("No providers match: " + name); 12503 pw.println("Use -h for help."); 12504 } 12505 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12506 synchronized (this) { 12507 dumpProvidersLocked(fd, pw, args, opti, true, null); 12508 } 12509 } else if ("service".equals(cmd)) { 12510 String[] newArgs; 12511 String name; 12512 if (opti >= args.length) { 12513 name = null; 12514 newArgs = EMPTY_STRING_ARRAY; 12515 } else { 12516 name = args[opti]; 12517 opti++; 12518 newArgs = new String[args.length - opti]; 12519 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12520 args.length - opti); 12521 } 12522 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12523 pw.println("No services match: " + name); 12524 pw.println("Use -h for help."); 12525 } 12526 } else if ("package".equals(cmd)) { 12527 String[] newArgs; 12528 if (opti >= args.length) { 12529 pw.println("package: no package name specified"); 12530 pw.println("Use -h for help."); 12531 } else { 12532 dumpPackage = args[opti]; 12533 opti++; 12534 newArgs = new String[args.length - opti]; 12535 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12536 args.length - opti); 12537 args = newArgs; 12538 opti = 0; 12539 more = true; 12540 } 12541 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12542 synchronized (this) { 12543 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12544 } 12545 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12546 synchronized (this) { 12547 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12548 } 12549 } else if ("write".equals(cmd)) { 12550 mTaskPersister.flush(); 12551 pw.println("All tasks persisted."); 12552 return; 12553 } else if ("track-associations".equals(cmd)) { 12554 synchronized (this) { 12555 if (!mTrackingAssociations) { 12556 mTrackingAssociations = true; 12557 pw.println("Association tracking started."); 12558 } else { 12559 pw.println("Association tracking already enabled."); 12560 } 12561 } 12562 return; 12563 } else if ("untrack-associations".equals(cmd)) { 12564 synchronized (this) { 12565 if (mTrackingAssociations) { 12566 mTrackingAssociations = false; 12567 mAssociations.clear(); 12568 pw.println("Association tracking stopped."); 12569 } else { 12570 pw.println("Association tracking not running."); 12571 } 12572 } 12573 return; 12574 } else { 12575 // Dumping a single activity? 12576 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12577 pw.println("Bad activity command, or no activities match: " + cmd); 12578 pw.println("Use -h for help."); 12579 } 12580 } 12581 if (!more) { 12582 Binder.restoreCallingIdentity(origId); 12583 return; 12584 } 12585 } 12586 12587 // No piece of data specified, dump everything. 12588 synchronized (this) { 12589 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12590 pw.println(); 12591 if (dumpAll) { 12592 pw.println("-------------------------------------------------------------------------------"); 12593 } 12594 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12595 pw.println(); 12596 if (dumpAll) { 12597 pw.println("-------------------------------------------------------------------------------"); 12598 } 12599 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12600 pw.println(); 12601 if (dumpAll) { 12602 pw.println("-------------------------------------------------------------------------------"); 12603 } 12604 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12605 pw.println(); 12606 if (dumpAll) { 12607 pw.println("-------------------------------------------------------------------------------"); 12608 } 12609 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12610 pw.println(); 12611 if (dumpAll) { 12612 pw.println("-------------------------------------------------------------------------------"); 12613 } 12614 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12615 if (mAssociations.size() > 0) { 12616 pw.println(); 12617 if (dumpAll) { 12618 pw.println("-------------------------------------------------------------------------------"); 12619 } 12620 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12621 } 12622 pw.println(); 12623 if (dumpAll) { 12624 pw.println("-------------------------------------------------------------------------------"); 12625 } 12626 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12627 } 12628 Binder.restoreCallingIdentity(origId); 12629 } 12630 12631 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12632 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12633 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12634 12635 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12636 dumpPackage); 12637 boolean needSep = printedAnything; 12638 12639 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12640 dumpPackage, needSep, " mFocusedActivity: "); 12641 if (printed) { 12642 printedAnything = true; 12643 needSep = false; 12644 } 12645 12646 if (dumpPackage == null) { 12647 if (needSep) { 12648 pw.println(); 12649 } 12650 needSep = true; 12651 printedAnything = true; 12652 mStackSupervisor.dump(pw, " "); 12653 } 12654 12655 if (!printedAnything) { 12656 pw.println(" (nothing)"); 12657 } 12658 } 12659 12660 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12661 int opti, boolean dumpAll, String dumpPackage) { 12662 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12663 12664 boolean printedAnything = false; 12665 12666 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12667 boolean printedHeader = false; 12668 12669 final int N = mRecentTasks.size(); 12670 for (int i=0; i<N; i++) { 12671 TaskRecord tr = mRecentTasks.get(i); 12672 if (dumpPackage != null) { 12673 if (tr.realActivity == null || 12674 !dumpPackage.equals(tr.realActivity)) { 12675 continue; 12676 } 12677 } 12678 if (!printedHeader) { 12679 pw.println(" Recent tasks:"); 12680 printedHeader = true; 12681 printedAnything = true; 12682 } 12683 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12684 pw.println(tr); 12685 if (dumpAll) { 12686 mRecentTasks.get(i).dump(pw, " "); 12687 } 12688 } 12689 } 12690 12691 if (!printedAnything) { 12692 pw.println(" (nothing)"); 12693 } 12694 } 12695 12696 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12697 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12698 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12699 12700 int dumpUid = 0; 12701 if (dumpPackage != null) { 12702 IPackageManager pm = AppGlobals.getPackageManager(); 12703 try { 12704 dumpUid = pm.getPackageUid(dumpPackage, 0); 12705 } catch (RemoteException e) { 12706 } 12707 } 12708 12709 boolean printedAnything = false; 12710 12711 final long now = SystemClock.uptimeMillis(); 12712 12713 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12714 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12715 = mAssociations.valueAt(i1); 12716 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12717 SparseArray<ArrayMap<String, Association>> sourceUids 12718 = targetComponents.valueAt(i2); 12719 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12720 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12721 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12722 Association ass = sourceProcesses.valueAt(i4); 12723 if (dumpPackage != null) { 12724 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12725 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12726 continue; 12727 } 12728 } 12729 printedAnything = true; 12730 pw.print(" "); 12731 pw.print(ass.mTargetProcess); 12732 pw.print("/"); 12733 UserHandle.formatUid(pw, ass.mTargetUid); 12734 pw.print(" <- "); 12735 pw.print(ass.mSourceProcess); 12736 pw.print("/"); 12737 UserHandle.formatUid(pw, ass.mSourceUid); 12738 pw.println(); 12739 pw.print(" via "); 12740 pw.print(ass.mTargetComponent.flattenToShortString()); 12741 pw.println(); 12742 pw.print(" "); 12743 long dur = ass.mTime; 12744 if (ass.mNesting > 0) { 12745 dur += now - ass.mStartTime; 12746 } 12747 TimeUtils.formatDuration(dur, pw); 12748 pw.print(" ("); 12749 pw.print(ass.mCount); 12750 pw.println(" times)"); 12751 if (ass.mNesting > 0) { 12752 pw.print(" "); 12753 pw.print(" Currently active: "); 12754 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12755 pw.println(); 12756 } 12757 } 12758 } 12759 } 12760 12761 } 12762 12763 if (!printedAnything) { 12764 pw.println(" (nothing)"); 12765 } 12766 } 12767 12768 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12769 int opti, boolean dumpAll, String dumpPackage) { 12770 boolean needSep = false; 12771 boolean printedAnything = false; 12772 int numPers = 0; 12773 12774 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12775 12776 if (dumpAll) { 12777 final int NP = mProcessNames.getMap().size(); 12778 for (int ip=0; ip<NP; ip++) { 12779 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12780 final int NA = procs.size(); 12781 for (int ia=0; ia<NA; ia++) { 12782 ProcessRecord r = procs.valueAt(ia); 12783 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12784 continue; 12785 } 12786 if (!needSep) { 12787 pw.println(" All known processes:"); 12788 needSep = true; 12789 printedAnything = true; 12790 } 12791 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12792 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12793 pw.print(" "); pw.println(r); 12794 r.dump(pw, " "); 12795 if (r.persistent) { 12796 numPers++; 12797 } 12798 } 12799 } 12800 } 12801 12802 if (mIsolatedProcesses.size() > 0) { 12803 boolean printed = false; 12804 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12805 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12806 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12807 continue; 12808 } 12809 if (!printed) { 12810 if (needSep) { 12811 pw.println(); 12812 } 12813 pw.println(" Isolated process list (sorted by uid):"); 12814 printedAnything = true; 12815 printed = true; 12816 needSep = true; 12817 } 12818 pw.println(String.format("%sIsolated #%2d: %s", 12819 " ", i, r.toString())); 12820 } 12821 } 12822 12823 if (mLruProcesses.size() > 0) { 12824 if (needSep) { 12825 pw.println(); 12826 } 12827 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12828 pw.print(" total, non-act at "); 12829 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12830 pw.print(", non-svc at "); 12831 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12832 pw.println("):"); 12833 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12834 needSep = true; 12835 printedAnything = true; 12836 } 12837 12838 if (dumpAll || dumpPackage != null) { 12839 synchronized (mPidsSelfLocked) { 12840 boolean printed = false; 12841 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12842 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12843 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12844 continue; 12845 } 12846 if (!printed) { 12847 if (needSep) pw.println(); 12848 needSep = true; 12849 pw.println(" PID mappings:"); 12850 printed = true; 12851 printedAnything = true; 12852 } 12853 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12854 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12855 } 12856 } 12857 } 12858 12859 if (mForegroundProcesses.size() > 0) { 12860 synchronized (mPidsSelfLocked) { 12861 boolean printed = false; 12862 for (int i=0; i<mForegroundProcesses.size(); i++) { 12863 ProcessRecord r = mPidsSelfLocked.get( 12864 mForegroundProcesses.valueAt(i).pid); 12865 if (dumpPackage != null && (r == null 12866 || !r.pkgList.containsKey(dumpPackage))) { 12867 continue; 12868 } 12869 if (!printed) { 12870 if (needSep) pw.println(); 12871 needSep = true; 12872 pw.println(" Foreground Processes:"); 12873 printed = true; 12874 printedAnything = true; 12875 } 12876 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12877 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12878 } 12879 } 12880 } 12881 12882 if (mPersistentStartingProcesses.size() > 0) { 12883 if (needSep) pw.println(); 12884 needSep = true; 12885 printedAnything = true; 12886 pw.println(" Persisent processes that are starting:"); 12887 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12888 "Starting Norm", "Restarting PERS", dumpPackage); 12889 } 12890 12891 if (mRemovedProcesses.size() > 0) { 12892 if (needSep) pw.println(); 12893 needSep = true; 12894 printedAnything = true; 12895 pw.println(" Processes that are being removed:"); 12896 dumpProcessList(pw, this, mRemovedProcesses, " ", 12897 "Removed Norm", "Removed PERS", dumpPackage); 12898 } 12899 12900 if (mProcessesOnHold.size() > 0) { 12901 if (needSep) pw.println(); 12902 needSep = true; 12903 printedAnything = true; 12904 pw.println(" Processes that are on old until the system is ready:"); 12905 dumpProcessList(pw, this, mProcessesOnHold, " ", 12906 "OnHold Norm", "OnHold PERS", dumpPackage); 12907 } 12908 12909 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12910 12911 if (mProcessCrashTimes.getMap().size() > 0) { 12912 boolean printed = false; 12913 long now = SystemClock.uptimeMillis(); 12914 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12915 final int NP = pmap.size(); 12916 for (int ip=0; ip<NP; ip++) { 12917 String pname = pmap.keyAt(ip); 12918 SparseArray<Long> uids = pmap.valueAt(ip); 12919 final int N = uids.size(); 12920 for (int i=0; i<N; i++) { 12921 int puid = uids.keyAt(i); 12922 ProcessRecord r = mProcessNames.get(pname, puid); 12923 if (dumpPackage != null && (r == null 12924 || !r.pkgList.containsKey(dumpPackage))) { 12925 continue; 12926 } 12927 if (!printed) { 12928 if (needSep) pw.println(); 12929 needSep = true; 12930 pw.println(" Time since processes crashed:"); 12931 printed = true; 12932 printedAnything = true; 12933 } 12934 pw.print(" Process "); pw.print(pname); 12935 pw.print(" uid "); pw.print(puid); 12936 pw.print(": last crashed "); 12937 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12938 pw.println(" ago"); 12939 } 12940 } 12941 } 12942 12943 if (mBadProcesses.getMap().size() > 0) { 12944 boolean printed = false; 12945 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12946 final int NP = pmap.size(); 12947 for (int ip=0; ip<NP; ip++) { 12948 String pname = pmap.keyAt(ip); 12949 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12950 final int N = uids.size(); 12951 for (int i=0; i<N; i++) { 12952 int puid = uids.keyAt(i); 12953 ProcessRecord r = mProcessNames.get(pname, puid); 12954 if (dumpPackage != null && (r == null 12955 || !r.pkgList.containsKey(dumpPackage))) { 12956 continue; 12957 } 12958 if (!printed) { 12959 if (needSep) pw.println(); 12960 needSep = true; 12961 pw.println(" Bad processes:"); 12962 printedAnything = true; 12963 } 12964 BadProcessInfo info = uids.valueAt(i); 12965 pw.print(" Bad process "); pw.print(pname); 12966 pw.print(" uid "); pw.print(puid); 12967 pw.print(": crashed at time "); pw.println(info.time); 12968 if (info.shortMsg != null) { 12969 pw.print(" Short msg: "); pw.println(info.shortMsg); 12970 } 12971 if (info.longMsg != null) { 12972 pw.print(" Long msg: "); pw.println(info.longMsg); 12973 } 12974 if (info.stack != null) { 12975 pw.println(" Stack:"); 12976 int lastPos = 0; 12977 for (int pos=0; pos<info.stack.length(); pos++) { 12978 if (info.stack.charAt(pos) == '\n') { 12979 pw.print(" "); 12980 pw.write(info.stack, lastPos, pos-lastPos); 12981 pw.println(); 12982 lastPos = pos+1; 12983 } 12984 } 12985 if (lastPos < info.stack.length()) { 12986 pw.print(" "); 12987 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12988 pw.println(); 12989 } 12990 } 12991 } 12992 } 12993 } 12994 12995 if (dumpPackage == null) { 12996 pw.println(); 12997 needSep = false; 12998 pw.println(" mStartedUsers:"); 12999 for (int i=0; i<mStartedUsers.size(); i++) { 13000 UserStartedState uss = mStartedUsers.valueAt(i); 13001 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 13002 pw.print(": "); uss.dump("", pw); 13003 } 13004 pw.print(" mStartedUserArray: ["); 13005 for (int i=0; i<mStartedUserArray.length; i++) { 13006 if (i > 0) pw.print(", "); 13007 pw.print(mStartedUserArray[i]); 13008 } 13009 pw.println("]"); 13010 pw.print(" mUserLru: ["); 13011 for (int i=0; i<mUserLru.size(); i++) { 13012 if (i > 0) pw.print(", "); 13013 pw.print(mUserLru.get(i)); 13014 } 13015 pw.println("]"); 13016 if (dumpAll) { 13017 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 13018 } 13019 synchronized (mUserProfileGroupIdsSelfLocked) { 13020 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 13021 pw.println(" mUserProfileGroupIds:"); 13022 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 13023 pw.print(" User #"); 13024 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 13025 pw.print(" -> profile #"); 13026 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 13027 } 13028 } 13029 } 13030 } 13031 if (mHomeProcess != null && (dumpPackage == null 13032 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13033 if (needSep) { 13034 pw.println(); 13035 needSep = false; 13036 } 13037 pw.println(" mHomeProcess: " + mHomeProcess); 13038 } 13039 if (mPreviousProcess != null && (dumpPackage == null 13040 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13041 if (needSep) { 13042 pw.println(); 13043 needSep = false; 13044 } 13045 pw.println(" mPreviousProcess: " + mPreviousProcess); 13046 } 13047 if (dumpAll) { 13048 StringBuilder sb = new StringBuilder(128); 13049 sb.append(" mPreviousProcessVisibleTime: "); 13050 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13051 pw.println(sb); 13052 } 13053 if (mHeavyWeightProcess != null && (dumpPackage == null 13054 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13055 if (needSep) { 13056 pw.println(); 13057 needSep = false; 13058 } 13059 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13060 } 13061 if (dumpPackage == null) { 13062 pw.println(" mConfiguration: " + mConfiguration); 13063 } 13064 if (dumpAll) { 13065 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13066 if (mCompatModePackages.getPackages().size() > 0) { 13067 boolean printed = false; 13068 for (Map.Entry<String, Integer> entry 13069 : mCompatModePackages.getPackages().entrySet()) { 13070 String pkg = entry.getKey(); 13071 int mode = entry.getValue(); 13072 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13073 continue; 13074 } 13075 if (!printed) { 13076 pw.println(" mScreenCompatPackages:"); 13077 printed = true; 13078 } 13079 pw.print(" "); pw.print(pkg); pw.print(": "); 13080 pw.print(mode); pw.println(); 13081 } 13082 } 13083 } 13084 if (dumpPackage == null) { 13085 pw.println(" mWakefulness=" 13086 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13087 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13088 + lockScreenShownToString()); 13089 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13090 + " mTestPssMode=" + mTestPssMode); 13091 } 13092 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13093 || mOrigWaitForDebugger) { 13094 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13095 || dumpPackage.equals(mOrigDebugApp)) { 13096 if (needSep) { 13097 pw.println(); 13098 needSep = false; 13099 } 13100 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13101 + " mDebugTransient=" + mDebugTransient 13102 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13103 } 13104 } 13105 if (mOpenGlTraceApp != null) { 13106 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13107 if (needSep) { 13108 pw.println(); 13109 needSep = false; 13110 } 13111 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13112 } 13113 } 13114 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13115 || mProfileFd != null) { 13116 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13117 if (needSep) { 13118 pw.println(); 13119 needSep = false; 13120 } 13121 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13122 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13123 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13124 + mAutoStopProfiler); 13125 pw.println(" mProfileType=" + mProfileType); 13126 } 13127 } 13128 if (dumpPackage == null) { 13129 if (mAlwaysFinishActivities || mController != null) { 13130 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13131 + " mController=" + mController); 13132 } 13133 if (dumpAll) { 13134 pw.println(" Total persistent processes: " + numPers); 13135 pw.println(" mProcessesReady=" + mProcessesReady 13136 + " mSystemReady=" + mSystemReady 13137 + " mBooted=" + mBooted 13138 + " mFactoryTest=" + mFactoryTest); 13139 pw.println(" mBooting=" + mBooting 13140 + " mCallFinishBooting=" + mCallFinishBooting 13141 + " mBootAnimationComplete=" + mBootAnimationComplete); 13142 pw.print(" mLastPowerCheckRealtime="); 13143 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13144 pw.println(""); 13145 pw.print(" mLastPowerCheckUptime="); 13146 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13147 pw.println(""); 13148 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13149 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13150 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13151 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13152 + " (" + mLruProcesses.size() + " total)" 13153 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13154 + " mNumServiceProcs=" + mNumServiceProcs 13155 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13156 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13157 + " mLastMemoryLevel" + mLastMemoryLevel 13158 + " mLastNumProcesses" + mLastNumProcesses); 13159 long now = SystemClock.uptimeMillis(); 13160 pw.print(" mLastIdleTime="); 13161 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13162 pw.print(" mLowRamSinceLastIdle="); 13163 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13164 pw.println(); 13165 } 13166 } 13167 13168 if (!printedAnything) { 13169 pw.println(" (nothing)"); 13170 } 13171 } 13172 13173 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13174 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13175 if (mProcessesToGc.size() > 0) { 13176 boolean printed = false; 13177 long now = SystemClock.uptimeMillis(); 13178 for (int i=0; i<mProcessesToGc.size(); i++) { 13179 ProcessRecord proc = mProcessesToGc.get(i); 13180 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13181 continue; 13182 } 13183 if (!printed) { 13184 if (needSep) pw.println(); 13185 needSep = true; 13186 pw.println(" Processes that are waiting to GC:"); 13187 printed = true; 13188 } 13189 pw.print(" Process "); pw.println(proc); 13190 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13191 pw.print(", last gced="); 13192 pw.print(now-proc.lastRequestedGc); 13193 pw.print(" ms ago, last lowMem="); 13194 pw.print(now-proc.lastLowMemory); 13195 pw.println(" ms ago"); 13196 13197 } 13198 } 13199 return needSep; 13200 } 13201 13202 void printOomLevel(PrintWriter pw, String name, int adj) { 13203 pw.print(" "); 13204 if (adj >= 0) { 13205 pw.print(' '); 13206 if (adj < 10) pw.print(' '); 13207 } else { 13208 if (adj > -10) pw.print(' '); 13209 } 13210 pw.print(adj); 13211 pw.print(": "); 13212 pw.print(name); 13213 pw.print(" ("); 13214 pw.print(mProcessList.getMemLevel(adj)/1024); 13215 pw.println(" kB)"); 13216 } 13217 13218 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13219 int opti, boolean dumpAll) { 13220 boolean needSep = false; 13221 13222 if (mLruProcesses.size() > 0) { 13223 if (needSep) pw.println(); 13224 needSep = true; 13225 pw.println(" OOM levels:"); 13226 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13227 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13228 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13229 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13230 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13231 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13232 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13233 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13234 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13235 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13236 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13237 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13238 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13239 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13240 13241 if (needSep) pw.println(); 13242 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13243 pw.print(" total, non-act at "); 13244 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13245 pw.print(", non-svc at "); 13246 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13247 pw.println("):"); 13248 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13249 needSep = true; 13250 } 13251 13252 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13253 13254 pw.println(); 13255 pw.println(" mHomeProcess: " + mHomeProcess); 13256 pw.println(" mPreviousProcess: " + mPreviousProcess); 13257 if (mHeavyWeightProcess != null) { 13258 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13259 } 13260 13261 return true; 13262 } 13263 13264 /** 13265 * There are three ways to call this: 13266 * - no provider specified: dump all the providers 13267 * - a flattened component name that matched an existing provider was specified as the 13268 * first arg: dump that one provider 13269 * - the first arg isn't the flattened component name of an existing provider: 13270 * dump all providers whose component contains the first arg as a substring 13271 */ 13272 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13273 int opti, boolean dumpAll) { 13274 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13275 } 13276 13277 static class ItemMatcher { 13278 ArrayList<ComponentName> components; 13279 ArrayList<String> strings; 13280 ArrayList<Integer> objects; 13281 boolean all; 13282 13283 ItemMatcher() { 13284 all = true; 13285 } 13286 13287 void build(String name) { 13288 ComponentName componentName = ComponentName.unflattenFromString(name); 13289 if (componentName != null) { 13290 if (components == null) { 13291 components = new ArrayList<ComponentName>(); 13292 } 13293 components.add(componentName); 13294 all = false; 13295 } else { 13296 int objectId = 0; 13297 // Not a '/' separated full component name; maybe an object ID? 13298 try { 13299 objectId = Integer.parseInt(name, 16); 13300 if (objects == null) { 13301 objects = new ArrayList<Integer>(); 13302 } 13303 objects.add(objectId); 13304 all = false; 13305 } catch (RuntimeException e) { 13306 // Not an integer; just do string match. 13307 if (strings == null) { 13308 strings = new ArrayList<String>(); 13309 } 13310 strings.add(name); 13311 all = false; 13312 } 13313 } 13314 } 13315 13316 int build(String[] args, int opti) { 13317 for (; opti<args.length; opti++) { 13318 String name = args[opti]; 13319 if ("--".equals(name)) { 13320 return opti+1; 13321 } 13322 build(name); 13323 } 13324 return opti; 13325 } 13326 13327 boolean match(Object object, ComponentName comp) { 13328 if (all) { 13329 return true; 13330 } 13331 if (components != null) { 13332 for (int i=0; i<components.size(); i++) { 13333 if (components.get(i).equals(comp)) { 13334 return true; 13335 } 13336 } 13337 } 13338 if (objects != null) { 13339 for (int i=0; i<objects.size(); i++) { 13340 if (System.identityHashCode(object) == objects.get(i)) { 13341 return true; 13342 } 13343 } 13344 } 13345 if (strings != null) { 13346 String flat = comp.flattenToString(); 13347 for (int i=0; i<strings.size(); i++) { 13348 if (flat.contains(strings.get(i))) { 13349 return true; 13350 } 13351 } 13352 } 13353 return false; 13354 } 13355 } 13356 13357 /** 13358 * There are three things that cmd can be: 13359 * - a flattened component name that matches an existing activity 13360 * - the cmd arg isn't the flattened component name of an existing activity: 13361 * dump all activity whose component contains the cmd as a substring 13362 * - A hex number of the ActivityRecord object instance. 13363 */ 13364 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13365 int opti, boolean dumpAll) { 13366 ArrayList<ActivityRecord> activities; 13367 13368 synchronized (this) { 13369 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13370 } 13371 13372 if (activities.size() <= 0) { 13373 return false; 13374 } 13375 13376 String[] newArgs = new String[args.length - opti]; 13377 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13378 13379 TaskRecord lastTask = null; 13380 boolean needSep = false; 13381 for (int i=activities.size()-1; i>=0; i--) { 13382 ActivityRecord r = activities.get(i); 13383 if (needSep) { 13384 pw.println(); 13385 } 13386 needSep = true; 13387 synchronized (this) { 13388 if (lastTask != r.task) { 13389 lastTask = r.task; 13390 pw.print("TASK "); pw.print(lastTask.affinity); 13391 pw.print(" id="); pw.println(lastTask.taskId); 13392 if (dumpAll) { 13393 lastTask.dump(pw, " "); 13394 } 13395 } 13396 } 13397 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13398 } 13399 return true; 13400 } 13401 13402 /** 13403 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13404 * there is a thread associated with the activity. 13405 */ 13406 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13407 final ActivityRecord r, String[] args, boolean dumpAll) { 13408 String innerPrefix = prefix + " "; 13409 synchronized (this) { 13410 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13411 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13412 pw.print(" pid="); 13413 if (r.app != null) pw.println(r.app.pid); 13414 else pw.println("(not running)"); 13415 if (dumpAll) { 13416 r.dump(pw, innerPrefix); 13417 } 13418 } 13419 if (r.app != null && r.app.thread != null) { 13420 // flush anything that is already in the PrintWriter since the thread is going 13421 // to write to the file descriptor directly 13422 pw.flush(); 13423 try { 13424 TransferPipe tp = new TransferPipe(); 13425 try { 13426 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13427 r.appToken, innerPrefix, args); 13428 tp.go(fd); 13429 } finally { 13430 tp.kill(); 13431 } 13432 } catch (IOException e) { 13433 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13434 } catch (RemoteException e) { 13435 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13436 } 13437 } 13438 } 13439 13440 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13441 int opti, boolean dumpAll, String dumpPackage) { 13442 boolean needSep = false; 13443 boolean onlyHistory = false; 13444 boolean printedAnything = false; 13445 13446 if ("history".equals(dumpPackage)) { 13447 if (opti < args.length && "-s".equals(args[opti])) { 13448 dumpAll = false; 13449 } 13450 onlyHistory = true; 13451 dumpPackage = null; 13452 } 13453 13454 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13455 if (!onlyHistory && dumpAll) { 13456 if (mRegisteredReceivers.size() > 0) { 13457 boolean printed = false; 13458 Iterator it = mRegisteredReceivers.values().iterator(); 13459 while (it.hasNext()) { 13460 ReceiverList r = (ReceiverList)it.next(); 13461 if (dumpPackage != null && (r.app == null || 13462 !dumpPackage.equals(r.app.info.packageName))) { 13463 continue; 13464 } 13465 if (!printed) { 13466 pw.println(" Registered Receivers:"); 13467 needSep = true; 13468 printed = true; 13469 printedAnything = true; 13470 } 13471 pw.print(" * "); pw.println(r); 13472 r.dump(pw, " "); 13473 } 13474 } 13475 13476 if (mReceiverResolver.dump(pw, needSep ? 13477 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13478 " ", dumpPackage, false, false)) { 13479 needSep = true; 13480 printedAnything = true; 13481 } 13482 } 13483 13484 for (BroadcastQueue q : mBroadcastQueues) { 13485 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13486 printedAnything |= needSep; 13487 } 13488 13489 needSep = true; 13490 13491 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13492 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13493 if (needSep) { 13494 pw.println(); 13495 } 13496 needSep = true; 13497 printedAnything = true; 13498 pw.print(" Sticky broadcasts for user "); 13499 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13500 StringBuilder sb = new StringBuilder(128); 13501 for (Map.Entry<String, ArrayList<Intent>> ent 13502 : mStickyBroadcasts.valueAt(user).entrySet()) { 13503 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13504 if (dumpAll) { 13505 pw.println(":"); 13506 ArrayList<Intent> intents = ent.getValue(); 13507 final int N = intents.size(); 13508 for (int i=0; i<N; i++) { 13509 sb.setLength(0); 13510 sb.append(" Intent: "); 13511 intents.get(i).toShortString(sb, false, true, false, false); 13512 pw.println(sb.toString()); 13513 Bundle bundle = intents.get(i).getExtras(); 13514 if (bundle != null) { 13515 pw.print(" "); 13516 pw.println(bundle.toString()); 13517 } 13518 } 13519 } else { 13520 pw.println(""); 13521 } 13522 } 13523 } 13524 } 13525 13526 if (!onlyHistory && dumpAll) { 13527 pw.println(); 13528 for (BroadcastQueue queue : mBroadcastQueues) { 13529 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13530 + queue.mBroadcastsScheduled); 13531 } 13532 pw.println(" mHandler:"); 13533 mHandler.dump(new PrintWriterPrinter(pw), " "); 13534 needSep = true; 13535 printedAnything = true; 13536 } 13537 13538 if (!printedAnything) { 13539 pw.println(" (nothing)"); 13540 } 13541 } 13542 13543 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13544 int opti, boolean dumpAll, String dumpPackage) { 13545 boolean needSep; 13546 boolean printedAnything = false; 13547 13548 ItemMatcher matcher = new ItemMatcher(); 13549 matcher.build(args, opti); 13550 13551 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13552 13553 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13554 printedAnything |= needSep; 13555 13556 if (mLaunchingProviders.size() > 0) { 13557 boolean printed = false; 13558 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13559 ContentProviderRecord r = mLaunchingProviders.get(i); 13560 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13561 continue; 13562 } 13563 if (!printed) { 13564 if (needSep) pw.println(); 13565 needSep = true; 13566 pw.println(" Launching content providers:"); 13567 printed = true; 13568 printedAnything = true; 13569 } 13570 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13571 pw.println(r); 13572 } 13573 } 13574 13575 if (mGrantedUriPermissions.size() > 0) { 13576 boolean printed = false; 13577 int dumpUid = -2; 13578 if (dumpPackage != null) { 13579 try { 13580 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13581 } catch (NameNotFoundException e) { 13582 dumpUid = -1; 13583 } 13584 } 13585 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13586 int uid = mGrantedUriPermissions.keyAt(i); 13587 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13588 continue; 13589 } 13590 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13591 if (!printed) { 13592 if (needSep) pw.println(); 13593 needSep = true; 13594 pw.println(" Granted Uri Permissions:"); 13595 printed = true; 13596 printedAnything = true; 13597 } 13598 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13599 for (UriPermission perm : perms.values()) { 13600 pw.print(" "); pw.println(perm); 13601 if (dumpAll) { 13602 perm.dump(pw, " "); 13603 } 13604 } 13605 } 13606 } 13607 13608 if (!printedAnything) { 13609 pw.println(" (nothing)"); 13610 } 13611 } 13612 13613 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13614 int opti, boolean dumpAll, String dumpPackage) { 13615 boolean printed = false; 13616 13617 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13618 13619 if (mIntentSenderRecords.size() > 0) { 13620 Iterator<WeakReference<PendingIntentRecord>> it 13621 = mIntentSenderRecords.values().iterator(); 13622 while (it.hasNext()) { 13623 WeakReference<PendingIntentRecord> ref = it.next(); 13624 PendingIntentRecord rec = ref != null ? ref.get(): null; 13625 if (dumpPackage != null && (rec == null 13626 || !dumpPackage.equals(rec.key.packageName))) { 13627 continue; 13628 } 13629 printed = true; 13630 if (rec != null) { 13631 pw.print(" * "); pw.println(rec); 13632 if (dumpAll) { 13633 rec.dump(pw, " "); 13634 } 13635 } else { 13636 pw.print(" * "); pw.println(ref); 13637 } 13638 } 13639 } 13640 13641 if (!printed) { 13642 pw.println(" (nothing)"); 13643 } 13644 } 13645 13646 private static final int dumpProcessList(PrintWriter pw, 13647 ActivityManagerService service, List list, 13648 String prefix, String normalLabel, String persistentLabel, 13649 String dumpPackage) { 13650 int numPers = 0; 13651 final int N = list.size()-1; 13652 for (int i=N; i>=0; i--) { 13653 ProcessRecord r = (ProcessRecord)list.get(i); 13654 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13655 continue; 13656 } 13657 pw.println(String.format("%s%s #%2d: %s", 13658 prefix, (r.persistent ? persistentLabel : normalLabel), 13659 i, r.toString())); 13660 if (r.persistent) { 13661 numPers++; 13662 } 13663 } 13664 return numPers; 13665 } 13666 13667 private static final boolean dumpProcessOomList(PrintWriter pw, 13668 ActivityManagerService service, List<ProcessRecord> origList, 13669 String prefix, String normalLabel, String persistentLabel, 13670 boolean inclDetails, String dumpPackage) { 13671 13672 ArrayList<Pair<ProcessRecord, Integer>> list 13673 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13674 for (int i=0; i<origList.size(); i++) { 13675 ProcessRecord r = origList.get(i); 13676 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13677 continue; 13678 } 13679 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13680 } 13681 13682 if (list.size() <= 0) { 13683 return false; 13684 } 13685 13686 Comparator<Pair<ProcessRecord, Integer>> comparator 13687 = new Comparator<Pair<ProcessRecord, Integer>>() { 13688 @Override 13689 public int compare(Pair<ProcessRecord, Integer> object1, 13690 Pair<ProcessRecord, Integer> object2) { 13691 if (object1.first.setAdj != object2.first.setAdj) { 13692 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13693 } 13694 if (object1.second.intValue() != object2.second.intValue()) { 13695 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13696 } 13697 return 0; 13698 } 13699 }; 13700 13701 Collections.sort(list, comparator); 13702 13703 final long curRealtime = SystemClock.elapsedRealtime(); 13704 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13705 final long curUptime = SystemClock.uptimeMillis(); 13706 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13707 13708 for (int i=list.size()-1; i>=0; i--) { 13709 ProcessRecord r = list.get(i).first; 13710 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13711 char schedGroup; 13712 switch (r.setSchedGroup) { 13713 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13714 schedGroup = 'B'; 13715 break; 13716 case Process.THREAD_GROUP_DEFAULT: 13717 schedGroup = 'F'; 13718 break; 13719 default: 13720 schedGroup = '?'; 13721 break; 13722 } 13723 char foreground; 13724 if (r.foregroundActivities) { 13725 foreground = 'A'; 13726 } else if (r.foregroundServices) { 13727 foreground = 'S'; 13728 } else { 13729 foreground = ' '; 13730 } 13731 String procState = ProcessList.makeProcStateString(r.curProcState); 13732 pw.print(prefix); 13733 pw.print(r.persistent ? persistentLabel : normalLabel); 13734 pw.print(" #"); 13735 int num = (origList.size()-1)-list.get(i).second; 13736 if (num < 10) pw.print(' '); 13737 pw.print(num); 13738 pw.print(": "); 13739 pw.print(oomAdj); 13740 pw.print(' '); 13741 pw.print(schedGroup); 13742 pw.print('/'); 13743 pw.print(foreground); 13744 pw.print('/'); 13745 pw.print(procState); 13746 pw.print(" trm:"); 13747 if (r.trimMemoryLevel < 10) pw.print(' '); 13748 pw.print(r.trimMemoryLevel); 13749 pw.print(' '); 13750 pw.print(r.toShortString()); 13751 pw.print(" ("); 13752 pw.print(r.adjType); 13753 pw.println(')'); 13754 if (r.adjSource != null || r.adjTarget != null) { 13755 pw.print(prefix); 13756 pw.print(" "); 13757 if (r.adjTarget instanceof ComponentName) { 13758 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13759 } else if (r.adjTarget != null) { 13760 pw.print(r.adjTarget.toString()); 13761 } else { 13762 pw.print("{null}"); 13763 } 13764 pw.print("<="); 13765 if (r.adjSource instanceof ProcessRecord) { 13766 pw.print("Proc{"); 13767 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13768 pw.println("}"); 13769 } else if (r.adjSource != null) { 13770 pw.println(r.adjSource.toString()); 13771 } else { 13772 pw.println("{null}"); 13773 } 13774 } 13775 if (inclDetails) { 13776 pw.print(prefix); 13777 pw.print(" "); 13778 pw.print("oom: max="); pw.print(r.maxAdj); 13779 pw.print(" curRaw="); pw.print(r.curRawAdj); 13780 pw.print(" setRaw="); pw.print(r.setRawAdj); 13781 pw.print(" cur="); pw.print(r.curAdj); 13782 pw.print(" set="); pw.println(r.setAdj); 13783 pw.print(prefix); 13784 pw.print(" "); 13785 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13786 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13787 pw.print(" lastPss="); pw.print(r.lastPss); 13788 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13789 pw.print(prefix); 13790 pw.print(" "); 13791 pw.print("cached="); pw.print(r.cached); 13792 pw.print(" empty="); pw.print(r.empty); 13793 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13794 13795 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13796 if (r.lastWakeTime != 0) { 13797 long wtime; 13798 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13799 synchronized (stats) { 13800 wtime = stats.getProcessWakeTime(r.info.uid, 13801 r.pid, curRealtime); 13802 } 13803 long timeUsed = wtime - r.lastWakeTime; 13804 pw.print(prefix); 13805 pw.print(" "); 13806 pw.print("keep awake over "); 13807 TimeUtils.formatDuration(realtimeSince, pw); 13808 pw.print(" used "); 13809 TimeUtils.formatDuration(timeUsed, pw); 13810 pw.print(" ("); 13811 pw.print((timeUsed*100)/realtimeSince); 13812 pw.println("%)"); 13813 } 13814 if (r.lastCpuTime != 0) { 13815 long timeUsed = r.curCpuTime - r.lastCpuTime; 13816 pw.print(prefix); 13817 pw.print(" "); 13818 pw.print("run cpu over "); 13819 TimeUtils.formatDuration(uptimeSince, pw); 13820 pw.print(" used "); 13821 TimeUtils.formatDuration(timeUsed, pw); 13822 pw.print(" ("); 13823 pw.print((timeUsed*100)/uptimeSince); 13824 pw.println("%)"); 13825 } 13826 } 13827 } 13828 } 13829 return true; 13830 } 13831 13832 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13833 String[] args) { 13834 ArrayList<ProcessRecord> procs; 13835 synchronized (this) { 13836 if (args != null && args.length > start 13837 && args[start].charAt(0) != '-') { 13838 procs = new ArrayList<ProcessRecord>(); 13839 int pid = -1; 13840 try { 13841 pid = Integer.parseInt(args[start]); 13842 } catch (NumberFormatException e) { 13843 } 13844 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13845 ProcessRecord proc = mLruProcesses.get(i); 13846 if (proc.pid == pid) { 13847 procs.add(proc); 13848 } else if (allPkgs && proc.pkgList != null 13849 && proc.pkgList.containsKey(args[start])) { 13850 procs.add(proc); 13851 } else if (proc.processName.equals(args[start])) { 13852 procs.add(proc); 13853 } 13854 } 13855 if (procs.size() <= 0) { 13856 return null; 13857 } 13858 } else { 13859 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13860 } 13861 } 13862 return procs; 13863 } 13864 13865 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13866 PrintWriter pw, String[] args) { 13867 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13868 if (procs == null) { 13869 pw.println("No process found for: " + args[0]); 13870 return; 13871 } 13872 13873 long uptime = SystemClock.uptimeMillis(); 13874 long realtime = SystemClock.elapsedRealtime(); 13875 pw.println("Applications Graphics Acceleration Info:"); 13876 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13877 13878 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13879 ProcessRecord r = procs.get(i); 13880 if (r.thread != null) { 13881 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13882 pw.flush(); 13883 try { 13884 TransferPipe tp = new TransferPipe(); 13885 try { 13886 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13887 tp.go(fd); 13888 } finally { 13889 tp.kill(); 13890 } 13891 } catch (IOException e) { 13892 pw.println("Failure while dumping the app: " + r); 13893 pw.flush(); 13894 } catch (RemoteException e) { 13895 pw.println("Got a RemoteException while dumping the app " + r); 13896 pw.flush(); 13897 } 13898 } 13899 } 13900 } 13901 13902 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13903 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13904 if (procs == null) { 13905 pw.println("No process found for: " + args[0]); 13906 return; 13907 } 13908 13909 pw.println("Applications Database Info:"); 13910 13911 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13912 ProcessRecord r = procs.get(i); 13913 if (r.thread != null) { 13914 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13915 pw.flush(); 13916 try { 13917 TransferPipe tp = new TransferPipe(); 13918 try { 13919 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13920 tp.go(fd); 13921 } finally { 13922 tp.kill(); 13923 } 13924 } catch (IOException e) { 13925 pw.println("Failure while dumping the app: " + r); 13926 pw.flush(); 13927 } catch (RemoteException e) { 13928 pw.println("Got a RemoteException while dumping the app " + r); 13929 pw.flush(); 13930 } 13931 } 13932 } 13933 } 13934 13935 final static class MemItem { 13936 final boolean isProc; 13937 final String label; 13938 final String shortLabel; 13939 final long pss; 13940 final int id; 13941 final boolean hasActivities; 13942 ArrayList<MemItem> subitems; 13943 13944 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13945 boolean _hasActivities) { 13946 isProc = true; 13947 label = _label; 13948 shortLabel = _shortLabel; 13949 pss = _pss; 13950 id = _id; 13951 hasActivities = _hasActivities; 13952 } 13953 13954 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13955 isProc = false; 13956 label = _label; 13957 shortLabel = _shortLabel; 13958 pss = _pss; 13959 id = _id; 13960 hasActivities = false; 13961 } 13962 } 13963 13964 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13965 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13966 if (sort && !isCompact) { 13967 Collections.sort(items, new Comparator<MemItem>() { 13968 @Override 13969 public int compare(MemItem lhs, MemItem rhs) { 13970 if (lhs.pss < rhs.pss) { 13971 return 1; 13972 } else if (lhs.pss > rhs.pss) { 13973 return -1; 13974 } 13975 return 0; 13976 } 13977 }); 13978 } 13979 13980 for (int i=0; i<items.size(); i++) { 13981 MemItem mi = items.get(i); 13982 if (!isCompact) { 13983 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13984 } else if (mi.isProc) { 13985 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13986 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13987 pw.println(mi.hasActivities ? ",a" : ",e"); 13988 } else { 13989 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13990 pw.println(mi.pss); 13991 } 13992 if (mi.subitems != null) { 13993 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13994 true, isCompact); 13995 } 13996 } 13997 } 13998 13999 // These are in KB. 14000 static final long[] DUMP_MEM_BUCKETS = new long[] { 14001 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 14002 120*1024, 160*1024, 200*1024, 14003 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 14004 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 14005 }; 14006 14007 static final void appendMemBucket(StringBuilder out, long memKB, String label, 14008 boolean stackLike) { 14009 int start = label.lastIndexOf('.'); 14010 if (start >= 0) start++; 14011 else start = 0; 14012 int end = label.length(); 14013 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 14014 if (DUMP_MEM_BUCKETS[i] >= memKB) { 14015 long bucket = DUMP_MEM_BUCKETS[i]/1024; 14016 out.append(bucket); 14017 out.append(stackLike ? "MB." : "MB "); 14018 out.append(label, start, end); 14019 return; 14020 } 14021 } 14022 out.append(memKB/1024); 14023 out.append(stackLike ? "MB." : "MB "); 14024 out.append(label, start, end); 14025 } 14026 14027 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 14028 ProcessList.NATIVE_ADJ, 14029 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 14030 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14031 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14032 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14033 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14034 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14035 }; 14036 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14037 "Native", 14038 "System", "Persistent", "Persistent Service", "Foreground", 14039 "Visible", "Perceptible", 14040 "Heavy Weight", "Backup", 14041 "A Services", "Home", 14042 "Previous", "B Services", "Cached" 14043 }; 14044 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14045 "native", 14046 "sys", "pers", "persvc", "fore", 14047 "vis", "percept", 14048 "heavy", "backup", 14049 "servicea", "home", 14050 "prev", "serviceb", "cached" 14051 }; 14052 14053 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14054 long realtime, boolean isCheckinRequest, boolean isCompact) { 14055 if (isCheckinRequest || isCompact) { 14056 // short checkin version 14057 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14058 } else { 14059 pw.println("Applications Memory Usage (kB):"); 14060 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14061 } 14062 } 14063 14064 private static final int KSM_SHARED = 0; 14065 private static final int KSM_SHARING = 1; 14066 private static final int KSM_UNSHARED = 2; 14067 private static final int KSM_VOLATILE = 3; 14068 14069 private final long[] getKsmInfo() { 14070 long[] longOut = new long[4]; 14071 final int[] SINGLE_LONG_FORMAT = new int[] { 14072 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14073 }; 14074 long[] longTmp = new long[1]; 14075 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14076 SINGLE_LONG_FORMAT, null, longTmp, null); 14077 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14078 longTmp[0] = 0; 14079 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14080 SINGLE_LONG_FORMAT, null, longTmp, null); 14081 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14082 longTmp[0] = 0; 14083 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14084 SINGLE_LONG_FORMAT, null, longTmp, null); 14085 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14086 longTmp[0] = 0; 14087 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14088 SINGLE_LONG_FORMAT, null, longTmp, null); 14089 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14090 return longOut; 14091 } 14092 14093 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14094 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14095 boolean dumpDetails = false; 14096 boolean dumpFullDetails = false; 14097 boolean dumpDalvik = false; 14098 boolean oomOnly = false; 14099 boolean isCompact = false; 14100 boolean localOnly = false; 14101 boolean packages = false; 14102 14103 int opti = 0; 14104 while (opti < args.length) { 14105 String opt = args[opti]; 14106 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14107 break; 14108 } 14109 opti++; 14110 if ("-a".equals(opt)) { 14111 dumpDetails = true; 14112 dumpFullDetails = true; 14113 dumpDalvik = true; 14114 } else if ("-d".equals(opt)) { 14115 dumpDalvik = true; 14116 } else if ("-c".equals(opt)) { 14117 isCompact = true; 14118 } else if ("--oom".equals(opt)) { 14119 oomOnly = true; 14120 } else if ("--local".equals(opt)) { 14121 localOnly = true; 14122 } else if ("--package".equals(opt)) { 14123 packages = true; 14124 } else if ("-h".equals(opt)) { 14125 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14126 pw.println(" -a: include all available information for each process."); 14127 pw.println(" -d: include dalvik details when dumping process details."); 14128 pw.println(" -c: dump in a compact machine-parseable representation."); 14129 pw.println(" --oom: only show processes organized by oom adj."); 14130 pw.println(" --local: only collect details locally, don't call process."); 14131 pw.println(" --package: interpret process arg as package, dumping all"); 14132 pw.println(" processes that have loaded that package."); 14133 pw.println("If [process] is specified it can be the name or "); 14134 pw.println("pid of a specific process to dump."); 14135 return; 14136 } else { 14137 pw.println("Unknown argument: " + opt + "; use -h for help"); 14138 } 14139 } 14140 14141 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14142 long uptime = SystemClock.uptimeMillis(); 14143 long realtime = SystemClock.elapsedRealtime(); 14144 final long[] tmpLong = new long[1]; 14145 14146 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14147 if (procs == null) { 14148 // No Java processes. Maybe they want to print a native process. 14149 if (args != null && args.length > opti 14150 && args[opti].charAt(0) != '-') { 14151 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14152 = new ArrayList<ProcessCpuTracker.Stats>(); 14153 updateCpuStatsNow(); 14154 int findPid = -1; 14155 try { 14156 findPid = Integer.parseInt(args[opti]); 14157 } catch (NumberFormatException e) { 14158 } 14159 synchronized (mProcessCpuTracker) { 14160 final int N = mProcessCpuTracker.countStats(); 14161 for (int i=0; i<N; i++) { 14162 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14163 if (st.pid == findPid || (st.baseName != null 14164 && st.baseName.equals(args[opti]))) { 14165 nativeProcs.add(st); 14166 } 14167 } 14168 } 14169 if (nativeProcs.size() > 0) { 14170 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14171 isCompact); 14172 Debug.MemoryInfo mi = null; 14173 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14174 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14175 final int pid = r.pid; 14176 if (!isCheckinRequest && dumpDetails) { 14177 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14178 } 14179 if (mi == null) { 14180 mi = new Debug.MemoryInfo(); 14181 } 14182 if (dumpDetails || (!brief && !oomOnly)) { 14183 Debug.getMemoryInfo(pid, mi); 14184 } else { 14185 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14186 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14187 } 14188 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14189 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14190 if (isCheckinRequest) { 14191 pw.println(); 14192 } 14193 } 14194 return; 14195 } 14196 } 14197 pw.println("No process found for: " + args[opti]); 14198 return; 14199 } 14200 14201 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14202 dumpDetails = true; 14203 } 14204 14205 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14206 14207 String[] innerArgs = new String[args.length-opti]; 14208 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14209 14210 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14211 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14212 long nativePss = 0; 14213 long dalvikPss = 0; 14214 long otherPss = 0; 14215 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14216 14217 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14218 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14219 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14220 14221 long totalPss = 0; 14222 long cachedPss = 0; 14223 14224 Debug.MemoryInfo mi = null; 14225 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14226 final ProcessRecord r = procs.get(i); 14227 final IApplicationThread thread; 14228 final int pid; 14229 final int oomAdj; 14230 final boolean hasActivities; 14231 synchronized (this) { 14232 thread = r.thread; 14233 pid = r.pid; 14234 oomAdj = r.getSetAdjWithServices(); 14235 hasActivities = r.activities.size() > 0; 14236 } 14237 if (thread != null) { 14238 if (!isCheckinRequest && dumpDetails) { 14239 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14240 } 14241 if (mi == null) { 14242 mi = new Debug.MemoryInfo(); 14243 } 14244 if (dumpDetails || (!brief && !oomOnly)) { 14245 Debug.getMemoryInfo(pid, mi); 14246 } else { 14247 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14248 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14249 } 14250 if (dumpDetails) { 14251 if (localOnly) { 14252 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14253 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14254 if (isCheckinRequest) { 14255 pw.println(); 14256 } 14257 } else { 14258 try { 14259 pw.flush(); 14260 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14261 dumpDalvik, innerArgs); 14262 } catch (RemoteException e) { 14263 if (!isCheckinRequest) { 14264 pw.println("Got RemoteException!"); 14265 pw.flush(); 14266 } 14267 } 14268 } 14269 } 14270 14271 final long myTotalPss = mi.getTotalPss(); 14272 final long myTotalUss = mi.getTotalUss(); 14273 14274 synchronized (this) { 14275 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14276 // Record this for posterity if the process has been stable. 14277 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14278 } 14279 } 14280 14281 if (!isCheckinRequest && mi != null) { 14282 totalPss += myTotalPss; 14283 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14284 (hasActivities ? " / activities)" : ")"), 14285 r.processName, myTotalPss, pid, hasActivities); 14286 procMems.add(pssItem); 14287 procMemsMap.put(pid, pssItem); 14288 14289 nativePss += mi.nativePss; 14290 dalvikPss += mi.dalvikPss; 14291 otherPss += mi.otherPss; 14292 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14293 long mem = mi.getOtherPss(j); 14294 miscPss[j] += mem; 14295 otherPss -= mem; 14296 } 14297 14298 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14299 cachedPss += myTotalPss; 14300 } 14301 14302 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14303 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14304 || oomIndex == (oomPss.length-1)) { 14305 oomPss[oomIndex] += myTotalPss; 14306 if (oomProcs[oomIndex] == null) { 14307 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14308 } 14309 oomProcs[oomIndex].add(pssItem); 14310 break; 14311 } 14312 } 14313 } 14314 } 14315 } 14316 14317 long nativeProcTotalPss = 0; 14318 14319 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14320 // If we are showing aggregations, also look for native processes to 14321 // include so that our aggregations are more accurate. 14322 updateCpuStatsNow(); 14323 mi = null; 14324 synchronized (mProcessCpuTracker) { 14325 final int N = mProcessCpuTracker.countStats(); 14326 for (int i=0; i<N; i++) { 14327 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14328 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14329 if (mi == null) { 14330 mi = new Debug.MemoryInfo(); 14331 } 14332 if (!brief && !oomOnly) { 14333 Debug.getMemoryInfo(st.pid, mi); 14334 } else { 14335 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14336 mi.nativePrivateDirty = (int)tmpLong[0]; 14337 } 14338 14339 final long myTotalPss = mi.getTotalPss(); 14340 totalPss += myTotalPss; 14341 nativeProcTotalPss += myTotalPss; 14342 14343 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14344 st.name, myTotalPss, st.pid, false); 14345 procMems.add(pssItem); 14346 14347 nativePss += mi.nativePss; 14348 dalvikPss += mi.dalvikPss; 14349 otherPss += mi.otherPss; 14350 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14351 long mem = mi.getOtherPss(j); 14352 miscPss[j] += mem; 14353 otherPss -= mem; 14354 } 14355 oomPss[0] += myTotalPss; 14356 if (oomProcs[0] == null) { 14357 oomProcs[0] = new ArrayList<MemItem>(); 14358 } 14359 oomProcs[0].add(pssItem); 14360 } 14361 } 14362 } 14363 14364 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14365 14366 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14367 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14368 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14369 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14370 String label = Debug.MemoryInfo.getOtherLabel(j); 14371 catMems.add(new MemItem(label, label, miscPss[j], j)); 14372 } 14373 14374 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14375 for (int j=0; j<oomPss.length; j++) { 14376 if (oomPss[j] != 0) { 14377 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14378 : DUMP_MEM_OOM_LABEL[j]; 14379 MemItem item = new MemItem(label, label, oomPss[j], 14380 DUMP_MEM_OOM_ADJ[j]); 14381 item.subitems = oomProcs[j]; 14382 oomMems.add(item); 14383 } 14384 } 14385 14386 if (!brief && !oomOnly && !isCompact) { 14387 pw.println(); 14388 pw.println("Total PSS by process:"); 14389 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14390 pw.println(); 14391 } 14392 if (!isCompact) { 14393 pw.println("Total PSS by OOM adjustment:"); 14394 } 14395 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14396 if (!brief && !oomOnly) { 14397 PrintWriter out = categoryPw != null ? categoryPw : pw; 14398 if (!isCompact) { 14399 out.println(); 14400 out.println("Total PSS by category:"); 14401 } 14402 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14403 } 14404 if (!isCompact) { 14405 pw.println(); 14406 } 14407 MemInfoReader memInfo = new MemInfoReader(); 14408 memInfo.readMemInfo(); 14409 if (nativeProcTotalPss > 0) { 14410 synchronized (this) { 14411 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14412 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14413 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14414 } 14415 } 14416 if (!brief) { 14417 if (!isCompact) { 14418 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14419 pw.print(" kB (status "); 14420 switch (mLastMemoryLevel) { 14421 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14422 pw.println("normal)"); 14423 break; 14424 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14425 pw.println("moderate)"); 14426 break; 14427 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14428 pw.println("low)"); 14429 break; 14430 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14431 pw.println("critical)"); 14432 break; 14433 default: 14434 pw.print(mLastMemoryLevel); 14435 pw.println(")"); 14436 break; 14437 } 14438 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14439 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14440 pw.print(cachedPss); pw.print(" cached pss + "); 14441 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14442 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14443 } else { 14444 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14445 pw.print(cachedPss + memInfo.getCachedSizeKb() 14446 + memInfo.getFreeSizeKb()); pw.print(","); 14447 pw.println(totalPss - cachedPss); 14448 } 14449 } 14450 if (!isCompact) { 14451 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14452 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14453 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14454 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14455 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14456 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14457 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14458 } 14459 if (!brief) { 14460 if (memInfo.getZramTotalSizeKb() != 0) { 14461 if (!isCompact) { 14462 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14463 pw.print(" kB physical used for "); 14464 pw.print(memInfo.getSwapTotalSizeKb() 14465 - memInfo.getSwapFreeSizeKb()); 14466 pw.print(" kB in swap ("); 14467 pw.print(memInfo.getSwapTotalSizeKb()); 14468 pw.println(" kB total swap)"); 14469 } else { 14470 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14471 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14472 pw.println(memInfo.getSwapFreeSizeKb()); 14473 } 14474 } 14475 final long[] ksm = getKsmInfo(); 14476 if (!isCompact) { 14477 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14478 || ksm[KSM_VOLATILE] != 0) { 14479 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14480 pw.print(" kB saved from shared "); 14481 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14482 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14483 pw.print(" kB unshared; "); 14484 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14485 } 14486 pw.print(" Tuning: "); 14487 pw.print(ActivityManager.staticGetMemoryClass()); 14488 pw.print(" (large "); 14489 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14490 pw.print("), oom "); 14491 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14492 pw.print(" kB"); 14493 pw.print(", restore limit "); 14494 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14495 pw.print(" kB"); 14496 if (ActivityManager.isLowRamDeviceStatic()) { 14497 pw.print(" (low-ram)"); 14498 } 14499 if (ActivityManager.isHighEndGfx()) { 14500 pw.print(" (high-end-gfx)"); 14501 } 14502 pw.println(); 14503 } else { 14504 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14505 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14506 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14507 pw.print("tuning,"); 14508 pw.print(ActivityManager.staticGetMemoryClass()); 14509 pw.print(','); 14510 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14511 pw.print(','); 14512 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14513 if (ActivityManager.isLowRamDeviceStatic()) { 14514 pw.print(",low-ram"); 14515 } 14516 if (ActivityManager.isHighEndGfx()) { 14517 pw.print(",high-end-gfx"); 14518 } 14519 pw.println(); 14520 } 14521 } 14522 } 14523 } 14524 14525 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14526 long memtrack, String name) { 14527 sb.append(" "); 14528 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14529 sb.append(' '); 14530 sb.append(ProcessList.makeProcStateString(procState)); 14531 sb.append(' '); 14532 ProcessList.appendRamKb(sb, pss); 14533 sb.append(" kB: "); 14534 sb.append(name); 14535 if (memtrack > 0) { 14536 sb.append(" ("); 14537 sb.append(memtrack); 14538 sb.append(" kB memtrack)"); 14539 } 14540 } 14541 14542 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14543 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14544 sb.append(" (pid "); 14545 sb.append(mi.pid); 14546 sb.append(") "); 14547 sb.append(mi.adjType); 14548 sb.append('\n'); 14549 if (mi.adjReason != null) { 14550 sb.append(" "); 14551 sb.append(mi.adjReason); 14552 sb.append('\n'); 14553 } 14554 } 14555 14556 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14557 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14558 for (int i=0, N=memInfos.size(); i<N; i++) { 14559 ProcessMemInfo mi = memInfos.get(i); 14560 infoMap.put(mi.pid, mi); 14561 } 14562 updateCpuStatsNow(); 14563 long[] memtrackTmp = new long[1]; 14564 synchronized (mProcessCpuTracker) { 14565 final int N = mProcessCpuTracker.countStats(); 14566 for (int i=0; i<N; i++) { 14567 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14568 if (st.vsize > 0) { 14569 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14570 if (pss > 0) { 14571 if (infoMap.indexOfKey(st.pid) < 0) { 14572 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14573 ProcessList.NATIVE_ADJ, -1, "native", null); 14574 mi.pss = pss; 14575 mi.memtrack = memtrackTmp[0]; 14576 memInfos.add(mi); 14577 } 14578 } 14579 } 14580 } 14581 } 14582 14583 long totalPss = 0; 14584 long totalMemtrack = 0; 14585 for (int i=0, N=memInfos.size(); i<N; i++) { 14586 ProcessMemInfo mi = memInfos.get(i); 14587 if (mi.pss == 0) { 14588 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14589 mi.memtrack = memtrackTmp[0]; 14590 } 14591 totalPss += mi.pss; 14592 totalMemtrack += mi.memtrack; 14593 } 14594 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14595 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14596 if (lhs.oomAdj != rhs.oomAdj) { 14597 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14598 } 14599 if (lhs.pss != rhs.pss) { 14600 return lhs.pss < rhs.pss ? 1 : -1; 14601 } 14602 return 0; 14603 } 14604 }); 14605 14606 StringBuilder tag = new StringBuilder(128); 14607 StringBuilder stack = new StringBuilder(128); 14608 tag.append("Low on memory -- "); 14609 appendMemBucket(tag, totalPss, "total", false); 14610 appendMemBucket(stack, totalPss, "total", true); 14611 14612 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14613 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14614 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14615 14616 boolean firstLine = true; 14617 int lastOomAdj = Integer.MIN_VALUE; 14618 long extraNativeRam = 0; 14619 long extraNativeMemtrack = 0; 14620 long cachedPss = 0; 14621 for (int i=0, N=memInfos.size(); i<N; i++) { 14622 ProcessMemInfo mi = memInfos.get(i); 14623 14624 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14625 cachedPss += mi.pss; 14626 } 14627 14628 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14629 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14630 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14631 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14632 if (lastOomAdj != mi.oomAdj) { 14633 lastOomAdj = mi.oomAdj; 14634 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14635 tag.append(" / "); 14636 } 14637 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14638 if (firstLine) { 14639 stack.append(":"); 14640 firstLine = false; 14641 } 14642 stack.append("\n\t at "); 14643 } else { 14644 stack.append("$"); 14645 } 14646 } else { 14647 tag.append(" "); 14648 stack.append("$"); 14649 } 14650 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14651 appendMemBucket(tag, mi.pss, mi.name, false); 14652 } 14653 appendMemBucket(stack, mi.pss, mi.name, true); 14654 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14655 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14656 stack.append("("); 14657 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14658 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14659 stack.append(DUMP_MEM_OOM_LABEL[k]); 14660 stack.append(":"); 14661 stack.append(DUMP_MEM_OOM_ADJ[k]); 14662 } 14663 } 14664 stack.append(")"); 14665 } 14666 } 14667 14668 appendMemInfo(fullNativeBuilder, mi); 14669 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14670 // The short form only has native processes that are >= 512K. 14671 if (mi.pss >= 512) { 14672 appendMemInfo(shortNativeBuilder, mi); 14673 } else { 14674 extraNativeRam += mi.pss; 14675 extraNativeMemtrack += mi.memtrack; 14676 } 14677 } else { 14678 // Short form has all other details, but if we have collected RAM 14679 // from smaller native processes let's dump a summary of that. 14680 if (extraNativeRam > 0) { 14681 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14682 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14683 shortNativeBuilder.append('\n'); 14684 extraNativeRam = 0; 14685 } 14686 appendMemInfo(fullJavaBuilder, mi); 14687 } 14688 } 14689 14690 fullJavaBuilder.append(" "); 14691 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14692 fullJavaBuilder.append(" kB: TOTAL"); 14693 if (totalMemtrack > 0) { 14694 fullJavaBuilder.append(" ("); 14695 fullJavaBuilder.append(totalMemtrack); 14696 fullJavaBuilder.append(" kB memtrack)"); 14697 } else { 14698 } 14699 fullJavaBuilder.append("\n"); 14700 14701 MemInfoReader memInfo = new MemInfoReader(); 14702 memInfo.readMemInfo(); 14703 final long[] infos = memInfo.getRawInfo(); 14704 14705 StringBuilder memInfoBuilder = new StringBuilder(1024); 14706 Debug.getMemInfo(infos); 14707 memInfoBuilder.append(" MemInfo: "); 14708 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14709 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14710 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14711 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14712 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14713 memInfoBuilder.append(" "); 14714 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14715 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14716 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14717 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14718 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14719 memInfoBuilder.append(" ZRAM: "); 14720 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14721 memInfoBuilder.append(" kB RAM, "); 14722 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14723 memInfoBuilder.append(" kB swap total, "); 14724 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14725 memInfoBuilder.append(" kB swap free\n"); 14726 } 14727 final long[] ksm = getKsmInfo(); 14728 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14729 || ksm[KSM_VOLATILE] != 0) { 14730 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14731 memInfoBuilder.append(" kB saved from shared "); 14732 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14733 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14734 memInfoBuilder.append(" kB unshared; "); 14735 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14736 } 14737 memInfoBuilder.append(" Free RAM: "); 14738 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14739 + memInfo.getFreeSizeKb()); 14740 memInfoBuilder.append(" kB\n"); 14741 memInfoBuilder.append(" Used RAM: "); 14742 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14743 memInfoBuilder.append(" kB\n"); 14744 memInfoBuilder.append(" Lost RAM: "); 14745 memInfoBuilder.append(memInfo.getTotalSizeKb() 14746 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14747 - memInfo.getKernelUsedSizeKb()); 14748 memInfoBuilder.append(" kB\n"); 14749 Slog.i(TAG, "Low on memory:"); 14750 Slog.i(TAG, shortNativeBuilder.toString()); 14751 Slog.i(TAG, fullJavaBuilder.toString()); 14752 Slog.i(TAG, memInfoBuilder.toString()); 14753 14754 StringBuilder dropBuilder = new StringBuilder(1024); 14755 /* 14756 StringWriter oomSw = new StringWriter(); 14757 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14758 StringWriter catSw = new StringWriter(); 14759 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14760 String[] emptyArgs = new String[] { }; 14761 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14762 oomPw.flush(); 14763 String oomString = oomSw.toString(); 14764 */ 14765 dropBuilder.append("Low on memory:"); 14766 dropBuilder.append(stack); 14767 dropBuilder.append('\n'); 14768 dropBuilder.append(fullNativeBuilder); 14769 dropBuilder.append(fullJavaBuilder); 14770 dropBuilder.append('\n'); 14771 dropBuilder.append(memInfoBuilder); 14772 dropBuilder.append('\n'); 14773 /* 14774 dropBuilder.append(oomString); 14775 dropBuilder.append('\n'); 14776 */ 14777 StringWriter catSw = new StringWriter(); 14778 synchronized (ActivityManagerService.this) { 14779 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14780 String[] emptyArgs = new String[] { }; 14781 catPw.println(); 14782 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14783 catPw.println(); 14784 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14785 false, false, null); 14786 catPw.println(); 14787 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14788 catPw.flush(); 14789 } 14790 dropBuilder.append(catSw.toString()); 14791 addErrorToDropBox("lowmem", null, "system_server", null, 14792 null, tag.toString(), dropBuilder.toString(), null, null); 14793 //Slog.i(TAG, "Sent to dropbox:"); 14794 //Slog.i(TAG, dropBuilder.toString()); 14795 synchronized (ActivityManagerService.this) { 14796 long now = SystemClock.uptimeMillis(); 14797 if (mLastMemUsageReportTime < now) { 14798 mLastMemUsageReportTime = now; 14799 } 14800 } 14801 } 14802 14803 /** 14804 * Searches array of arguments for the specified string 14805 * @param args array of argument strings 14806 * @param value value to search for 14807 * @return true if the value is contained in the array 14808 */ 14809 private static boolean scanArgs(String[] args, String value) { 14810 if (args != null) { 14811 for (String arg : args) { 14812 if (value.equals(arg)) { 14813 return true; 14814 } 14815 } 14816 } 14817 return false; 14818 } 14819 14820 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14821 ContentProviderRecord cpr, boolean always) { 14822 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14823 14824 if (!inLaunching || always) { 14825 synchronized (cpr) { 14826 cpr.launchingApp = null; 14827 cpr.notifyAll(); 14828 } 14829 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14830 String names[] = cpr.info.authority.split(";"); 14831 for (int j = 0; j < names.length; j++) { 14832 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14833 } 14834 } 14835 14836 for (int i=0; i<cpr.connections.size(); i++) { 14837 ContentProviderConnection conn = cpr.connections.get(i); 14838 if (conn.waiting) { 14839 // If this connection is waiting for the provider, then we don't 14840 // need to mess with its process unless we are always removing 14841 // or for some reason the provider is not currently launching. 14842 if (inLaunching && !always) { 14843 continue; 14844 } 14845 } 14846 ProcessRecord capp = conn.client; 14847 conn.dead = true; 14848 if (conn.stableCount > 0) { 14849 if (!capp.persistent && capp.thread != null 14850 && capp.pid != 0 14851 && capp.pid != MY_PID) { 14852 capp.kill("depends on provider " 14853 + cpr.name.flattenToShortString() 14854 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14855 } 14856 } else if (capp.thread != null && conn.provider.provider != null) { 14857 try { 14858 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14859 } catch (RemoteException e) { 14860 } 14861 // In the protocol here, we don't expect the client to correctly 14862 // clean up this connection, we'll just remove it. 14863 cpr.connections.remove(i); 14864 if (conn.client.conProviders.remove(conn)) { 14865 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14866 } 14867 } 14868 } 14869 14870 if (inLaunching && always) { 14871 mLaunchingProviders.remove(cpr); 14872 } 14873 return inLaunching; 14874 } 14875 14876 /** 14877 * Main code for cleaning up a process when it has gone away. This is 14878 * called both as a result of the process dying, or directly when stopping 14879 * a process when running in single process mode. 14880 * 14881 * @return Returns true if the given process has been restarted, so the 14882 * app that was passed in must remain on the process lists. 14883 */ 14884 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14885 boolean restarting, boolean allowRestart, int index) { 14886 if (index >= 0) { 14887 removeLruProcessLocked(app); 14888 ProcessList.remove(app.pid); 14889 } 14890 14891 mProcessesToGc.remove(app); 14892 mPendingPssProcesses.remove(app); 14893 14894 // Dismiss any open dialogs. 14895 if (app.crashDialog != null && !app.forceCrashReport) { 14896 app.crashDialog.dismiss(); 14897 app.crashDialog = null; 14898 } 14899 if (app.anrDialog != null) { 14900 app.anrDialog.dismiss(); 14901 app.anrDialog = null; 14902 } 14903 if (app.waitDialog != null) { 14904 app.waitDialog.dismiss(); 14905 app.waitDialog = null; 14906 } 14907 14908 app.crashing = false; 14909 app.notResponding = false; 14910 14911 app.resetPackageList(mProcessStats); 14912 app.unlinkDeathRecipient(); 14913 app.makeInactive(mProcessStats); 14914 app.waitingToKill = null; 14915 app.forcingToForeground = null; 14916 updateProcessForegroundLocked(app, false, false); 14917 app.foregroundActivities = false; 14918 app.hasShownUi = false; 14919 app.treatLikeActivity = false; 14920 app.hasAboveClient = false; 14921 app.hasClientActivities = false; 14922 14923 mServices.killServicesLocked(app, allowRestart); 14924 14925 boolean restart = false; 14926 14927 // Remove published content providers. 14928 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14929 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14930 final boolean always = app.bad || !allowRestart; 14931 if (removeDyingProviderLocked(app, cpr, always) || always) { 14932 // We left the provider in the launching list, need to 14933 // restart it. 14934 restart = true; 14935 } 14936 14937 cpr.provider = null; 14938 cpr.proc = null; 14939 } 14940 app.pubProviders.clear(); 14941 14942 // Take care of any launching providers waiting for this process. 14943 if (checkAppInLaunchingProvidersLocked(app, false)) { 14944 restart = true; 14945 } 14946 14947 // Unregister from connected content providers. 14948 if (!app.conProviders.isEmpty()) { 14949 for (int i=0; i<app.conProviders.size(); i++) { 14950 ContentProviderConnection conn = app.conProviders.get(i); 14951 conn.provider.connections.remove(conn); 14952 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14953 conn.provider.name); 14954 } 14955 app.conProviders.clear(); 14956 } 14957 14958 // At this point there may be remaining entries in mLaunchingProviders 14959 // where we were the only one waiting, so they are no longer of use. 14960 // Look for these and clean up if found. 14961 // XXX Commented out for now. Trying to figure out a way to reproduce 14962 // the actual situation to identify what is actually going on. 14963 if (false) { 14964 for (int i=0; i<mLaunchingProviders.size(); i++) { 14965 ContentProviderRecord cpr = (ContentProviderRecord) 14966 mLaunchingProviders.get(i); 14967 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14968 synchronized (cpr) { 14969 cpr.launchingApp = null; 14970 cpr.notifyAll(); 14971 } 14972 } 14973 } 14974 } 14975 14976 skipCurrentReceiverLocked(app); 14977 14978 // Unregister any receivers. 14979 for (int i=app.receivers.size()-1; i>=0; i--) { 14980 removeReceiverLocked(app.receivers.valueAt(i)); 14981 } 14982 app.receivers.clear(); 14983 14984 // If the app is undergoing backup, tell the backup manager about it 14985 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14986 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14987 + mBackupTarget.appInfo + " died during backup"); 14988 try { 14989 IBackupManager bm = IBackupManager.Stub.asInterface( 14990 ServiceManager.getService(Context.BACKUP_SERVICE)); 14991 bm.agentDisconnected(app.info.packageName); 14992 } catch (RemoteException e) { 14993 // can't happen; backup manager is local 14994 } 14995 } 14996 14997 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14998 ProcessChangeItem item = mPendingProcessChanges.get(i); 14999 if (item.pid == app.pid) { 15000 mPendingProcessChanges.remove(i); 15001 mAvailProcessChanges.add(item); 15002 } 15003 } 15004 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 15005 15006 // If the caller is restarting this app, then leave it in its 15007 // current lists and let the caller take care of it. 15008 if (restarting) { 15009 return false; 15010 } 15011 15012 if (!app.persistent || app.isolated) { 15013 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 15014 "Removing non-persistent process during cleanup: " + app); 15015 mProcessNames.remove(app.processName, app.uid); 15016 mIsolatedProcesses.remove(app.uid); 15017 if (mHeavyWeightProcess == app) { 15018 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 15019 mHeavyWeightProcess.userId, 0)); 15020 mHeavyWeightProcess = null; 15021 } 15022 } else if (!app.removed) { 15023 // This app is persistent, so we need to keep its record around. 15024 // If it is not already on the pending app list, add it there 15025 // and start a new process for it. 15026 if (mPersistentStartingProcesses.indexOf(app) < 0) { 15027 mPersistentStartingProcesses.add(app); 15028 restart = true; 15029 } 15030 } 15031 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15032 "Clean-up removing on hold: " + app); 15033 mProcessesOnHold.remove(app); 15034 15035 if (app == mHomeProcess) { 15036 mHomeProcess = null; 15037 } 15038 if (app == mPreviousProcess) { 15039 mPreviousProcess = null; 15040 } 15041 15042 if (restart && !app.isolated) { 15043 // We have components that still need to be running in the 15044 // process, so re-launch it. 15045 if (index < 0) { 15046 ProcessList.remove(app.pid); 15047 } 15048 mProcessNames.put(app.processName, app.uid, app); 15049 startProcessLocked(app, "restart", app.processName); 15050 return true; 15051 } else if (app.pid > 0 && app.pid != MY_PID) { 15052 // Goodbye! 15053 boolean removed; 15054 synchronized (mPidsSelfLocked) { 15055 mPidsSelfLocked.remove(app.pid); 15056 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15057 } 15058 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15059 if (app.isolated) { 15060 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15061 } 15062 app.setPid(0); 15063 } 15064 return false; 15065 } 15066 15067 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15068 // Look through the content providers we are waiting to have launched, 15069 // and if any run in this process then either schedule a restart of 15070 // the process or kill the client waiting for it if this process has 15071 // gone bad. 15072 int NL = mLaunchingProviders.size(); 15073 boolean restart = false; 15074 for (int i=0; i<NL; i++) { 15075 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15076 if (cpr.launchingApp == app) { 15077 if (!alwaysBad && !app.bad) { 15078 restart = true; 15079 } else { 15080 removeDyingProviderLocked(app, cpr, true); 15081 // cpr should have been removed from mLaunchingProviders 15082 NL = mLaunchingProviders.size(); 15083 i--; 15084 } 15085 } 15086 } 15087 return restart; 15088 } 15089 15090 // ========================================================= 15091 // SERVICES 15092 // ========================================================= 15093 15094 @Override 15095 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15096 int flags) { 15097 enforceNotIsolatedCaller("getServices"); 15098 synchronized (this) { 15099 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15100 } 15101 } 15102 15103 @Override 15104 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15105 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15106 synchronized (this) { 15107 return mServices.getRunningServiceControlPanelLocked(name); 15108 } 15109 } 15110 15111 @Override 15112 public ComponentName startService(IApplicationThread caller, Intent service, 15113 String resolvedType, int userId) { 15114 enforceNotIsolatedCaller("startService"); 15115 // Refuse possible leaked file descriptors 15116 if (service != null && service.hasFileDescriptors() == true) { 15117 throw new IllegalArgumentException("File descriptors passed in Intent"); 15118 } 15119 15120 if (DEBUG_SERVICE) 15121 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15122 synchronized(this) { 15123 final int callingPid = Binder.getCallingPid(); 15124 final int callingUid = Binder.getCallingUid(); 15125 final long origId = Binder.clearCallingIdentity(); 15126 ComponentName res = mServices.startServiceLocked(caller, service, 15127 resolvedType, callingPid, callingUid, userId); 15128 Binder.restoreCallingIdentity(origId); 15129 return res; 15130 } 15131 } 15132 15133 ComponentName startServiceInPackage(int uid, 15134 Intent service, String resolvedType, int userId) { 15135 synchronized(this) { 15136 if (DEBUG_SERVICE) 15137 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15138 final long origId = Binder.clearCallingIdentity(); 15139 ComponentName res = mServices.startServiceLocked(null, service, 15140 resolvedType, -1, uid, userId); 15141 Binder.restoreCallingIdentity(origId); 15142 return res; 15143 } 15144 } 15145 15146 @Override 15147 public int stopService(IApplicationThread caller, Intent service, 15148 String resolvedType, int userId) { 15149 enforceNotIsolatedCaller("stopService"); 15150 // Refuse possible leaked file descriptors 15151 if (service != null && service.hasFileDescriptors() == true) { 15152 throw new IllegalArgumentException("File descriptors passed in Intent"); 15153 } 15154 15155 synchronized(this) { 15156 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15157 } 15158 } 15159 15160 @Override 15161 public IBinder peekService(Intent service, String resolvedType) { 15162 enforceNotIsolatedCaller("peekService"); 15163 // Refuse possible leaked file descriptors 15164 if (service != null && service.hasFileDescriptors() == true) { 15165 throw new IllegalArgumentException("File descriptors passed in Intent"); 15166 } 15167 synchronized(this) { 15168 return mServices.peekServiceLocked(service, resolvedType); 15169 } 15170 } 15171 15172 @Override 15173 public boolean stopServiceToken(ComponentName className, IBinder token, 15174 int startId) { 15175 synchronized(this) { 15176 return mServices.stopServiceTokenLocked(className, token, startId); 15177 } 15178 } 15179 15180 @Override 15181 public void setServiceForeground(ComponentName className, IBinder token, 15182 int id, Notification notification, boolean removeNotification) { 15183 synchronized(this) { 15184 mServices.setServiceForegroundLocked(className, token, id, notification, 15185 removeNotification); 15186 } 15187 } 15188 15189 @Override 15190 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15191 boolean requireFull, String name, String callerPackage) { 15192 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15193 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15194 } 15195 15196 int unsafeConvertIncomingUser(int userId) { 15197 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15198 ? mCurrentUserId : userId; 15199 } 15200 15201 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15202 int allowMode, String name, String callerPackage) { 15203 final int callingUserId = UserHandle.getUserId(callingUid); 15204 if (callingUserId == userId) { 15205 return userId; 15206 } 15207 15208 // Note that we may be accessing mCurrentUserId outside of a lock... 15209 // shouldn't be a big deal, if this is being called outside 15210 // of a locked context there is intrinsically a race with 15211 // the value the caller will receive and someone else changing it. 15212 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15213 // we will switch to the calling user if access to the current user fails. 15214 int targetUserId = unsafeConvertIncomingUser(userId); 15215 15216 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15217 final boolean allow; 15218 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15219 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15220 // If the caller has this permission, they always pass go. And collect $200. 15221 allow = true; 15222 } else if (allowMode == ALLOW_FULL_ONLY) { 15223 // We require full access, sucks to be you. 15224 allow = false; 15225 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15226 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15227 // If the caller does not have either permission, they are always doomed. 15228 allow = false; 15229 } else if (allowMode == ALLOW_NON_FULL) { 15230 // We are blanket allowing non-full access, you lucky caller! 15231 allow = true; 15232 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15233 // We may or may not allow this depending on whether the two users are 15234 // in the same profile. 15235 synchronized (mUserProfileGroupIdsSelfLocked) { 15236 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15237 UserInfo.NO_PROFILE_GROUP_ID); 15238 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15239 UserInfo.NO_PROFILE_GROUP_ID); 15240 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15241 && callingProfile == targetProfile; 15242 } 15243 } else { 15244 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15245 } 15246 if (!allow) { 15247 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15248 // In this case, they would like to just execute as their 15249 // owner user instead of failing. 15250 targetUserId = callingUserId; 15251 } else { 15252 StringBuilder builder = new StringBuilder(128); 15253 builder.append("Permission Denial: "); 15254 builder.append(name); 15255 if (callerPackage != null) { 15256 builder.append(" from "); 15257 builder.append(callerPackage); 15258 } 15259 builder.append(" asks to run as user "); 15260 builder.append(userId); 15261 builder.append(" but is calling from user "); 15262 builder.append(UserHandle.getUserId(callingUid)); 15263 builder.append("; this requires "); 15264 builder.append(INTERACT_ACROSS_USERS_FULL); 15265 if (allowMode != ALLOW_FULL_ONLY) { 15266 builder.append(" or "); 15267 builder.append(INTERACT_ACROSS_USERS); 15268 } 15269 String msg = builder.toString(); 15270 Slog.w(TAG, msg); 15271 throw new SecurityException(msg); 15272 } 15273 } 15274 } 15275 if (!allowAll && targetUserId < 0) { 15276 throw new IllegalArgumentException( 15277 "Call does not support special user #" + targetUserId); 15278 } 15279 // Check shell permission 15280 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15281 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15282 targetUserId)) { 15283 throw new SecurityException("Shell does not have permission to access user " 15284 + targetUserId + "\n " + Debug.getCallers(3)); 15285 } 15286 } 15287 return targetUserId; 15288 } 15289 15290 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15291 String className, int flags) { 15292 boolean result = false; 15293 // For apps that don't have pre-defined UIDs, check for permission 15294 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15295 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15296 if (ActivityManager.checkUidPermission( 15297 INTERACT_ACROSS_USERS, 15298 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15299 ComponentName comp = new ComponentName(aInfo.packageName, className); 15300 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15301 + " requests FLAG_SINGLE_USER, but app does not hold " 15302 + INTERACT_ACROSS_USERS; 15303 Slog.w(TAG, msg); 15304 throw new SecurityException(msg); 15305 } 15306 // Permission passed 15307 result = true; 15308 } 15309 } else if ("system".equals(componentProcessName)) { 15310 result = true; 15311 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15312 // Phone app and persistent apps are allowed to export singleuser providers. 15313 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15314 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15315 } 15316 if (DEBUG_MU) { 15317 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15318 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15319 } 15320 return result; 15321 } 15322 15323 /** 15324 * Checks to see if the caller is in the same app as the singleton 15325 * component, or the component is in a special app. It allows special apps 15326 * to export singleton components but prevents exporting singleton 15327 * components for regular apps. 15328 */ 15329 boolean isValidSingletonCall(int callingUid, int componentUid) { 15330 int componentAppId = UserHandle.getAppId(componentUid); 15331 return UserHandle.isSameApp(callingUid, componentUid) 15332 || componentAppId == Process.SYSTEM_UID 15333 || componentAppId == Process.PHONE_UID 15334 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15335 == PackageManager.PERMISSION_GRANTED; 15336 } 15337 15338 public int bindService(IApplicationThread caller, IBinder token, 15339 Intent service, String resolvedType, 15340 IServiceConnection connection, int flags, int userId) { 15341 enforceNotIsolatedCaller("bindService"); 15342 15343 // Refuse possible leaked file descriptors 15344 if (service != null && service.hasFileDescriptors() == true) { 15345 throw new IllegalArgumentException("File descriptors passed in Intent"); 15346 } 15347 15348 synchronized(this) { 15349 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15350 connection, flags, userId); 15351 } 15352 } 15353 15354 public boolean unbindService(IServiceConnection connection) { 15355 synchronized (this) { 15356 return mServices.unbindServiceLocked(connection); 15357 } 15358 } 15359 15360 public void publishService(IBinder token, Intent intent, IBinder service) { 15361 // Refuse possible leaked file descriptors 15362 if (intent != null && intent.hasFileDescriptors() == true) { 15363 throw new IllegalArgumentException("File descriptors passed in Intent"); 15364 } 15365 15366 synchronized(this) { 15367 if (!(token instanceof ServiceRecord)) { 15368 throw new IllegalArgumentException("Invalid service token"); 15369 } 15370 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15371 } 15372 } 15373 15374 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15375 // Refuse possible leaked file descriptors 15376 if (intent != null && intent.hasFileDescriptors() == true) { 15377 throw new IllegalArgumentException("File descriptors passed in Intent"); 15378 } 15379 15380 synchronized(this) { 15381 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15382 } 15383 } 15384 15385 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15386 synchronized(this) { 15387 if (!(token instanceof ServiceRecord)) { 15388 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 15389 throw new IllegalArgumentException("Invalid service token"); 15390 } 15391 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15392 } 15393 } 15394 15395 // ========================================================= 15396 // BACKUP AND RESTORE 15397 // ========================================================= 15398 15399 // Cause the target app to be launched if necessary and its backup agent 15400 // instantiated. The backup agent will invoke backupAgentCreated() on the 15401 // activity manager to announce its creation. 15402 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15403 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15404 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15405 15406 synchronized(this) { 15407 // !!! TODO: currently no check here that we're already bound 15408 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15409 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15410 synchronized (stats) { 15411 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15412 } 15413 15414 // Backup agent is now in use, its package can't be stopped. 15415 try { 15416 AppGlobals.getPackageManager().setPackageStoppedState( 15417 app.packageName, false, UserHandle.getUserId(app.uid)); 15418 } catch (RemoteException e) { 15419 } catch (IllegalArgumentException e) { 15420 Slog.w(TAG, "Failed trying to unstop package " 15421 + app.packageName + ": " + e); 15422 } 15423 15424 BackupRecord r = new BackupRecord(ss, app, backupMode); 15425 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15426 ? new ComponentName(app.packageName, app.backupAgentName) 15427 : new ComponentName("android", "FullBackupAgent"); 15428 // startProcessLocked() returns existing proc's record if it's already running 15429 ProcessRecord proc = startProcessLocked(app.processName, app, 15430 false, 0, "backup", hostingName, false, false, false); 15431 if (proc == null) { 15432 Slog.e(TAG, "Unable to start backup agent process " + r); 15433 return false; 15434 } 15435 15436 r.app = proc; 15437 mBackupTarget = r; 15438 mBackupAppName = app.packageName; 15439 15440 // Try not to kill the process during backup 15441 updateOomAdjLocked(proc); 15442 15443 // If the process is already attached, schedule the creation of the backup agent now. 15444 // If it is not yet live, this will be done when it attaches to the framework. 15445 if (proc.thread != null) { 15446 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15447 try { 15448 proc.thread.scheduleCreateBackupAgent(app, 15449 compatibilityInfoForPackageLocked(app), backupMode); 15450 } catch (RemoteException e) { 15451 // Will time out on the backup manager side 15452 } 15453 } else { 15454 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15455 } 15456 // Invariants: at this point, the target app process exists and the application 15457 // is either already running or in the process of coming up. mBackupTarget and 15458 // mBackupAppName describe the app, so that when it binds back to the AM we 15459 // know that it's scheduled for a backup-agent operation. 15460 } 15461 15462 return true; 15463 } 15464 15465 @Override 15466 public void clearPendingBackup() { 15467 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15468 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15469 15470 synchronized (this) { 15471 mBackupTarget = null; 15472 mBackupAppName = null; 15473 } 15474 } 15475 15476 // A backup agent has just come up 15477 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15478 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15479 + " = " + agent); 15480 15481 synchronized(this) { 15482 if (!agentPackageName.equals(mBackupAppName)) { 15483 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15484 return; 15485 } 15486 } 15487 15488 long oldIdent = Binder.clearCallingIdentity(); 15489 try { 15490 IBackupManager bm = IBackupManager.Stub.asInterface( 15491 ServiceManager.getService(Context.BACKUP_SERVICE)); 15492 bm.agentConnected(agentPackageName, agent); 15493 } catch (RemoteException e) { 15494 // can't happen; the backup manager service is local 15495 } catch (Exception e) { 15496 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15497 e.printStackTrace(); 15498 } finally { 15499 Binder.restoreCallingIdentity(oldIdent); 15500 } 15501 } 15502 15503 // done with this agent 15504 public void unbindBackupAgent(ApplicationInfo appInfo) { 15505 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15506 if (appInfo == null) { 15507 Slog.w(TAG, "unbind backup agent for null app"); 15508 return; 15509 } 15510 15511 synchronized(this) { 15512 try { 15513 if (mBackupAppName == null) { 15514 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15515 return; 15516 } 15517 15518 if (!mBackupAppName.equals(appInfo.packageName)) { 15519 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15520 return; 15521 } 15522 15523 // Not backing this app up any more; reset its OOM adjustment 15524 final ProcessRecord proc = mBackupTarget.app; 15525 updateOomAdjLocked(proc); 15526 15527 // If the app crashed during backup, 'thread' will be null here 15528 if (proc.thread != null) { 15529 try { 15530 proc.thread.scheduleDestroyBackupAgent(appInfo, 15531 compatibilityInfoForPackageLocked(appInfo)); 15532 } catch (Exception e) { 15533 Slog.e(TAG, "Exception when unbinding backup agent:"); 15534 e.printStackTrace(); 15535 } 15536 } 15537 } finally { 15538 mBackupTarget = null; 15539 mBackupAppName = null; 15540 } 15541 } 15542 } 15543 // ========================================================= 15544 // BROADCASTS 15545 // ========================================================= 15546 15547 boolean isPendingBroadcastProcessLocked(int pid) { 15548 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15549 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15550 } 15551 15552 void skipPendingBroadcastLocked(int pid) { 15553 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15554 for (BroadcastQueue queue : mBroadcastQueues) { 15555 queue.skipPendingBroadcastLocked(pid); 15556 } 15557 } 15558 15559 // The app just attached; send any pending broadcasts that it should receive 15560 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15561 boolean didSomething = false; 15562 for (BroadcastQueue queue : mBroadcastQueues) { 15563 didSomething |= queue.sendPendingBroadcastsLocked(app); 15564 } 15565 return didSomething; 15566 } 15567 15568 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15569 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15570 enforceNotIsolatedCaller("registerReceiver"); 15571 ArrayList<Intent> stickyIntents = null; 15572 ProcessRecord callerApp = null; 15573 int callingUid; 15574 int callingPid; 15575 synchronized(this) { 15576 if (caller != null) { 15577 callerApp = getRecordForAppLocked(caller); 15578 if (callerApp == null) { 15579 throw new SecurityException( 15580 "Unable to find app for caller " + caller 15581 + " (pid=" + Binder.getCallingPid() 15582 + ") when registering receiver " + receiver); 15583 } 15584 if (callerApp.info.uid != Process.SYSTEM_UID && 15585 !callerApp.pkgList.containsKey(callerPackage) && 15586 !"android".equals(callerPackage)) { 15587 throw new SecurityException("Given caller package " + callerPackage 15588 + " is not running in process " + callerApp); 15589 } 15590 callingUid = callerApp.info.uid; 15591 callingPid = callerApp.pid; 15592 } else { 15593 callerPackage = null; 15594 callingUid = Binder.getCallingUid(); 15595 callingPid = Binder.getCallingPid(); 15596 } 15597 15598 userId = handleIncomingUser(callingPid, callingUid, userId, 15599 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15600 15601 Iterator<String> actions = filter.actionsIterator(); 15602 if (actions == null) { 15603 ArrayList<String> noAction = new ArrayList<String>(1); 15604 noAction.add(null); 15605 actions = noAction.iterator(); 15606 } 15607 15608 // Collect stickies of users 15609 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; 15610 while (actions.hasNext()) { 15611 String action = actions.next(); 15612 for (int id : userIds) { 15613 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); 15614 if (stickies != null) { 15615 ArrayList<Intent> intents = stickies.get(action); 15616 if (intents != null) { 15617 if (stickyIntents == null) { 15618 stickyIntents = new ArrayList<Intent>(); 15619 } 15620 stickyIntents.addAll(intents); 15621 } 15622 } 15623 } 15624 } 15625 } 15626 15627 ArrayList<Intent> allSticky = null; 15628 if (stickyIntents != null) { 15629 final ContentResolver resolver = mContext.getContentResolver(); 15630 // Look for any matching sticky broadcasts... 15631 for (int i = 0, N = stickyIntents.size(); i < N; i++) { 15632 Intent intent = stickyIntents.get(i); 15633 // If intent has scheme "content", it will need to acccess 15634 // provider that needs to lock mProviderMap in ActivityThread 15635 // and also it may need to wait application response, so we 15636 // cannot lock ActivityManagerService here. 15637 if (filter.match(resolver, intent, true, TAG) >= 0) { 15638 if (allSticky == null) { 15639 allSticky = new ArrayList<Intent>(); 15640 } 15641 allSticky.add(intent); 15642 } 15643 } 15644 } 15645 15646 // The first sticky in the list is returned directly back to the client. 15647 Intent sticky = allSticky != null ? allSticky.get(0) : null; 15648 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky); 15649 if (receiver == null) { 15650 return sticky; 15651 } 15652 15653 synchronized (this) { 15654 if (callerApp != null && callerApp.pid == 0) { 15655 // Caller already died 15656 return null; 15657 } 15658 ReceiverList rl 15659 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15660 if (rl == null) { 15661 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15662 userId, receiver); 15663 if (rl.app != null) { 15664 rl.app.receivers.add(rl); 15665 } else { 15666 try { 15667 receiver.asBinder().linkToDeath(rl, 0); 15668 } catch (RemoteException e) { 15669 return sticky; 15670 } 15671 rl.linkedToDeath = true; 15672 } 15673 mRegisteredReceivers.put(receiver.asBinder(), rl); 15674 } else if (rl.uid != callingUid) { 15675 throw new IllegalArgumentException( 15676 "Receiver requested to register for uid " + callingUid 15677 + " was previously registered for uid " + rl.uid); 15678 } else if (rl.pid != callingPid) { 15679 throw new IllegalArgumentException( 15680 "Receiver requested to register for pid " + callingPid 15681 + " was previously registered for pid " + rl.pid); 15682 } else if (rl.userId != userId) { 15683 throw new IllegalArgumentException( 15684 "Receiver requested to register for user " + userId 15685 + " was previously registered for user " + rl.userId); 15686 } 15687 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15688 permission, callingUid, userId); 15689 rl.add(bf); 15690 if (!bf.debugCheck()) { 15691 Slog.w(TAG, "==> For Dynamic broadast"); 15692 } 15693 mReceiverResolver.addFilter(bf); 15694 15695 // Enqueue broadcasts for all existing stickies that match 15696 // this filter. 15697 if (allSticky != null) { 15698 ArrayList receivers = new ArrayList(); 15699 receivers.add(bf); 15700 15701 int N = allSticky.size(); 15702 for (int i=0; i<N; i++) { 15703 Intent intent = (Intent)allSticky.get(i); 15704 BroadcastQueue queue = broadcastQueueForIntent(intent); 15705 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15706 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15707 null, null, false, true, true, -1); 15708 queue.enqueueParallelBroadcastLocked(r); 15709 queue.scheduleBroadcastsLocked(); 15710 } 15711 } 15712 15713 return sticky; 15714 } 15715 } 15716 15717 public void unregisterReceiver(IIntentReceiver receiver) { 15718 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15719 15720 final long origId = Binder.clearCallingIdentity(); 15721 try { 15722 boolean doTrim = false; 15723 15724 synchronized(this) { 15725 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15726 if (rl != null) { 15727 final BroadcastRecord r = rl.curBroadcast; 15728 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 15729 final boolean doNext = r.queue.finishReceiverLocked( 15730 r, r.resultCode, r.resultData, r.resultExtras, 15731 r.resultAbort, false); 15732 if (doNext) { 15733 doTrim = true; 15734 r.queue.processNextBroadcast(false); 15735 } 15736 } 15737 15738 if (rl.app != null) { 15739 rl.app.receivers.remove(rl); 15740 } 15741 removeReceiverLocked(rl); 15742 if (rl.linkedToDeath) { 15743 rl.linkedToDeath = false; 15744 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15745 } 15746 } 15747 } 15748 15749 // If we actually concluded any broadcasts, we might now be able 15750 // to trim the recipients' apps from our working set 15751 if (doTrim) { 15752 trimApplications(); 15753 return; 15754 } 15755 15756 } finally { 15757 Binder.restoreCallingIdentity(origId); 15758 } 15759 } 15760 15761 void removeReceiverLocked(ReceiverList rl) { 15762 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15763 int N = rl.size(); 15764 for (int i=0; i<N; i++) { 15765 mReceiverResolver.removeFilter(rl.get(i)); 15766 } 15767 } 15768 15769 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15770 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15771 ProcessRecord r = mLruProcesses.get(i); 15772 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15773 try { 15774 r.thread.dispatchPackageBroadcast(cmd, packages); 15775 } catch (RemoteException ex) { 15776 } 15777 } 15778 } 15779 } 15780 15781 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15782 int callingUid, int[] users) { 15783 List<ResolveInfo> receivers = null; 15784 try { 15785 HashSet<ComponentName> singleUserReceivers = null; 15786 boolean scannedFirstReceivers = false; 15787 for (int user : users) { 15788 // Skip users that have Shell restrictions 15789 if (callingUid == Process.SHELL_UID 15790 && getUserManagerLocked().hasUserRestriction( 15791 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15792 continue; 15793 } 15794 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15795 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15796 if (user != 0 && newReceivers != null) { 15797 // If this is not the primary user, we need to check for 15798 // any receivers that should be filtered out. 15799 for (int i=0; i<newReceivers.size(); i++) { 15800 ResolveInfo ri = newReceivers.get(i); 15801 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15802 newReceivers.remove(i); 15803 i--; 15804 } 15805 } 15806 } 15807 if (newReceivers != null && newReceivers.size() == 0) { 15808 newReceivers = null; 15809 } 15810 if (receivers == null) { 15811 receivers = newReceivers; 15812 } else if (newReceivers != null) { 15813 // We need to concatenate the additional receivers 15814 // found with what we have do far. This would be easy, 15815 // but we also need to de-dup any receivers that are 15816 // singleUser. 15817 if (!scannedFirstReceivers) { 15818 // Collect any single user receivers we had already retrieved. 15819 scannedFirstReceivers = true; 15820 for (int i=0; i<receivers.size(); i++) { 15821 ResolveInfo ri = receivers.get(i); 15822 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15823 ComponentName cn = new ComponentName( 15824 ri.activityInfo.packageName, ri.activityInfo.name); 15825 if (singleUserReceivers == null) { 15826 singleUserReceivers = new HashSet<ComponentName>(); 15827 } 15828 singleUserReceivers.add(cn); 15829 } 15830 } 15831 } 15832 // Add the new results to the existing results, tracking 15833 // and de-dupping single user receivers. 15834 for (int i=0; i<newReceivers.size(); i++) { 15835 ResolveInfo ri = newReceivers.get(i); 15836 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15837 ComponentName cn = new ComponentName( 15838 ri.activityInfo.packageName, ri.activityInfo.name); 15839 if (singleUserReceivers == null) { 15840 singleUserReceivers = new HashSet<ComponentName>(); 15841 } 15842 if (!singleUserReceivers.contains(cn)) { 15843 singleUserReceivers.add(cn); 15844 receivers.add(ri); 15845 } 15846 } else { 15847 receivers.add(ri); 15848 } 15849 } 15850 } 15851 } 15852 } catch (RemoteException ex) { 15853 // pm is in same process, this will never happen. 15854 } 15855 return receivers; 15856 } 15857 15858 private final int broadcastIntentLocked(ProcessRecord callerApp, 15859 String callerPackage, Intent intent, String resolvedType, 15860 IIntentReceiver resultTo, int resultCode, String resultData, 15861 Bundle map, String requiredPermission, int appOp, 15862 boolean ordered, boolean sticky, int callingPid, int callingUid, 15863 int userId) { 15864 intent = new Intent(intent); 15865 15866 // By default broadcasts do not go to stopped apps. 15867 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15868 15869 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15870 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15871 + " ordered=" + ordered + " userid=" + userId); 15872 if ((resultTo != null) && !ordered) { 15873 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15874 } 15875 15876 userId = handleIncomingUser(callingPid, callingUid, userId, 15877 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15878 15879 // Make sure that the user who is receiving this broadcast is running. 15880 // If not, we will just skip it. Make an exception for shutdown broadcasts 15881 // and upgrade steps. 15882 15883 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15884 if ((callingUid != Process.SYSTEM_UID 15885 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15886 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15887 Slog.w(TAG, "Skipping broadcast of " + intent 15888 + ": user " + userId + " is stopped"); 15889 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15890 } 15891 } 15892 15893 /* 15894 * Prevent non-system code (defined here to be non-persistent 15895 * processes) from sending protected broadcasts. 15896 */ 15897 int callingAppId = UserHandle.getAppId(callingUid); 15898 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15899 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15900 || callingAppId == Process.NFC_UID || callingUid == 0) { 15901 // Always okay. 15902 } else if (callerApp == null || !callerApp.persistent) { 15903 try { 15904 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15905 intent.getAction())) { 15906 String msg = "Permission Denial: not allowed to send broadcast " 15907 + intent.getAction() + " from pid=" 15908 + callingPid + ", uid=" + callingUid; 15909 Slog.w(TAG, msg); 15910 throw new SecurityException(msg); 15911 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15912 // Special case for compatibility: we don't want apps to send this, 15913 // but historically it has not been protected and apps may be using it 15914 // to poke their own app widget. So, instead of making it protected, 15915 // just limit it to the caller. 15916 if (callerApp == null) { 15917 String msg = "Permission Denial: not allowed to send broadcast " 15918 + intent.getAction() + " from unknown caller."; 15919 Slog.w(TAG, msg); 15920 throw new SecurityException(msg); 15921 } else if (intent.getComponent() != null) { 15922 // They are good enough to send to an explicit component... verify 15923 // it is being sent to the calling app. 15924 if (!intent.getComponent().getPackageName().equals( 15925 callerApp.info.packageName)) { 15926 String msg = "Permission Denial: not allowed to send broadcast " 15927 + intent.getAction() + " to " 15928 + intent.getComponent().getPackageName() + " from " 15929 + callerApp.info.packageName; 15930 Slog.w(TAG, msg); 15931 throw new SecurityException(msg); 15932 } 15933 } else { 15934 // Limit broadcast to their own package. 15935 intent.setPackage(callerApp.info.packageName); 15936 } 15937 } 15938 } catch (RemoteException e) { 15939 Slog.w(TAG, "Remote exception", e); 15940 return ActivityManager.BROADCAST_SUCCESS; 15941 } 15942 } 15943 15944 final String action = intent.getAction(); 15945 if (action != null) { 15946 switch (action) { 15947 case Intent.ACTION_UID_REMOVED: 15948 case Intent.ACTION_PACKAGE_REMOVED: 15949 case Intent.ACTION_PACKAGE_CHANGED: 15950 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15951 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15952 // Handle special intents: if this broadcast is from the package 15953 // manager about a package being removed, we need to remove all of 15954 // its activities from the history stack. 15955 if (checkComponentPermission( 15956 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15957 callingPid, callingUid, -1, true) 15958 != PackageManager.PERMISSION_GRANTED) { 15959 String msg = "Permission Denial: " + intent.getAction() 15960 + " broadcast from " + callerPackage + " (pid=" + callingPid 15961 + ", uid=" + callingUid + ")" 15962 + " requires " 15963 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15964 Slog.w(TAG, msg); 15965 throw new SecurityException(msg); 15966 } 15967 switch (action) { 15968 case Intent.ACTION_UID_REMOVED: 15969 final Bundle intentExtras = intent.getExtras(); 15970 final int uid = intentExtras != null 15971 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15972 if (uid >= 0) { 15973 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15974 synchronized (bs) { 15975 bs.removeUidStatsLocked(uid); 15976 } 15977 mAppOpsService.uidRemoved(uid); 15978 } 15979 break; 15980 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15981 // If resources are unavailable just force stop all those packages 15982 // and flush the attribute cache as well. 15983 String list[] = 15984 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15985 if (list != null && list.length > 0) { 15986 for (int i = 0; i < list.length; i++) { 15987 forceStopPackageLocked(list[i], -1, false, true, true, 15988 false, false, userId, "storage unmount"); 15989 } 15990 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15991 sendPackageBroadcastLocked( 15992 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15993 userId); 15994 } 15995 break; 15996 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15997 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15998 break; 15999 case Intent.ACTION_PACKAGE_REMOVED: 16000 case Intent.ACTION_PACKAGE_CHANGED: 16001 Uri data = intent.getData(); 16002 String ssp; 16003 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 16004 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 16005 boolean fullUninstall = removed && 16006 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16007 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 16008 forceStopPackageLocked(ssp, UserHandle.getAppId( 16009 intent.getIntExtra(Intent.EXTRA_UID, -1)), 16010 false, true, true, false, fullUninstall, userId, 16011 removed ? "pkg removed" : "pkg changed"); 16012 } 16013 if (removed) { 16014 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 16015 new String[] {ssp}, userId); 16016 if (fullUninstall) { 16017 mAppOpsService.packageRemoved( 16018 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 16019 16020 // Remove all permissions granted from/to this package 16021 removeUriPermissionsForPackageLocked(ssp, userId, true); 16022 16023 removeTasksByPackageNameLocked(ssp, userId); 16024 if (userId == UserHandle.USER_OWNER) { 16025 mTaskPersister.removeFromPackageCache(ssp); 16026 } 16027 } 16028 } else { 16029 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16030 if (userId == UserHandle.USER_OWNER) { 16031 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16032 } 16033 } 16034 } 16035 break; 16036 } 16037 break; 16038 case Intent.ACTION_PACKAGE_ADDED: 16039 // Special case for adding a package: by default turn on compatibility mode. 16040 Uri data = intent.getData(); 16041 String ssp; 16042 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16043 final boolean replacing = 16044 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16045 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16046 16047 if (replacing) { 16048 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16049 } 16050 if (userId == UserHandle.USER_OWNER) { 16051 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16052 } 16053 } 16054 break; 16055 case Intent.ACTION_TIMEZONE_CHANGED: 16056 // If this is the time zone changed action, queue up a message that will reset 16057 // the timezone of all currently running processes. This message will get 16058 // queued up before the broadcast happens. 16059 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16060 break; 16061 case Intent.ACTION_TIME_CHANGED: 16062 // If the user set the time, let all running processes know. 16063 final int is24Hour = 16064 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16065 : 0; 16066 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16067 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16068 synchronized (stats) { 16069 stats.noteCurrentTimeChangedLocked(); 16070 } 16071 break; 16072 case Intent.ACTION_CLEAR_DNS_CACHE: 16073 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16074 break; 16075 case Proxy.PROXY_CHANGE_ACTION: 16076 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16077 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16078 break; 16079 } 16080 } 16081 16082 // Add to the sticky list if requested. 16083 if (sticky) { 16084 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16085 callingPid, callingUid) 16086 != PackageManager.PERMISSION_GRANTED) { 16087 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16088 + callingPid + ", uid=" + callingUid 16089 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16090 Slog.w(TAG, msg); 16091 throw new SecurityException(msg); 16092 } 16093 if (requiredPermission != null) { 16094 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16095 + " and enforce permission " + requiredPermission); 16096 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16097 } 16098 if (intent.getComponent() != null) { 16099 throw new SecurityException( 16100 "Sticky broadcasts can't target a specific component"); 16101 } 16102 // We use userId directly here, since the "all" target is maintained 16103 // as a separate set of sticky broadcasts. 16104 if (userId != UserHandle.USER_ALL) { 16105 // But first, if this is not a broadcast to all users, then 16106 // make sure it doesn't conflict with an existing broadcast to 16107 // all users. 16108 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16109 UserHandle.USER_ALL); 16110 if (stickies != null) { 16111 ArrayList<Intent> list = stickies.get(intent.getAction()); 16112 if (list != null) { 16113 int N = list.size(); 16114 int i; 16115 for (i=0; i<N; i++) { 16116 if (intent.filterEquals(list.get(i))) { 16117 throw new IllegalArgumentException( 16118 "Sticky broadcast " + intent + " for user " 16119 + userId + " conflicts with existing global broadcast"); 16120 } 16121 } 16122 } 16123 } 16124 } 16125 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16126 if (stickies == null) { 16127 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16128 mStickyBroadcasts.put(userId, stickies); 16129 } 16130 ArrayList<Intent> list = stickies.get(intent.getAction()); 16131 if (list == null) { 16132 list = new ArrayList<Intent>(); 16133 stickies.put(intent.getAction(), list); 16134 } 16135 int N = list.size(); 16136 int i; 16137 for (i=0; i<N; i++) { 16138 if (intent.filterEquals(list.get(i))) { 16139 // This sticky already exists, replace it. 16140 list.set(i, new Intent(intent)); 16141 break; 16142 } 16143 } 16144 if (i >= N) { 16145 list.add(new Intent(intent)); 16146 } 16147 } 16148 16149 int[] users; 16150 if (userId == UserHandle.USER_ALL) { 16151 // Caller wants broadcast to go to all started users. 16152 users = mStartedUserArray; 16153 } else { 16154 // Caller wants broadcast to go to one specific user. 16155 users = new int[] {userId}; 16156 } 16157 16158 // Figure out who all will receive this broadcast. 16159 List receivers = null; 16160 List<BroadcastFilter> registeredReceivers = null; 16161 // Need to resolve the intent to interested receivers... 16162 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16163 == 0) { 16164 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16165 } 16166 if (intent.getComponent() == null) { 16167 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16168 // Query one target user at a time, excluding shell-restricted users 16169 UserManagerService ums = getUserManagerLocked(); 16170 for (int i = 0; i < users.length; i++) { 16171 if (ums.hasUserRestriction( 16172 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16173 continue; 16174 } 16175 List<BroadcastFilter> registeredReceiversForUser = 16176 mReceiverResolver.queryIntent(intent, 16177 resolvedType, false, users[i]); 16178 if (registeredReceivers == null) { 16179 registeredReceivers = registeredReceiversForUser; 16180 } else if (registeredReceiversForUser != null) { 16181 registeredReceivers.addAll(registeredReceiversForUser); 16182 } 16183 } 16184 } else { 16185 registeredReceivers = mReceiverResolver.queryIntent(intent, 16186 resolvedType, false, userId); 16187 } 16188 } 16189 16190 final boolean replacePending = 16191 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16192 16193 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16194 + " replacePending=" + replacePending); 16195 16196 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16197 if (!ordered && NR > 0) { 16198 // If we are not serializing this broadcast, then send the 16199 // registered receivers separately so they don't wait for the 16200 // components to be launched. 16201 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16202 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16203 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16204 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16205 ordered, sticky, false, userId); 16206 if (DEBUG_BROADCAST) Slog.v( 16207 TAG, "Enqueueing parallel broadcast " + r); 16208 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16209 if (!replaced) { 16210 queue.enqueueParallelBroadcastLocked(r); 16211 queue.scheduleBroadcastsLocked(); 16212 } 16213 registeredReceivers = null; 16214 NR = 0; 16215 } 16216 16217 // Merge into one list. 16218 int ir = 0; 16219 if (receivers != null) { 16220 // A special case for PACKAGE_ADDED: do not allow the package 16221 // being added to see this broadcast. This prevents them from 16222 // using this as a back door to get run as soon as they are 16223 // installed. Maybe in the future we want to have a special install 16224 // broadcast or such for apps, but we'd like to deliberately make 16225 // this decision. 16226 String skipPackages[] = null; 16227 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16228 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16229 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16230 Uri data = intent.getData(); 16231 if (data != null) { 16232 String pkgName = data.getSchemeSpecificPart(); 16233 if (pkgName != null) { 16234 skipPackages = new String[] { pkgName }; 16235 } 16236 } 16237 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16238 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16239 } 16240 if (skipPackages != null && (skipPackages.length > 0)) { 16241 for (String skipPackage : skipPackages) { 16242 if (skipPackage != null) { 16243 int NT = receivers.size(); 16244 for (int it=0; it<NT; it++) { 16245 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16246 if (curt.activityInfo.packageName.equals(skipPackage)) { 16247 receivers.remove(it); 16248 it--; 16249 NT--; 16250 } 16251 } 16252 } 16253 } 16254 } 16255 16256 int NT = receivers != null ? receivers.size() : 0; 16257 int it = 0; 16258 ResolveInfo curt = null; 16259 BroadcastFilter curr = null; 16260 while (it < NT && ir < NR) { 16261 if (curt == null) { 16262 curt = (ResolveInfo)receivers.get(it); 16263 } 16264 if (curr == null) { 16265 curr = registeredReceivers.get(ir); 16266 } 16267 if (curr.getPriority() >= curt.priority) { 16268 // Insert this broadcast record into the final list. 16269 receivers.add(it, curr); 16270 ir++; 16271 curr = null; 16272 it++; 16273 NT++; 16274 } else { 16275 // Skip to the next ResolveInfo in the final list. 16276 it++; 16277 curt = null; 16278 } 16279 } 16280 } 16281 while (ir < NR) { 16282 if (receivers == null) { 16283 receivers = new ArrayList(); 16284 } 16285 receivers.add(registeredReceivers.get(ir)); 16286 ir++; 16287 } 16288 16289 if ((receivers != null && receivers.size() > 0) 16290 || resultTo != null) { 16291 BroadcastQueue queue = broadcastQueueForIntent(intent); 16292 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16293 callerPackage, callingPid, callingUid, resolvedType, 16294 requiredPermission, appOp, receivers, resultTo, resultCode, 16295 resultData, map, ordered, sticky, false, userId); 16296 if (DEBUG_BROADCAST) Slog.v( 16297 TAG, "Enqueueing ordered broadcast " + r 16298 + ": prev had " + queue.mOrderedBroadcasts.size()); 16299 if (DEBUG_BROADCAST) { 16300 int seq = r.intent.getIntExtra("seq", -1); 16301 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16302 } 16303 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16304 if (!replaced) { 16305 queue.enqueueOrderedBroadcastLocked(r); 16306 queue.scheduleBroadcastsLocked(); 16307 } 16308 } 16309 16310 return ActivityManager.BROADCAST_SUCCESS; 16311 } 16312 16313 final Intent verifyBroadcastLocked(Intent intent) { 16314 // Refuse possible leaked file descriptors 16315 if (intent != null && intent.hasFileDescriptors() == true) { 16316 throw new IllegalArgumentException("File descriptors passed in Intent"); 16317 } 16318 16319 int flags = intent.getFlags(); 16320 16321 if (!mProcessesReady) { 16322 // if the caller really truly claims to know what they're doing, go 16323 // ahead and allow the broadcast without launching any receivers 16324 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16325 intent = new Intent(intent); 16326 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16327 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16328 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16329 + " before boot completion"); 16330 throw new IllegalStateException("Cannot broadcast before boot completed"); 16331 } 16332 } 16333 16334 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16335 throw new IllegalArgumentException( 16336 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16337 } 16338 16339 return intent; 16340 } 16341 16342 public final int broadcastIntent(IApplicationThread caller, 16343 Intent intent, String resolvedType, IIntentReceiver resultTo, 16344 int resultCode, String resultData, Bundle map, 16345 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16346 enforceNotIsolatedCaller("broadcastIntent"); 16347 synchronized(this) { 16348 intent = verifyBroadcastLocked(intent); 16349 16350 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16351 final int callingPid = Binder.getCallingPid(); 16352 final int callingUid = Binder.getCallingUid(); 16353 final long origId = Binder.clearCallingIdentity(); 16354 int res = broadcastIntentLocked(callerApp, 16355 callerApp != null ? callerApp.info.packageName : null, 16356 intent, resolvedType, resultTo, 16357 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16358 callingPid, callingUid, userId); 16359 Binder.restoreCallingIdentity(origId); 16360 return res; 16361 } 16362 } 16363 16364 int broadcastIntentInPackage(String packageName, int uid, 16365 Intent intent, String resolvedType, IIntentReceiver resultTo, 16366 int resultCode, String resultData, Bundle map, 16367 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16368 synchronized(this) { 16369 intent = verifyBroadcastLocked(intent); 16370 16371 final long origId = Binder.clearCallingIdentity(); 16372 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16373 resultTo, resultCode, resultData, map, requiredPermission, 16374 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16375 Binder.restoreCallingIdentity(origId); 16376 return res; 16377 } 16378 } 16379 16380 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16381 // Refuse possible leaked file descriptors 16382 if (intent != null && intent.hasFileDescriptors() == true) { 16383 throw new IllegalArgumentException("File descriptors passed in Intent"); 16384 } 16385 16386 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16387 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16388 16389 synchronized(this) { 16390 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16391 != PackageManager.PERMISSION_GRANTED) { 16392 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16393 + Binder.getCallingPid() 16394 + ", uid=" + Binder.getCallingUid() 16395 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16396 Slog.w(TAG, msg); 16397 throw new SecurityException(msg); 16398 } 16399 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16400 if (stickies != null) { 16401 ArrayList<Intent> list = stickies.get(intent.getAction()); 16402 if (list != null) { 16403 int N = list.size(); 16404 int i; 16405 for (i=0; i<N; i++) { 16406 if (intent.filterEquals(list.get(i))) { 16407 list.remove(i); 16408 break; 16409 } 16410 } 16411 if (list.size() <= 0) { 16412 stickies.remove(intent.getAction()); 16413 } 16414 } 16415 if (stickies.size() <= 0) { 16416 mStickyBroadcasts.remove(userId); 16417 } 16418 } 16419 } 16420 } 16421 16422 void backgroundServicesFinishedLocked(int userId) { 16423 for (BroadcastQueue queue : mBroadcastQueues) { 16424 queue.backgroundServicesFinishedLocked(userId); 16425 } 16426 } 16427 16428 public void finishReceiver(IBinder who, int resultCode, String resultData, 16429 Bundle resultExtras, boolean resultAbort, int flags) { 16430 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16431 16432 // Refuse possible leaked file descriptors 16433 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16434 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16435 } 16436 16437 final long origId = Binder.clearCallingIdentity(); 16438 try { 16439 boolean doNext = false; 16440 BroadcastRecord r; 16441 16442 synchronized(this) { 16443 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 16444 ? mFgBroadcastQueue : mBgBroadcastQueue; 16445 r = queue.getMatchingOrderedReceiver(who); 16446 if (r != null) { 16447 doNext = r.queue.finishReceiverLocked(r, resultCode, 16448 resultData, resultExtras, resultAbort, true); 16449 } 16450 } 16451 16452 if (doNext) { 16453 r.queue.processNextBroadcast(false); 16454 } 16455 trimApplications(); 16456 } finally { 16457 Binder.restoreCallingIdentity(origId); 16458 } 16459 } 16460 16461 // ========================================================= 16462 // INSTRUMENTATION 16463 // ========================================================= 16464 16465 public boolean startInstrumentation(ComponentName className, 16466 String profileFile, int flags, Bundle arguments, 16467 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16468 int userId, String abiOverride) { 16469 enforceNotIsolatedCaller("startInstrumentation"); 16470 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16471 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16472 // Refuse possible leaked file descriptors 16473 if (arguments != null && arguments.hasFileDescriptors()) { 16474 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16475 } 16476 16477 synchronized(this) { 16478 InstrumentationInfo ii = null; 16479 ApplicationInfo ai = null; 16480 try { 16481 ii = mContext.getPackageManager().getInstrumentationInfo( 16482 className, STOCK_PM_FLAGS); 16483 ai = AppGlobals.getPackageManager().getApplicationInfo( 16484 ii.targetPackage, STOCK_PM_FLAGS, userId); 16485 } catch (PackageManager.NameNotFoundException e) { 16486 } catch (RemoteException e) { 16487 } 16488 if (ii == null) { 16489 reportStartInstrumentationFailure(watcher, className, 16490 "Unable to find instrumentation info for: " + className); 16491 return false; 16492 } 16493 if (ai == null) { 16494 reportStartInstrumentationFailure(watcher, className, 16495 "Unable to find instrumentation target package: " + ii.targetPackage); 16496 return false; 16497 } 16498 16499 int match = mContext.getPackageManager().checkSignatures( 16500 ii.targetPackage, ii.packageName); 16501 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16502 String msg = "Permission Denial: starting instrumentation " 16503 + className + " from pid=" 16504 + Binder.getCallingPid() 16505 + ", uid=" + Binder.getCallingPid() 16506 + " not allowed because package " + ii.packageName 16507 + " does not have a signature matching the target " 16508 + ii.targetPackage; 16509 reportStartInstrumentationFailure(watcher, className, msg); 16510 throw new SecurityException(msg); 16511 } 16512 16513 final long origId = Binder.clearCallingIdentity(); 16514 // Instrumentation can kill and relaunch even persistent processes 16515 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16516 "start instr"); 16517 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16518 app.instrumentationClass = className; 16519 app.instrumentationInfo = ai; 16520 app.instrumentationProfileFile = profileFile; 16521 app.instrumentationArguments = arguments; 16522 app.instrumentationWatcher = watcher; 16523 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16524 app.instrumentationResultClass = className; 16525 Binder.restoreCallingIdentity(origId); 16526 } 16527 16528 return true; 16529 } 16530 16531 /** 16532 * Report errors that occur while attempting to start Instrumentation. Always writes the 16533 * error to the logs, but if somebody is watching, send the report there too. This enables 16534 * the "am" command to report errors with more information. 16535 * 16536 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16537 * @param cn The component name of the instrumentation. 16538 * @param report The error report. 16539 */ 16540 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16541 ComponentName cn, String report) { 16542 Slog.w(TAG, report); 16543 try { 16544 if (watcher != null) { 16545 Bundle results = new Bundle(); 16546 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16547 results.putString("Error", report); 16548 watcher.instrumentationStatus(cn, -1, results); 16549 } 16550 } catch (RemoteException e) { 16551 Slog.w(TAG, e); 16552 } 16553 } 16554 16555 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16556 if (app.instrumentationWatcher != null) { 16557 try { 16558 // NOTE: IInstrumentationWatcher *must* be oneway here 16559 app.instrumentationWatcher.instrumentationFinished( 16560 app.instrumentationClass, 16561 resultCode, 16562 results); 16563 } catch (RemoteException e) { 16564 } 16565 } 16566 if (app.instrumentationUiAutomationConnection != null) { 16567 try { 16568 app.instrumentationUiAutomationConnection.shutdown(); 16569 } catch (RemoteException re) { 16570 /* ignore */ 16571 } 16572 // Only a UiAutomation can set this flag and now that 16573 // it is finished we make sure it is reset to its default. 16574 mUserIsMonkey = false; 16575 } 16576 app.instrumentationWatcher = null; 16577 app.instrumentationUiAutomationConnection = null; 16578 app.instrumentationClass = null; 16579 app.instrumentationInfo = null; 16580 app.instrumentationProfileFile = null; 16581 app.instrumentationArguments = null; 16582 16583 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16584 "finished inst"); 16585 } 16586 16587 public void finishInstrumentation(IApplicationThread target, 16588 int resultCode, Bundle results) { 16589 int userId = UserHandle.getCallingUserId(); 16590 // Refuse possible leaked file descriptors 16591 if (results != null && results.hasFileDescriptors()) { 16592 throw new IllegalArgumentException("File descriptors passed in Intent"); 16593 } 16594 16595 synchronized(this) { 16596 ProcessRecord app = getRecordForAppLocked(target); 16597 if (app == null) { 16598 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16599 return; 16600 } 16601 final long origId = Binder.clearCallingIdentity(); 16602 finishInstrumentationLocked(app, resultCode, results); 16603 Binder.restoreCallingIdentity(origId); 16604 } 16605 } 16606 16607 // ========================================================= 16608 // CONFIGURATION 16609 // ========================================================= 16610 16611 public ConfigurationInfo getDeviceConfigurationInfo() { 16612 ConfigurationInfo config = new ConfigurationInfo(); 16613 synchronized (this) { 16614 config.reqTouchScreen = mConfiguration.touchscreen; 16615 config.reqKeyboardType = mConfiguration.keyboard; 16616 config.reqNavigation = mConfiguration.navigation; 16617 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16618 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16619 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16620 } 16621 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16622 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16623 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16624 } 16625 config.reqGlEsVersion = GL_ES_VERSION; 16626 } 16627 return config; 16628 } 16629 16630 ActivityStack getFocusedStack() { 16631 return mStackSupervisor.getFocusedStack(); 16632 } 16633 16634 public Configuration getConfiguration() { 16635 Configuration ci; 16636 synchronized(this) { 16637 ci = new Configuration(mConfiguration); 16638 ci.userSetLocale = false; 16639 } 16640 return ci; 16641 } 16642 16643 public void updatePersistentConfiguration(Configuration values) { 16644 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16645 "updateConfiguration()"); 16646 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16647 "updateConfiguration()"); 16648 if (values == null) { 16649 throw new NullPointerException("Configuration must not be null"); 16650 } 16651 16652 synchronized(this) { 16653 final long origId = Binder.clearCallingIdentity(); 16654 updateConfigurationLocked(values, null, true, false); 16655 Binder.restoreCallingIdentity(origId); 16656 } 16657 } 16658 16659 public void updateConfiguration(Configuration values) { 16660 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16661 "updateConfiguration()"); 16662 16663 synchronized(this) { 16664 if (values == null && mWindowManager != null) { 16665 // sentinel: fetch the current configuration from the window manager 16666 values = mWindowManager.computeNewConfiguration(); 16667 } 16668 16669 if (mWindowManager != null) { 16670 mProcessList.applyDisplaySize(mWindowManager); 16671 } 16672 16673 final long origId = Binder.clearCallingIdentity(); 16674 if (values != null) { 16675 Settings.System.clearConfiguration(values); 16676 } 16677 updateConfigurationLocked(values, null, false, false); 16678 Binder.restoreCallingIdentity(origId); 16679 } 16680 } 16681 16682 /** 16683 * Do either or both things: (1) change the current configuration, and (2) 16684 * make sure the given activity is running with the (now) current 16685 * configuration. Returns true if the activity has been left running, or 16686 * false if <var>starting</var> is being destroyed to match the new 16687 * configuration. 16688 * @param persistent TODO 16689 */ 16690 boolean updateConfigurationLocked(Configuration values, 16691 ActivityRecord starting, boolean persistent, boolean initLocale) { 16692 int changes = 0; 16693 16694 if (values != null) { 16695 Configuration newConfig = new Configuration(mConfiguration); 16696 changes = newConfig.updateFrom(values); 16697 if (changes != 0) { 16698 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16699 Slog.i(TAG, "Updating configuration to: " + values); 16700 } 16701 16702 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16703 16704 if (!initLocale && values.locale != null && values.userSetLocale) { 16705 final String languageTag = values.locale.toLanguageTag(); 16706 SystemProperties.set("persist.sys.locale", languageTag); 16707 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, 16708 values.locale)); 16709 } 16710 16711 mConfigurationSeq++; 16712 if (mConfigurationSeq <= 0) { 16713 mConfigurationSeq = 1; 16714 } 16715 newConfig.seq = mConfigurationSeq; 16716 mConfiguration = newConfig; 16717 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16718 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16719 //mUsageStatsService.noteStartConfig(newConfig); 16720 16721 final Configuration configCopy = new Configuration(mConfiguration); 16722 16723 // TODO: If our config changes, should we auto dismiss any currently 16724 // showing dialogs? 16725 mShowDialogs = shouldShowDialogs(newConfig); 16726 16727 AttributeCache ac = AttributeCache.instance(); 16728 if (ac != null) { 16729 ac.updateConfiguration(configCopy); 16730 } 16731 16732 // Make sure all resources in our process are updated 16733 // right now, so that anyone who is going to retrieve 16734 // resource values after we return will be sure to get 16735 // the new ones. This is especially important during 16736 // boot, where the first config change needs to guarantee 16737 // all resources have that config before following boot 16738 // code is executed. 16739 mSystemThread.applyConfigurationToResources(configCopy); 16740 16741 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16742 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16743 msg.obj = new Configuration(configCopy); 16744 mHandler.sendMessage(msg); 16745 } 16746 16747 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16748 ProcessRecord app = mLruProcesses.get(i); 16749 try { 16750 if (app.thread != null) { 16751 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16752 + app.processName + " new config " + mConfiguration); 16753 app.thread.scheduleConfigurationChanged(configCopy); 16754 } 16755 } catch (Exception e) { 16756 } 16757 } 16758 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16759 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16760 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16761 | Intent.FLAG_RECEIVER_FOREGROUND); 16762 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16763 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16764 Process.SYSTEM_UID, UserHandle.USER_ALL); 16765 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16766 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16767 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16768 broadcastIntentLocked(null, null, intent, 16769 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16770 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16771 } 16772 } 16773 } 16774 16775 boolean kept = true; 16776 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16777 // mainStack is null during startup. 16778 if (mainStack != null) { 16779 if (changes != 0 && starting == null) { 16780 // If the configuration changed, and the caller is not already 16781 // in the process of starting an activity, then find the top 16782 // activity to check if its configuration needs to change. 16783 starting = mainStack.topRunningActivityLocked(null); 16784 } 16785 16786 if (starting != null) { 16787 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16788 // And we need to make sure at this point that all other activities 16789 // are made visible with the correct configuration. 16790 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16791 } 16792 } 16793 16794 if (values != null && mWindowManager != null) { 16795 mWindowManager.setNewConfiguration(mConfiguration); 16796 } 16797 16798 return kept; 16799 } 16800 16801 /** 16802 * Decide based on the configuration whether we should shouw the ANR, 16803 * crash, etc dialogs. The idea is that if there is no affordnace to 16804 * press the on-screen buttons, we shouldn't show the dialog. 16805 * 16806 * A thought: SystemUI might also want to get told about this, the Power 16807 * dialog / global actions also might want different behaviors. 16808 */ 16809 private static final boolean shouldShowDialogs(Configuration config) { 16810 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16811 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16812 } 16813 16814 @Override 16815 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16816 synchronized (this) { 16817 ActivityRecord srec = ActivityRecord.forToken(token); 16818 if (srec.task != null && srec.task.stack != null) { 16819 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16820 } 16821 } 16822 return false; 16823 } 16824 16825 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16826 Intent resultData) { 16827 16828 synchronized (this) { 16829 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16830 if (stack != null) { 16831 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16832 } 16833 return false; 16834 } 16835 } 16836 16837 public int getLaunchedFromUid(IBinder activityToken) { 16838 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16839 if (srec == null) { 16840 return -1; 16841 } 16842 return srec.launchedFromUid; 16843 } 16844 16845 public String getLaunchedFromPackage(IBinder activityToken) { 16846 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16847 if (srec == null) { 16848 return null; 16849 } 16850 return srec.launchedFromPackage; 16851 } 16852 16853 // ========================================================= 16854 // LIFETIME MANAGEMENT 16855 // ========================================================= 16856 16857 // Returns which broadcast queue the app is the current [or imminent] receiver 16858 // on, or 'null' if the app is not an active broadcast recipient. 16859 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16860 BroadcastRecord r = app.curReceiver; 16861 if (r != null) { 16862 return r.queue; 16863 } 16864 16865 // It's not the current receiver, but it might be starting up to become one 16866 synchronized (this) { 16867 for (BroadcastQueue queue : mBroadcastQueues) { 16868 r = queue.mPendingBroadcast; 16869 if (r != null && r.curApp == app) { 16870 // found it; report which queue it's in 16871 return queue; 16872 } 16873 } 16874 } 16875 16876 return null; 16877 } 16878 16879 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16880 ComponentName targetComponent, String targetProcess) { 16881 if (!mTrackingAssociations) { 16882 return null; 16883 } 16884 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16885 = mAssociations.get(targetUid); 16886 if (components == null) { 16887 components = new ArrayMap<>(); 16888 mAssociations.put(targetUid, components); 16889 } 16890 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16891 if (sourceUids == null) { 16892 sourceUids = new SparseArray<>(); 16893 components.put(targetComponent, sourceUids); 16894 } 16895 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16896 if (sourceProcesses == null) { 16897 sourceProcesses = new ArrayMap<>(); 16898 sourceUids.put(sourceUid, sourceProcesses); 16899 } 16900 Association ass = sourceProcesses.get(sourceProcess); 16901 if (ass == null) { 16902 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16903 targetProcess); 16904 sourceProcesses.put(sourceProcess, ass); 16905 } 16906 ass.mCount++; 16907 ass.mNesting++; 16908 if (ass.mNesting == 1) { 16909 ass.mStartTime = SystemClock.uptimeMillis(); 16910 } 16911 return ass; 16912 } 16913 16914 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16915 ComponentName targetComponent) { 16916 if (!mTrackingAssociations) { 16917 return; 16918 } 16919 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16920 = mAssociations.get(targetUid); 16921 if (components == null) { 16922 return; 16923 } 16924 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16925 if (sourceUids == null) { 16926 return; 16927 } 16928 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16929 if (sourceProcesses == null) { 16930 return; 16931 } 16932 Association ass = sourceProcesses.get(sourceProcess); 16933 if (ass == null || ass.mNesting <= 0) { 16934 return; 16935 } 16936 ass.mNesting--; 16937 if (ass.mNesting == 0) { 16938 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16939 } 16940 } 16941 16942 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16943 boolean doingAll, long now) { 16944 if (mAdjSeq == app.adjSeq) { 16945 // This adjustment has already been computed. 16946 return app.curRawAdj; 16947 } 16948 16949 if (app.thread == null) { 16950 app.adjSeq = mAdjSeq; 16951 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16952 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16953 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16954 } 16955 16956 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16957 app.adjSource = null; 16958 app.adjTarget = null; 16959 app.empty = false; 16960 app.cached = false; 16961 16962 final int activitiesSize = app.activities.size(); 16963 16964 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16965 // The max adjustment doesn't allow this app to be anything 16966 // below foreground, so it is not worth doing work for it. 16967 app.adjType = "fixed"; 16968 app.adjSeq = mAdjSeq; 16969 app.curRawAdj = app.maxAdj; 16970 app.foregroundActivities = false; 16971 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16972 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16973 // System processes can do UI, and when they do we want to have 16974 // them trim their memory after the user leaves the UI. To 16975 // facilitate this, here we need to determine whether or not it 16976 // is currently showing UI. 16977 app.systemNoUi = true; 16978 if (app == TOP_APP) { 16979 app.systemNoUi = false; 16980 } else if (activitiesSize > 0) { 16981 for (int j = 0; j < activitiesSize; j++) { 16982 final ActivityRecord r = app.activities.get(j); 16983 if (r.visible) { 16984 app.systemNoUi = false; 16985 } 16986 } 16987 } 16988 if (!app.systemNoUi) { 16989 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16990 } 16991 return (app.curAdj=app.maxAdj); 16992 } 16993 16994 app.systemNoUi = false; 16995 16996 // Determine the importance of the process, starting with most 16997 // important to least, and assign an appropriate OOM adjustment. 16998 int adj; 16999 int schedGroup; 17000 int procState; 17001 boolean foregroundActivities = false; 17002 BroadcastQueue queue; 17003 if (app == TOP_APP) { 17004 // The last app on the list is the foreground app. 17005 adj = ProcessList.FOREGROUND_APP_ADJ; 17006 schedGroup = Process.THREAD_GROUP_DEFAULT; 17007 app.adjType = "top-activity"; 17008 foregroundActivities = true; 17009 procState = ActivityManager.PROCESS_STATE_TOP; 17010 } else if (app.instrumentationClass != null) { 17011 // Don't want to kill running instrumentation. 17012 adj = ProcessList.FOREGROUND_APP_ADJ; 17013 schedGroup = Process.THREAD_GROUP_DEFAULT; 17014 app.adjType = "instrumentation"; 17015 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17016 } else if ((queue = isReceivingBroadcast(app)) != null) { 17017 // An app that is currently receiving a broadcast also 17018 // counts as being in the foreground for OOM killer purposes. 17019 // It's placed in a sched group based on the nature of the 17020 // broadcast as reflected by which queue it's active in. 17021 adj = ProcessList.FOREGROUND_APP_ADJ; 17022 schedGroup = (queue == mFgBroadcastQueue) 17023 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17024 app.adjType = "broadcast"; 17025 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17026 } else if (app.executingServices.size() > 0) { 17027 // An app that is currently executing a service callback also 17028 // counts as being in the foreground. 17029 adj = ProcessList.FOREGROUND_APP_ADJ; 17030 schedGroup = app.execServicesFg ? 17031 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17032 app.adjType = "exec-service"; 17033 procState = ActivityManager.PROCESS_STATE_SERVICE; 17034 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17035 } else { 17036 // As far as we know the process is empty. We may change our mind later. 17037 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17038 // At this point we don't actually know the adjustment. Use the cached adj 17039 // value that the caller wants us to. 17040 adj = cachedAdj; 17041 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17042 app.cached = true; 17043 app.empty = true; 17044 app.adjType = "cch-empty"; 17045 } 17046 17047 // Examine all activities if not already foreground. 17048 if (!foregroundActivities && activitiesSize > 0) { 17049 for (int j = 0; j < activitiesSize; j++) { 17050 final ActivityRecord r = app.activities.get(j); 17051 if (r.app != app) { 17052 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17053 + app + "?!?"); 17054 continue; 17055 } 17056 if (r.visible) { 17057 // App has a visible activity; only upgrade adjustment. 17058 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17059 adj = ProcessList.VISIBLE_APP_ADJ; 17060 app.adjType = "visible"; 17061 } 17062 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17063 procState = ActivityManager.PROCESS_STATE_TOP; 17064 } 17065 schedGroup = Process.THREAD_GROUP_DEFAULT; 17066 app.cached = false; 17067 app.empty = false; 17068 foregroundActivities = true; 17069 break; 17070 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17071 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17072 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17073 app.adjType = "pausing"; 17074 } 17075 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17076 procState = ActivityManager.PROCESS_STATE_TOP; 17077 } 17078 schedGroup = Process.THREAD_GROUP_DEFAULT; 17079 app.cached = false; 17080 app.empty = false; 17081 foregroundActivities = true; 17082 } else if (r.state == ActivityState.STOPPING) { 17083 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17084 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17085 app.adjType = "stopping"; 17086 } 17087 // For the process state, we will at this point consider the 17088 // process to be cached. It will be cached either as an activity 17089 // or empty depending on whether the activity is finishing. We do 17090 // this so that we can treat the process as cached for purposes of 17091 // memory trimming (determing current memory level, trim command to 17092 // send to process) since there can be an arbitrary number of stopping 17093 // processes and they should soon all go into the cached state. 17094 if (!r.finishing) { 17095 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17096 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17097 } 17098 } 17099 app.cached = false; 17100 app.empty = false; 17101 foregroundActivities = true; 17102 } else { 17103 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17104 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17105 app.adjType = "cch-act"; 17106 } 17107 } 17108 } 17109 } 17110 17111 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17112 if (app.foregroundServices) { 17113 // The user is aware of this app, so make it visible. 17114 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17115 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17116 app.cached = false; 17117 app.adjType = "fg-service"; 17118 schedGroup = Process.THREAD_GROUP_DEFAULT; 17119 } else if (app.forcingToForeground != null) { 17120 // The user is aware of this app, so make it visible. 17121 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17122 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17123 app.cached = false; 17124 app.adjType = "force-fg"; 17125 app.adjSource = app.forcingToForeground; 17126 schedGroup = Process.THREAD_GROUP_DEFAULT; 17127 } 17128 } 17129 17130 if (app == mHeavyWeightProcess) { 17131 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17132 // We don't want to kill the current heavy-weight process. 17133 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17134 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17135 app.cached = false; 17136 app.adjType = "heavy"; 17137 } 17138 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17139 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17140 } 17141 } 17142 17143 if (app == mHomeProcess) { 17144 if (adj > ProcessList.HOME_APP_ADJ) { 17145 // This process is hosting what we currently consider to be the 17146 // home app, so we don't want to let it go into the background. 17147 adj = ProcessList.HOME_APP_ADJ; 17148 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17149 app.cached = false; 17150 app.adjType = "home"; 17151 } 17152 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17153 procState = ActivityManager.PROCESS_STATE_HOME; 17154 } 17155 } 17156 17157 if (app == mPreviousProcess && app.activities.size() > 0) { 17158 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17159 // This was the previous process that showed UI to the user. 17160 // We want to try to keep it around more aggressively, to give 17161 // a good experience around switching between two apps. 17162 adj = ProcessList.PREVIOUS_APP_ADJ; 17163 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17164 app.cached = false; 17165 app.adjType = "previous"; 17166 } 17167 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17168 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17169 } 17170 } 17171 17172 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17173 + " reason=" + app.adjType); 17174 17175 // By default, we use the computed adjustment. It may be changed if 17176 // there are applications dependent on our services or providers, but 17177 // this gives us a baseline and makes sure we don't get into an 17178 // infinite recursion. 17179 app.adjSeq = mAdjSeq; 17180 app.curRawAdj = adj; 17181 app.hasStartedServices = false; 17182 17183 if (mBackupTarget != null && app == mBackupTarget.app) { 17184 // If possible we want to avoid killing apps while they're being backed up 17185 if (adj > ProcessList.BACKUP_APP_ADJ) { 17186 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17187 adj = ProcessList.BACKUP_APP_ADJ; 17188 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17189 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17190 } 17191 app.adjType = "backup"; 17192 app.cached = false; 17193 } 17194 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17195 procState = ActivityManager.PROCESS_STATE_BACKUP; 17196 } 17197 } 17198 17199 boolean mayBeTop = false; 17200 17201 for (int is = app.services.size()-1; 17202 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17203 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17204 || procState > ActivityManager.PROCESS_STATE_TOP); 17205 is--) { 17206 ServiceRecord s = app.services.valueAt(is); 17207 if (s.startRequested) { 17208 app.hasStartedServices = true; 17209 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17210 procState = ActivityManager.PROCESS_STATE_SERVICE; 17211 } 17212 if (app.hasShownUi && app != mHomeProcess) { 17213 // If this process has shown some UI, let it immediately 17214 // go to the LRU list because it may be pretty heavy with 17215 // UI stuff. We'll tag it with a label just to help 17216 // debug and understand what is going on. 17217 if (adj > ProcessList.SERVICE_ADJ) { 17218 app.adjType = "cch-started-ui-services"; 17219 } 17220 } else { 17221 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17222 // This service has seen some activity within 17223 // recent memory, so we will keep its process ahead 17224 // of the background processes. 17225 if (adj > ProcessList.SERVICE_ADJ) { 17226 adj = ProcessList.SERVICE_ADJ; 17227 app.adjType = "started-services"; 17228 app.cached = false; 17229 } 17230 } 17231 // If we have let the service slide into the background 17232 // state, still have some text describing what it is doing 17233 // even though the service no longer has an impact. 17234 if (adj > ProcessList.SERVICE_ADJ) { 17235 app.adjType = "cch-started-services"; 17236 } 17237 } 17238 } 17239 for (int conni = s.connections.size()-1; 17240 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17241 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17242 || procState > ActivityManager.PROCESS_STATE_TOP); 17243 conni--) { 17244 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17245 for (int i = 0; 17246 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17247 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17248 || procState > ActivityManager.PROCESS_STATE_TOP); 17249 i++) { 17250 // XXX should compute this based on the max of 17251 // all connected clients. 17252 ConnectionRecord cr = clist.get(i); 17253 if (cr.binding.client == app) { 17254 // Binding to ourself is not interesting. 17255 continue; 17256 } 17257 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17258 ProcessRecord client = cr.binding.client; 17259 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17260 TOP_APP, doingAll, now); 17261 int clientProcState = client.curProcState; 17262 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17263 // If the other app is cached for any reason, for purposes here 17264 // we are going to consider it empty. The specific cached state 17265 // doesn't propagate except under certain conditions. 17266 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17267 } 17268 String adjType = null; 17269 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17270 // Not doing bind OOM management, so treat 17271 // this guy more like a started service. 17272 if (app.hasShownUi && app != mHomeProcess) { 17273 // If this process has shown some UI, let it immediately 17274 // go to the LRU list because it may be pretty heavy with 17275 // UI stuff. We'll tag it with a label just to help 17276 // debug and understand what is going on. 17277 if (adj > clientAdj) { 17278 adjType = "cch-bound-ui-services"; 17279 } 17280 app.cached = false; 17281 clientAdj = adj; 17282 clientProcState = procState; 17283 } else { 17284 if (now >= (s.lastActivity 17285 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17286 // This service has not seen activity within 17287 // recent memory, so allow it to drop to the 17288 // LRU list if there is no other reason to keep 17289 // it around. We'll also tag it with a label just 17290 // to help debug and undertand what is going on. 17291 if (adj > clientAdj) { 17292 adjType = "cch-bound-services"; 17293 } 17294 clientAdj = adj; 17295 } 17296 } 17297 } 17298 if (adj > clientAdj) { 17299 // If this process has recently shown UI, and 17300 // the process that is binding to it is less 17301 // important than being visible, then we don't 17302 // care about the binding as much as we care 17303 // about letting this process get into the LRU 17304 // list to be killed and restarted if needed for 17305 // memory. 17306 if (app.hasShownUi && app != mHomeProcess 17307 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17308 adjType = "cch-bound-ui-services"; 17309 } else { 17310 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17311 |Context.BIND_IMPORTANT)) != 0) { 17312 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17313 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17314 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17315 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17316 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17317 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17318 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17319 adj = clientAdj; 17320 } else { 17321 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17322 adj = ProcessList.VISIBLE_APP_ADJ; 17323 } 17324 } 17325 if (!client.cached) { 17326 app.cached = false; 17327 } 17328 adjType = "service"; 17329 } 17330 } 17331 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17332 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17333 schedGroup = Process.THREAD_GROUP_DEFAULT; 17334 } 17335 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17336 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17337 // Special handling of clients who are in the top state. 17338 // We *may* want to consider this process to be in the 17339 // top state as well, but only if there is not another 17340 // reason for it to be running. Being on the top is a 17341 // special state, meaning you are specifically running 17342 // for the current top app. If the process is already 17343 // running in the background for some other reason, it 17344 // is more important to continue considering it to be 17345 // in the background state. 17346 mayBeTop = true; 17347 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17348 } else { 17349 // Special handling for above-top states (persistent 17350 // processes). These should not bring the current process 17351 // into the top state, since they are not on top. Instead 17352 // give them the best state after that. 17353 clientProcState = 17354 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17355 } 17356 } 17357 } else { 17358 if (clientProcState < 17359 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17360 clientProcState = 17361 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17362 } 17363 } 17364 if (procState > clientProcState) { 17365 procState = clientProcState; 17366 } 17367 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17368 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17369 app.pendingUiClean = true; 17370 } 17371 if (adjType != null) { 17372 app.adjType = adjType; 17373 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17374 .REASON_SERVICE_IN_USE; 17375 app.adjSource = cr.binding.client; 17376 app.adjSourceProcState = clientProcState; 17377 app.adjTarget = s.name; 17378 } 17379 } 17380 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17381 app.treatLikeActivity = true; 17382 } 17383 final ActivityRecord a = cr.activity; 17384 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17385 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17386 (a.visible || a.state == ActivityState.RESUMED 17387 || a.state == ActivityState.PAUSING)) { 17388 adj = ProcessList.FOREGROUND_APP_ADJ; 17389 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17390 schedGroup = Process.THREAD_GROUP_DEFAULT; 17391 } 17392 app.cached = false; 17393 app.adjType = "service"; 17394 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17395 .REASON_SERVICE_IN_USE; 17396 app.adjSource = a; 17397 app.adjSourceProcState = procState; 17398 app.adjTarget = s.name; 17399 } 17400 } 17401 } 17402 } 17403 } 17404 17405 for (int provi = app.pubProviders.size()-1; 17406 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17407 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17408 || procState > ActivityManager.PROCESS_STATE_TOP); 17409 provi--) { 17410 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17411 for (int i = cpr.connections.size()-1; 17412 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17413 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17414 || procState > ActivityManager.PROCESS_STATE_TOP); 17415 i--) { 17416 ContentProviderConnection conn = cpr.connections.get(i); 17417 ProcessRecord client = conn.client; 17418 if (client == app) { 17419 // Being our own client is not interesting. 17420 continue; 17421 } 17422 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17423 int clientProcState = client.curProcState; 17424 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17425 // If the other app is cached for any reason, for purposes here 17426 // we are going to consider it empty. 17427 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17428 } 17429 if (adj > clientAdj) { 17430 if (app.hasShownUi && app != mHomeProcess 17431 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17432 app.adjType = "cch-ui-provider"; 17433 } else { 17434 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17435 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17436 app.adjType = "provider"; 17437 } 17438 app.cached &= client.cached; 17439 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17440 .REASON_PROVIDER_IN_USE; 17441 app.adjSource = client; 17442 app.adjSourceProcState = clientProcState; 17443 app.adjTarget = cpr.name; 17444 } 17445 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17446 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17447 // Special handling of clients who are in the top state. 17448 // We *may* want to consider this process to be in the 17449 // top state as well, but only if there is not another 17450 // reason for it to be running. Being on the top is a 17451 // special state, meaning you are specifically running 17452 // for the current top app. If the process is already 17453 // running in the background for some other reason, it 17454 // is more important to continue considering it to be 17455 // in the background state. 17456 mayBeTop = true; 17457 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17458 } else { 17459 // Special handling for above-top states (persistent 17460 // processes). These should not bring the current process 17461 // into the top state, since they are not on top. Instead 17462 // give them the best state after that. 17463 clientProcState = 17464 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17465 } 17466 } 17467 if (procState > clientProcState) { 17468 procState = clientProcState; 17469 } 17470 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17471 schedGroup = Process.THREAD_GROUP_DEFAULT; 17472 } 17473 } 17474 // If the provider has external (non-framework) process 17475 // dependencies, ensure that its adjustment is at least 17476 // FOREGROUND_APP_ADJ. 17477 if (cpr.hasExternalProcessHandles()) { 17478 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17479 adj = ProcessList.FOREGROUND_APP_ADJ; 17480 schedGroup = Process.THREAD_GROUP_DEFAULT; 17481 app.cached = false; 17482 app.adjType = "provider"; 17483 app.adjTarget = cpr.name; 17484 } 17485 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17486 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17487 } 17488 } 17489 } 17490 17491 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17492 // A client of one of our services or providers is in the top state. We 17493 // *may* want to be in the top state, but not if we are already running in 17494 // the background for some other reason. For the decision here, we are going 17495 // to pick out a few specific states that we want to remain in when a client 17496 // is top (states that tend to be longer-term) and otherwise allow it to go 17497 // to the top state. 17498 switch (procState) { 17499 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17500 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17501 case ActivityManager.PROCESS_STATE_SERVICE: 17502 // These all are longer-term states, so pull them up to the top 17503 // of the background states, but not all the way to the top state. 17504 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17505 break; 17506 default: 17507 // Otherwise, top is a better choice, so take it. 17508 procState = ActivityManager.PROCESS_STATE_TOP; 17509 break; 17510 } 17511 } 17512 17513 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17514 if (app.hasClientActivities) { 17515 // This is a cached process, but with client activities. Mark it so. 17516 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17517 app.adjType = "cch-client-act"; 17518 } else if (app.treatLikeActivity) { 17519 // This is a cached process, but somebody wants us to treat it like it has 17520 // an activity, okay! 17521 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17522 app.adjType = "cch-as-act"; 17523 } 17524 } 17525 17526 if (adj == ProcessList.SERVICE_ADJ) { 17527 if (doingAll) { 17528 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17529 mNewNumServiceProcs++; 17530 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17531 if (!app.serviceb) { 17532 // This service isn't far enough down on the LRU list to 17533 // normally be a B service, but if we are low on RAM and it 17534 // is large we want to force it down since we would prefer to 17535 // keep launcher over it. 17536 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17537 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17538 app.serviceHighRam = true; 17539 app.serviceb = true; 17540 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17541 } else { 17542 mNewNumAServiceProcs++; 17543 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17544 } 17545 } else { 17546 app.serviceHighRam = false; 17547 } 17548 } 17549 if (app.serviceb) { 17550 adj = ProcessList.SERVICE_B_ADJ; 17551 } 17552 } 17553 17554 app.curRawAdj = adj; 17555 17556 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17557 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17558 if (adj > app.maxAdj) { 17559 adj = app.maxAdj; 17560 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17561 schedGroup = Process.THREAD_GROUP_DEFAULT; 17562 } 17563 } 17564 17565 // Do final modification to adj. Everything we do between here and applying 17566 // the final setAdj must be done in this function, because we will also use 17567 // it when computing the final cached adj later. Note that we don't need to 17568 // worry about this for max adj above, since max adj will always be used to 17569 // keep it out of the cached vaues. 17570 app.curAdj = app.modifyRawOomAdj(adj); 17571 app.curSchedGroup = schedGroup; 17572 app.curProcState = procState; 17573 app.foregroundActivities = foregroundActivities; 17574 17575 return app.curRawAdj; 17576 } 17577 17578 /** 17579 * Record new PSS sample for a process. 17580 */ 17581 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17582 proc.lastPssTime = now; 17583 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17584 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17585 + ": " + pss + " lastPss=" + proc.lastPss 17586 + " state=" + ProcessList.makeProcStateString(procState)); 17587 if (proc.initialIdlePss == 0) { 17588 proc.initialIdlePss = pss; 17589 } 17590 proc.lastPss = pss; 17591 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17592 proc.lastCachedPss = pss; 17593 } 17594 } 17595 17596 /** 17597 * Schedule PSS collection of a process. 17598 */ 17599 void requestPssLocked(ProcessRecord proc, int procState) { 17600 if (mPendingPssProcesses.contains(proc)) { 17601 return; 17602 } 17603 if (mPendingPssProcesses.size() == 0) { 17604 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17605 } 17606 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17607 proc.pssProcState = procState; 17608 mPendingPssProcesses.add(proc); 17609 } 17610 17611 /** 17612 * Schedule PSS collection of all processes. 17613 */ 17614 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17615 if (!always) { 17616 if (now < (mLastFullPssTime + 17617 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17618 return; 17619 } 17620 } 17621 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17622 mLastFullPssTime = now; 17623 mFullPssPending = true; 17624 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17625 mPendingPssProcesses.clear(); 17626 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17627 ProcessRecord app = mLruProcesses.get(i); 17628 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17629 app.pssProcState = app.setProcState; 17630 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17631 mTestPssMode, isSleeping(), now); 17632 mPendingPssProcesses.add(app); 17633 } 17634 } 17635 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17636 } 17637 17638 public void setTestPssMode(boolean enabled) { 17639 synchronized (this) { 17640 mTestPssMode = enabled; 17641 if (enabled) { 17642 // Whenever we enable the mode, we want to take a snapshot all of current 17643 // process mem use. 17644 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17645 } 17646 } 17647 } 17648 17649 /** 17650 * Ask a given process to GC right now. 17651 */ 17652 final void performAppGcLocked(ProcessRecord app) { 17653 try { 17654 app.lastRequestedGc = SystemClock.uptimeMillis(); 17655 if (app.thread != null) { 17656 if (app.reportLowMemory) { 17657 app.reportLowMemory = false; 17658 app.thread.scheduleLowMemory(); 17659 } else { 17660 app.thread.processInBackground(); 17661 } 17662 } 17663 } catch (Exception e) { 17664 // whatever. 17665 } 17666 } 17667 17668 /** 17669 * Returns true if things are idle enough to perform GCs. 17670 */ 17671 private final boolean canGcNowLocked() { 17672 boolean processingBroadcasts = false; 17673 for (BroadcastQueue q : mBroadcastQueues) { 17674 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17675 processingBroadcasts = true; 17676 } 17677 } 17678 return !processingBroadcasts 17679 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17680 } 17681 17682 /** 17683 * Perform GCs on all processes that are waiting for it, but only 17684 * if things are idle. 17685 */ 17686 final void performAppGcsLocked() { 17687 final int N = mProcessesToGc.size(); 17688 if (N <= 0) { 17689 return; 17690 } 17691 if (canGcNowLocked()) { 17692 while (mProcessesToGc.size() > 0) { 17693 ProcessRecord proc = mProcessesToGc.remove(0); 17694 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17695 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17696 <= SystemClock.uptimeMillis()) { 17697 // To avoid spamming the system, we will GC processes one 17698 // at a time, waiting a few seconds between each. 17699 performAppGcLocked(proc); 17700 scheduleAppGcsLocked(); 17701 return; 17702 } else { 17703 // It hasn't been long enough since we last GCed this 17704 // process... put it in the list to wait for its time. 17705 addProcessToGcListLocked(proc); 17706 break; 17707 } 17708 } 17709 } 17710 17711 scheduleAppGcsLocked(); 17712 } 17713 } 17714 17715 /** 17716 * If all looks good, perform GCs on all processes waiting for them. 17717 */ 17718 final void performAppGcsIfAppropriateLocked() { 17719 if (canGcNowLocked()) { 17720 performAppGcsLocked(); 17721 return; 17722 } 17723 // Still not idle, wait some more. 17724 scheduleAppGcsLocked(); 17725 } 17726 17727 /** 17728 * Schedule the execution of all pending app GCs. 17729 */ 17730 final void scheduleAppGcsLocked() { 17731 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17732 17733 if (mProcessesToGc.size() > 0) { 17734 // Schedule a GC for the time to the next process. 17735 ProcessRecord proc = mProcessesToGc.get(0); 17736 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17737 17738 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17739 long now = SystemClock.uptimeMillis(); 17740 if (when < (now+GC_TIMEOUT)) { 17741 when = now + GC_TIMEOUT; 17742 } 17743 mHandler.sendMessageAtTime(msg, when); 17744 } 17745 } 17746 17747 /** 17748 * Add a process to the array of processes waiting to be GCed. Keeps the 17749 * list in sorted order by the last GC time. The process can't already be 17750 * on the list. 17751 */ 17752 final void addProcessToGcListLocked(ProcessRecord proc) { 17753 boolean added = false; 17754 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17755 if (mProcessesToGc.get(i).lastRequestedGc < 17756 proc.lastRequestedGc) { 17757 added = true; 17758 mProcessesToGc.add(i+1, proc); 17759 break; 17760 } 17761 } 17762 if (!added) { 17763 mProcessesToGc.add(0, proc); 17764 } 17765 } 17766 17767 /** 17768 * Set up to ask a process to GC itself. This will either do it 17769 * immediately, or put it on the list of processes to gc the next 17770 * time things are idle. 17771 */ 17772 final void scheduleAppGcLocked(ProcessRecord app) { 17773 long now = SystemClock.uptimeMillis(); 17774 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17775 return; 17776 } 17777 if (!mProcessesToGc.contains(app)) { 17778 addProcessToGcListLocked(app); 17779 scheduleAppGcsLocked(); 17780 } 17781 } 17782 17783 final void checkExcessivePowerUsageLocked(boolean doKills) { 17784 updateCpuStatsNow(); 17785 17786 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17787 boolean doWakeKills = doKills; 17788 boolean doCpuKills = doKills; 17789 if (mLastPowerCheckRealtime == 0) { 17790 doWakeKills = false; 17791 } 17792 if (mLastPowerCheckUptime == 0) { 17793 doCpuKills = false; 17794 } 17795 if (stats.isScreenOn()) { 17796 doWakeKills = false; 17797 } 17798 final long curRealtime = SystemClock.elapsedRealtime(); 17799 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17800 final long curUptime = SystemClock.uptimeMillis(); 17801 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17802 mLastPowerCheckRealtime = curRealtime; 17803 mLastPowerCheckUptime = curUptime; 17804 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17805 doWakeKills = false; 17806 } 17807 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17808 doCpuKills = false; 17809 } 17810 int i = mLruProcesses.size(); 17811 while (i > 0) { 17812 i--; 17813 ProcessRecord app = mLruProcesses.get(i); 17814 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17815 long wtime; 17816 synchronized (stats) { 17817 wtime = stats.getProcessWakeTime(app.info.uid, 17818 app.pid, curRealtime); 17819 } 17820 long wtimeUsed = wtime - app.lastWakeTime; 17821 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17822 if (DEBUG_POWER) { 17823 StringBuilder sb = new StringBuilder(128); 17824 sb.append("Wake for "); 17825 app.toShortString(sb); 17826 sb.append(": over "); 17827 TimeUtils.formatDuration(realtimeSince, sb); 17828 sb.append(" used "); 17829 TimeUtils.formatDuration(wtimeUsed, sb); 17830 sb.append(" ("); 17831 sb.append((wtimeUsed*100)/realtimeSince); 17832 sb.append("%)"); 17833 Slog.i(TAG, sb.toString()); 17834 sb.setLength(0); 17835 sb.append("CPU for "); 17836 app.toShortString(sb); 17837 sb.append(": over "); 17838 TimeUtils.formatDuration(uptimeSince, sb); 17839 sb.append(" used "); 17840 TimeUtils.formatDuration(cputimeUsed, sb); 17841 sb.append(" ("); 17842 sb.append((cputimeUsed*100)/uptimeSince); 17843 sb.append("%)"); 17844 Slog.i(TAG, sb.toString()); 17845 } 17846 // If a process has held a wake lock for more 17847 // than 50% of the time during this period, 17848 // that sounds bad. Kill! 17849 if (doWakeKills && realtimeSince > 0 17850 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17851 synchronized (stats) { 17852 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17853 realtimeSince, wtimeUsed); 17854 } 17855 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17856 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17857 } else if (doCpuKills && uptimeSince > 0 17858 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17859 synchronized (stats) { 17860 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17861 uptimeSince, cputimeUsed); 17862 } 17863 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17864 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17865 } else { 17866 app.lastWakeTime = wtime; 17867 app.lastCpuTime = app.curCpuTime; 17868 } 17869 } 17870 } 17871 } 17872 17873 private final boolean applyOomAdjLocked(ProcessRecord app, 17874 ProcessRecord TOP_APP, boolean doingAll, long now) { 17875 boolean success = true; 17876 17877 if (app.curRawAdj != app.setRawAdj) { 17878 app.setRawAdj = app.curRawAdj; 17879 } 17880 17881 int changes = 0; 17882 17883 if (app.curAdj != app.setAdj) { 17884 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17885 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17886 TAG, "Set " + app.pid + " " + app.processName + 17887 " adj " + app.curAdj + ": " + app.adjType); 17888 app.setAdj = app.curAdj; 17889 } 17890 17891 if (app.setSchedGroup != app.curSchedGroup) { 17892 app.setSchedGroup = app.curSchedGroup; 17893 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17894 "Setting process group of " + app.processName 17895 + " to " + app.curSchedGroup); 17896 if (app.waitingToKill != null && 17897 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17898 app.kill(app.waitingToKill, true); 17899 success = false; 17900 } else { 17901 if (true) { 17902 long oldId = Binder.clearCallingIdentity(); 17903 try { 17904 Process.setProcessGroup(app.pid, app.curSchedGroup); 17905 } catch (Exception e) { 17906 Slog.w(TAG, "Failed setting process group of " + app.pid 17907 + " to " + app.curSchedGroup); 17908 e.printStackTrace(); 17909 } finally { 17910 Binder.restoreCallingIdentity(oldId); 17911 } 17912 } else { 17913 if (app.thread != null) { 17914 try { 17915 app.thread.setSchedulingGroup(app.curSchedGroup); 17916 } catch (RemoteException e) { 17917 } 17918 } 17919 } 17920 Process.setSwappiness(app.pid, 17921 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17922 } 17923 } 17924 if (app.repForegroundActivities != app.foregroundActivities) { 17925 app.repForegroundActivities = app.foregroundActivities; 17926 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17927 } 17928 if (app.repProcState != app.curProcState) { 17929 app.repProcState = app.curProcState; 17930 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17931 if (app.thread != null) { 17932 try { 17933 if (false) { 17934 //RuntimeException h = new RuntimeException("here"); 17935 Slog.i(TAG, "Sending new process state " + app.repProcState 17936 + " to " + app /*, h*/); 17937 } 17938 app.thread.setProcessState(app.repProcState); 17939 } catch (RemoteException e) { 17940 } 17941 } 17942 } 17943 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17944 app.setProcState)) { 17945 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17946 // Experimental code to more aggressively collect pss while 17947 // running test... the problem is that this tends to collect 17948 // the data right when a process is transitioning between process 17949 // states, which well tend to give noisy data. 17950 long start = SystemClock.uptimeMillis(); 17951 long pss = Debug.getPss(app.pid, mTmpLong, null); 17952 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17953 mPendingPssProcesses.remove(app); 17954 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17955 + " to " + app.curProcState + ": " 17956 + (SystemClock.uptimeMillis()-start) + "ms"); 17957 } 17958 app.lastStateTime = now; 17959 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17960 mTestPssMode, isSleeping(), now); 17961 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17962 + ProcessList.makeProcStateString(app.setProcState) + " to " 17963 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17964 + (app.nextPssTime-now) + ": " + app); 17965 } else { 17966 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17967 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17968 mTestPssMode)))) { 17969 requestPssLocked(app, app.setProcState); 17970 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17971 mTestPssMode, isSleeping(), now); 17972 } else if (false && DEBUG_PSS) { 17973 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17974 } 17975 } 17976 if (app.setProcState != app.curProcState) { 17977 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17978 "Proc state change of " + app.processName 17979 + " to " + app.curProcState); 17980 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17981 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17982 if (setImportant && !curImportant) { 17983 // This app is no longer something we consider important enough to allow to 17984 // use arbitrary amounts of battery power. Note 17985 // its current wake lock time to later know to kill it if 17986 // it is not behaving well. 17987 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17988 synchronized (stats) { 17989 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17990 app.pid, SystemClock.elapsedRealtime()); 17991 } 17992 app.lastCpuTime = app.curCpuTime; 17993 17994 } 17995 app.setProcState = app.curProcState; 17996 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17997 app.notCachedSinceIdle = false; 17998 } 17999 if (!doingAll) { 18000 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 18001 } else { 18002 app.procStateChanged = true; 18003 } 18004 } 18005 18006 if (changes != 0) { 18007 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 18008 int i = mPendingProcessChanges.size()-1; 18009 ProcessChangeItem item = null; 18010 while (i >= 0) { 18011 item = mPendingProcessChanges.get(i); 18012 if (item.pid == app.pid) { 18013 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18014 break; 18015 } 18016 i--; 18017 } 18018 if (i < 0) { 18019 // No existing item in pending changes; need a new one. 18020 final int NA = mAvailProcessChanges.size(); 18021 if (NA > 0) { 18022 item = mAvailProcessChanges.remove(NA-1); 18023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18024 } else { 18025 item = new ProcessChangeItem(); 18026 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18027 } 18028 item.changes = 0; 18029 item.pid = app.pid; 18030 item.uid = app.info.uid; 18031 if (mPendingProcessChanges.size() == 0) { 18032 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18033 "*** Enqueueing dispatch processes changed!"); 18034 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18035 } 18036 mPendingProcessChanges.add(item); 18037 } 18038 item.changes |= changes; 18039 item.processState = app.repProcState; 18040 item.foregroundActivities = app.repForegroundActivities; 18041 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18042 + Integer.toHexString(System.identityHashCode(item)) 18043 + " " + app.toShortString() + ": changes=" + item.changes 18044 + " procState=" + item.processState 18045 + " foreground=" + item.foregroundActivities 18046 + " type=" + app.adjType + " source=" + app.adjSource 18047 + " target=" + app.adjTarget); 18048 } 18049 18050 return success; 18051 } 18052 18053 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18054 if (proc.thread != null) { 18055 if (proc.baseProcessTracker != null) { 18056 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18057 } 18058 if (proc.repProcState >= 0) { 18059 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18060 proc.repProcState); 18061 } 18062 } 18063 } 18064 18065 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18066 ProcessRecord TOP_APP, boolean doingAll, long now) { 18067 if (app.thread == null) { 18068 return false; 18069 } 18070 18071 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18072 18073 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18074 } 18075 18076 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18077 boolean oomAdj) { 18078 if (isForeground != proc.foregroundServices) { 18079 proc.foregroundServices = isForeground; 18080 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18081 proc.info.uid); 18082 if (isForeground) { 18083 if (curProcs == null) { 18084 curProcs = new ArrayList<ProcessRecord>(); 18085 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18086 } 18087 if (!curProcs.contains(proc)) { 18088 curProcs.add(proc); 18089 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18090 proc.info.packageName, proc.info.uid); 18091 } 18092 } else { 18093 if (curProcs != null) { 18094 if (curProcs.remove(proc)) { 18095 mBatteryStatsService.noteEvent( 18096 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18097 proc.info.packageName, proc.info.uid); 18098 if (curProcs.size() <= 0) { 18099 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18100 } 18101 } 18102 } 18103 } 18104 if (oomAdj) { 18105 updateOomAdjLocked(); 18106 } 18107 } 18108 } 18109 18110 private final ActivityRecord resumedAppLocked() { 18111 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18112 String pkg; 18113 int uid; 18114 if (act != null) { 18115 pkg = act.packageName; 18116 uid = act.info.applicationInfo.uid; 18117 } else { 18118 pkg = null; 18119 uid = -1; 18120 } 18121 // Has the UID or resumed package name changed? 18122 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18123 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18124 if (mCurResumedPackage != null) { 18125 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18126 mCurResumedPackage, mCurResumedUid); 18127 } 18128 mCurResumedPackage = pkg; 18129 mCurResumedUid = uid; 18130 if (mCurResumedPackage != null) { 18131 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18132 mCurResumedPackage, mCurResumedUid); 18133 } 18134 } 18135 return act; 18136 } 18137 18138 final boolean updateOomAdjLocked(ProcessRecord app) { 18139 final ActivityRecord TOP_ACT = resumedAppLocked(); 18140 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18141 final boolean wasCached = app.cached; 18142 18143 mAdjSeq++; 18144 18145 // This is the desired cached adjusment we want to tell it to use. 18146 // If our app is currently cached, we know it, and that is it. Otherwise, 18147 // we don't know it yet, and it needs to now be cached we will then 18148 // need to do a complete oom adj. 18149 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18150 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18151 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18152 SystemClock.uptimeMillis()); 18153 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18154 // Changed to/from cached state, so apps after it in the LRU 18155 // list may also be changed. 18156 updateOomAdjLocked(); 18157 } 18158 return success; 18159 } 18160 18161 final void updateOomAdjLocked() { 18162 final ActivityRecord TOP_ACT = resumedAppLocked(); 18163 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18164 final long now = SystemClock.uptimeMillis(); 18165 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18166 final int N = mLruProcesses.size(); 18167 18168 if (false) { 18169 RuntimeException e = new RuntimeException(); 18170 e.fillInStackTrace(); 18171 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18172 } 18173 18174 mAdjSeq++; 18175 mNewNumServiceProcs = 0; 18176 mNewNumAServiceProcs = 0; 18177 18178 final int emptyProcessLimit; 18179 final int cachedProcessLimit; 18180 if (mProcessLimit <= 0) { 18181 emptyProcessLimit = cachedProcessLimit = 0; 18182 } else if (mProcessLimit == 1) { 18183 emptyProcessLimit = 1; 18184 cachedProcessLimit = 0; 18185 } else { 18186 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18187 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18188 } 18189 18190 // Let's determine how many processes we have running vs. 18191 // how many slots we have for background processes; we may want 18192 // to put multiple processes in a slot of there are enough of 18193 // them. 18194 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18195 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18196 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18197 if (numEmptyProcs > cachedProcessLimit) { 18198 // If there are more empty processes than our limit on cached 18199 // processes, then use the cached process limit for the factor. 18200 // This ensures that the really old empty processes get pushed 18201 // down to the bottom, so if we are running low on memory we will 18202 // have a better chance at keeping around more cached processes 18203 // instead of a gazillion empty processes. 18204 numEmptyProcs = cachedProcessLimit; 18205 } 18206 int emptyFactor = numEmptyProcs/numSlots; 18207 if (emptyFactor < 1) emptyFactor = 1; 18208 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18209 if (cachedFactor < 1) cachedFactor = 1; 18210 int stepCached = 0; 18211 int stepEmpty = 0; 18212 int numCached = 0; 18213 int numEmpty = 0; 18214 int numTrimming = 0; 18215 18216 mNumNonCachedProcs = 0; 18217 mNumCachedHiddenProcs = 0; 18218 18219 // First update the OOM adjustment for each of the 18220 // application processes based on their current state. 18221 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18222 int nextCachedAdj = curCachedAdj+1; 18223 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18224 int nextEmptyAdj = curEmptyAdj+2; 18225 for (int i=N-1; i>=0; i--) { 18226 ProcessRecord app = mLruProcesses.get(i); 18227 if (!app.killedByAm && app.thread != null) { 18228 app.procStateChanged = false; 18229 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18230 18231 // If we haven't yet assigned the final cached adj 18232 // to the process, do that now. 18233 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18234 switch (app.curProcState) { 18235 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18236 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18237 // This process is a cached process holding activities... 18238 // assign it the next cached value for that type, and then 18239 // step that cached level. 18240 app.curRawAdj = curCachedAdj; 18241 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18242 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18243 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18244 + ")"); 18245 if (curCachedAdj != nextCachedAdj) { 18246 stepCached++; 18247 if (stepCached >= cachedFactor) { 18248 stepCached = 0; 18249 curCachedAdj = nextCachedAdj; 18250 nextCachedAdj += 2; 18251 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18252 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18253 } 18254 } 18255 } 18256 break; 18257 default: 18258 // For everything else, assign next empty cached process 18259 // level and bump that up. Note that this means that 18260 // long-running services that have dropped down to the 18261 // cached level will be treated as empty (since their process 18262 // state is still as a service), which is what we want. 18263 app.curRawAdj = curEmptyAdj; 18264 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18265 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18266 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18267 + ")"); 18268 if (curEmptyAdj != nextEmptyAdj) { 18269 stepEmpty++; 18270 if (stepEmpty >= emptyFactor) { 18271 stepEmpty = 0; 18272 curEmptyAdj = nextEmptyAdj; 18273 nextEmptyAdj += 2; 18274 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18275 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18276 } 18277 } 18278 } 18279 break; 18280 } 18281 } 18282 18283 applyOomAdjLocked(app, TOP_APP, true, now); 18284 18285 // Count the number of process types. 18286 switch (app.curProcState) { 18287 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18288 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18289 mNumCachedHiddenProcs++; 18290 numCached++; 18291 if (numCached > cachedProcessLimit) { 18292 app.kill("cached #" + numCached, true); 18293 } 18294 break; 18295 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18296 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18297 && app.lastActivityTime < oldTime) { 18298 app.kill("empty for " 18299 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18300 / 1000) + "s", true); 18301 } else { 18302 numEmpty++; 18303 if (numEmpty > emptyProcessLimit) { 18304 app.kill("empty #" + numEmpty, true); 18305 } 18306 } 18307 break; 18308 default: 18309 mNumNonCachedProcs++; 18310 break; 18311 } 18312 18313 if (app.isolated && app.services.size() <= 0) { 18314 // If this is an isolated process, and there are no 18315 // services running in it, then the process is no longer 18316 // needed. We agressively kill these because we can by 18317 // definition not re-use the same process again, and it is 18318 // good to avoid having whatever code was running in them 18319 // left sitting around after no longer needed. 18320 app.kill("isolated not needed", true); 18321 } 18322 18323 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18324 && !app.killedByAm) { 18325 numTrimming++; 18326 } 18327 } 18328 } 18329 18330 mNumServiceProcs = mNewNumServiceProcs; 18331 18332 // Now determine the memory trimming level of background processes. 18333 // Unfortunately we need to start at the back of the list to do this 18334 // properly. We only do this if the number of background apps we 18335 // are managing to keep around is less than half the maximum we desire; 18336 // if we are keeping a good number around, we'll let them use whatever 18337 // memory they want. 18338 final int numCachedAndEmpty = numCached + numEmpty; 18339 int memFactor; 18340 if (numCached <= ProcessList.TRIM_CACHED_APPS 18341 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18342 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18343 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18344 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18345 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18346 } else { 18347 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18348 } 18349 } else { 18350 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18351 } 18352 // We always allow the memory level to go up (better). We only allow it to go 18353 // down if we are in a state where that is allowed, *and* the total number of processes 18354 // has gone down since last time. 18355 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18356 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18357 + " last=" + mLastNumProcesses); 18358 if (memFactor > mLastMemoryLevel) { 18359 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18360 memFactor = mLastMemoryLevel; 18361 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18362 } 18363 } 18364 mLastMemoryLevel = memFactor; 18365 mLastNumProcesses = mLruProcesses.size(); 18366 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18367 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18368 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18369 if (mLowRamStartTime == 0) { 18370 mLowRamStartTime = now; 18371 } 18372 int step = 0; 18373 int fgTrimLevel; 18374 switch (memFactor) { 18375 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18376 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18377 break; 18378 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18379 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18380 break; 18381 default: 18382 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18383 break; 18384 } 18385 int factor = numTrimming/3; 18386 int minFactor = 2; 18387 if (mHomeProcess != null) minFactor++; 18388 if (mPreviousProcess != null) minFactor++; 18389 if (factor < minFactor) factor = minFactor; 18390 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18391 for (int i=N-1; i>=0; i--) { 18392 ProcessRecord app = mLruProcesses.get(i); 18393 if (allChanged || app.procStateChanged) { 18394 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18395 app.procStateChanged = false; 18396 } 18397 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18398 && !app.killedByAm) { 18399 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18400 try { 18401 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18402 "Trimming memory of " + app.processName 18403 + " to " + curLevel); 18404 app.thread.scheduleTrimMemory(curLevel); 18405 } catch (RemoteException e) { 18406 } 18407 if (false) { 18408 // For now we won't do this; our memory trimming seems 18409 // to be good enough at this point that destroying 18410 // activities causes more harm than good. 18411 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18412 && app != mHomeProcess && app != mPreviousProcess) { 18413 // Need to do this on its own message because the stack may not 18414 // be in a consistent state at this point. 18415 // For these apps we will also finish their activities 18416 // to help them free memory. 18417 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18418 } 18419 } 18420 } 18421 app.trimMemoryLevel = curLevel; 18422 step++; 18423 if (step >= factor) { 18424 step = 0; 18425 switch (curLevel) { 18426 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18427 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18428 break; 18429 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18430 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18431 break; 18432 } 18433 } 18434 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18435 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18436 && app.thread != null) { 18437 try { 18438 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18439 "Trimming memory of heavy-weight " + app.processName 18440 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18441 app.thread.scheduleTrimMemory( 18442 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18443 } catch (RemoteException e) { 18444 } 18445 } 18446 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18447 } else { 18448 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18449 || app.systemNoUi) && app.pendingUiClean) { 18450 // If this application is now in the background and it 18451 // had done UI, then give it the special trim level to 18452 // have it free UI resources. 18453 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18454 if (app.trimMemoryLevel < level && app.thread != null) { 18455 try { 18456 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18457 "Trimming memory of bg-ui " + app.processName 18458 + " to " + level); 18459 app.thread.scheduleTrimMemory(level); 18460 } catch (RemoteException e) { 18461 } 18462 } 18463 app.pendingUiClean = false; 18464 } 18465 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18466 try { 18467 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18468 "Trimming memory of fg " + app.processName 18469 + " to " + fgTrimLevel); 18470 app.thread.scheduleTrimMemory(fgTrimLevel); 18471 } catch (RemoteException e) { 18472 } 18473 } 18474 app.trimMemoryLevel = fgTrimLevel; 18475 } 18476 } 18477 } else { 18478 if (mLowRamStartTime != 0) { 18479 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18480 mLowRamStartTime = 0; 18481 } 18482 for (int i=N-1; i>=0; i--) { 18483 ProcessRecord app = mLruProcesses.get(i); 18484 if (allChanged || app.procStateChanged) { 18485 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18486 app.procStateChanged = false; 18487 } 18488 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18489 || app.systemNoUi) && app.pendingUiClean) { 18490 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18491 && app.thread != null) { 18492 try { 18493 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18494 "Trimming memory of ui hidden " + app.processName 18495 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18496 app.thread.scheduleTrimMemory( 18497 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18498 } catch (RemoteException e) { 18499 } 18500 } 18501 app.pendingUiClean = false; 18502 } 18503 app.trimMemoryLevel = 0; 18504 } 18505 } 18506 18507 if (mAlwaysFinishActivities) { 18508 // Need to do this on its own message because the stack may not 18509 // be in a consistent state at this point. 18510 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18511 } 18512 18513 if (allChanged) { 18514 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18515 } 18516 18517 if (mProcessStats.shouldWriteNowLocked(now)) { 18518 mHandler.post(new Runnable() { 18519 @Override public void run() { 18520 synchronized (ActivityManagerService.this) { 18521 mProcessStats.writeStateAsyncLocked(); 18522 } 18523 } 18524 }); 18525 } 18526 18527 if (DEBUG_OOM_ADJ) { 18528 if (false) { 18529 RuntimeException here = new RuntimeException("here"); 18530 here.fillInStackTrace(); 18531 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18532 } else { 18533 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18534 } 18535 } 18536 } 18537 18538 final void trimApplications() { 18539 synchronized (this) { 18540 int i; 18541 18542 // First remove any unused application processes whose package 18543 // has been removed. 18544 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18545 final ProcessRecord app = mRemovedProcesses.get(i); 18546 if (app.activities.size() == 0 18547 && app.curReceiver == null && app.services.size() == 0) { 18548 Slog.i( 18549 TAG, "Exiting empty application process " 18550 + app.processName + " (" 18551 + (app.thread != null ? app.thread.asBinder() : null) 18552 + ")\n"); 18553 if (app.pid > 0 && app.pid != MY_PID) { 18554 app.kill("empty", false); 18555 } else { 18556 try { 18557 app.thread.scheduleExit(); 18558 } catch (Exception e) { 18559 // Ignore exceptions. 18560 } 18561 } 18562 cleanUpApplicationRecordLocked(app, false, true, -1); 18563 mRemovedProcesses.remove(i); 18564 18565 if (app.persistent) { 18566 addAppLocked(app.info, false, null /* ABI override */); 18567 } 18568 } 18569 } 18570 18571 // Now update the oom adj for all processes. 18572 updateOomAdjLocked(); 18573 } 18574 } 18575 18576 /** This method sends the specified signal to each of the persistent apps */ 18577 public void signalPersistentProcesses(int sig) throws RemoteException { 18578 if (sig != Process.SIGNAL_USR1) { 18579 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18580 } 18581 18582 synchronized (this) { 18583 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18584 != PackageManager.PERMISSION_GRANTED) { 18585 throw new SecurityException("Requires permission " 18586 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18587 } 18588 18589 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18590 ProcessRecord r = mLruProcesses.get(i); 18591 if (r.thread != null && r.persistent) { 18592 Process.sendSignal(r.pid, sig); 18593 } 18594 } 18595 } 18596 } 18597 18598 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18599 if (proc == null || proc == mProfileProc) { 18600 proc = mProfileProc; 18601 profileType = mProfileType; 18602 clearProfilerLocked(); 18603 } 18604 if (proc == null) { 18605 return; 18606 } 18607 try { 18608 proc.thread.profilerControl(false, null, profileType); 18609 } catch (RemoteException e) { 18610 throw new IllegalStateException("Process disappeared"); 18611 } 18612 } 18613 18614 private void clearProfilerLocked() { 18615 if (mProfileFd != null) { 18616 try { 18617 mProfileFd.close(); 18618 } catch (IOException e) { 18619 } 18620 } 18621 mProfileApp = null; 18622 mProfileProc = null; 18623 mProfileFile = null; 18624 mProfileType = 0; 18625 mAutoStopProfiler = false; 18626 mSamplingInterval = 0; 18627 } 18628 18629 public boolean profileControl(String process, int userId, boolean start, 18630 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18631 18632 try { 18633 synchronized (this) { 18634 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18635 // its own permission. 18636 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18637 != PackageManager.PERMISSION_GRANTED) { 18638 throw new SecurityException("Requires permission " 18639 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18640 } 18641 18642 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18643 throw new IllegalArgumentException("null profile info or fd"); 18644 } 18645 18646 ProcessRecord proc = null; 18647 if (process != null) { 18648 proc = findProcessLocked(process, userId, "profileControl"); 18649 } 18650 18651 if (start && (proc == null || proc.thread == null)) { 18652 throw new IllegalArgumentException("Unknown process: " + process); 18653 } 18654 18655 if (start) { 18656 stopProfilerLocked(null, 0); 18657 setProfileApp(proc.info, proc.processName, profilerInfo); 18658 mProfileProc = proc; 18659 mProfileType = profileType; 18660 ParcelFileDescriptor fd = profilerInfo.profileFd; 18661 try { 18662 fd = fd.dup(); 18663 } catch (IOException e) { 18664 fd = null; 18665 } 18666 profilerInfo.profileFd = fd; 18667 proc.thread.profilerControl(start, profilerInfo, profileType); 18668 fd = null; 18669 mProfileFd = null; 18670 } else { 18671 stopProfilerLocked(proc, profileType); 18672 if (profilerInfo != null && profilerInfo.profileFd != null) { 18673 try { 18674 profilerInfo.profileFd.close(); 18675 } catch (IOException e) { 18676 } 18677 } 18678 } 18679 18680 return true; 18681 } 18682 } catch (RemoteException e) { 18683 throw new IllegalStateException("Process disappeared"); 18684 } finally { 18685 if (profilerInfo != null && profilerInfo.profileFd != null) { 18686 try { 18687 profilerInfo.profileFd.close(); 18688 } catch (IOException e) { 18689 } 18690 } 18691 } 18692 } 18693 18694 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18695 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18696 userId, true, ALLOW_FULL_ONLY, callName, null); 18697 ProcessRecord proc = null; 18698 try { 18699 int pid = Integer.parseInt(process); 18700 synchronized (mPidsSelfLocked) { 18701 proc = mPidsSelfLocked.get(pid); 18702 } 18703 } catch (NumberFormatException e) { 18704 } 18705 18706 if (proc == null) { 18707 ArrayMap<String, SparseArray<ProcessRecord>> all 18708 = mProcessNames.getMap(); 18709 SparseArray<ProcessRecord> procs = all.get(process); 18710 if (procs != null && procs.size() > 0) { 18711 proc = procs.valueAt(0); 18712 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18713 for (int i=1; i<procs.size(); i++) { 18714 ProcessRecord thisProc = procs.valueAt(i); 18715 if (thisProc.userId == userId) { 18716 proc = thisProc; 18717 break; 18718 } 18719 } 18720 } 18721 } 18722 } 18723 18724 return proc; 18725 } 18726 18727 public boolean dumpHeap(String process, int userId, boolean managed, 18728 String path, ParcelFileDescriptor fd) throws RemoteException { 18729 18730 try { 18731 synchronized (this) { 18732 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18733 // its own permission (same as profileControl). 18734 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18735 != PackageManager.PERMISSION_GRANTED) { 18736 throw new SecurityException("Requires permission " 18737 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18738 } 18739 18740 if (fd == null) { 18741 throw new IllegalArgumentException("null fd"); 18742 } 18743 18744 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18745 if (proc == null || proc.thread == null) { 18746 throw new IllegalArgumentException("Unknown process: " + process); 18747 } 18748 18749 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18750 if (!isDebuggable) { 18751 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18752 throw new SecurityException("Process not debuggable: " + proc); 18753 } 18754 } 18755 18756 proc.thread.dumpHeap(managed, path, fd); 18757 fd = null; 18758 return true; 18759 } 18760 } catch (RemoteException e) { 18761 throw new IllegalStateException("Process disappeared"); 18762 } finally { 18763 if (fd != null) { 18764 try { 18765 fd.close(); 18766 } catch (IOException e) { 18767 } 18768 } 18769 } 18770 } 18771 18772 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18773 public void monitor() { 18774 synchronized (this) { } 18775 } 18776 18777 void onCoreSettingsChange(Bundle settings) { 18778 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18779 ProcessRecord processRecord = mLruProcesses.get(i); 18780 try { 18781 if (processRecord.thread != null) { 18782 processRecord.thread.setCoreSettings(settings); 18783 } 18784 } catch (RemoteException re) { 18785 /* ignore */ 18786 } 18787 } 18788 } 18789 18790 // Multi-user methods 18791 18792 /** 18793 * Start user, if its not already running, but don't bring it to foreground. 18794 */ 18795 @Override 18796 public boolean startUserInBackground(final int userId) { 18797 return startUser(userId, /* foreground */ false); 18798 } 18799 18800 /** 18801 * Start user, if its not already running, and bring it to foreground. 18802 */ 18803 boolean startUserInForeground(final int userId, Dialog dlg) { 18804 boolean result = startUser(userId, /* foreground */ true); 18805 dlg.dismiss(); 18806 return result; 18807 } 18808 18809 /** 18810 * Refreshes the list of users related to the current user when either a 18811 * user switch happens or when a new related user is started in the 18812 * background. 18813 */ 18814 private void updateCurrentProfileIdsLocked() { 18815 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18816 mCurrentUserId, false /* enabledOnly */); 18817 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18818 for (int i = 0; i < currentProfileIds.length; i++) { 18819 currentProfileIds[i] = profiles.get(i).id; 18820 } 18821 mCurrentProfileIds = currentProfileIds; 18822 18823 synchronized (mUserProfileGroupIdsSelfLocked) { 18824 mUserProfileGroupIdsSelfLocked.clear(); 18825 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18826 for (int i = 0; i < users.size(); i++) { 18827 UserInfo user = users.get(i); 18828 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18829 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18830 } 18831 } 18832 } 18833 } 18834 18835 private Set getProfileIdsLocked(int userId) { 18836 Set userIds = new HashSet<Integer>(); 18837 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18838 userId, false /* enabledOnly */); 18839 for (UserInfo user : profiles) { 18840 userIds.add(Integer.valueOf(user.id)); 18841 } 18842 return userIds; 18843 } 18844 18845 @Override 18846 public boolean switchUser(final int userId) { 18847 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18848 String userName; 18849 synchronized (this) { 18850 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18851 if (userInfo == null) { 18852 Slog.w(TAG, "No user info for user #" + userId); 18853 return false; 18854 } 18855 if (userInfo.isManagedProfile()) { 18856 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18857 return false; 18858 } 18859 userName = userInfo.name; 18860 mTargetUserId = userId; 18861 } 18862 mHandler.removeMessages(START_USER_SWITCH_MSG); 18863 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18864 return true; 18865 } 18866 18867 private void showUserSwitchDialog(int userId, String userName) { 18868 // The dialog will show and then initiate the user switch by calling startUserInForeground 18869 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18870 true /* above system */); 18871 d.show(); 18872 } 18873 18874 private boolean startUser(final int userId, final boolean foreground) { 18875 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18876 != PackageManager.PERMISSION_GRANTED) { 18877 String msg = "Permission Denial: switchUser() from pid=" 18878 + Binder.getCallingPid() 18879 + ", uid=" + Binder.getCallingUid() 18880 + " requires " + INTERACT_ACROSS_USERS_FULL; 18881 Slog.w(TAG, msg); 18882 throw new SecurityException(msg); 18883 } 18884 18885 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18886 18887 final long ident = Binder.clearCallingIdentity(); 18888 try { 18889 synchronized (this) { 18890 final int oldUserId = mCurrentUserId; 18891 if (oldUserId == userId) { 18892 return true; 18893 } 18894 18895 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser"); 18896 18897 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18898 if (userInfo == null) { 18899 Slog.w(TAG, "No user info for user #" + userId); 18900 return false; 18901 } 18902 if (foreground && userInfo.isManagedProfile()) { 18903 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18904 return false; 18905 } 18906 18907 if (foreground) { 18908 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18909 R.anim.screen_user_enter); 18910 } 18911 18912 boolean needStart = false; 18913 18914 // If the user we are switching to is not currently started, then 18915 // we need to start it now. 18916 if (mStartedUsers.get(userId) == null) { 18917 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18918 updateStartedUserArrayLocked(); 18919 needStart = true; 18920 } 18921 18922 final Integer userIdInt = Integer.valueOf(userId); 18923 mUserLru.remove(userIdInt); 18924 mUserLru.add(userIdInt); 18925 18926 if (foreground) { 18927 mCurrentUserId = userId; 18928 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18929 updateCurrentProfileIdsLocked(); 18930 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18931 // Once the internal notion of the active user has switched, we lock the device 18932 // with the option to show the user switcher on the keyguard. 18933 mWindowManager.lockNow(null); 18934 } else { 18935 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18936 updateCurrentProfileIdsLocked(); 18937 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18938 mUserLru.remove(currentUserIdInt); 18939 mUserLru.add(currentUserIdInt); 18940 } 18941 18942 final UserStartedState uss = mStartedUsers.get(userId); 18943 18944 // Make sure user is in the started state. If it is currently 18945 // stopping, we need to knock that off. 18946 if (uss.mState == UserStartedState.STATE_STOPPING) { 18947 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18948 // so we can just fairly silently bring the user back from 18949 // the almost-dead. 18950 uss.mState = UserStartedState.STATE_RUNNING; 18951 updateStartedUserArrayLocked(); 18952 needStart = true; 18953 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18954 // This means ACTION_SHUTDOWN has been sent, so we will 18955 // need to treat this as a new boot of the user. 18956 uss.mState = UserStartedState.STATE_BOOTING; 18957 updateStartedUserArrayLocked(); 18958 needStart = true; 18959 } 18960 18961 if (uss.mState == UserStartedState.STATE_BOOTING) { 18962 // Booting up a new user, need to tell system services about it. 18963 // Note that this is on the same handler as scheduling of broadcasts, 18964 // which is important because it needs to go first. 18965 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18966 } 18967 18968 if (foreground) { 18969 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18970 oldUserId)); 18971 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18972 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18973 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18974 oldUserId, userId, uss)); 18975 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18976 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18977 } 18978 18979 if (needStart) { 18980 // Send USER_STARTED broadcast 18981 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18982 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18983 | Intent.FLAG_RECEIVER_FOREGROUND); 18984 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18985 broadcastIntentLocked(null, null, intent, 18986 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18987 false, false, MY_PID, Process.SYSTEM_UID, userId); 18988 } 18989 18990 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18991 if (userId != UserHandle.USER_OWNER) { 18992 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18993 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18994 broadcastIntentLocked(null, null, intent, null, 18995 new IIntentReceiver.Stub() { 18996 public void performReceive(Intent intent, int resultCode, 18997 String data, Bundle extras, boolean ordered, 18998 boolean sticky, int sendingUser) { 18999 onUserInitialized(uss, foreground, oldUserId, userId); 19000 } 19001 }, 0, null, null, null, AppOpsManager.OP_NONE, 19002 true, false, MY_PID, Process.SYSTEM_UID, 19003 userId); 19004 uss.initializing = true; 19005 } else { 19006 getUserManagerLocked().makeInitialized(userInfo.id); 19007 } 19008 } 19009 19010 if (foreground) { 19011 if (!uss.initializing) { 19012 moveUserToForeground(uss, oldUserId, userId); 19013 } 19014 } else { 19015 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19016 } 19017 19018 if (needStart) { 19019 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19020 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19021 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19022 broadcastIntentLocked(null, null, intent, 19023 null, new IIntentReceiver.Stub() { 19024 @Override 19025 public void performReceive(Intent intent, int resultCode, String data, 19026 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19027 throws RemoteException { 19028 } 19029 }, 0, null, null, 19030 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19031 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19032 } 19033 } 19034 } finally { 19035 Binder.restoreCallingIdentity(ident); 19036 } 19037 19038 return true; 19039 } 19040 19041 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19042 long ident = Binder.clearCallingIdentity(); 19043 try { 19044 Intent intent; 19045 if (oldUserId >= 0) { 19046 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19047 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19048 int count = profiles.size(); 19049 for (int i = 0; i < count; i++) { 19050 int profileUserId = profiles.get(i).id; 19051 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19052 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19053 | Intent.FLAG_RECEIVER_FOREGROUND); 19054 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19055 broadcastIntentLocked(null, null, intent, 19056 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19057 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19058 } 19059 } 19060 if (newUserId >= 0) { 19061 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19062 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19063 int count = profiles.size(); 19064 for (int i = 0; i < count; i++) { 19065 int profileUserId = profiles.get(i).id; 19066 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19067 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19068 | Intent.FLAG_RECEIVER_FOREGROUND); 19069 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19070 broadcastIntentLocked(null, null, intent, 19071 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19072 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19073 } 19074 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19075 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19076 | Intent.FLAG_RECEIVER_FOREGROUND); 19077 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19078 broadcastIntentLocked(null, null, intent, 19079 null, null, 0, null, null, 19080 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19081 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19082 } 19083 } finally { 19084 Binder.restoreCallingIdentity(ident); 19085 } 19086 } 19087 19088 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19089 final int newUserId) { 19090 final int N = mUserSwitchObservers.beginBroadcast(); 19091 if (N > 0) { 19092 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19093 int mCount = 0; 19094 @Override 19095 public void sendResult(Bundle data) throws RemoteException { 19096 synchronized (ActivityManagerService.this) { 19097 if (mCurUserSwitchCallback == this) { 19098 mCount++; 19099 if (mCount == N) { 19100 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19101 } 19102 } 19103 } 19104 } 19105 }; 19106 synchronized (this) { 19107 uss.switching = true; 19108 mCurUserSwitchCallback = callback; 19109 } 19110 for (int i=0; i<N; i++) { 19111 try { 19112 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19113 newUserId, callback); 19114 } catch (RemoteException e) { 19115 } 19116 } 19117 } else { 19118 synchronized (this) { 19119 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19120 } 19121 } 19122 mUserSwitchObservers.finishBroadcast(); 19123 } 19124 19125 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19126 synchronized (this) { 19127 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19128 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19129 } 19130 } 19131 19132 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19133 mCurUserSwitchCallback = null; 19134 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19135 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19136 oldUserId, newUserId, uss)); 19137 } 19138 19139 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19140 synchronized (this) { 19141 if (foreground) { 19142 moveUserToForeground(uss, oldUserId, newUserId); 19143 } 19144 } 19145 19146 completeSwitchAndInitalize(uss, newUserId, true, false); 19147 } 19148 19149 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19150 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19151 if (homeInFront) { 19152 startHomeActivityLocked(newUserId, "moveUserToFroreground"); 19153 } else { 19154 mStackSupervisor.resumeTopActivitiesLocked(); 19155 } 19156 EventLogTags.writeAmSwitchUser(newUserId); 19157 getUserManagerLocked().userForeground(newUserId); 19158 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19159 } 19160 19161 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19162 completeSwitchAndInitalize(uss, newUserId, false, true); 19163 } 19164 19165 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19166 boolean clearInitializing, boolean clearSwitching) { 19167 boolean unfrozen = false; 19168 synchronized (this) { 19169 if (clearInitializing) { 19170 uss.initializing = false; 19171 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19172 } 19173 if (clearSwitching) { 19174 uss.switching = false; 19175 } 19176 if (!uss.switching && !uss.initializing) { 19177 mWindowManager.stopFreezingScreen(); 19178 unfrozen = true; 19179 } 19180 } 19181 if (unfrozen) { 19182 final int N = mUserSwitchObservers.beginBroadcast(); 19183 for (int i=0; i<N; i++) { 19184 try { 19185 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19186 } catch (RemoteException e) { 19187 } 19188 } 19189 mUserSwitchObservers.finishBroadcast(); 19190 } 19191 stopGuestUserIfBackground(); 19192 } 19193 19194 /** 19195 * Stops the guest user if it has gone to the background. 19196 */ 19197 private void stopGuestUserIfBackground() { 19198 synchronized (this) { 19199 final int num = mUserLru.size(); 19200 for (int i = 0; i < num; i++) { 19201 Integer oldUserId = mUserLru.get(i); 19202 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19203 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19204 || oldUss.mState == UserStartedState.STATE_STOPPING 19205 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19206 continue; 19207 } 19208 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19209 if (userInfo.isGuest()) { 19210 // This is a user to be stopped. 19211 stopUserLocked(oldUserId, null); 19212 break; 19213 } 19214 } 19215 } 19216 } 19217 19218 void scheduleStartProfilesLocked() { 19219 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19220 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19221 DateUtils.SECOND_IN_MILLIS); 19222 } 19223 } 19224 19225 void startProfilesLocked() { 19226 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19227 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19228 mCurrentUserId, false /* enabledOnly */); 19229 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19230 for (UserInfo user : profiles) { 19231 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19232 && user.id != mCurrentUserId) { 19233 toStart.add(user); 19234 } 19235 } 19236 final int n = toStart.size(); 19237 int i = 0; 19238 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19239 startUserInBackground(toStart.get(i).id); 19240 } 19241 if (i < n) { 19242 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19243 } 19244 } 19245 19246 void finishUserBoot(UserStartedState uss) { 19247 synchronized (this) { 19248 if (uss.mState == UserStartedState.STATE_BOOTING 19249 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19250 uss.mState = UserStartedState.STATE_RUNNING; 19251 final int userId = uss.mHandle.getIdentifier(); 19252 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19253 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19254 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19255 broadcastIntentLocked(null, null, intent, 19256 null, null, 0, null, null, 19257 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19258 true, false, MY_PID, Process.SYSTEM_UID, userId); 19259 } 19260 } 19261 } 19262 19263 void finishUserSwitch(UserStartedState uss) { 19264 synchronized (this) { 19265 finishUserBoot(uss); 19266 19267 startProfilesLocked(); 19268 19269 int num = mUserLru.size(); 19270 int i = 0; 19271 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19272 Integer oldUserId = mUserLru.get(i); 19273 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19274 if (oldUss == null) { 19275 // Shouldn't happen, but be sane if it does. 19276 mUserLru.remove(i); 19277 num--; 19278 continue; 19279 } 19280 if (oldUss.mState == UserStartedState.STATE_STOPPING 19281 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19282 // This user is already stopping, doesn't count. 19283 num--; 19284 i++; 19285 continue; 19286 } 19287 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19288 // Owner and current can't be stopped, but count as running. 19289 i++; 19290 continue; 19291 } 19292 // This is a user to be stopped. 19293 stopUserLocked(oldUserId, null); 19294 num--; 19295 i++; 19296 } 19297 } 19298 } 19299 19300 @Override 19301 public int stopUser(final int userId, final IStopUserCallback callback) { 19302 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19303 != PackageManager.PERMISSION_GRANTED) { 19304 String msg = "Permission Denial: switchUser() from pid=" 19305 + Binder.getCallingPid() 19306 + ", uid=" + Binder.getCallingUid() 19307 + " requires " + INTERACT_ACROSS_USERS_FULL; 19308 Slog.w(TAG, msg); 19309 throw new SecurityException(msg); 19310 } 19311 if (userId <= 0) { 19312 throw new IllegalArgumentException("Can't stop primary user " + userId); 19313 } 19314 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19315 synchronized (this) { 19316 return stopUserLocked(userId, callback); 19317 } 19318 } 19319 19320 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19321 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19322 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19323 return ActivityManager.USER_OP_IS_CURRENT; 19324 } 19325 19326 final UserStartedState uss = mStartedUsers.get(userId); 19327 if (uss == null) { 19328 // User is not started, nothing to do... but we do need to 19329 // callback if requested. 19330 if (callback != null) { 19331 mHandler.post(new Runnable() { 19332 @Override 19333 public void run() { 19334 try { 19335 callback.userStopped(userId); 19336 } catch (RemoteException e) { 19337 } 19338 } 19339 }); 19340 } 19341 return ActivityManager.USER_OP_SUCCESS; 19342 } 19343 19344 if (callback != null) { 19345 uss.mStopCallbacks.add(callback); 19346 } 19347 19348 if (uss.mState != UserStartedState.STATE_STOPPING 19349 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19350 uss.mState = UserStartedState.STATE_STOPPING; 19351 updateStartedUserArrayLocked(); 19352 19353 long ident = Binder.clearCallingIdentity(); 19354 try { 19355 // We are going to broadcast ACTION_USER_STOPPING and then 19356 // once that is done send a final ACTION_SHUTDOWN and then 19357 // stop the user. 19358 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19359 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19360 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19361 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19362 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19363 // This is the result receiver for the final shutdown broadcast. 19364 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19365 @Override 19366 public void performReceive(Intent intent, int resultCode, String data, 19367 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19368 finishUserStop(uss); 19369 } 19370 }; 19371 // This is the result receiver for the initial stopping broadcast. 19372 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19373 @Override 19374 public void performReceive(Intent intent, int resultCode, String data, 19375 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19376 // On to the next. 19377 synchronized (ActivityManagerService.this) { 19378 if (uss.mState != UserStartedState.STATE_STOPPING) { 19379 // Whoops, we are being started back up. Abort, abort! 19380 return; 19381 } 19382 uss.mState = UserStartedState.STATE_SHUTDOWN; 19383 } 19384 mBatteryStatsService.noteEvent( 19385 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19386 Integer.toString(userId), userId); 19387 mSystemServiceManager.stopUser(userId); 19388 broadcastIntentLocked(null, null, shutdownIntent, 19389 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19390 true, false, MY_PID, Process.SYSTEM_UID, userId); 19391 } 19392 }; 19393 // Kick things off. 19394 broadcastIntentLocked(null, null, stoppingIntent, 19395 null, stoppingReceiver, 0, null, null, 19396 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19397 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19398 } finally { 19399 Binder.restoreCallingIdentity(ident); 19400 } 19401 } 19402 19403 return ActivityManager.USER_OP_SUCCESS; 19404 } 19405 19406 void finishUserStop(UserStartedState uss) { 19407 final int userId = uss.mHandle.getIdentifier(); 19408 boolean stopped; 19409 ArrayList<IStopUserCallback> callbacks; 19410 synchronized (this) { 19411 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19412 if (mStartedUsers.get(userId) != uss) { 19413 stopped = false; 19414 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19415 stopped = false; 19416 } else { 19417 stopped = true; 19418 // User can no longer run. 19419 mStartedUsers.remove(userId); 19420 mUserLru.remove(Integer.valueOf(userId)); 19421 updateStartedUserArrayLocked(); 19422 19423 // Clean up all state and processes associated with the user. 19424 // Kill all the processes for the user. 19425 forceStopUserLocked(userId, "finish user"); 19426 } 19427 19428 // Explicitly remove the old information in mRecentTasks. 19429 removeRecentTasksForUserLocked(userId); 19430 } 19431 19432 for (int i=0; i<callbacks.size(); i++) { 19433 try { 19434 if (stopped) callbacks.get(i).userStopped(userId); 19435 else callbacks.get(i).userStopAborted(userId); 19436 } catch (RemoteException e) { 19437 } 19438 } 19439 19440 if (stopped) { 19441 mSystemServiceManager.cleanupUser(userId); 19442 synchronized (this) { 19443 mStackSupervisor.removeUserLocked(userId); 19444 } 19445 } 19446 } 19447 19448 @Override 19449 public UserInfo getCurrentUser() { 19450 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19451 != PackageManager.PERMISSION_GRANTED) && ( 19452 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19453 != PackageManager.PERMISSION_GRANTED)) { 19454 String msg = "Permission Denial: getCurrentUser() from pid=" 19455 + Binder.getCallingPid() 19456 + ", uid=" + Binder.getCallingUid() 19457 + " requires " + INTERACT_ACROSS_USERS; 19458 Slog.w(TAG, msg); 19459 throw new SecurityException(msg); 19460 } 19461 synchronized (this) { 19462 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19463 return getUserManagerLocked().getUserInfo(userId); 19464 } 19465 } 19466 19467 int getCurrentUserIdLocked() { 19468 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19469 } 19470 19471 @Override 19472 public boolean isUserRunning(int userId, boolean orStopped) { 19473 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19474 != PackageManager.PERMISSION_GRANTED) { 19475 String msg = "Permission Denial: isUserRunning() from pid=" 19476 + Binder.getCallingPid() 19477 + ", uid=" + Binder.getCallingUid() 19478 + " requires " + INTERACT_ACROSS_USERS; 19479 Slog.w(TAG, msg); 19480 throw new SecurityException(msg); 19481 } 19482 synchronized (this) { 19483 return isUserRunningLocked(userId, orStopped); 19484 } 19485 } 19486 19487 boolean isUserRunningLocked(int userId, boolean orStopped) { 19488 UserStartedState state = mStartedUsers.get(userId); 19489 if (state == null) { 19490 return false; 19491 } 19492 if (orStopped) { 19493 return true; 19494 } 19495 return state.mState != UserStartedState.STATE_STOPPING 19496 && state.mState != UserStartedState.STATE_SHUTDOWN; 19497 } 19498 19499 @Override 19500 public int[] getRunningUserIds() { 19501 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19502 != PackageManager.PERMISSION_GRANTED) { 19503 String msg = "Permission Denial: isUserRunning() from pid=" 19504 + Binder.getCallingPid() 19505 + ", uid=" + Binder.getCallingUid() 19506 + " requires " + INTERACT_ACROSS_USERS; 19507 Slog.w(TAG, msg); 19508 throw new SecurityException(msg); 19509 } 19510 synchronized (this) { 19511 return mStartedUserArray; 19512 } 19513 } 19514 19515 private void updateStartedUserArrayLocked() { 19516 int num = 0; 19517 for (int i=0; i<mStartedUsers.size(); i++) { 19518 UserStartedState uss = mStartedUsers.valueAt(i); 19519 // This list does not include stopping users. 19520 if (uss.mState != UserStartedState.STATE_STOPPING 19521 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19522 num++; 19523 } 19524 } 19525 mStartedUserArray = new int[num]; 19526 num = 0; 19527 for (int i=0; i<mStartedUsers.size(); i++) { 19528 UserStartedState uss = mStartedUsers.valueAt(i); 19529 if (uss.mState != UserStartedState.STATE_STOPPING 19530 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19531 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19532 num++; 19533 } 19534 } 19535 } 19536 19537 @Override 19538 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19539 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19540 != PackageManager.PERMISSION_GRANTED) { 19541 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19542 + Binder.getCallingPid() 19543 + ", uid=" + Binder.getCallingUid() 19544 + " requires " + INTERACT_ACROSS_USERS_FULL; 19545 Slog.w(TAG, msg); 19546 throw new SecurityException(msg); 19547 } 19548 19549 mUserSwitchObservers.register(observer); 19550 } 19551 19552 @Override 19553 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19554 mUserSwitchObservers.unregister(observer); 19555 } 19556 19557 private boolean userExists(int userId) { 19558 if (userId == 0) { 19559 return true; 19560 } 19561 UserManagerService ums = getUserManagerLocked(); 19562 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19563 } 19564 19565 int[] getUsersLocked() { 19566 UserManagerService ums = getUserManagerLocked(); 19567 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19568 } 19569 19570 UserManagerService getUserManagerLocked() { 19571 if (mUserManager == null) { 19572 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19573 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19574 } 19575 return mUserManager; 19576 } 19577 19578 private int applyUserId(int uid, int userId) { 19579 return UserHandle.getUid(userId, uid); 19580 } 19581 19582 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19583 if (info == null) return null; 19584 ApplicationInfo newInfo = new ApplicationInfo(info); 19585 newInfo.uid = applyUserId(info.uid, userId); 19586 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19587 + info.packageName; 19588 return newInfo; 19589 } 19590 19591 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19592 if (aInfo == null 19593 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19594 return aInfo; 19595 } 19596 19597 ActivityInfo info = new ActivityInfo(aInfo); 19598 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19599 return info; 19600 } 19601 19602 private final class LocalService extends ActivityManagerInternal { 19603 @Override 19604 public void onWakefulnessChanged(int wakefulness) { 19605 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19606 } 19607 19608 @Override 19609 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19610 String processName, String abiOverride, int uid, Runnable crashHandler) { 19611 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19612 processName, abiOverride, uid, crashHandler); 19613 } 19614 } 19615 19616 /** 19617 * An implementation of IAppTask, that allows an app to manage its own tasks via 19618 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19619 * only the process that calls getAppTasks() can call the AppTask methods. 19620 */ 19621 class AppTaskImpl extends IAppTask.Stub { 19622 private int mTaskId; 19623 private int mCallingUid; 19624 19625 public AppTaskImpl(int taskId, int callingUid) { 19626 mTaskId = taskId; 19627 mCallingUid = callingUid; 19628 } 19629 19630 private void checkCaller() { 19631 if (mCallingUid != Binder.getCallingUid()) { 19632 throw new SecurityException("Caller " + mCallingUid 19633 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19634 } 19635 } 19636 19637 @Override 19638 public void finishAndRemoveTask() { 19639 checkCaller(); 19640 19641 synchronized (ActivityManagerService.this) { 19642 long origId = Binder.clearCallingIdentity(); 19643 try { 19644 if (!removeTaskByIdLocked(mTaskId, false)) { 19645 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19646 } 19647 } finally { 19648 Binder.restoreCallingIdentity(origId); 19649 } 19650 } 19651 } 19652 19653 @Override 19654 public ActivityManager.RecentTaskInfo getTaskInfo() { 19655 checkCaller(); 19656 19657 synchronized (ActivityManagerService.this) { 19658 long origId = Binder.clearCallingIdentity(); 19659 try { 19660 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19661 if (tr == null) { 19662 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19663 } 19664 return createRecentTaskInfoFromTaskRecord(tr); 19665 } finally { 19666 Binder.restoreCallingIdentity(origId); 19667 } 19668 } 19669 } 19670 19671 @Override 19672 public void moveToFront() { 19673 checkCaller(); 19674 // Will bring task to front if it already has a root activity. 19675 startActivityFromRecentsInner(mTaskId, null); 19676 } 19677 19678 @Override 19679 public int startActivity(IBinder whoThread, String callingPackage, 19680 Intent intent, String resolvedType, Bundle options) { 19681 checkCaller(); 19682 19683 int callingUser = UserHandle.getCallingUserId(); 19684 TaskRecord tr; 19685 IApplicationThread appThread; 19686 synchronized (ActivityManagerService.this) { 19687 tr = recentTaskForIdLocked(mTaskId); 19688 if (tr == null) { 19689 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19690 } 19691 appThread = ApplicationThreadNative.asInterface(whoThread); 19692 if (appThread == null) { 19693 throw new IllegalArgumentException("Bad app thread " + appThread); 19694 } 19695 } 19696 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19697 resolvedType, null, null, null, null, 0, 0, null, null, 19698 null, options, callingUser, null, tr); 19699 } 19700 19701 @Override 19702 public void setExcludeFromRecents(boolean exclude) { 19703 checkCaller(); 19704 19705 synchronized (ActivityManagerService.this) { 19706 long origId = Binder.clearCallingIdentity(); 19707 try { 19708 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19709 if (tr == null) { 19710 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19711 } 19712 Intent intent = tr.getBaseIntent(); 19713 if (exclude) { 19714 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19715 } else { 19716 intent.setFlags(intent.getFlags() 19717 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19718 } 19719 } finally { 19720 Binder.restoreCallingIdentity(origId); 19721 } 19722 } 19723 } 19724 } 19725} 19726