ActivityManagerService.java revision de313753d0fd0173d0558518d9a410fdc0127c76
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35import android.Manifest; 36import android.app.AppOpsManager; 37import android.app.ApplicationThreadNative; 38import android.app.IActivityContainer; 39import android.app.IActivityContainerCallback; 40import android.app.IAppTask; 41import android.app.ITaskStackListener; 42import android.app.ProfilerInfo; 43import android.app.admin.DevicePolicyManager; 44import android.app.usage.UsageEvents; 45import android.app.usage.UsageStatsManagerInternal; 46import android.appwidget.AppWidgetManager; 47import android.content.res.Resources; 48import android.graphics.Bitmap; 49import android.graphics.Point; 50import android.graphics.Rect; 51import android.os.BatteryStats; 52import android.os.PersistableBundle; 53import android.os.storage.IMountService; 54import android.os.storage.StorageManager; 55import android.service.voice.IVoiceInteractionSession; 56import android.util.ArrayMap; 57import android.util.ArraySet; 58import android.util.SparseIntArray; 59 60import com.android.internal.R; 61import com.android.internal.annotations.GuardedBy; 62import com.android.internal.app.IAppOpsService; 63import com.android.internal.app.IVoiceInteractor; 64import com.android.internal.app.ProcessMap; 65import com.android.internal.app.ProcessStats; 66import com.android.internal.os.BackgroundThread; 67import com.android.internal.os.BatteryStatsImpl; 68import com.android.internal.os.ProcessCpuTracker; 69import com.android.internal.os.TransferPipe; 70import com.android.internal.os.Zygote; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.MemInfoReader; 74import com.android.internal.util.Preconditions; 75import com.android.server.AppOpsService; 76import com.android.server.AttributeCache; 77import com.android.server.IntentResolver; 78import com.android.server.LocalServices; 79import com.android.server.ServiceThread; 80import com.android.server.SystemService; 81import com.android.server.SystemServiceManager; 82import com.android.server.Watchdog; 83import com.android.server.am.ActivityStack.ActivityState; 84import com.android.server.firewall.IntentFirewall; 85import com.android.server.pm.Installer; 86import com.android.server.pm.UserManagerService; 87import com.android.server.statusbar.StatusBarManagerInternal; 88import com.android.server.wm.AppTransition; 89import com.android.server.wm.WindowManagerService; 90import com.google.android.collect.Lists; 91import com.google.android.collect.Maps; 92 93import libcore.io.IoUtils; 94 95import org.xmlpull.v1.XmlPullParser; 96import org.xmlpull.v1.XmlPullParserException; 97import org.xmlpull.v1.XmlSerializer; 98 99import android.app.Activity; 100import android.app.ActivityManager; 101import android.app.ActivityManager.RunningTaskInfo; 102import android.app.ActivityManager.StackInfo; 103import android.app.ActivityManagerInternal; 104import android.app.ActivityManagerNative; 105import android.app.ActivityOptions; 106import android.app.ActivityThread; 107import android.app.AlertDialog; 108import android.app.AppGlobals; 109import android.app.ApplicationErrorReport; 110import android.app.Dialog; 111import android.app.IActivityController; 112import android.app.IApplicationThread; 113import android.app.IInstrumentationWatcher; 114import android.app.INotificationManager; 115import android.app.IProcessObserver; 116import android.app.IServiceConnection; 117import android.app.IStopUserCallback; 118import android.app.IUiAutomationConnection; 119import android.app.IUserSwitchObserver; 120import android.app.Instrumentation; 121import android.app.Notification; 122import android.app.NotificationManager; 123import android.app.PendingIntent; 124import android.app.backup.IBackupManager; 125import android.content.ActivityNotFoundException; 126import android.content.BroadcastReceiver; 127import android.content.ClipData; 128import android.content.ComponentCallbacks2; 129import android.content.ComponentName; 130import android.content.ContentProvider; 131import android.content.ContentResolver; 132import android.content.Context; 133import android.content.DialogInterface; 134import android.content.IContentProvider; 135import android.content.IIntentReceiver; 136import android.content.IIntentSender; 137import android.content.Intent; 138import android.content.IntentFilter; 139import android.content.IntentSender; 140import android.content.pm.ActivityInfo; 141import android.content.pm.ApplicationInfo; 142import android.content.pm.ConfigurationInfo; 143import android.content.pm.IPackageDataObserver; 144import android.content.pm.IPackageManager; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.PackageInfo; 147import android.content.pm.PackageManager; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.UserInfo; 150import android.content.pm.PackageManager.NameNotFoundException; 151import android.content.pm.PathPermission; 152import android.content.pm.ProviderInfo; 153import android.content.pm.ResolveInfo; 154import android.content.pm.ServiceInfo; 155import android.content.res.CompatibilityInfo; 156import android.content.res.Configuration; 157import android.net.Proxy; 158import android.net.ProxyInfo; 159import android.net.Uri; 160import android.os.Binder; 161import android.os.Build; 162import android.os.Bundle; 163import android.os.Debug; 164import android.os.DropBoxManager; 165import android.os.Environment; 166import android.os.FactoryTest; 167import android.os.FileObserver; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.IPermissionController; 172import android.os.IRemoteCallback; 173import android.os.IUserManager; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.PowerManagerInternal; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.SELinux; 183import android.os.ServiceManager; 184import android.os.StrictMode; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.UpdateLock; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.provider.Settings; 191import android.text.format.DateUtils; 192import android.text.format.Time; 193import android.util.AtomicFile; 194import android.util.EventLog; 195import android.util.Log; 196import android.util.Pair; 197import android.util.PrintWriterPrinter; 198import android.util.Slog; 199import android.util.SparseArray; 200import android.util.TimeUtils; 201import android.util.Xml; 202import android.view.Gravity; 203import android.view.LayoutInflater; 204import android.view.View; 205import android.view.WindowManager; 206 207import dalvik.system.VMRuntime; 208 209import java.io.BufferedInputStream; 210import java.io.BufferedOutputStream; 211import java.io.DataInputStream; 212import java.io.DataOutputStream; 213import java.io.File; 214import java.io.FileDescriptor; 215import java.io.FileInputStream; 216import java.io.FileNotFoundException; 217import java.io.FileOutputStream; 218import java.io.IOException; 219import java.io.InputStreamReader; 220import java.io.PrintWriter; 221import java.io.StringWriter; 222import java.lang.ref.WeakReference; 223import java.util.ArrayList; 224import java.util.Arrays; 225import java.util.Collections; 226import java.util.Comparator; 227import java.util.HashMap; 228import java.util.HashSet; 229import java.util.Iterator; 230import java.util.List; 231import java.util.Locale; 232import java.util.Map; 233import java.util.Set; 234import java.util.concurrent.atomic.AtomicBoolean; 235import java.util.concurrent.atomic.AtomicLong; 236 237public final class ActivityManagerService extends ActivityManagerNative 238 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 239 240 private static final String USER_DATA_DIR = "/data/user/"; 241 // File that stores last updated system version and called preboot receivers 242 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 243 244 static final String TAG = "ActivityManager"; 245 static final String TAG_MU = "ActivityManagerServiceMU"; 246 static final boolean DEBUG = false; 247 static final boolean localLOGV = DEBUG; 248 static final boolean DEBUG_BACKUP = localLOGV || false; 249 static final boolean DEBUG_BROADCAST = localLOGV || false; 250 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_CLEANUP = localLOGV || false; 253 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 254 static final boolean DEBUG_FOCUS = false; 255 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 256 static final boolean DEBUG_MU = localLOGV || false; 257 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 258 static final boolean DEBUG_LRU = localLOGV || false; 259 static final boolean DEBUG_PAUSE = localLOGV || false; 260 static final boolean DEBUG_POWER = localLOGV || false; 261 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 262 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 263 static final boolean DEBUG_PROCESSES = localLOGV || false; 264 static final boolean DEBUG_PROVIDER = localLOGV || false; 265 static final boolean DEBUG_RESULTS = localLOGV || false; 266 static final boolean DEBUG_SERVICE = localLOGV || false; 267 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 268 static final boolean DEBUG_STACK = localLOGV || false; 269 static final boolean DEBUG_SWITCH = localLOGV || false; 270 static final boolean DEBUG_TASKS = localLOGV || false; 271 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 272 static final boolean DEBUG_TRANSITION = localLOGV || false; 273 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 274 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 275 static final boolean DEBUG_VISBILITY = localLOGV || false; 276 static final boolean DEBUG_PSS = localLOGV || false; 277 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 278 static final boolean DEBUG_RECENTS = localLOGV || false; 279 static final boolean VALIDATE_TOKENS = false; 280 static final boolean SHOW_ACTIVITY_START_TIME = true; 281 282 // Control over CPU and battery monitoring. 283 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 284 static final boolean MONITOR_CPU_USAGE = true; 285 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 286 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 287 static final boolean MONITOR_THREAD_CPU_USAGE = false; 288 289 // The flags that are set for all calls we make to the package manager. 290 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 291 292 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 293 294 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 295 296 // Maximum number recent bitmaps to keep in memory. 297 static final int MAX_RECENT_BITMAPS = 3; 298 299 // Amount of time after a call to stopAppSwitches() during which we will 300 // prevent further untrusted switches from happening. 301 static final long APP_SWITCH_DELAY_TIME = 5*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real. 305 static final int PROC_START_TIMEOUT = 10*1000; 306 307 // How long we wait for a launched process to attach to the activity manager 308 // before we decide it's never going to come up for real, when the process was 309 // started with a wrapper for instrumentation (such as Valgrind) because it 310 // could take much longer than usual. 311 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 312 313 // How long to wait after going idle before forcing apps to GC. 314 static final int GC_TIMEOUT = 5*1000; 315 316 // The minimum amount of time between successive GC requests for a process. 317 static final int GC_MIN_INTERVAL = 60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process. 320 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 321 322 // The minimum amount of time between successive PSS requests for a process 323 // when the request is due to the memory state being lowered. 324 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 325 326 // The rate at which we check for apps using excessive power -- 15 mins. 327 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on wake locks to start killing things. 331 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // The minimum sample duration we will allow before deciding we have 334 // enough data on CPU usage to start killing things. 335 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 336 337 // How long we allow a receiver to run before giving up on it. 338 static final int BROADCAST_FG_TIMEOUT = 10*1000; 339 static final int BROADCAST_BG_TIMEOUT = 60*1000; 340 341 // How long we wait until we timeout on key dispatching. 342 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 343 344 // How long we wait until we timeout on key dispatching during instrumentation. 345 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 346 347 // Amount of time we wait for observers to handle a user switch before 348 // giving up on them and unfreezing the screen. 349 static final int USER_SWITCH_TIMEOUT = 2*1000; 350 351 // Maximum number of users we allow to be running at a time. 352 static final int MAX_RUNNING_USERS = 3; 353 354 // How long to wait in getAssistContextExtras for the activity and foreground services 355 // to respond with the result. 356 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 357 358 // Maximum number of persisted Uri grants a package is allowed 359 static final int MAX_PERSISTED_URI_GRANTS = 128; 360 361 static final int MY_PID = Process.myPid(); 362 363 static final String[] EMPTY_STRING_ARRAY = new String[0]; 364 365 // How many bytes to write into the dropbox log before truncating 366 static final int DROPBOX_MAX_SIZE = 256 * 1024; 367 368 // Access modes for handleIncomingUser. 369 static final int ALLOW_NON_FULL = 0; 370 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 371 static final int ALLOW_FULL_ONLY = 2; 372 373 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 374 375 // Delay in notifying task stack change listeners (in millis) 376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 377 378 /** All system services */ 379 SystemServiceManager mSystemServiceManager; 380 381 private Installer mInstaller; 382 383 /** Run all ActivityStacks through this */ 384 ActivityStackSupervisor mStackSupervisor; 385 386 /** Task stack change listeners. */ 387 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 388 new RemoteCallbackList<ITaskStackListener>(); 389 390 public IntentFirewall mIntentFirewall; 391 392 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 393 // default actuion automatically. Important for devices without direct input 394 // devices. 395 private boolean mShowDialogs = true; 396 397 BroadcastQueue mFgBroadcastQueue; 398 BroadcastQueue mBgBroadcastQueue; 399 // Convenient for easy iteration over the queues. Foreground is first 400 // so that dispatch of foreground broadcasts gets precedence. 401 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 402 403 BroadcastQueue broadcastQueueForIntent(Intent intent) { 404 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 405 if (DEBUG_BACKGROUND_BROADCAST) { 406 Slog.i(TAG, "Broadcast intent " + intent + " on " 407 + (isFg ? "foreground" : "background") 408 + " queue"); 409 } 410 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 411 } 412 413 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 414 for (BroadcastQueue queue : mBroadcastQueues) { 415 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 416 if (r != null) { 417 return r; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Activity we have told the window manager to have key focus. 425 */ 426 ActivityRecord mFocusedActivity = null; 427 428 /** 429 * List of intents that were used to start the most recent tasks. 430 */ 431 ArrayList<TaskRecord> mRecentTasks; 432 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 433 434 /** 435 * For addAppTask: cached of the last activity component that was added. 436 */ 437 ComponentName mLastAddedTaskComponent; 438 439 /** 440 * For addAppTask: cached of the last activity uid that was added. 441 */ 442 int mLastAddedTaskUid; 443 444 /** 445 * For addAppTask: cached of the last ActivityInfo that was added. 446 */ 447 ActivityInfo mLastAddedTaskActivity; 448 449 public class PendingAssistExtras extends Binder implements Runnable { 450 public final ActivityRecord activity; 451 public final Bundle extras; 452 public final Intent intent; 453 public final String hint; 454 public final int userHandle; 455 public boolean haveResult = false; 456 public Bundle result = null; 457 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 458 String _hint, int _userHandle) { 459 activity = _activity; 460 extras = _extras; 461 intent = _intent; 462 hint = _hint; 463 userHandle = _userHandle; 464 } 465 @Override 466 public void run() { 467 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 468 synchronized (this) { 469 haveResult = true; 470 notifyAll(); 471 } 472 } 473 } 474 475 final ArrayList<PendingAssistExtras> mPendingAssistExtras 476 = new ArrayList<PendingAssistExtras>(); 477 478 /** 479 * Process management. 480 */ 481 final ProcessList mProcessList = new ProcessList(); 482 483 /** 484 * All of the applications we currently have running organized by name. 485 * The keys are strings of the application package name (as 486 * returned by the package manager), and the keys are ApplicationRecord 487 * objects. 488 */ 489 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 490 491 /** 492 * Tracking long-term execution of processes to look for abuse and other 493 * bad app behavior. 494 */ 495 final ProcessStatsService mProcessStats; 496 497 /** 498 * The currently running isolated processes. 499 */ 500 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 501 502 /** 503 * Counter for assigning isolated process uids, to avoid frequently reusing the 504 * same ones. 505 */ 506 int mNextIsolatedProcessUid = 0; 507 508 /** 509 * The currently running heavy-weight process, if any. 510 */ 511 ProcessRecord mHeavyWeightProcess = null; 512 513 /** 514 * The last time that various processes have crashed. 515 */ 516 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 517 518 /** 519 * Information about a process that is currently marked as bad. 520 */ 521 static final class BadProcessInfo { 522 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 523 this.time = time; 524 this.shortMsg = shortMsg; 525 this.longMsg = longMsg; 526 this.stack = stack; 527 } 528 529 final long time; 530 final String shortMsg; 531 final String longMsg; 532 final String stack; 533 } 534 535 /** 536 * Set of applications that we consider to be bad, and will reject 537 * incoming broadcasts from (which the user has no control over). 538 * Processes are added to this set when they have crashed twice within 539 * a minimum amount of time; they are removed from it when they are 540 * later restarted (hopefully due to some user action). The value is the 541 * time it was added to the list. 542 */ 543 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 544 545 /** 546 * All of the processes we currently have running organized by pid. 547 * The keys are the pid running the application. 548 * 549 * <p>NOTE: This object is protected by its own lock, NOT the global 550 * activity manager lock! 551 */ 552 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 553 554 /** 555 * All of the processes that have been forced to be foreground. The key 556 * is the pid of the caller who requested it (we hold a death 557 * link on it). 558 */ 559 abstract class ForegroundToken implements IBinder.DeathRecipient { 560 int pid; 561 IBinder token; 562 } 563 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 564 565 /** 566 * List of records for processes that someone had tried to start before the 567 * system was ready. We don't start them at that point, but ensure they 568 * are started by the time booting is complete. 569 */ 570 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of persistent applications that are in the process 574 * of being started. 575 */ 576 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes that are being forcibly torn down. 580 */ 581 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * List of running applications, sorted by recent usage. 585 * The first entry in the list is the least recently used. 586 */ 587 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Where in mLruProcesses that the processes hosting activities start. 591 */ 592 int mLruProcessActivityStart = 0; 593 594 /** 595 * Where in mLruProcesses that the processes hosting services start. 596 * This is after (lower index) than mLruProcessesActivityStart. 597 */ 598 int mLruProcessServiceStart = 0; 599 600 /** 601 * List of processes that should gc as soon as things are idle. 602 */ 603 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 604 605 /** 606 * Processes we want to collect PSS data from. 607 */ 608 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 609 610 /** 611 * Last time we requested PSS data of all processes. 612 */ 613 long mLastFullPssTime = SystemClock.uptimeMillis(); 614 615 /** 616 * If set, the next time we collect PSS data we should do a full collection 617 * with data from native processes and the kernel. 618 */ 619 boolean mFullPssPending = false; 620 621 /** 622 * This is the process holding what we currently consider to be 623 * the "home" activity. 624 */ 625 ProcessRecord mHomeProcess; 626 627 /** 628 * This is the process holding the activity the user last visited that 629 * is in a different process from the one they are currently in. 630 */ 631 ProcessRecord mPreviousProcess; 632 633 /** 634 * The time at which the previous process was last visible. 635 */ 636 long mPreviousProcessVisibleTime; 637 638 /** 639 * Which uses have been started, so are allowed to run code. 640 */ 641 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 642 643 /** 644 * LRU list of history of current users. Most recently current is at the end. 645 */ 646 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 647 648 /** 649 * Constant array of the users that are currently started. 650 */ 651 int[] mStartedUserArray = new int[] { 0 }; 652 653 /** 654 * Registered observers of the user switching mechanics. 655 */ 656 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 657 = new RemoteCallbackList<IUserSwitchObserver>(); 658 659 /** 660 * Currently active user switch. 661 */ 662 Object mCurUserSwitchCallback; 663 664 /** 665 * Packages that the user has asked to have run in screen size 666 * compatibility mode instead of filling the screen. 667 */ 668 final CompatModePackages mCompatModePackages; 669 670 /** 671 * Set of IntentSenderRecord objects that are currently active. 672 */ 673 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 674 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 675 676 /** 677 * Fingerprints (hashCode()) of stack traces that we've 678 * already logged DropBox entries for. Guarded by itself. If 679 * something (rogue user app) forces this over 680 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 681 */ 682 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 683 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 684 685 /** 686 * Strict Mode background batched logging state. 687 * 688 * The string buffer is guarded by itself, and its lock is also 689 * used to determine if another batched write is already 690 * in-flight. 691 */ 692 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 693 694 /** 695 * Keeps track of all IIntentReceivers that have been registered for 696 * broadcasts. Hash keys are the receiver IBinder, hash value is 697 * a ReceiverList. 698 */ 699 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 700 new HashMap<IBinder, ReceiverList>(); 701 702 /** 703 * Resolver for broadcast intents to registered receivers. 704 * Holds BroadcastFilter (subclass of IntentFilter). 705 */ 706 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 707 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 708 @Override 709 protected boolean allowFilterResult( 710 BroadcastFilter filter, List<BroadcastFilter> dest) { 711 IBinder target = filter.receiverList.receiver.asBinder(); 712 for (int i=dest.size()-1; i>=0; i--) { 713 if (dest.get(i).receiverList.receiver.asBinder() == target) { 714 return false; 715 } 716 } 717 return true; 718 } 719 720 @Override 721 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 722 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 723 || userId == filter.owningUserId) { 724 return super.newResult(filter, match, userId); 725 } 726 return null; 727 } 728 729 @Override 730 protected BroadcastFilter[] newArray(int size) { 731 return new BroadcastFilter[size]; 732 } 733 734 @Override 735 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 736 return packageName.equals(filter.packageName); 737 } 738 }; 739 740 /** 741 * State of all active sticky broadcasts per user. Keys are the action of the 742 * sticky Intent, values are an ArrayList of all broadcasted intents with 743 * that action (which should usually be one). The SparseArray is keyed 744 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 745 * for stickies that are sent to all users. 746 */ 747 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 748 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 749 750 final ActiveServices mServices; 751 752 final static class Association { 753 final int mSourceUid; 754 final String mSourceProcess; 755 final int mTargetUid; 756 final ComponentName mTargetComponent; 757 final String mTargetProcess; 758 759 int mCount; 760 long mTime; 761 762 int mNesting; 763 long mStartTime; 764 765 Association(int sourceUid, String sourceProcess, int targetUid, 766 ComponentName targetComponent, String targetProcess) { 767 mSourceUid = sourceUid; 768 mSourceProcess = sourceProcess; 769 mTargetUid = targetUid; 770 mTargetComponent = targetComponent; 771 mTargetProcess = targetProcess; 772 } 773 } 774 775 /** 776 * When service association tracking is enabled, this is all of the associations we 777 * have seen. Mapping is target uid -> target component -> source uid -> source process name 778 * -> association data. 779 */ 780 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 781 mAssociations = new SparseArray<>(); 782 boolean mTrackingAssociations; 783 784 /** 785 * Backup/restore process management 786 */ 787 String mBackupAppName = null; 788 BackupRecord mBackupTarget = null; 789 790 final ProviderMap mProviderMap; 791 792 /** 793 * List of content providers who have clients waiting for them. The 794 * application is currently being launched and the provider will be 795 * removed from this list once it is published. 796 */ 797 final ArrayList<ContentProviderRecord> mLaunchingProviders 798 = new ArrayList<ContentProviderRecord>(); 799 800 /** 801 * File storing persisted {@link #mGrantedUriPermissions}. 802 */ 803 private final AtomicFile mGrantFile; 804 805 /** XML constants used in {@link #mGrantFile} */ 806 private static final String TAG_URI_GRANTS = "uri-grants"; 807 private static final String TAG_URI_GRANT = "uri-grant"; 808 private static final String ATTR_USER_HANDLE = "userHandle"; 809 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 810 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 811 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 812 private static final String ATTR_TARGET_PKG = "targetPkg"; 813 private static final String ATTR_URI = "uri"; 814 private static final String ATTR_MODE_FLAGS = "modeFlags"; 815 private static final String ATTR_CREATED_TIME = "createdTime"; 816 private static final String ATTR_PREFIX = "prefix"; 817 818 /** 819 * Global set of specific {@link Uri} permissions that have been granted. 820 * This optimized lookup structure maps from {@link UriPermission#targetUid} 821 * to {@link UriPermission#uri} to {@link UriPermission}. 822 */ 823 @GuardedBy("this") 824 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 825 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 826 827 public static class GrantUri { 828 public final int sourceUserId; 829 public final Uri uri; 830 public boolean prefix; 831 832 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 833 this.sourceUserId = sourceUserId; 834 this.uri = uri; 835 this.prefix = prefix; 836 } 837 838 @Override 839 public int hashCode() { 840 int hashCode = 1; 841 hashCode = 31 * hashCode + sourceUserId; 842 hashCode = 31 * hashCode + uri.hashCode(); 843 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 844 return hashCode; 845 } 846 847 @Override 848 public boolean equals(Object o) { 849 if (o instanceof GrantUri) { 850 GrantUri other = (GrantUri) o; 851 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 852 && prefix == other.prefix; 853 } 854 return false; 855 } 856 857 @Override 858 public String toString() { 859 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 860 if (prefix) result += " [prefix]"; 861 return result; 862 } 863 864 public String toSafeString() { 865 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 866 if (prefix) result += " [prefix]"; 867 return result; 868 } 869 870 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 871 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 872 ContentProvider.getUriWithoutUserId(uri), false); 873 } 874 } 875 876 CoreSettingsObserver mCoreSettingsObserver; 877 878 /** 879 * Thread-local storage used to carry caller permissions over through 880 * indirect content-provider access. 881 */ 882 private class Identity { 883 public final IBinder token; 884 public final int pid; 885 public final int uid; 886 887 Identity(IBinder _token, int _pid, int _uid) { 888 token = _token; 889 pid = _pid; 890 uid = _uid; 891 } 892 } 893 894 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 895 896 /** 897 * All information we have collected about the runtime performance of 898 * any user id that can impact battery performance. 899 */ 900 final BatteryStatsService mBatteryStatsService; 901 902 /** 903 * Information about component usage 904 */ 905 UsageStatsManagerInternal mUsageStatsService; 906 907 /** 908 * Information about and control over application operations 909 */ 910 final AppOpsService mAppOpsService; 911 912 /** 913 * Save recent tasks information across reboots. 914 */ 915 final TaskPersister mTaskPersister; 916 917 /** 918 * Current configuration information. HistoryRecord objects are given 919 * a reference to this object to indicate which configuration they are 920 * currently running in, so this object must be kept immutable. 921 */ 922 Configuration mConfiguration = new Configuration(); 923 924 /** 925 * Current sequencing integer of the configuration, for skipping old 926 * configurations. 927 */ 928 int mConfigurationSeq = 0; 929 930 /** 931 * Hardware-reported OpenGLES version. 932 */ 933 final int GL_ES_VERSION; 934 935 /** 936 * List of initialization arguments to pass to all processes when binding applications to them. 937 * For example, references to the commonly used services. 938 */ 939 HashMap<String, IBinder> mAppBindArgs; 940 941 /** 942 * Temporary to avoid allocations. Protected by main lock. 943 */ 944 final StringBuilder mStringBuilder = new StringBuilder(256); 945 946 /** 947 * Used to control how we initialize the service. 948 */ 949 ComponentName mTopComponent; 950 String mTopAction = Intent.ACTION_MAIN; 951 String mTopData; 952 boolean mProcessesReady = false; 953 boolean mSystemReady = false; 954 boolean mBooting = false; 955 boolean mCallFinishBooting = false; 956 boolean mBootAnimationComplete = false; 957 boolean mWaitingUpdate = false; 958 boolean mDidUpdate = false; 959 boolean mOnBattery = false; 960 boolean mLaunchWarningShown = false; 961 962 Context mContext; 963 964 int mFactoryTest; 965 966 boolean mCheckedForSetup; 967 968 /** 969 * The time at which we will allow normal application switches again, 970 * after a call to {@link #stopAppSwitches()}. 971 */ 972 long mAppSwitchesAllowedTime; 973 974 /** 975 * This is set to true after the first switch after mAppSwitchesAllowedTime 976 * is set; any switches after that will clear the time. 977 */ 978 boolean mDidAppSwitch; 979 980 /** 981 * Last time (in realtime) at which we checked for power usage. 982 */ 983 long mLastPowerCheckRealtime; 984 985 /** 986 * Last time (in uptime) at which we checked for power usage. 987 */ 988 long mLastPowerCheckUptime; 989 990 /** 991 * Set while we are wanting to sleep, to prevent any 992 * activities from being started/resumed. 993 */ 994 private boolean mSleeping = false; 995 996 /** 997 * Set while we are running a voice interaction. This overrides 998 * sleeping while it is active. 999 */ 1000 private boolean mRunningVoice = false; 1001 1002 /** 1003 * State of external calls telling us if the device is awake or asleep. 1004 */ 1005 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 1006 1007 static final int LOCK_SCREEN_HIDDEN = 0; 1008 static final int LOCK_SCREEN_LEAVING = 1; 1009 static final int LOCK_SCREEN_SHOWN = 2; 1010 /** 1011 * State of external call telling us if the lock screen is shown. 1012 */ 1013 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 1014 1015 /** 1016 * Set if we are shutting down the system, similar to sleeping. 1017 */ 1018 boolean mShuttingDown = false; 1019 1020 /** 1021 * Current sequence id for oom_adj computation traversal. 1022 */ 1023 int mAdjSeq = 0; 1024 1025 /** 1026 * Current sequence id for process LRU updating. 1027 */ 1028 int mLruSeq = 0; 1029 1030 /** 1031 * Keep track of the non-cached/empty process we last found, to help 1032 * determine how to distribute cached/empty processes next time. 1033 */ 1034 int mNumNonCachedProcs = 0; 1035 1036 /** 1037 * Keep track of the number of cached hidden procs, to balance oom adj 1038 * distribution between those and empty procs. 1039 */ 1040 int mNumCachedHiddenProcs = 0; 1041 1042 /** 1043 * Keep track of the number of service processes we last found, to 1044 * determine on the next iteration which should be B services. 1045 */ 1046 int mNumServiceProcs = 0; 1047 int mNewNumAServiceProcs = 0; 1048 int mNewNumServiceProcs = 0; 1049 1050 /** 1051 * Allow the current computed overall memory level of the system to go down? 1052 * This is set to false when we are killing processes for reasons other than 1053 * memory management, so that the now smaller process list will not be taken as 1054 * an indication that memory is tighter. 1055 */ 1056 boolean mAllowLowerMemLevel = false; 1057 1058 /** 1059 * The last computed memory level, for holding when we are in a state that 1060 * processes are going away for other reasons. 1061 */ 1062 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1063 1064 /** 1065 * The last total number of process we have, to determine if changes actually look 1066 * like a shrinking number of process due to lower RAM. 1067 */ 1068 int mLastNumProcesses; 1069 1070 /** 1071 * The uptime of the last time we performed idle maintenance. 1072 */ 1073 long mLastIdleTime = SystemClock.uptimeMillis(); 1074 1075 /** 1076 * Total time spent with RAM that has been added in the past since the last idle time. 1077 */ 1078 long mLowRamTimeSinceLastIdle = 0; 1079 1080 /** 1081 * If RAM is currently low, when that horrible situation started. 1082 */ 1083 long mLowRamStartTime = 0; 1084 1085 /** 1086 * For reporting to battery stats the current top application. 1087 */ 1088 private String mCurResumedPackage = null; 1089 private int mCurResumedUid = -1; 1090 1091 /** 1092 * For reporting to battery stats the apps currently running foreground 1093 * service. The ProcessMap is package/uid tuples; each of these contain 1094 * an array of the currently foreground processes. 1095 */ 1096 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1097 = new ProcessMap<ArrayList<ProcessRecord>>(); 1098 1099 /** 1100 * This is set if we had to do a delayed dexopt of an app before launching 1101 * it, to increase the ANR timeouts in that case. 1102 */ 1103 boolean mDidDexOpt; 1104 1105 /** 1106 * Set if the systemServer made a call to enterSafeMode. 1107 */ 1108 boolean mSafeMode; 1109 1110 /** 1111 * If true, we are running under a test environment so will sample PSS from processes 1112 * much more rapidly to try to collect better data when the tests are rapidly 1113 * running through apps. 1114 */ 1115 boolean mTestPssMode = false; 1116 1117 String mDebugApp = null; 1118 boolean mWaitForDebugger = false; 1119 boolean mDebugTransient = false; 1120 String mOrigDebugApp = null; 1121 boolean mOrigWaitForDebugger = false; 1122 boolean mAlwaysFinishActivities = false; 1123 IActivityController mController = null; 1124 String mProfileApp = null; 1125 ProcessRecord mProfileProc = null; 1126 String mProfileFile; 1127 ParcelFileDescriptor mProfileFd; 1128 int mSamplingInterval = 0; 1129 boolean mAutoStopProfiler = false; 1130 int mProfileType = 0; 1131 String mOpenGlTraceApp = null; 1132 1133 final long[] mTmpLong = new long[1]; 1134 1135 static class ProcessChangeItem { 1136 static final int CHANGE_ACTIVITIES = 1<<0; 1137 static final int CHANGE_PROCESS_STATE = 1<<1; 1138 int changes; 1139 int uid; 1140 int pid; 1141 int processState; 1142 boolean foregroundActivities; 1143 } 1144 1145 final RemoteCallbackList<IProcessObserver> mProcessObservers 1146 = new RemoteCallbackList<IProcessObserver>(); 1147 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1148 1149 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1150 = new ArrayList<ProcessChangeItem>(); 1151 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1152 = new ArrayList<ProcessChangeItem>(); 1153 1154 /** 1155 * Runtime CPU use collection thread. This object's lock is used to 1156 * perform synchronization with the thread (notifying it to run). 1157 */ 1158 final Thread mProcessCpuThread; 1159 1160 /** 1161 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1162 * Must acquire this object's lock when accessing it. 1163 * NOTE: this lock will be held while doing long operations (trawling 1164 * through all processes in /proc), so it should never be acquired by 1165 * any critical paths such as when holding the main activity manager lock. 1166 */ 1167 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1168 MONITOR_THREAD_CPU_USAGE); 1169 final AtomicLong mLastCpuTime = new AtomicLong(0); 1170 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1171 1172 long mLastWriteTime = 0; 1173 1174 /** 1175 * Used to retain an update lock when the foreground activity is in 1176 * immersive mode. 1177 */ 1178 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1179 1180 /** 1181 * Set to true after the system has finished booting. 1182 */ 1183 boolean mBooted = false; 1184 1185 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1186 int mProcessLimitOverride = -1; 1187 1188 WindowManagerService mWindowManager; 1189 1190 final ActivityThread mSystemThread; 1191 1192 // Holds the current foreground user's id 1193 int mCurrentUserId = 0; 1194 // Holds the target user's id during a user switch 1195 int mTargetUserId = UserHandle.USER_NULL; 1196 // If there are multiple profiles for the current user, their ids are here 1197 // Currently only the primary user can have managed profiles 1198 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1199 1200 /** 1201 * Mapping from each known user ID to the profile group ID it is associated with. 1202 */ 1203 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1204 1205 private UserManagerService mUserManager; 1206 1207 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1208 final ProcessRecord mApp; 1209 final int mPid; 1210 final IApplicationThread mAppThread; 1211 1212 AppDeathRecipient(ProcessRecord app, int pid, 1213 IApplicationThread thread) { 1214 if (localLOGV) Slog.v( 1215 TAG, "New death recipient " + this 1216 + " for thread " + thread.asBinder()); 1217 mApp = app; 1218 mPid = pid; 1219 mAppThread = thread; 1220 } 1221 1222 @Override 1223 public void binderDied() { 1224 if (localLOGV) Slog.v( 1225 TAG, "Death received in " + this 1226 + " for thread " + mAppThread.asBinder()); 1227 synchronized(ActivityManagerService.this) { 1228 appDiedLocked(mApp, mPid, mAppThread); 1229 } 1230 } 1231 } 1232 1233 static final int SHOW_ERROR_MSG = 1; 1234 static final int SHOW_NOT_RESPONDING_MSG = 2; 1235 static final int SHOW_FACTORY_ERROR_MSG = 3; 1236 static final int UPDATE_CONFIGURATION_MSG = 4; 1237 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1238 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1239 static final int SERVICE_TIMEOUT_MSG = 12; 1240 static final int UPDATE_TIME_ZONE = 13; 1241 static final int SHOW_UID_ERROR_MSG = 14; 1242 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1243 static final int PROC_START_TIMEOUT_MSG = 20; 1244 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1245 static final int KILL_APPLICATION_MSG = 22; 1246 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1247 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1248 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1249 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1250 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1251 static final int CLEAR_DNS_CACHE_MSG = 28; 1252 static final int UPDATE_HTTP_PROXY_MSG = 29; 1253 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1254 static final int DISPATCH_PROCESSES_CHANGED = 31; 1255 static final int DISPATCH_PROCESS_DIED = 32; 1256 static final int REPORT_MEM_USAGE_MSG = 33; 1257 static final int REPORT_USER_SWITCH_MSG = 34; 1258 static final int CONTINUE_USER_SWITCH_MSG = 35; 1259 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1260 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1261 static final int PERSIST_URI_GRANTS_MSG = 38; 1262 static final int REQUEST_ALL_PSS_MSG = 39; 1263 static final int START_PROFILES_MSG = 40; 1264 static final int UPDATE_TIME = 41; 1265 static final int SYSTEM_USER_START_MSG = 42; 1266 static final int SYSTEM_USER_CURRENT_MSG = 43; 1267 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1268 static final int FINISH_BOOTING_MSG = 45; 1269 static final int START_USER_SWITCH_MSG = 46; 1270 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1271 static final int DISMISS_DIALOG_MSG = 48; 1272 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1273 1274 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1275 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1276 static final int FIRST_COMPAT_MODE_MSG = 300; 1277 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1278 1279 CompatModeDialog mCompatModeDialog; 1280 long mLastMemUsageReportTime = 0; 1281 1282 /** 1283 * Flag whether the current user is a "monkey", i.e. whether 1284 * the UI is driven by a UI automation tool. 1285 */ 1286 private boolean mUserIsMonkey; 1287 1288 /** Flag whether the device has a Recents UI */ 1289 boolean mHasRecents; 1290 1291 /** The dimensions of the thumbnails in the Recents UI. */ 1292 int mThumbnailWidth; 1293 int mThumbnailHeight; 1294 1295 final ServiceThread mHandlerThread; 1296 final MainHandler mHandler; 1297 1298 final class MainHandler extends Handler { 1299 public MainHandler(Looper looper) { 1300 super(looper, null, true); 1301 } 1302 1303 @Override 1304 public void handleMessage(Message msg) { 1305 switch (msg.what) { 1306 case SHOW_ERROR_MSG: { 1307 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1308 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1309 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1310 synchronized (ActivityManagerService.this) { 1311 ProcessRecord proc = (ProcessRecord)data.get("app"); 1312 AppErrorResult res = (AppErrorResult) data.get("result"); 1313 if (proc != null && proc.crashDialog != null) { 1314 Slog.e(TAG, "App already has crash dialog: " + proc); 1315 if (res != null) { 1316 res.set(0); 1317 } 1318 return; 1319 } 1320 boolean isBackground = (UserHandle.getAppId(proc.uid) 1321 >= Process.FIRST_APPLICATION_UID 1322 && proc.pid != MY_PID); 1323 for (int userId : mCurrentProfileIds) { 1324 isBackground &= (proc.userId != userId); 1325 } 1326 if (isBackground && !showBackground) { 1327 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1328 if (res != null) { 1329 res.set(0); 1330 } 1331 return; 1332 } 1333 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1334 Dialog d = new AppErrorDialog(mContext, 1335 ActivityManagerService.this, res, proc); 1336 d.show(); 1337 proc.crashDialog = d; 1338 } else { 1339 // The device is asleep, so just pretend that the user 1340 // saw a crash dialog and hit "force quit". 1341 if (res != null) { 1342 res.set(0); 1343 } 1344 } 1345 } 1346 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_NOT_RESPONDING_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1352 ProcessRecord proc = (ProcessRecord)data.get("app"); 1353 if (proc != null && proc.anrDialog != null) { 1354 Slog.e(TAG, "App already has anr dialog: " + proc); 1355 return; 1356 } 1357 1358 Intent intent = new Intent("android.intent.action.ANR"); 1359 if (!mProcessesReady) { 1360 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1361 | Intent.FLAG_RECEIVER_FOREGROUND); 1362 } 1363 broadcastIntentLocked(null, null, intent, 1364 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1365 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1366 1367 if (mShowDialogs) { 1368 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1369 mContext, proc, (ActivityRecord)data.get("activity"), 1370 msg.arg1 != 0); 1371 d.show(); 1372 proc.anrDialog = d; 1373 } else { 1374 // Just kill the app if there is no dialog to be shown. 1375 killAppAtUsersRequest(proc, null); 1376 } 1377 } 1378 1379 ensureBootCompleted(); 1380 } break; 1381 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1382 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1383 synchronized (ActivityManagerService.this) { 1384 ProcessRecord proc = (ProcessRecord) data.get("app"); 1385 if (proc == null) { 1386 Slog.e(TAG, "App not found when showing strict mode dialog."); 1387 break; 1388 } 1389 if (proc.crashDialog != null) { 1390 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1391 return; 1392 } 1393 AppErrorResult res = (AppErrorResult) data.get("result"); 1394 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1395 Dialog d = new StrictModeViolationDialog(mContext, 1396 ActivityManagerService.this, res, proc); 1397 d.show(); 1398 proc.crashDialog = d; 1399 } else { 1400 // The device is asleep, so just pretend that the user 1401 // saw a crash dialog and hit "force quit". 1402 res.set(0); 1403 } 1404 } 1405 ensureBootCompleted(); 1406 } break; 1407 case SHOW_FACTORY_ERROR_MSG: { 1408 Dialog d = new FactoryErrorDialog( 1409 mContext, msg.getData().getCharSequence("msg")); 1410 d.show(); 1411 ensureBootCompleted(); 1412 } break; 1413 case UPDATE_CONFIGURATION_MSG: { 1414 final ContentResolver resolver = mContext.getContentResolver(); 1415 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1416 } break; 1417 case GC_BACKGROUND_PROCESSES_MSG: { 1418 synchronized (ActivityManagerService.this) { 1419 performAppGcsIfAppropriateLocked(); 1420 } 1421 } break; 1422 case WAIT_FOR_DEBUGGER_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 ProcessRecord app = (ProcessRecord)msg.obj; 1425 if (msg.arg1 != 0) { 1426 if (!app.waitedForDebugger) { 1427 Dialog d = new AppWaitingForDebuggerDialog( 1428 ActivityManagerService.this, 1429 mContext, app); 1430 app.waitDialog = d; 1431 app.waitedForDebugger = true; 1432 d.show(); 1433 } 1434 } else { 1435 if (app.waitDialog != null) { 1436 app.waitDialog.dismiss(); 1437 app.waitDialog = null; 1438 } 1439 } 1440 } 1441 } break; 1442 case SERVICE_TIMEOUT_MSG: { 1443 if (mDidDexOpt) { 1444 mDidDexOpt = false; 1445 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1446 nmsg.obj = msg.obj; 1447 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1448 return; 1449 } 1450 mServices.serviceTimeout((ProcessRecord)msg.obj); 1451 } break; 1452 case UPDATE_TIME_ZONE: { 1453 synchronized (ActivityManagerService.this) { 1454 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1455 ProcessRecord r = mLruProcesses.get(i); 1456 if (r.thread != null) { 1457 try { 1458 r.thread.updateTimeZone(); 1459 } catch (RemoteException ex) { 1460 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1461 } 1462 } 1463 } 1464 } 1465 } break; 1466 case CLEAR_DNS_CACHE_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1469 ProcessRecord r = mLruProcesses.get(i); 1470 if (r.thread != null) { 1471 try { 1472 r.thread.clearDnsCache(); 1473 } catch (RemoteException ex) { 1474 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1475 } 1476 } 1477 } 1478 } 1479 } break; 1480 case UPDATE_HTTP_PROXY_MSG: { 1481 ProxyInfo proxy = (ProxyInfo)msg.obj; 1482 String host = ""; 1483 String port = ""; 1484 String exclList = ""; 1485 Uri pacFileUrl = Uri.EMPTY; 1486 if (proxy != null) { 1487 host = proxy.getHost(); 1488 port = Integer.toString(proxy.getPort()); 1489 exclList = proxy.getExclusionListAsString(); 1490 pacFileUrl = proxy.getPacFileUrl(); 1491 } 1492 synchronized (ActivityManagerService.this) { 1493 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1494 ProcessRecord r = mLruProcesses.get(i); 1495 if (r.thread != null) { 1496 try { 1497 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1498 } catch (RemoteException ex) { 1499 Slog.w(TAG, "Failed to update http proxy for: " + 1500 r.info.processName); 1501 } 1502 } 1503 } 1504 } 1505 } break; 1506 case SHOW_UID_ERROR_MSG: { 1507 if (mShowDialogs) { 1508 AlertDialog d = new BaseErrorDialog(mContext); 1509 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1510 d.setCancelable(false); 1511 d.setTitle(mContext.getText(R.string.android_system_label)); 1512 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1513 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1514 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1515 d.show(); 1516 } 1517 } break; 1518 case SHOW_FINGERPRINT_ERROR_MSG: { 1519 if (mShowDialogs) { 1520 AlertDialog d = new BaseErrorDialog(mContext); 1521 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1522 d.setCancelable(false); 1523 d.setTitle(mContext.getText(R.string.android_system_label)); 1524 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1525 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1526 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1527 d.show(); 1528 } 1529 } break; 1530 case PROC_START_TIMEOUT_MSG: { 1531 if (mDidDexOpt) { 1532 mDidDexOpt = false; 1533 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1534 nmsg.obj = msg.obj; 1535 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1536 return; 1537 } 1538 ProcessRecord app = (ProcessRecord)msg.obj; 1539 synchronized (ActivityManagerService.this) { 1540 processStartTimedOutLocked(app); 1541 } 1542 } break; 1543 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1544 synchronized (ActivityManagerService.this) { 1545 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1546 } 1547 } break; 1548 case KILL_APPLICATION_MSG: { 1549 synchronized (ActivityManagerService.this) { 1550 int appid = msg.arg1; 1551 boolean restart = (msg.arg2 == 1); 1552 Bundle bundle = (Bundle)msg.obj; 1553 String pkg = bundle.getString("pkg"); 1554 String reason = bundle.getString("reason"); 1555 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1556 false, UserHandle.USER_ALL, reason); 1557 } 1558 } break; 1559 case FINALIZE_PENDING_INTENT_MSG: { 1560 ((PendingIntentRecord)msg.obj).completeFinalize(); 1561 } break; 1562 case POST_HEAVY_NOTIFICATION_MSG: { 1563 INotificationManager inm = NotificationManager.getService(); 1564 if (inm == null) { 1565 return; 1566 } 1567 1568 ActivityRecord root = (ActivityRecord)msg.obj; 1569 ProcessRecord process = root.app; 1570 if (process == null) { 1571 return; 1572 } 1573 1574 try { 1575 Context context = mContext.createPackageContext(process.info.packageName, 0); 1576 String text = mContext.getString(R.string.heavy_weight_notification, 1577 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1578 Notification notification = new Notification(); 1579 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1580 notification.when = 0; 1581 notification.flags = Notification.FLAG_ONGOING_EVENT; 1582 notification.tickerText = text; 1583 notification.defaults = 0; // please be quiet 1584 notification.sound = null; 1585 notification.vibrate = null; 1586 notification.color = mContext.getResources().getColor( 1587 com.android.internal.R.color.system_notification_accent_color); 1588 notification.setLatestEventInfo(context, text, 1589 mContext.getText(R.string.heavy_weight_notification_detail), 1590 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1591 PendingIntent.FLAG_CANCEL_CURRENT, null, 1592 new UserHandle(root.userId))); 1593 1594 try { 1595 int[] outId = new int[1]; 1596 inm.enqueueNotificationWithTag("android", "android", null, 1597 R.string.heavy_weight_notification, 1598 notification, outId, root.userId); 1599 } catch (RuntimeException e) { 1600 Slog.w(ActivityManagerService.TAG, 1601 "Error showing notification for heavy-weight app", e); 1602 } catch (RemoteException e) { 1603 } 1604 } catch (NameNotFoundException e) { 1605 Slog.w(TAG, "Unable to create context for heavy notification", e); 1606 } 1607 } break; 1608 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1609 INotificationManager inm = NotificationManager.getService(); 1610 if (inm == null) { 1611 return; 1612 } 1613 try { 1614 inm.cancelNotificationWithTag("android", null, 1615 R.string.heavy_weight_notification, msg.arg1); 1616 } catch (RuntimeException e) { 1617 Slog.w(ActivityManagerService.TAG, 1618 "Error canceling notification for service", e); 1619 } catch (RemoteException e) { 1620 } 1621 } break; 1622 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1623 synchronized (ActivityManagerService.this) { 1624 checkExcessivePowerUsageLocked(true); 1625 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1626 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1627 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1628 } 1629 } break; 1630 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1631 synchronized (ActivityManagerService.this) { 1632 ActivityRecord ar = (ActivityRecord)msg.obj; 1633 if (mCompatModeDialog != null) { 1634 if (mCompatModeDialog.mAppInfo.packageName.equals( 1635 ar.info.applicationInfo.packageName)) { 1636 return; 1637 } 1638 mCompatModeDialog.dismiss(); 1639 mCompatModeDialog = null; 1640 } 1641 if (ar != null && false) { 1642 if (mCompatModePackages.getPackageAskCompatModeLocked( 1643 ar.packageName)) { 1644 int mode = mCompatModePackages.computeCompatModeLocked( 1645 ar.info.applicationInfo); 1646 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1647 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1648 mCompatModeDialog = new CompatModeDialog( 1649 ActivityManagerService.this, mContext, 1650 ar.info.applicationInfo); 1651 mCompatModeDialog.show(); 1652 } 1653 } 1654 } 1655 } 1656 break; 1657 } 1658 case DISPATCH_PROCESSES_CHANGED: { 1659 dispatchProcessesChanged(); 1660 break; 1661 } 1662 case DISPATCH_PROCESS_DIED: { 1663 final int pid = msg.arg1; 1664 final int uid = msg.arg2; 1665 dispatchProcessDied(pid, uid); 1666 break; 1667 } 1668 case REPORT_MEM_USAGE_MSG: { 1669 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1670 Thread thread = new Thread() { 1671 @Override public void run() { 1672 reportMemUsage(memInfos); 1673 } 1674 }; 1675 thread.start(); 1676 break; 1677 } 1678 case START_USER_SWITCH_MSG: { 1679 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1680 break; 1681 } 1682 case REPORT_USER_SWITCH_MSG: { 1683 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1684 break; 1685 } 1686 case CONTINUE_USER_SWITCH_MSG: { 1687 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1688 break; 1689 } 1690 case USER_SWITCH_TIMEOUT_MSG: { 1691 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1692 break; 1693 } 1694 case IMMERSIVE_MODE_LOCK_MSG: { 1695 final boolean nextState = (msg.arg1 != 0); 1696 if (mUpdateLock.isHeld() != nextState) { 1697 if (DEBUG_IMMERSIVE) { 1698 final ActivityRecord r = (ActivityRecord) msg.obj; 1699 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1700 } 1701 if (nextState) { 1702 mUpdateLock.acquire(); 1703 } else { 1704 mUpdateLock.release(); 1705 } 1706 } 1707 break; 1708 } 1709 case PERSIST_URI_GRANTS_MSG: { 1710 writeGrantedUriPermissions(); 1711 break; 1712 } 1713 case REQUEST_ALL_PSS_MSG: { 1714 synchronized (ActivityManagerService.this) { 1715 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1716 } 1717 break; 1718 } 1719 case START_PROFILES_MSG: { 1720 synchronized (ActivityManagerService.this) { 1721 startProfilesLocked(); 1722 } 1723 break; 1724 } 1725 case UPDATE_TIME: { 1726 synchronized (ActivityManagerService.this) { 1727 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1728 ProcessRecord r = mLruProcesses.get(i); 1729 if (r.thread != null) { 1730 try { 1731 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1732 } catch (RemoteException ex) { 1733 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1734 } 1735 } 1736 } 1737 } 1738 break; 1739 } 1740 case SYSTEM_USER_START_MSG: { 1741 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1742 Integer.toString(msg.arg1), msg.arg1); 1743 mSystemServiceManager.startUser(msg.arg1); 1744 break; 1745 } 1746 case SYSTEM_USER_CURRENT_MSG: { 1747 mBatteryStatsService.noteEvent( 1748 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1749 Integer.toString(msg.arg2), msg.arg2); 1750 mBatteryStatsService.noteEvent( 1751 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1752 Integer.toString(msg.arg1), msg.arg1); 1753 mSystemServiceManager.switchUser(msg.arg1); 1754 break; 1755 } 1756 case ENTER_ANIMATION_COMPLETE_MSG: { 1757 synchronized (ActivityManagerService.this) { 1758 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1759 if (r != null && r.app != null && r.app.thread != null) { 1760 try { 1761 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1762 } catch (RemoteException e) { 1763 } 1764 } 1765 } 1766 break; 1767 } 1768 case FINISH_BOOTING_MSG: { 1769 if (msg.arg1 != 0) { 1770 finishBooting(); 1771 } 1772 if (msg.arg2 != 0) { 1773 enableScreenAfterBoot(); 1774 } 1775 break; 1776 } 1777 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1778 try { 1779 Locale l = (Locale) msg.obj; 1780 IBinder service = ServiceManager.getService("mount"); 1781 IMountService mountService = IMountService.Stub.asInterface(service); 1782 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1783 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1784 } catch (RemoteException e) { 1785 Log.e(TAG, "Error storing locale for decryption UI", e); 1786 } 1787 break; 1788 } 1789 case DISMISS_DIALOG_MSG: { 1790 final Dialog d = (Dialog) msg.obj; 1791 d.dismiss(); 1792 break; 1793 } 1794 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1795 synchronized (ActivityManagerService.this) { 1796 int i = mTaskStackListeners.beginBroadcast(); 1797 while (i > 0) { 1798 i--; 1799 try { 1800 // Make a one-way callback to the listener 1801 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1802 } catch (RemoteException e){ 1803 // Handled by the RemoteCallbackList 1804 } 1805 } 1806 mTaskStackListeners.finishBroadcast(); 1807 } 1808 break; 1809 } 1810 } 1811 } 1812 }; 1813 1814 static final int COLLECT_PSS_BG_MSG = 1; 1815 1816 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1817 @Override 1818 public void handleMessage(Message msg) { 1819 switch (msg.what) { 1820 case COLLECT_PSS_BG_MSG: { 1821 long start = SystemClock.uptimeMillis(); 1822 MemInfoReader memInfo = null; 1823 synchronized (ActivityManagerService.this) { 1824 if (mFullPssPending) { 1825 mFullPssPending = false; 1826 memInfo = new MemInfoReader(); 1827 } 1828 } 1829 if (memInfo != null) { 1830 updateCpuStatsNow(); 1831 long nativeTotalPss = 0; 1832 synchronized (mProcessCpuTracker) { 1833 final int N = mProcessCpuTracker.countStats(); 1834 for (int j=0; j<N; j++) { 1835 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1836 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1837 // This is definitely an application process; skip it. 1838 continue; 1839 } 1840 synchronized (mPidsSelfLocked) { 1841 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1842 // This is one of our own processes; skip it. 1843 continue; 1844 } 1845 } 1846 nativeTotalPss += Debug.getPss(st.pid, null, null); 1847 } 1848 } 1849 memInfo.readMemInfo(); 1850 synchronized (ActivityManagerService.this) { 1851 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1852 + (SystemClock.uptimeMillis()-start) + "ms"); 1853 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1854 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1855 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1856 } 1857 } 1858 1859 int num = 0; 1860 long[] tmp = new long[1]; 1861 do { 1862 ProcessRecord proc; 1863 int procState; 1864 int pid; 1865 long lastPssTime; 1866 synchronized (ActivityManagerService.this) { 1867 if (mPendingPssProcesses.size() <= 0) { 1868 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1869 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1870 mPendingPssProcesses.clear(); 1871 return; 1872 } 1873 proc = mPendingPssProcesses.remove(0); 1874 procState = proc.pssProcState; 1875 lastPssTime = proc.lastPssTime; 1876 if (proc.thread != null && procState == proc.setProcState 1877 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1878 < SystemClock.uptimeMillis()) { 1879 pid = proc.pid; 1880 } else { 1881 proc = null; 1882 pid = 0; 1883 } 1884 } 1885 if (proc != null) { 1886 long pss = Debug.getPss(pid, tmp, null); 1887 synchronized (ActivityManagerService.this) { 1888 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1889 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1890 num++; 1891 recordPssSample(proc, procState, pss, tmp[0], 1892 SystemClock.uptimeMillis()); 1893 } 1894 } 1895 } 1896 } while (true); 1897 } 1898 } 1899 } 1900 }; 1901 1902 public void setSystemProcess() { 1903 try { 1904 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1905 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1906 ServiceManager.addService("meminfo", new MemBinder(this)); 1907 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1908 ServiceManager.addService("dbinfo", new DbBinder(this)); 1909 if (MONITOR_CPU_USAGE) { 1910 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1911 } 1912 ServiceManager.addService("permission", new PermissionController(this)); 1913 1914 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1915 "android", STOCK_PM_FLAGS); 1916 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1917 1918 synchronized (this) { 1919 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1920 app.persistent = true; 1921 app.pid = MY_PID; 1922 app.maxAdj = ProcessList.SYSTEM_ADJ; 1923 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1924 mProcessNames.put(app.processName, app.uid, app); 1925 synchronized (mPidsSelfLocked) { 1926 mPidsSelfLocked.put(app.pid, app); 1927 } 1928 updateLruProcessLocked(app, false, null); 1929 updateOomAdjLocked(); 1930 } 1931 } catch (PackageManager.NameNotFoundException e) { 1932 throw new RuntimeException( 1933 "Unable to find android system package", e); 1934 } 1935 } 1936 1937 public void setWindowManager(WindowManagerService wm) { 1938 mWindowManager = wm; 1939 mStackSupervisor.setWindowManager(wm); 1940 } 1941 1942 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1943 mUsageStatsService = usageStatsManager; 1944 } 1945 1946 public void startObservingNativeCrashes() { 1947 final NativeCrashListener ncl = new NativeCrashListener(this); 1948 ncl.start(); 1949 } 1950 1951 public IAppOpsService getAppOpsService() { 1952 return mAppOpsService; 1953 } 1954 1955 static class MemBinder extends Binder { 1956 ActivityManagerService mActivityManagerService; 1957 MemBinder(ActivityManagerService activityManagerService) { 1958 mActivityManagerService = activityManagerService; 1959 } 1960 1961 @Override 1962 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1963 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1964 != PackageManager.PERMISSION_GRANTED) { 1965 pw.println("Permission Denial: can't dump meminfo from from pid=" 1966 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1967 + " without permission " + android.Manifest.permission.DUMP); 1968 return; 1969 } 1970 1971 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1972 } 1973 } 1974 1975 static class GraphicsBinder extends Binder { 1976 ActivityManagerService mActivityManagerService; 1977 GraphicsBinder(ActivityManagerService activityManagerService) { 1978 mActivityManagerService = activityManagerService; 1979 } 1980 1981 @Override 1982 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1983 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1984 != PackageManager.PERMISSION_GRANTED) { 1985 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1986 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1987 + " without permission " + android.Manifest.permission.DUMP); 1988 return; 1989 } 1990 1991 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1992 } 1993 } 1994 1995 static class DbBinder extends Binder { 1996 ActivityManagerService mActivityManagerService; 1997 DbBinder(ActivityManagerService activityManagerService) { 1998 mActivityManagerService = activityManagerService; 1999 } 2000 2001 @Override 2002 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2003 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2004 != PackageManager.PERMISSION_GRANTED) { 2005 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2006 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2007 + " without permission " + android.Manifest.permission.DUMP); 2008 return; 2009 } 2010 2011 mActivityManagerService.dumpDbInfo(fd, pw, args); 2012 } 2013 } 2014 2015 static class CpuBinder extends Binder { 2016 ActivityManagerService mActivityManagerService; 2017 CpuBinder(ActivityManagerService activityManagerService) { 2018 mActivityManagerService = activityManagerService; 2019 } 2020 2021 @Override 2022 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2023 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2024 != PackageManager.PERMISSION_GRANTED) { 2025 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2026 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2027 + " without permission " + android.Manifest.permission.DUMP); 2028 return; 2029 } 2030 2031 synchronized (mActivityManagerService.mProcessCpuTracker) { 2032 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2033 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2034 SystemClock.uptimeMillis())); 2035 } 2036 } 2037 } 2038 2039 public static final class Lifecycle extends SystemService { 2040 private final ActivityManagerService mService; 2041 2042 public Lifecycle(Context context) { 2043 super(context); 2044 mService = new ActivityManagerService(context); 2045 } 2046 2047 @Override 2048 public void onStart() { 2049 mService.start(); 2050 } 2051 2052 public ActivityManagerService getService() { 2053 return mService; 2054 } 2055 } 2056 2057 // Note: This method is invoked on the main thread but may need to attach various 2058 // handlers to other threads. So take care to be explicit about the looper. 2059 public ActivityManagerService(Context systemContext) { 2060 mContext = systemContext; 2061 mFactoryTest = FactoryTest.getMode(); 2062 mSystemThread = ActivityThread.currentActivityThread(); 2063 2064 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2065 2066 mHandlerThread = new ServiceThread(TAG, 2067 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2068 mHandlerThread.start(); 2069 mHandler = new MainHandler(mHandlerThread.getLooper()); 2070 2071 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2072 "foreground", BROADCAST_FG_TIMEOUT, false); 2073 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2074 "background", BROADCAST_BG_TIMEOUT, true); 2075 mBroadcastQueues[0] = mFgBroadcastQueue; 2076 mBroadcastQueues[1] = mBgBroadcastQueue; 2077 2078 mServices = new ActiveServices(this); 2079 mProviderMap = new ProviderMap(this); 2080 2081 // TODO: Move creation of battery stats service outside of activity manager service. 2082 File dataDir = Environment.getDataDirectory(); 2083 File systemDir = new File(dataDir, "system"); 2084 systemDir.mkdirs(); 2085 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2086 mBatteryStatsService.getActiveStatistics().readLocked(); 2087 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2088 mOnBattery = DEBUG_POWER ? true 2089 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2090 mBatteryStatsService.getActiveStatistics().setCallback(this); 2091 2092 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2093 2094 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2095 2096 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2097 2098 // User 0 is the first and only user that runs at boot. 2099 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2100 mUserLru.add(Integer.valueOf(0)); 2101 updateStartedUserArrayLocked(); 2102 2103 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2104 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2105 2106 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2107 2108 mConfiguration.setToDefaults(); 2109 mConfiguration.locale = Locale.getDefault(); 2110 2111 mConfigurationSeq = mConfiguration.seq = 1; 2112 mProcessCpuTracker.init(); 2113 2114 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2115 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2116 mStackSupervisor = new ActivityStackSupervisor(this); 2117 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2118 2119 mProcessCpuThread = new Thread("CpuTracker") { 2120 @Override 2121 public void run() { 2122 while (true) { 2123 try { 2124 try { 2125 synchronized(this) { 2126 final long now = SystemClock.uptimeMillis(); 2127 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2128 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2129 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2130 // + ", write delay=" + nextWriteDelay); 2131 if (nextWriteDelay < nextCpuDelay) { 2132 nextCpuDelay = nextWriteDelay; 2133 } 2134 if (nextCpuDelay > 0) { 2135 mProcessCpuMutexFree.set(true); 2136 this.wait(nextCpuDelay); 2137 } 2138 } 2139 } catch (InterruptedException e) { 2140 } 2141 updateCpuStatsNow(); 2142 } catch (Exception e) { 2143 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2144 } 2145 } 2146 } 2147 }; 2148 2149 Watchdog.getInstance().addMonitor(this); 2150 Watchdog.getInstance().addThread(mHandler); 2151 } 2152 2153 public void setSystemServiceManager(SystemServiceManager mgr) { 2154 mSystemServiceManager = mgr; 2155 } 2156 2157 public void setInstaller(Installer installer) { 2158 mInstaller = installer; 2159 } 2160 2161 private void start() { 2162 Process.removeAllProcessGroups(); 2163 mProcessCpuThread.start(); 2164 2165 mBatteryStatsService.publish(mContext); 2166 mAppOpsService.publish(mContext); 2167 Slog.d("AppOps", "AppOpsService published"); 2168 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2169 } 2170 2171 public void initPowerManagement() { 2172 mStackSupervisor.initPowerManagement(); 2173 mBatteryStatsService.initPowerManagement(); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuTracker) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<>(); 2347 2348 // Isolated processes won't get this optimization, so that we don't 2349 // violate the rules about which services they have access to. 2350 if (!isolated) { 2351 // Setup the application init args 2352 mAppBindArgs.put("package", ServiceManager.getService("package")); 2353 mAppBindArgs.put("window", ServiceManager.getService("window")); 2354 mAppBindArgs.put(Context.ALARM_SERVICE, 2355 ServiceManager.getService(Context.ALARM_SERVICE)); 2356 } 2357 } 2358 return mAppBindArgs; 2359 } 2360 2361 final void setFocusedActivityLocked(ActivityRecord r) { 2362 if (mFocusedActivity != r) { 2363 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2364 mFocusedActivity = r; 2365 if (r.task != null && r.task.voiceInteractor != null) { 2366 startRunningVoiceLocked(); 2367 } else { 2368 finishRunningVoiceLocked(); 2369 } 2370 mStackSupervisor.setFocusedStack(r); 2371 if (r != null) { 2372 mWindowManager.setFocusedApp(r.appToken, true); 2373 } 2374 applyUpdateLockStateLocked(r); 2375 } 2376 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId, 2377 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName); 2378 } 2379 2380 final void clearFocusedActivity(ActivityRecord r) { 2381 if (mFocusedActivity == r) { 2382 mFocusedActivity = null; 2383 } 2384 } 2385 2386 @Override 2387 public void setFocusedStack(int stackId) { 2388 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2389 synchronized (ActivityManagerService.this) { 2390 ActivityStack stack = mStackSupervisor.getStack(stackId); 2391 if (stack != null) { 2392 ActivityRecord r = stack.topRunningActivityLocked(null); 2393 if (r != null) { 2394 setFocusedActivityLocked(r); 2395 } 2396 } 2397 } 2398 } 2399 2400 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2401 @Override 2402 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2403 synchronized (ActivityManagerService.this) { 2404 if (listener != null) { 2405 mTaskStackListeners.register(listener); 2406 } 2407 } 2408 } 2409 2410 @Override 2411 public void notifyActivityDrawn(IBinder token) { 2412 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2413 synchronized (this) { 2414 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2415 if (r != null) { 2416 r.task.stack.notifyActivityDrawnLocked(r); 2417 } 2418 } 2419 } 2420 2421 final void applyUpdateLockStateLocked(ActivityRecord r) { 2422 // Modifications to the UpdateLock state are done on our handler, outside 2423 // the activity manager's locks. The new state is determined based on the 2424 // state *now* of the relevant activity record. The object is passed to 2425 // the handler solely for logging detail, not to be consulted/modified. 2426 final boolean nextState = r != null && r.immersive; 2427 mHandler.sendMessage( 2428 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2429 } 2430 2431 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2432 Message msg = Message.obtain(); 2433 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2434 msg.obj = r.task.askedCompatMode ? null : r; 2435 mHandler.sendMessage(msg); 2436 } 2437 2438 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2439 String what, Object obj, ProcessRecord srcApp) { 2440 app.lastActivityTime = now; 2441 2442 if (app.activities.size() > 0) { 2443 // Don't want to touch dependent processes that are hosting activities. 2444 return index; 2445 } 2446 2447 int lrui = mLruProcesses.lastIndexOf(app); 2448 if (lrui < 0) { 2449 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2450 + what + " " + obj + " from " + srcApp); 2451 return index; 2452 } 2453 2454 if (lrui >= index) { 2455 // Don't want to cause this to move dependent processes *back* in the 2456 // list as if they were less frequently used. 2457 return index; 2458 } 2459 2460 if (lrui >= mLruProcessActivityStart) { 2461 // Don't want to touch dependent processes that are hosting activities. 2462 return index; 2463 } 2464 2465 mLruProcesses.remove(lrui); 2466 if (index > 0) { 2467 index--; 2468 } 2469 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2470 + " in LRU list: " + app); 2471 mLruProcesses.add(index, app); 2472 return index; 2473 } 2474 2475 final void removeLruProcessLocked(ProcessRecord app) { 2476 int lrui = mLruProcesses.lastIndexOf(app); 2477 if (lrui >= 0) { 2478 if (!app.killed) { 2479 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2480 Process.killProcessQuiet(app.pid); 2481 Process.killProcessGroup(app.info.uid, app.pid); 2482 } 2483 if (lrui <= mLruProcessActivityStart) { 2484 mLruProcessActivityStart--; 2485 } 2486 if (lrui <= mLruProcessServiceStart) { 2487 mLruProcessServiceStart--; 2488 } 2489 mLruProcesses.remove(lrui); 2490 } 2491 } 2492 2493 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2494 ProcessRecord client) { 2495 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2496 || app.treatLikeActivity; 2497 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2498 if (!activityChange && hasActivity) { 2499 // The process has activities, so we are only allowing activity-based adjustments 2500 // to move it. It should be kept in the front of the list with other 2501 // processes that have activities, and we don't want those to change their 2502 // order except due to activity operations. 2503 return; 2504 } 2505 2506 mLruSeq++; 2507 final long now = SystemClock.uptimeMillis(); 2508 app.lastActivityTime = now; 2509 2510 // First a quick reject: if the app is already at the position we will 2511 // put it, then there is nothing to do. 2512 if (hasActivity) { 2513 final int N = mLruProcesses.size(); 2514 if (N > 0 && mLruProcesses.get(N-1) == app) { 2515 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2516 return; 2517 } 2518 } else { 2519 if (mLruProcessServiceStart > 0 2520 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2521 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2522 return; 2523 } 2524 } 2525 2526 int lrui = mLruProcesses.lastIndexOf(app); 2527 2528 if (app.persistent && lrui >= 0) { 2529 // We don't care about the position of persistent processes, as long as 2530 // they are in the list. 2531 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2532 return; 2533 } 2534 2535 /* In progress: compute new position first, so we can avoid doing work 2536 if the process is not actually going to move. Not yet working. 2537 int addIndex; 2538 int nextIndex; 2539 boolean inActivity = false, inService = false; 2540 if (hasActivity) { 2541 // Process has activities, put it at the very tipsy-top. 2542 addIndex = mLruProcesses.size(); 2543 nextIndex = mLruProcessServiceStart; 2544 inActivity = true; 2545 } else if (hasService) { 2546 // Process has services, put it at the top of the service list. 2547 addIndex = mLruProcessActivityStart; 2548 nextIndex = mLruProcessServiceStart; 2549 inActivity = true; 2550 inService = true; 2551 } else { 2552 // Process not otherwise of interest, it goes to the top of the non-service area. 2553 addIndex = mLruProcessServiceStart; 2554 if (client != null) { 2555 int clientIndex = mLruProcesses.lastIndexOf(client); 2556 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2557 + app); 2558 if (clientIndex >= 0 && addIndex > clientIndex) { 2559 addIndex = clientIndex; 2560 } 2561 } 2562 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2563 } 2564 2565 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2566 + mLruProcessActivityStart + "): " + app); 2567 */ 2568 2569 if (lrui >= 0) { 2570 if (lrui < mLruProcessActivityStart) { 2571 mLruProcessActivityStart--; 2572 } 2573 if (lrui < mLruProcessServiceStart) { 2574 mLruProcessServiceStart--; 2575 } 2576 /* 2577 if (addIndex > lrui) { 2578 addIndex--; 2579 } 2580 if (nextIndex > lrui) { 2581 nextIndex--; 2582 } 2583 */ 2584 mLruProcesses.remove(lrui); 2585 } 2586 2587 /* 2588 mLruProcesses.add(addIndex, app); 2589 if (inActivity) { 2590 mLruProcessActivityStart++; 2591 } 2592 if (inService) { 2593 mLruProcessActivityStart++; 2594 } 2595 */ 2596 2597 int nextIndex; 2598 if (hasActivity) { 2599 final int N = mLruProcesses.size(); 2600 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2601 // Process doesn't have activities, but has clients with 2602 // activities... move it up, but one below the top (the top 2603 // should always have a real activity). 2604 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2605 mLruProcesses.add(N-1, app); 2606 // To keep it from spamming the LRU list (by making a bunch of clients), 2607 // we will push down any other entries owned by the app. 2608 final int uid = app.info.uid; 2609 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2610 ProcessRecord subProc = mLruProcesses.get(i); 2611 if (subProc.info.uid == uid) { 2612 // We want to push this one down the list. If the process after 2613 // it is for the same uid, however, don't do so, because we don't 2614 // want them internally to be re-ordered. 2615 if (mLruProcesses.get(i-1).info.uid != uid) { 2616 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2617 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2618 ProcessRecord tmp = mLruProcesses.get(i); 2619 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2620 mLruProcesses.set(i-1, tmp); 2621 i--; 2622 } 2623 } else { 2624 // A gap, we can stop here. 2625 break; 2626 } 2627 } 2628 } else { 2629 // Process has activities, put it at the very tipsy-top. 2630 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2631 mLruProcesses.add(app); 2632 } 2633 nextIndex = mLruProcessServiceStart; 2634 } else if (hasService) { 2635 // Process has services, put it at the top of the service list. 2636 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2637 mLruProcesses.add(mLruProcessActivityStart, app); 2638 nextIndex = mLruProcessServiceStart; 2639 mLruProcessActivityStart++; 2640 } else { 2641 // Process not otherwise of interest, it goes to the top of the non-service area. 2642 int index = mLruProcessServiceStart; 2643 if (client != null) { 2644 // If there is a client, don't allow the process to be moved up higher 2645 // in the list than that client. 2646 int clientIndex = mLruProcesses.lastIndexOf(client); 2647 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2648 + " when updating " + app); 2649 if (clientIndex <= lrui) { 2650 // Don't allow the client index restriction to push it down farther in the 2651 // list than it already is. 2652 clientIndex = lrui; 2653 } 2654 if (clientIndex >= 0 && index > clientIndex) { 2655 index = clientIndex; 2656 } 2657 } 2658 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2659 mLruProcesses.add(index, app); 2660 nextIndex = index-1; 2661 mLruProcessActivityStart++; 2662 mLruProcessServiceStart++; 2663 } 2664 2665 // If the app is currently using a content provider or service, 2666 // bump those processes as well. 2667 for (int j=app.connections.size()-1; j>=0; j--) { 2668 ConnectionRecord cr = app.connections.valueAt(j); 2669 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2670 && cr.binding.service.app != null 2671 && cr.binding.service.app.lruSeq != mLruSeq 2672 && !cr.binding.service.app.persistent) { 2673 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2674 "service connection", cr, app); 2675 } 2676 } 2677 for (int j=app.conProviders.size()-1; j>=0; j--) { 2678 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2679 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2680 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2681 "provider reference", cpr, app); 2682 } 2683 } 2684 } 2685 2686 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2687 if (uid == Process.SYSTEM_UID) { 2688 // The system gets to run in any process. If there are multiple 2689 // processes with the same uid, just pick the first (this 2690 // should never happen). 2691 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2692 if (procs == null) return null; 2693 final int N = procs.size(); 2694 for (int i = 0; i < N; i++) { 2695 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2696 } 2697 } 2698 ProcessRecord proc = mProcessNames.get(processName, uid); 2699 if (false && proc != null && !keepIfLarge 2700 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2701 && proc.lastCachedPss >= 4000) { 2702 // Turn this condition on to cause killing to happen regularly, for testing. 2703 if (proc.baseProcessTracker != null) { 2704 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2705 } 2706 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2707 } else if (proc != null && !keepIfLarge 2708 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2709 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2710 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2711 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 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 } 2717 } 2718 return proc; 2719 } 2720 2721 void ensurePackageDexOpt(String packageName) { 2722 IPackageManager pm = AppGlobals.getPackageManager(); 2723 try { 2724 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2725 mDidDexOpt = true; 2726 } 2727 } catch (RemoteException e) { 2728 } 2729 } 2730 2731 boolean isNextTransitionForward() { 2732 int transit = mWindowManager.getPendingAppTransition(); 2733 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2734 || transit == AppTransition.TRANSIT_TASK_OPEN 2735 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2736 } 2737 2738 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2739 String processName, String abiOverride, int uid, Runnable crashHandler) { 2740 synchronized(this) { 2741 ApplicationInfo info = new ApplicationInfo(); 2742 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2743 // For isolated processes, the former contains the parent's uid and the latter the 2744 // actual uid of the isolated process. 2745 // In the special case introduced by this method (which is, starting an isolated 2746 // process directly from the SystemServer without an actual parent app process) the 2747 // closest thing to a parent's uid is SYSTEM_UID. 2748 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2749 // the |isolated| logic in the ProcessRecord constructor. 2750 info.uid = Process.SYSTEM_UID; 2751 info.processName = processName; 2752 info.className = entryPoint; 2753 info.packageName = "android"; 2754 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2755 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2756 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2757 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2758 crashHandler); 2759 return proc != null ? proc.pid : 0; 2760 } 2761 } 2762 2763 final ProcessRecord startProcessLocked(String processName, 2764 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2765 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2766 boolean isolated, boolean keepIfLarge) { 2767 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2768 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2769 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2770 null /* crashHandler */); 2771 } 2772 2773 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2774 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2775 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2776 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2777 long startTime = SystemClock.elapsedRealtime(); 2778 ProcessRecord app; 2779 if (!isolated) { 2780 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2781 checkTime(startTime, "startProcess: after getProcessRecord"); 2782 } else { 2783 // If this is an isolated process, it can't re-use an existing process. 2784 app = null; 2785 } 2786 // We don't have to do anything more if: 2787 // (1) There is an existing application record; and 2788 // (2) The caller doesn't think it is dead, OR there is no thread 2789 // object attached to it so we know it couldn't have crashed; and 2790 // (3) There is a pid assigned to it, so it is either starting or 2791 // already running. 2792 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2793 + " app=" + app + " knownToBeDead=" + knownToBeDead 2794 + " thread=" + (app != null ? app.thread : null) 2795 + " pid=" + (app != null ? app.pid : -1)); 2796 if (app != null && app.pid > 0) { 2797 if (!knownToBeDead || app.thread == null) { 2798 // We already have the app running, or are waiting for it to 2799 // come up (we have a pid but not yet its thread), so keep it. 2800 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2801 // If this is a new package in the process, add the package to the list 2802 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2803 checkTime(startTime, "startProcess: done, added package to proc"); 2804 return app; 2805 } 2806 2807 // An application record is attached to a previous process, 2808 // clean it up now. 2809 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2810 checkTime(startTime, "startProcess: bad proc running, killing"); 2811 Process.killProcessGroup(app.info.uid, app.pid); 2812 handleAppDiedLocked(app, true, true); 2813 checkTime(startTime, "startProcess: done killing old proc"); 2814 } 2815 2816 String hostingNameStr = hostingName != null 2817 ? hostingName.flattenToShortString() : null; 2818 2819 if (!isolated) { 2820 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2821 // If we are in the background, then check to see if this process 2822 // is bad. If so, we will just silently fail. 2823 if (mBadProcesses.get(info.processName, info.uid) != null) { 2824 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2825 + "/" + info.processName); 2826 return null; 2827 } 2828 } else { 2829 // When the user is explicitly starting a process, then clear its 2830 // crash count so that we won't make it bad until they see at 2831 // least one crash dialog again, and make the process good again 2832 // if it had been bad. 2833 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2834 + "/" + info.processName); 2835 mProcessCrashTimes.remove(info.processName, info.uid); 2836 if (mBadProcesses.get(info.processName, info.uid) != null) { 2837 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2838 UserHandle.getUserId(info.uid), info.uid, 2839 info.processName); 2840 mBadProcesses.remove(info.processName, info.uid); 2841 if (app != null) { 2842 app.bad = false; 2843 } 2844 } 2845 } 2846 } 2847 2848 if (app == null) { 2849 checkTime(startTime, "startProcess: creating new process record"); 2850 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2851 if (app == null) { 2852 Slog.w(TAG, "Failed making new process record for " 2853 + processName + "/" + info.uid + " isolated=" + isolated); 2854 return null; 2855 } 2856 app.crashHandler = crashHandler; 2857 mProcessNames.put(processName, app.uid, app); 2858 if (isolated) { 2859 mIsolatedProcesses.put(app.uid, app); 2860 } 2861 checkTime(startTime, "startProcess: done creating new process record"); 2862 } else { 2863 // If this is a new package in the process, add the package to the list 2864 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2865 checkTime(startTime, "startProcess: added package to existing proc"); 2866 } 2867 2868 // If the system is not ready yet, then hold off on starting this 2869 // process until it is. 2870 if (!mProcessesReady 2871 && !isAllowedWhileBooting(info) 2872 && !allowWhileBooting) { 2873 if (!mProcessesOnHold.contains(app)) { 2874 mProcessesOnHold.add(app); 2875 } 2876 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2877 checkTime(startTime, "startProcess: returning with proc on hold"); 2878 return app; 2879 } 2880 2881 checkTime(startTime, "startProcess: stepping in to startProcess"); 2882 startProcessLocked( 2883 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2884 checkTime(startTime, "startProcess: done starting proc!"); 2885 return (app.pid != 0) ? app : null; 2886 } 2887 2888 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2889 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2890 } 2891 2892 private final void startProcessLocked(ProcessRecord app, 2893 String hostingType, String hostingNameStr) { 2894 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2895 null /* entryPoint */, null /* entryPointArgs */); 2896 } 2897 2898 private final void startProcessLocked(ProcessRecord app, String hostingType, 2899 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2900 long startTime = SystemClock.elapsedRealtime(); 2901 if (app.pid > 0 && app.pid != MY_PID) { 2902 checkTime(startTime, "startProcess: removing from pids map"); 2903 synchronized (mPidsSelfLocked) { 2904 mPidsSelfLocked.remove(app.pid); 2905 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2906 } 2907 checkTime(startTime, "startProcess: done removing from pids map"); 2908 app.setPid(0); 2909 } 2910 2911 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2912 "startProcessLocked removing on hold: " + app); 2913 mProcessesOnHold.remove(app); 2914 2915 checkTime(startTime, "startProcess: starting to update cpu stats"); 2916 updateCpuStats(); 2917 checkTime(startTime, "startProcess: done updating cpu stats"); 2918 2919 try { 2920 int uid = app.uid; 2921 2922 int[] gids = null; 2923 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2924 if (!app.isolated) { 2925 int[] permGids = null; 2926 try { 2927 checkTime(startTime, "startProcess: getting gids from package manager"); 2928 final PackageManager pm = mContext.getPackageManager(); 2929 permGids = pm.getPackageGids(app.info.packageName); 2930 2931 if (Environment.isExternalStorageEmulated()) { 2932 checkTime(startTime, "startProcess: checking external storage perm"); 2933 if (pm.checkPermission( 2934 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2935 app.info.packageName) == PERMISSION_GRANTED) { 2936 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2937 } else { 2938 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2939 } 2940 } 2941 } catch (PackageManager.NameNotFoundException e) { 2942 Slog.w(TAG, "Unable to retrieve gids", e); 2943 } 2944 2945 /* 2946 * Add shared application and profile GIDs so applications can share some 2947 * resources like shared libraries and access user-wide resources 2948 */ 2949 if (permGids == null) { 2950 gids = new int[2]; 2951 } else { 2952 gids = new int[permGids.length + 2]; 2953 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2954 } 2955 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2956 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2957 } 2958 checkTime(startTime, "startProcess: building args"); 2959 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2960 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2961 && mTopComponent != null 2962 && app.processName.equals(mTopComponent.getPackageName())) { 2963 uid = 0; 2964 } 2965 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2966 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2967 uid = 0; 2968 } 2969 } 2970 int debugFlags = 0; 2971 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2972 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2973 // Also turn on CheckJNI for debuggable apps. It's quite 2974 // awkward to turn on otherwise. 2975 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2976 } 2977 // Run the app in safe mode if its manifest requests so or the 2978 // system is booted in safe mode. 2979 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2980 mSafeMode == true) { 2981 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2982 } 2983 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2984 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2985 } 2986 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2987 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2988 } 2989 if ("1".equals(SystemProperties.get("debug.assert"))) { 2990 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2991 } 2992 2993 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2994 if (requiredAbi == null) { 2995 requiredAbi = Build.SUPPORTED_ABIS[0]; 2996 } 2997 2998 String instructionSet = null; 2999 if (app.info.primaryCpuAbi != null) { 3000 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3001 } 3002 3003 app.gids = gids; 3004 app.requiredAbi = requiredAbi; 3005 app.instructionSet = instructionSet; 3006 3007 // Start the process. It will either succeed and return a result containing 3008 // the PID of the new process, or else throw a RuntimeException. 3009 boolean isActivityProcess = (entryPoint == null); 3010 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3011 checkTime(startTime, "startProcess: asking zygote to start proc"); 3012 Process.ProcessStartResult startResult = Process.start(entryPoint, 3013 app.processName, uid, uid, gids, debugFlags, mountExternal, 3014 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3015 app.info.dataDir, entryPointArgs); 3016 checkTime(startTime, "startProcess: returned from zygote!"); 3017 3018 if (app.isolated) { 3019 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3020 } 3021 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3022 checkTime(startTime, "startProcess: done updating battery stats"); 3023 3024 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3025 UserHandle.getUserId(uid), startResult.pid, uid, 3026 app.processName, hostingType, 3027 hostingNameStr != null ? hostingNameStr : ""); 3028 3029 if (app.persistent) { 3030 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3031 } 3032 3033 checkTime(startTime, "startProcess: building log message"); 3034 StringBuilder buf = mStringBuilder; 3035 buf.setLength(0); 3036 buf.append("Start proc "); 3037 buf.append(startResult.pid); 3038 buf.append(':'); 3039 buf.append(app.processName); 3040 buf.append('/'); 3041 UserHandle.formatUid(buf, uid); 3042 if (!isActivityProcess) { 3043 buf.append(" ["); 3044 buf.append(entryPoint); 3045 buf.append("]"); 3046 } 3047 buf.append(" for "); 3048 buf.append(hostingType); 3049 if (hostingNameStr != null) { 3050 buf.append(" "); 3051 buf.append(hostingNameStr); 3052 } 3053 Slog.i(TAG, buf.toString()); 3054 app.setPid(startResult.pid); 3055 app.usingWrapper = startResult.usingWrapper; 3056 app.removed = false; 3057 app.killed = false; 3058 app.killedByAm = false; 3059 checkTime(startTime, "startProcess: starting to update pids map"); 3060 synchronized (mPidsSelfLocked) { 3061 this.mPidsSelfLocked.put(startResult.pid, app); 3062 if (isActivityProcess) { 3063 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3064 msg.obj = app; 3065 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3066 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3067 } 3068 } 3069 checkTime(startTime, "startProcess: done updating pids map"); 3070 } catch (RuntimeException e) { 3071 // XXX do better error recovery. 3072 app.setPid(0); 3073 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3074 if (app.isolated) { 3075 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3076 } 3077 Slog.e(TAG, "Failure starting process " + app.processName, e); 3078 } 3079 } 3080 3081 void updateUsageStats(ActivityRecord component, boolean resumed) { 3082 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3083 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3084 if (resumed) { 3085 if (mUsageStatsService != null) { 3086 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3087 UsageEvents.Event.MOVE_TO_FOREGROUND); 3088 } 3089 synchronized (stats) { 3090 stats.noteActivityResumedLocked(component.app.uid); 3091 } 3092 } else { 3093 if (mUsageStatsService != null) { 3094 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3095 UsageEvents.Event.MOVE_TO_BACKGROUND); 3096 } 3097 synchronized (stats) { 3098 stats.noteActivityPausedLocked(component.app.uid); 3099 } 3100 } 3101 } 3102 3103 Intent getHomeIntent() { 3104 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3105 intent.setComponent(mTopComponent); 3106 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3107 intent.addCategory(Intent.CATEGORY_HOME); 3108 } 3109 return intent; 3110 } 3111 3112 boolean startHomeActivityLocked(int userId) { 3113 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3114 && mTopAction == null) { 3115 // We are running in factory test mode, but unable to find 3116 // the factory test app, so just sit around displaying the 3117 // error message and don't try to start anything. 3118 return false; 3119 } 3120 Intent intent = getHomeIntent(); 3121 ActivityInfo aInfo = 3122 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3123 if (aInfo != null) { 3124 intent.setComponent(new ComponentName( 3125 aInfo.applicationInfo.packageName, aInfo.name)); 3126 // Don't do this if the home app is currently being 3127 // instrumented. 3128 aInfo = new ActivityInfo(aInfo); 3129 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3130 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3131 aInfo.applicationInfo.uid, true); 3132 if (app == null || app.instrumentationClass == null) { 3133 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3134 mStackSupervisor.startHomeActivity(intent, aInfo); 3135 } 3136 } 3137 3138 return true; 3139 } 3140 3141 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3142 ActivityInfo ai = null; 3143 ComponentName comp = intent.getComponent(); 3144 try { 3145 if (comp != null) { 3146 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3147 } else { 3148 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3149 intent, 3150 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3151 flags, userId); 3152 3153 if (info != null) { 3154 ai = info.activityInfo; 3155 } 3156 } 3157 } catch (RemoteException e) { 3158 // ignore 3159 } 3160 3161 return ai; 3162 } 3163 3164 /** 3165 * Starts the "new version setup screen" if appropriate. 3166 */ 3167 void startSetupActivityLocked() { 3168 // Only do this once per boot. 3169 if (mCheckedForSetup) { 3170 return; 3171 } 3172 3173 // We will show this screen if the current one is a different 3174 // version than the last one shown, and we are not running in 3175 // low-level factory test mode. 3176 final ContentResolver resolver = mContext.getContentResolver(); 3177 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3178 Settings.Global.getInt(resolver, 3179 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3180 mCheckedForSetup = true; 3181 3182 // See if we should be showing the platform update setup UI. 3183 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3184 List<ResolveInfo> ris = mContext.getPackageManager() 3185 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3186 3187 // We don't allow third party apps to replace this. 3188 ResolveInfo ri = null; 3189 for (int i=0; ris != null && i<ris.size(); i++) { 3190 if ((ris.get(i).activityInfo.applicationInfo.flags 3191 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3192 ri = ris.get(i); 3193 break; 3194 } 3195 } 3196 3197 if (ri != null) { 3198 String vers = ri.activityInfo.metaData != null 3199 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3200 : null; 3201 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3202 vers = ri.activityInfo.applicationInfo.metaData.getString( 3203 Intent.METADATA_SETUP_VERSION); 3204 } 3205 String lastVers = Settings.Secure.getString( 3206 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3207 if (vers != null && !vers.equals(lastVers)) { 3208 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3209 intent.setComponent(new ComponentName( 3210 ri.activityInfo.packageName, ri.activityInfo.name)); 3211 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3212 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3213 null); 3214 } 3215 } 3216 } 3217 } 3218 3219 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3220 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3221 } 3222 3223 void enforceNotIsolatedCaller(String caller) { 3224 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3225 throw new SecurityException("Isolated process not allowed to call " + caller); 3226 } 3227 } 3228 3229 void enforceShellRestriction(String restriction, int userHandle) { 3230 if (Binder.getCallingUid() == Process.SHELL_UID) { 3231 if (userHandle < 0 3232 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3233 throw new SecurityException("Shell does not have permission to access user " 3234 + userHandle); 3235 } 3236 } 3237 } 3238 3239 @Override 3240 public int getFrontActivityScreenCompatMode() { 3241 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3242 synchronized (this) { 3243 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3244 } 3245 } 3246 3247 @Override 3248 public void setFrontActivityScreenCompatMode(int mode) { 3249 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3250 "setFrontActivityScreenCompatMode"); 3251 synchronized (this) { 3252 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3253 } 3254 } 3255 3256 @Override 3257 public int getPackageScreenCompatMode(String packageName) { 3258 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3259 synchronized (this) { 3260 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3261 } 3262 } 3263 3264 @Override 3265 public void setPackageScreenCompatMode(String packageName, int mode) { 3266 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3267 "setPackageScreenCompatMode"); 3268 synchronized (this) { 3269 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3270 } 3271 } 3272 3273 @Override 3274 public boolean getPackageAskScreenCompat(String packageName) { 3275 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3276 synchronized (this) { 3277 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3278 } 3279 } 3280 3281 @Override 3282 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3283 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3284 "setPackageAskScreenCompat"); 3285 synchronized (this) { 3286 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3287 } 3288 } 3289 3290 private void dispatchProcessesChanged() { 3291 int N; 3292 synchronized (this) { 3293 N = mPendingProcessChanges.size(); 3294 if (mActiveProcessChanges.length < N) { 3295 mActiveProcessChanges = new ProcessChangeItem[N]; 3296 } 3297 mPendingProcessChanges.toArray(mActiveProcessChanges); 3298 mAvailProcessChanges.addAll(mPendingProcessChanges); 3299 mPendingProcessChanges.clear(); 3300 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3301 } 3302 3303 int i = mProcessObservers.beginBroadcast(); 3304 while (i > 0) { 3305 i--; 3306 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3307 if (observer != null) { 3308 try { 3309 for (int j=0; j<N; j++) { 3310 ProcessChangeItem item = mActiveProcessChanges[j]; 3311 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3312 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3313 + item.pid + " uid=" + item.uid + ": " 3314 + item.foregroundActivities); 3315 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3316 item.foregroundActivities); 3317 } 3318 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3320 + item.pid + " uid=" + item.uid + ": " + item.processState); 3321 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3322 } 3323 } 3324 } catch (RemoteException e) { 3325 } 3326 } 3327 } 3328 mProcessObservers.finishBroadcast(); 3329 } 3330 3331 private void dispatchProcessDied(int pid, int uid) { 3332 int i = mProcessObservers.beginBroadcast(); 3333 while (i > 0) { 3334 i--; 3335 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3336 if (observer != null) { 3337 try { 3338 observer.onProcessDied(pid, uid); 3339 } catch (RemoteException e) { 3340 } 3341 } 3342 } 3343 mProcessObservers.finishBroadcast(); 3344 } 3345 3346 @Override 3347 public final int startActivity(IApplicationThread caller, String callingPackage, 3348 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3349 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3350 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3351 resultWho, requestCode, startFlags, profilerInfo, options, 3352 UserHandle.getCallingUserId()); 3353 } 3354 3355 @Override 3356 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3357 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3358 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3359 enforceNotIsolatedCaller("startActivity"); 3360 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3361 false, ALLOW_FULL_ONLY, "startActivity", null); 3362 // TODO: Switch to user app stacks here. 3363 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3364 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3365 profilerInfo, null, null, options, userId, null, null); 3366 } 3367 3368 @Override 3369 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3370 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3371 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3372 3373 // This is very dangerous -- it allows you to perform a start activity (including 3374 // permission grants) as any app that may launch one of your own activities. So 3375 // we will only allow this to be done from activities that are part of the core framework, 3376 // and then only when they are running as the system. 3377 final ActivityRecord sourceRecord; 3378 final int targetUid; 3379 final String targetPackage; 3380 synchronized (this) { 3381 if (resultTo == null) { 3382 throw new SecurityException("Must be called from an activity"); 3383 } 3384 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3385 if (sourceRecord == null) { 3386 throw new SecurityException("Called with bad activity token: " + resultTo); 3387 } 3388 if (!sourceRecord.info.packageName.equals("android")) { 3389 throw new SecurityException( 3390 "Must be called from an activity that is declared in the android package"); 3391 } 3392 if (sourceRecord.app == null) { 3393 throw new SecurityException("Called without a process attached to activity"); 3394 } 3395 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3396 // This is still okay, as long as this activity is running under the 3397 // uid of the original calling activity. 3398 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3399 throw new SecurityException( 3400 "Calling activity in uid " + sourceRecord.app.uid 3401 + " must be system uid or original calling uid " 3402 + sourceRecord.launchedFromUid); 3403 } 3404 } 3405 targetUid = sourceRecord.launchedFromUid; 3406 targetPackage = sourceRecord.launchedFromPackage; 3407 } 3408 3409 if (userId == UserHandle.USER_NULL) { 3410 userId = UserHandle.getUserId(sourceRecord.app.uid); 3411 } 3412 3413 // TODO: Switch to user app stacks here. 3414 try { 3415 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3416 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3417 null, null, options, userId, null, null); 3418 return ret; 3419 } catch (SecurityException e) { 3420 // XXX need to figure out how to propagate to original app. 3421 // A SecurityException here is generally actually a fault of the original 3422 // calling activity (such as a fairly granting permissions), so propagate it 3423 // back to them. 3424 /* 3425 StringBuilder msg = new StringBuilder(); 3426 msg.append("While launching"); 3427 msg.append(intent.toString()); 3428 msg.append(": "); 3429 msg.append(e.getMessage()); 3430 */ 3431 throw e; 3432 } 3433 } 3434 3435 @Override 3436 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3437 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3438 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3439 enforceNotIsolatedCaller("startActivityAndWait"); 3440 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3441 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3442 WaitResult res = new WaitResult(); 3443 // TODO: Switch to user app stacks here. 3444 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3445 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3446 options, userId, null, null); 3447 return res; 3448 } 3449 3450 @Override 3451 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3452 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3453 int startFlags, Configuration config, Bundle options, int userId) { 3454 enforceNotIsolatedCaller("startActivityWithConfig"); 3455 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3456 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3457 // TODO: Switch to user app stacks here. 3458 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3459 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3460 null, null, config, options, userId, null, null); 3461 return ret; 3462 } 3463 3464 @Override 3465 public int startActivityIntentSender(IApplicationThread caller, 3466 IntentSender intent, Intent fillInIntent, String resolvedType, 3467 IBinder resultTo, String resultWho, int requestCode, 3468 int flagsMask, int flagsValues, Bundle options) { 3469 enforceNotIsolatedCaller("startActivityIntentSender"); 3470 // Refuse possible leaked file descriptors 3471 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3472 throw new IllegalArgumentException("File descriptors passed in Intent"); 3473 } 3474 3475 IIntentSender sender = intent.getTarget(); 3476 if (!(sender instanceof PendingIntentRecord)) { 3477 throw new IllegalArgumentException("Bad PendingIntent object"); 3478 } 3479 3480 PendingIntentRecord pir = (PendingIntentRecord)sender; 3481 3482 synchronized (this) { 3483 // If this is coming from the currently resumed activity, it is 3484 // effectively saying that app switches are allowed at this point. 3485 final ActivityStack stack = getFocusedStack(); 3486 if (stack.mResumedActivity != null && 3487 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3488 mAppSwitchesAllowedTime = 0; 3489 } 3490 } 3491 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3492 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3493 return ret; 3494 } 3495 3496 @Override 3497 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3498 Intent intent, String resolvedType, IVoiceInteractionSession session, 3499 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3500 Bundle options, int userId) { 3501 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3502 != PackageManager.PERMISSION_GRANTED) { 3503 String msg = "Permission Denial: startVoiceActivity() from pid=" 3504 + Binder.getCallingPid() 3505 + ", uid=" + Binder.getCallingUid() 3506 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3507 Slog.w(TAG, msg); 3508 throw new SecurityException(msg); 3509 } 3510 if (session == null || interactor == null) { 3511 throw new NullPointerException("null session or interactor"); 3512 } 3513 userId = handleIncomingUser(callingPid, callingUid, userId, 3514 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3515 // TODO: Switch to user app stacks here. 3516 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3517 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3518 null, options, userId, null, null); 3519 } 3520 3521 @Override 3522 public boolean startNextMatchingActivity(IBinder callingActivity, 3523 Intent intent, Bundle options) { 3524 // Refuse possible leaked file descriptors 3525 if (intent != null && intent.hasFileDescriptors() == true) { 3526 throw new IllegalArgumentException("File descriptors passed in Intent"); 3527 } 3528 3529 synchronized (this) { 3530 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3531 if (r == null) { 3532 ActivityOptions.abort(options); 3533 return false; 3534 } 3535 if (r.app == null || r.app.thread == null) { 3536 // The caller is not running... d'oh! 3537 ActivityOptions.abort(options); 3538 return false; 3539 } 3540 intent = new Intent(intent); 3541 // The caller is not allowed to change the data. 3542 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3543 // And we are resetting to find the next component... 3544 intent.setComponent(null); 3545 3546 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3547 3548 ActivityInfo aInfo = null; 3549 try { 3550 List<ResolveInfo> resolves = 3551 AppGlobals.getPackageManager().queryIntentActivities( 3552 intent, r.resolvedType, 3553 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3554 UserHandle.getCallingUserId()); 3555 3556 // Look for the original activity in the list... 3557 final int N = resolves != null ? resolves.size() : 0; 3558 for (int i=0; i<N; i++) { 3559 ResolveInfo rInfo = resolves.get(i); 3560 if (rInfo.activityInfo.packageName.equals(r.packageName) 3561 && rInfo.activityInfo.name.equals(r.info.name)) { 3562 // We found the current one... the next matching is 3563 // after it. 3564 i++; 3565 if (i<N) { 3566 aInfo = resolves.get(i).activityInfo; 3567 } 3568 if (debug) { 3569 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3570 + "/" + r.info.name); 3571 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3572 + "/" + aInfo.name); 3573 } 3574 break; 3575 } 3576 } 3577 } catch (RemoteException e) { 3578 } 3579 3580 if (aInfo == null) { 3581 // Nobody who is next! 3582 ActivityOptions.abort(options); 3583 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3584 return false; 3585 } 3586 3587 intent.setComponent(new ComponentName( 3588 aInfo.applicationInfo.packageName, aInfo.name)); 3589 intent.setFlags(intent.getFlags()&~( 3590 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3591 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3592 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3593 Intent.FLAG_ACTIVITY_NEW_TASK)); 3594 3595 // Okay now we need to start the new activity, replacing the 3596 // currently running activity. This is a little tricky because 3597 // we want to start the new one as if the current one is finished, 3598 // but not finish the current one first so that there is no flicker. 3599 // And thus... 3600 final boolean wasFinishing = r.finishing; 3601 r.finishing = true; 3602 3603 // Propagate reply information over to the new activity. 3604 final ActivityRecord resultTo = r.resultTo; 3605 final String resultWho = r.resultWho; 3606 final int requestCode = r.requestCode; 3607 r.resultTo = null; 3608 if (resultTo != null) { 3609 resultTo.removeResultsLocked(r, resultWho, requestCode); 3610 } 3611 3612 final long origId = Binder.clearCallingIdentity(); 3613 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3614 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3615 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3616 -1, r.launchedFromUid, 0, options, false, null, null, null); 3617 Binder.restoreCallingIdentity(origId); 3618 3619 r.finishing = wasFinishing; 3620 if (res != ActivityManager.START_SUCCESS) { 3621 return false; 3622 } 3623 return true; 3624 } 3625 } 3626 3627 @Override 3628 public final int startActivityFromRecents(int taskId, Bundle options) { 3629 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3630 String msg = "Permission Denial: startActivityFromRecents called without " + 3631 START_TASKS_FROM_RECENTS; 3632 Slog.w(TAG, msg); 3633 throw new SecurityException(msg); 3634 } 3635 return startActivityFromRecentsInner(taskId, options); 3636 } 3637 3638 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3639 final TaskRecord task; 3640 final int callingUid; 3641 final String callingPackage; 3642 final Intent intent; 3643 final int userId; 3644 synchronized (this) { 3645 task = recentTaskForIdLocked(taskId); 3646 if (task == null) { 3647 throw new IllegalArgumentException("Task " + taskId + " not found."); 3648 } 3649 if (task.getRootActivity() != null) { 3650 moveTaskToFrontLocked(task.taskId, 0, null); 3651 return ActivityManager.START_TASK_TO_FRONT; 3652 } 3653 callingUid = task.mCallingUid; 3654 callingPackage = task.mCallingPackage; 3655 intent = task.intent; 3656 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3657 userId = task.userId; 3658 } 3659 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3660 options, userId, null, task); 3661 } 3662 3663 final int startActivityInPackage(int uid, String callingPackage, 3664 Intent intent, String resolvedType, IBinder resultTo, 3665 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3666 IActivityContainer container, TaskRecord inTask) { 3667 3668 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3669 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3670 3671 // TODO: Switch to user app stacks here. 3672 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3673 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3674 null, null, null, options, userId, container, inTask); 3675 return ret; 3676 } 3677 3678 @Override 3679 public final int startActivities(IApplicationThread caller, String callingPackage, 3680 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3681 int userId) { 3682 enforceNotIsolatedCaller("startActivities"); 3683 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3684 false, ALLOW_FULL_ONLY, "startActivity", null); 3685 // TODO: Switch to user app stacks here. 3686 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3687 resolvedTypes, resultTo, options, userId); 3688 return ret; 3689 } 3690 3691 final int startActivitiesInPackage(int uid, String callingPackage, 3692 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3693 Bundle options, int userId) { 3694 3695 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3696 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3697 // TODO: Switch to user app stacks here. 3698 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3699 resultTo, options, userId); 3700 return ret; 3701 } 3702 3703 //explicitly remove thd old information in mRecentTasks when removing existing user. 3704 private void removeRecentTasksForUserLocked(int userId) { 3705 if(userId <= 0) { 3706 Slog.i(TAG, "Can't remove recent task on user " + userId); 3707 return; 3708 } 3709 3710 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3711 TaskRecord tr = mRecentTasks.get(i); 3712 if (tr.userId == userId) { 3713 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3714 + " when finishing user" + userId); 3715 mRecentTasks.remove(i); 3716 tr.removedFromRecents(); 3717 } 3718 } 3719 3720 // Remove tasks from persistent storage. 3721 notifyTaskPersisterLocked(null, true); 3722 } 3723 3724 // Sort by taskId 3725 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3726 @Override 3727 public int compare(TaskRecord lhs, TaskRecord rhs) { 3728 return rhs.taskId - lhs.taskId; 3729 } 3730 }; 3731 3732 // Extract the affiliates of the chain containing mRecentTasks[start]. 3733 private int processNextAffiliateChainLocked(int start) { 3734 final TaskRecord startTask = mRecentTasks.get(start); 3735 final int affiliateId = startTask.mAffiliatedTaskId; 3736 3737 // Quick identification of isolated tasks. I.e. those not launched behind. 3738 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3739 startTask.mNextAffiliate == null) { 3740 // There is still a slim chance that there are other tasks that point to this task 3741 // and that the chain is so messed up that this task no longer points to them but 3742 // the gain of this optimization outweighs the risk. 3743 startTask.inRecents = true; 3744 return start + 1; 3745 } 3746 3747 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3748 mTmpRecents.clear(); 3749 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3750 final TaskRecord task = mRecentTasks.get(i); 3751 if (task.mAffiliatedTaskId == affiliateId) { 3752 mRecentTasks.remove(i); 3753 mTmpRecents.add(task); 3754 } 3755 } 3756 3757 // Sort them all by taskId. That is the order they were create in and that order will 3758 // always be correct. 3759 Collections.sort(mTmpRecents, mTaskRecordComparator); 3760 3761 // Go through and fix up the linked list. 3762 // The first one is the end of the chain and has no next. 3763 final TaskRecord first = mTmpRecents.get(0); 3764 first.inRecents = true; 3765 if (first.mNextAffiliate != null) { 3766 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3767 first.setNextAffiliate(null); 3768 notifyTaskPersisterLocked(first, false); 3769 } 3770 // Everything in the middle is doubly linked from next to prev. 3771 final int tmpSize = mTmpRecents.size(); 3772 for (int i = 0; i < tmpSize - 1; ++i) { 3773 final TaskRecord next = mTmpRecents.get(i); 3774 final TaskRecord prev = mTmpRecents.get(i + 1); 3775 if (next.mPrevAffiliate != prev) { 3776 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3777 " setting prev=" + prev); 3778 next.setPrevAffiliate(prev); 3779 notifyTaskPersisterLocked(next, false); 3780 } 3781 if (prev.mNextAffiliate != next) { 3782 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3783 " setting next=" + next); 3784 prev.setNextAffiliate(next); 3785 notifyTaskPersisterLocked(prev, false); 3786 } 3787 prev.inRecents = true; 3788 } 3789 // The last one is the beginning of the list and has no prev. 3790 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3791 if (last.mPrevAffiliate != null) { 3792 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3793 last.setPrevAffiliate(null); 3794 notifyTaskPersisterLocked(last, false); 3795 } 3796 3797 // Insert the group back into mRecentTasks at start. 3798 mRecentTasks.addAll(start, mTmpRecents); 3799 3800 // Let the caller know where we left off. 3801 return start + tmpSize; 3802 } 3803 3804 /** 3805 * Update the recent tasks lists: make sure tasks should still be here (their 3806 * applications / activities still exist), update their availability, fixup ordering 3807 * of affiliations. 3808 */ 3809 void cleanupRecentTasksLocked(int userId) { 3810 if (mRecentTasks == null) { 3811 // Happens when called from the packagemanager broadcast before boot. 3812 return; 3813 } 3814 3815 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3816 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3817 final IPackageManager pm = AppGlobals.getPackageManager(); 3818 final ActivityInfo dummyAct = new ActivityInfo(); 3819 final ApplicationInfo dummyApp = new ApplicationInfo(); 3820 3821 int N = mRecentTasks.size(); 3822 3823 int[] users = userId == UserHandle.USER_ALL 3824 ? getUsersLocked() : new int[] { userId }; 3825 for (int user : users) { 3826 for (int i = 0; i < N; i++) { 3827 TaskRecord task = mRecentTasks.get(i); 3828 if (task.userId != user) { 3829 // Only look at tasks for the user ID of interest. 3830 continue; 3831 } 3832 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3833 // This situation is broken, and we should just get rid of it now. 3834 mRecentTasks.remove(i); 3835 task.removedFromRecents(); 3836 i--; 3837 N--; 3838 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3839 continue; 3840 } 3841 // Check whether this activity is currently available. 3842 if (task.realActivity != null) { 3843 ActivityInfo ai = availActCache.get(task.realActivity); 3844 if (ai == null) { 3845 try { 3846 ai = pm.getActivityInfo(task.realActivity, 3847 PackageManager.GET_UNINSTALLED_PACKAGES 3848 | PackageManager.GET_DISABLED_COMPONENTS, user); 3849 } catch (RemoteException e) { 3850 // Will never happen. 3851 continue; 3852 } 3853 if (ai == null) { 3854 ai = dummyAct; 3855 } 3856 availActCache.put(task.realActivity, ai); 3857 } 3858 if (ai == dummyAct) { 3859 // This could be either because the activity no longer exists, or the 3860 // app is temporarily gone. For the former we want to remove the recents 3861 // entry; for the latter we want to mark it as unavailable. 3862 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3863 if (app == null) { 3864 try { 3865 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3866 PackageManager.GET_UNINSTALLED_PACKAGES 3867 | PackageManager.GET_DISABLED_COMPONENTS, user); 3868 } catch (RemoteException e) { 3869 // Will never happen. 3870 continue; 3871 } 3872 if (app == null) { 3873 app = dummyApp; 3874 } 3875 availAppCache.put(task.realActivity.getPackageName(), app); 3876 } 3877 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3878 // Doesn't exist any more! Good-bye. 3879 mRecentTasks.remove(i); 3880 task.removedFromRecents(); 3881 i--; 3882 N--; 3883 Slog.w(TAG, "Removing no longer valid recent: " + task); 3884 continue; 3885 } else { 3886 // Otherwise just not available for now. 3887 if (task.isAvailable) { 3888 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3889 + task); 3890 } 3891 task.isAvailable = false; 3892 } 3893 } else { 3894 if (!ai.enabled || !ai.applicationInfo.enabled 3895 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3896 if (task.isAvailable) { 3897 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3898 + task + " (enabled=" + ai.enabled + "/" 3899 + ai.applicationInfo.enabled + " flags=" 3900 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3901 } 3902 task.isAvailable = false; 3903 } else { 3904 if (!task.isAvailable) { 3905 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3906 + task); 3907 } 3908 task.isAvailable = true; 3909 } 3910 } 3911 } 3912 } 3913 } 3914 3915 // Verify the affiliate chain for each task. 3916 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3917 } 3918 3919 mTmpRecents.clear(); 3920 // mRecentTasks is now in sorted, affiliated order. 3921 } 3922 3923 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3924 int N = mRecentTasks.size(); 3925 TaskRecord top = task; 3926 int topIndex = taskIndex; 3927 while (top.mNextAffiliate != null && topIndex > 0) { 3928 top = top.mNextAffiliate; 3929 topIndex--; 3930 } 3931 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3932 + topIndex + " from intial " + taskIndex); 3933 // Find the end of the chain, doing a sanity check along the way. 3934 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3935 int endIndex = topIndex; 3936 TaskRecord prev = top; 3937 while (endIndex < N) { 3938 TaskRecord cur = mRecentTasks.get(endIndex); 3939 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3940 + endIndex + " " + cur); 3941 if (cur == top) { 3942 // Verify start of the chain. 3943 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3944 Slog.wtf(TAG, "Bad chain @" + endIndex 3945 + ": first task has next affiliate: " + prev); 3946 sane = false; 3947 break; 3948 } 3949 } else { 3950 // Verify middle of the chain's next points back to the one before. 3951 if (cur.mNextAffiliate != prev 3952 || cur.mNextAffiliateTaskId != prev.taskId) { 3953 Slog.wtf(TAG, "Bad chain @" + endIndex 3954 + ": middle task " + cur + " @" + endIndex 3955 + " has bad next affiliate " 3956 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3957 + ", expected " + prev); 3958 sane = false; 3959 break; 3960 } 3961 } 3962 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3963 // Chain ends here. 3964 if (cur.mPrevAffiliate != null) { 3965 Slog.wtf(TAG, "Bad chain @" + endIndex 3966 + ": last task " + cur + " has previous affiliate " 3967 + cur.mPrevAffiliate); 3968 sane = false; 3969 } 3970 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3971 break; 3972 } else { 3973 // Verify middle of the chain's prev points to a valid item. 3974 if (cur.mPrevAffiliate == null) { 3975 Slog.wtf(TAG, "Bad chain @" + endIndex 3976 + ": task " + cur + " has previous affiliate " 3977 + cur.mPrevAffiliate + " but should be id " 3978 + cur.mPrevAffiliate); 3979 sane = false; 3980 break; 3981 } 3982 } 3983 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3984 Slog.wtf(TAG, "Bad chain @" + endIndex 3985 + ": task " + cur + " has affiliated id " 3986 + cur.mAffiliatedTaskId + " but should be " 3987 + task.mAffiliatedTaskId); 3988 sane = false; 3989 break; 3990 } 3991 prev = cur; 3992 endIndex++; 3993 if (endIndex >= N) { 3994 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3995 + ": last task " + prev); 3996 sane = false; 3997 break; 3998 } 3999 } 4000 if (sane) { 4001 if (endIndex < taskIndex) { 4002 Slog.wtf(TAG, "Bad chain @" + endIndex 4003 + ": did not extend to task " + task + " @" + taskIndex); 4004 sane = false; 4005 } 4006 } 4007 if (sane) { 4008 // All looks good, we can just move all of the affiliated tasks 4009 // to the top. 4010 for (int i=topIndex; i<=endIndex; i++) { 4011 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4012 + " from " + i + " to " + (i-topIndex)); 4013 TaskRecord cur = mRecentTasks.remove(i); 4014 mRecentTasks.add(i-topIndex, cur); 4015 } 4016 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4017 + " to " + endIndex); 4018 return true; 4019 } 4020 4021 // Whoops, couldn't do it. 4022 return false; 4023 } 4024 4025 final void addRecentTaskLocked(TaskRecord task) { 4026 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4027 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4028 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4029 4030 int N = mRecentTasks.size(); 4031 // Quick case: check if the top-most recent task is the same. 4032 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4033 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4034 return; 4035 } 4036 // Another quick case: check if this is part of a set of affiliated 4037 // tasks that are at the top. 4038 if (isAffiliated && N > 0 && task.inRecents 4039 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4040 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4041 + " at top when adding " + task); 4042 return; 4043 } 4044 // Another quick case: never add voice sessions. 4045 if (task.voiceSession != null) { 4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4047 return; 4048 } 4049 4050 boolean needAffiliationFix = false; 4051 4052 // Slightly less quick case: the task is already in recents, so all we need 4053 // to do is move it. 4054 if (task.inRecents) { 4055 int taskIndex = mRecentTasks.indexOf(task); 4056 if (taskIndex >= 0) { 4057 if (!isAffiliated) { 4058 // Simple case: this is not an affiliated task, so we just move it to the front. 4059 mRecentTasks.remove(taskIndex); 4060 mRecentTasks.add(0, task); 4061 notifyTaskPersisterLocked(task, false); 4062 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4063 + " from " + taskIndex); 4064 return; 4065 } else { 4066 // More complicated: need to keep all affiliated tasks together. 4067 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4068 // All went well. 4069 return; 4070 } 4071 4072 // Uh oh... something bad in the affiliation chain, try to rebuild 4073 // everything and then go through our general path of adding a new task. 4074 needAffiliationFix = true; 4075 } 4076 } else { 4077 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4078 needAffiliationFix = true; 4079 } 4080 } 4081 4082 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4083 trimRecentsForTaskLocked(task, true); 4084 4085 N = mRecentTasks.size(); 4086 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4087 final TaskRecord tr = mRecentTasks.remove(N - 1); 4088 tr.removedFromRecents(); 4089 N--; 4090 } 4091 task.inRecents = true; 4092 if (!isAffiliated || needAffiliationFix) { 4093 // If this is a simple non-affiliated task, or we had some failure trying to 4094 // handle it as part of an affilated task, then just place it at the top. 4095 mRecentTasks.add(0, task); 4096 } else if (isAffiliated) { 4097 // If this is a new affiliated task, then move all of the affiliated tasks 4098 // to the front and insert this new one. 4099 TaskRecord other = task.mNextAffiliate; 4100 if (other == null) { 4101 other = task.mPrevAffiliate; 4102 } 4103 if (other != null) { 4104 int otherIndex = mRecentTasks.indexOf(other); 4105 if (otherIndex >= 0) { 4106 // Insert new task at appropriate location. 4107 int taskIndex; 4108 if (other == task.mNextAffiliate) { 4109 // We found the index of our next affiliation, which is who is 4110 // before us in the list, so add after that point. 4111 taskIndex = otherIndex+1; 4112 } else { 4113 // We found the index of our previous affiliation, which is who is 4114 // after us in the list, so add at their position. 4115 taskIndex = otherIndex; 4116 } 4117 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4118 + taskIndex + ": " + task); 4119 mRecentTasks.add(taskIndex, task); 4120 4121 // Now move everything to the front. 4122 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4123 // All went well. 4124 return; 4125 } 4126 4127 // Uh oh... something bad in the affiliation chain, try to rebuild 4128 // everything and then go through our general path of adding a new task. 4129 needAffiliationFix = true; 4130 } else { 4131 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4132 + other); 4133 needAffiliationFix = true; 4134 } 4135 } else { 4136 if (DEBUG_RECENTS) Slog.d(TAG, 4137 "addRecent: adding affiliated task without next/prev:" + task); 4138 needAffiliationFix = true; 4139 } 4140 } 4141 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4142 4143 if (needAffiliationFix) { 4144 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4145 cleanupRecentTasksLocked(task.userId); 4146 } 4147 } 4148 4149 /** 4150 * If needed, remove oldest existing entries in recents that are for the same kind 4151 * of task as the given one. 4152 */ 4153 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4154 int N = mRecentTasks.size(); 4155 final Intent intent = task.intent; 4156 final boolean document = intent != null && intent.isDocument(); 4157 4158 int maxRecents = task.maxRecents - 1; 4159 for (int i=0; i<N; i++) { 4160 final TaskRecord tr = mRecentTasks.get(i); 4161 if (task != tr) { 4162 if (task.userId != tr.userId) { 4163 continue; 4164 } 4165 if (i > MAX_RECENT_BITMAPS) { 4166 tr.freeLastThumbnail(); 4167 } 4168 final Intent trIntent = tr.intent; 4169 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4170 (intent == null || !intent.filterEquals(trIntent))) { 4171 continue; 4172 } 4173 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4174 if (document && trIsDocument) { 4175 // These are the same document activity (not necessarily the same doc). 4176 if (maxRecents > 0) { 4177 --maxRecents; 4178 continue; 4179 } 4180 // Hit the maximum number of documents for this task. Fall through 4181 // and remove this document from recents. 4182 } else if (document || trIsDocument) { 4183 // Only one of these is a document. Not the droid we're looking for. 4184 continue; 4185 } 4186 } 4187 4188 if (!doTrim) { 4189 // If the caller is not actually asking for a trim, just tell them we reached 4190 // a point where the trim would happen. 4191 return i; 4192 } 4193 4194 // Either task and tr are the same or, their affinities match or their intents match 4195 // and neither of them is a document, or they are documents using the same activity 4196 // and their maxRecents has been reached. 4197 tr.disposeThumbnail(); 4198 mRecentTasks.remove(i); 4199 if (task != tr) { 4200 tr.removedFromRecents(); 4201 } 4202 i--; 4203 N--; 4204 if (task.intent == null) { 4205 // If the new recent task we are adding is not fully 4206 // specified, then replace it with the existing recent task. 4207 task = tr; 4208 } 4209 notifyTaskPersisterLocked(tr, false); 4210 } 4211 4212 return -1; 4213 } 4214 4215 @Override 4216 public void reportActivityFullyDrawn(IBinder token) { 4217 synchronized (this) { 4218 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4219 if (r == null) { 4220 return; 4221 } 4222 r.reportFullyDrawnLocked(); 4223 } 4224 } 4225 4226 @Override 4227 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4228 synchronized (this) { 4229 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4230 if (r == null) { 4231 return; 4232 } 4233 final long origId = Binder.clearCallingIdentity(); 4234 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4235 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4236 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4237 if (config != null) { 4238 r.frozenBeforeDestroy = true; 4239 if (!updateConfigurationLocked(config, r, false, false)) { 4240 mStackSupervisor.resumeTopActivitiesLocked(); 4241 } 4242 } 4243 Binder.restoreCallingIdentity(origId); 4244 } 4245 } 4246 4247 @Override 4248 public int getRequestedOrientation(IBinder token) { 4249 synchronized (this) { 4250 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4251 if (r == null) { 4252 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4253 } 4254 return mWindowManager.getAppOrientation(r.appToken); 4255 } 4256 } 4257 4258 /** 4259 * This is the internal entry point for handling Activity.finish(). 4260 * 4261 * @param token The Binder token referencing the Activity we want to finish. 4262 * @param resultCode Result code, if any, from this Activity. 4263 * @param resultData Result data (Intent), if any, from this Activity. 4264 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4265 * the root Activity in the task. 4266 * 4267 * @return Returns true if the activity successfully finished, or false if it is still running. 4268 */ 4269 @Override 4270 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4271 boolean finishTask) { 4272 // Refuse possible leaked file descriptors 4273 if (resultData != null && resultData.hasFileDescriptors() == true) { 4274 throw new IllegalArgumentException("File descriptors passed in Intent"); 4275 } 4276 4277 synchronized(this) { 4278 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4279 if (r == null) { 4280 return true; 4281 } 4282 // Keep track of the root activity of the task before we finish it 4283 TaskRecord tr = r.task; 4284 ActivityRecord rootR = tr.getRootActivity(); 4285 if (rootR == null) { 4286 Slog.w(TAG, "Finishing task with all activities already finished"); 4287 } 4288 // Do not allow task to finish in Lock Task mode. 4289 if (tr == mStackSupervisor.mLockTaskModeTask) { 4290 if (rootR == r) { 4291 Slog.i(TAG, "Not finishing task in lock task mode"); 4292 mStackSupervisor.showLockTaskToast(); 4293 return false; 4294 } 4295 } 4296 if (mController != null) { 4297 // Find the first activity that is not finishing. 4298 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4299 if (next != null) { 4300 // ask watcher if this is allowed 4301 boolean resumeOK = true; 4302 try { 4303 resumeOK = mController.activityResuming(next.packageName); 4304 } catch (RemoteException e) { 4305 mController = null; 4306 Watchdog.getInstance().setActivityController(null); 4307 } 4308 4309 if (!resumeOK) { 4310 Slog.i(TAG, "Not finishing activity because controller resumed"); 4311 return false; 4312 } 4313 } 4314 } 4315 final long origId = Binder.clearCallingIdentity(); 4316 try { 4317 boolean res; 4318 if (finishTask && r == rootR) { 4319 // If requested, remove the task that is associated to this activity only if it 4320 // was the root activity in the task. The result code and data is ignored 4321 // because we don't support returning them across task boundaries. 4322 res = removeTaskByIdLocked(tr.taskId, false); 4323 if (!res) { 4324 Slog.i(TAG, "Removing task failed to finish activity"); 4325 } 4326 } else { 4327 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4328 resultData, "app-request", true); 4329 if (!res) { 4330 Slog.i(TAG, "Failed to finish by app-request"); 4331 } 4332 } 4333 return res; 4334 } finally { 4335 Binder.restoreCallingIdentity(origId); 4336 } 4337 } 4338 } 4339 4340 @Override 4341 public final void finishHeavyWeightApp() { 4342 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4343 != PackageManager.PERMISSION_GRANTED) { 4344 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4345 + Binder.getCallingPid() 4346 + ", uid=" + Binder.getCallingUid() 4347 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4348 Slog.w(TAG, msg); 4349 throw new SecurityException(msg); 4350 } 4351 4352 synchronized(this) { 4353 if (mHeavyWeightProcess == null) { 4354 return; 4355 } 4356 4357 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4358 mHeavyWeightProcess.activities); 4359 for (int i=0; i<activities.size(); i++) { 4360 ActivityRecord r = activities.get(i); 4361 if (!r.finishing) { 4362 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4363 null, "finish-heavy", true); 4364 } 4365 } 4366 4367 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4368 mHeavyWeightProcess.userId, 0)); 4369 mHeavyWeightProcess = null; 4370 } 4371 } 4372 4373 @Override 4374 public void crashApplication(int uid, int initialPid, String packageName, 4375 String message) { 4376 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4377 != PackageManager.PERMISSION_GRANTED) { 4378 String msg = "Permission Denial: crashApplication() from pid=" 4379 + Binder.getCallingPid() 4380 + ", uid=" + Binder.getCallingUid() 4381 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4382 Slog.w(TAG, msg); 4383 throw new SecurityException(msg); 4384 } 4385 4386 synchronized(this) { 4387 ProcessRecord proc = null; 4388 4389 // Figure out which process to kill. We don't trust that initialPid 4390 // still has any relation to current pids, so must scan through the 4391 // list. 4392 synchronized (mPidsSelfLocked) { 4393 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4394 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4395 if (p.uid != uid) { 4396 continue; 4397 } 4398 if (p.pid == initialPid) { 4399 proc = p; 4400 break; 4401 } 4402 if (p.pkgList.containsKey(packageName)) { 4403 proc = p; 4404 } 4405 } 4406 } 4407 4408 if (proc == null) { 4409 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4410 + " initialPid=" + initialPid 4411 + " packageName=" + packageName); 4412 return; 4413 } 4414 4415 if (proc.thread != null) { 4416 if (proc.pid == Process.myPid()) { 4417 Log.w(TAG, "crashApplication: trying to crash self!"); 4418 return; 4419 } 4420 long ident = Binder.clearCallingIdentity(); 4421 try { 4422 proc.thread.scheduleCrash(message); 4423 } catch (RemoteException e) { 4424 } 4425 Binder.restoreCallingIdentity(ident); 4426 } 4427 } 4428 } 4429 4430 @Override 4431 public final void finishSubActivity(IBinder token, String resultWho, 4432 int requestCode) { 4433 synchronized(this) { 4434 final long origId = Binder.clearCallingIdentity(); 4435 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4436 if (r != null) { 4437 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4438 } 4439 Binder.restoreCallingIdentity(origId); 4440 } 4441 } 4442 4443 @Override 4444 public boolean finishActivityAffinity(IBinder token) { 4445 synchronized(this) { 4446 final long origId = Binder.clearCallingIdentity(); 4447 try { 4448 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4449 4450 ActivityRecord rootR = r.task.getRootActivity(); 4451 // Do not allow task to finish in Lock Task mode. 4452 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4453 if (rootR == r) { 4454 mStackSupervisor.showLockTaskToast(); 4455 return false; 4456 } 4457 } 4458 boolean res = false; 4459 if (r != null) { 4460 res = r.task.stack.finishActivityAffinityLocked(r); 4461 } 4462 return res; 4463 } finally { 4464 Binder.restoreCallingIdentity(origId); 4465 } 4466 } 4467 } 4468 4469 @Override 4470 public void finishVoiceTask(IVoiceInteractionSession session) { 4471 synchronized(this) { 4472 final long origId = Binder.clearCallingIdentity(); 4473 try { 4474 mStackSupervisor.finishVoiceTask(session); 4475 } finally { 4476 Binder.restoreCallingIdentity(origId); 4477 } 4478 } 4479 4480 } 4481 4482 @Override 4483 public boolean releaseActivityInstance(IBinder token) { 4484 synchronized(this) { 4485 final long origId = Binder.clearCallingIdentity(); 4486 try { 4487 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4488 if (r.task == null || r.task.stack == null) { 4489 return false; 4490 } 4491 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4492 } finally { 4493 Binder.restoreCallingIdentity(origId); 4494 } 4495 } 4496 } 4497 4498 @Override 4499 public void releaseSomeActivities(IApplicationThread appInt) { 4500 synchronized(this) { 4501 final long origId = Binder.clearCallingIdentity(); 4502 try { 4503 ProcessRecord app = getRecordForAppLocked(appInt); 4504 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4505 } finally { 4506 Binder.restoreCallingIdentity(origId); 4507 } 4508 } 4509 } 4510 4511 @Override 4512 public boolean willActivityBeVisible(IBinder token) { 4513 synchronized(this) { 4514 ActivityStack stack = ActivityRecord.getStackLocked(token); 4515 if (stack != null) { 4516 return stack.willActivityBeVisibleLocked(token); 4517 } 4518 return false; 4519 } 4520 } 4521 4522 @Override 4523 public void overridePendingTransition(IBinder token, String packageName, 4524 int enterAnim, int exitAnim) { 4525 synchronized(this) { 4526 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4527 if (self == null) { 4528 return; 4529 } 4530 4531 final long origId = Binder.clearCallingIdentity(); 4532 4533 if (self.state == ActivityState.RESUMED 4534 || self.state == ActivityState.PAUSING) { 4535 mWindowManager.overridePendingAppTransition(packageName, 4536 enterAnim, exitAnim, null); 4537 } 4538 4539 Binder.restoreCallingIdentity(origId); 4540 } 4541 } 4542 4543 /** 4544 * Main function for removing an existing process from the activity manager 4545 * as a result of that process going away. Clears out all connections 4546 * to the process. 4547 */ 4548 private final void handleAppDiedLocked(ProcessRecord app, 4549 boolean restarting, boolean allowRestart) { 4550 int pid = app.pid; 4551 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4552 if (!kept && !restarting) { 4553 removeLruProcessLocked(app); 4554 if (pid > 0) { 4555 ProcessList.remove(pid); 4556 } 4557 } 4558 4559 if (mProfileProc == app) { 4560 clearProfilerLocked(); 4561 } 4562 4563 // Remove this application's activities from active lists. 4564 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4565 4566 app.activities.clear(); 4567 4568 if (app.instrumentationClass != null) { 4569 Slog.w(TAG, "Crash of app " + app.processName 4570 + " running instrumentation " + app.instrumentationClass); 4571 Bundle info = new Bundle(); 4572 info.putString("shortMsg", "Process crashed."); 4573 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4574 } 4575 4576 if (!restarting) { 4577 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4578 // If there was nothing to resume, and we are not already 4579 // restarting this process, but there is a visible activity that 4580 // is hosted by the process... then make sure all visible 4581 // activities are running, taking care of restarting this 4582 // process. 4583 if (hasVisibleActivities) { 4584 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4585 } 4586 } 4587 } 4588 } 4589 4590 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4591 IBinder threadBinder = thread.asBinder(); 4592 // Find the application record. 4593 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4594 ProcessRecord rec = mLruProcesses.get(i); 4595 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4596 return i; 4597 } 4598 } 4599 return -1; 4600 } 4601 4602 final ProcessRecord getRecordForAppLocked( 4603 IApplicationThread thread) { 4604 if (thread == null) { 4605 return null; 4606 } 4607 4608 int appIndex = getLRURecordIndexForAppLocked(thread); 4609 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4610 } 4611 4612 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4613 // If there are no longer any background processes running, 4614 // and the app that died was not running instrumentation, 4615 // then tell everyone we are now low on memory. 4616 boolean haveBg = false; 4617 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4618 ProcessRecord rec = mLruProcesses.get(i); 4619 if (rec.thread != null 4620 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4621 haveBg = true; 4622 break; 4623 } 4624 } 4625 4626 if (!haveBg) { 4627 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4628 if (doReport) { 4629 long now = SystemClock.uptimeMillis(); 4630 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4631 doReport = false; 4632 } else { 4633 mLastMemUsageReportTime = now; 4634 } 4635 } 4636 final ArrayList<ProcessMemInfo> memInfos 4637 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4638 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4639 long now = SystemClock.uptimeMillis(); 4640 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4641 ProcessRecord rec = mLruProcesses.get(i); 4642 if (rec == dyingProc || rec.thread == null) { 4643 continue; 4644 } 4645 if (doReport) { 4646 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4647 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4648 } 4649 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4650 // The low memory report is overriding any current 4651 // state for a GC request. Make sure to do 4652 // heavy/important/visible/foreground processes first. 4653 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4654 rec.lastRequestedGc = 0; 4655 } else { 4656 rec.lastRequestedGc = rec.lastLowMemory; 4657 } 4658 rec.reportLowMemory = true; 4659 rec.lastLowMemory = now; 4660 mProcessesToGc.remove(rec); 4661 addProcessToGcListLocked(rec); 4662 } 4663 } 4664 if (doReport) { 4665 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4666 mHandler.sendMessage(msg); 4667 } 4668 scheduleAppGcsLocked(); 4669 } 4670 } 4671 4672 final void appDiedLocked(ProcessRecord app) { 4673 appDiedLocked(app, app.pid, app.thread); 4674 } 4675 4676 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4677 // First check if this ProcessRecord is actually active for the pid. 4678 synchronized (mPidsSelfLocked) { 4679 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4680 if (curProc != app) { 4681 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4682 return; 4683 } 4684 } 4685 4686 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4687 synchronized (stats) { 4688 stats.noteProcessDiedLocked(app.info.uid, pid); 4689 } 4690 4691 if (!app.killed) { 4692 Process.killProcessQuiet(pid); 4693 Process.killProcessGroup(app.info.uid, pid); 4694 app.killed = true; 4695 } 4696 4697 // Clean up already done if the process has been re-started. 4698 if (app.pid == pid && app.thread != null && 4699 app.thread.asBinder() == thread.asBinder()) { 4700 boolean doLowMem = app.instrumentationClass == null; 4701 boolean doOomAdj = doLowMem; 4702 if (!app.killedByAm) { 4703 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4704 + ") has died"); 4705 mAllowLowerMemLevel = true; 4706 } else { 4707 // Note that we always want to do oom adj to update our state with the 4708 // new number of procs. 4709 mAllowLowerMemLevel = false; 4710 doLowMem = false; 4711 } 4712 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4713 if (DEBUG_CLEANUP) Slog.v( 4714 TAG, "Dying app: " + app + ", pid: " + pid 4715 + ", thread: " + thread.asBinder()); 4716 handleAppDiedLocked(app, false, true); 4717 4718 if (doOomAdj) { 4719 updateOomAdjLocked(); 4720 } 4721 if (doLowMem) { 4722 doLowMemReportIfNeededLocked(app); 4723 } 4724 } else if (app.pid != pid) { 4725 // A new process has already been started. 4726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4727 + ") has died and restarted (pid " + app.pid + ")."); 4728 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4729 } else if (DEBUG_PROCESSES) { 4730 Slog.d(TAG, "Received spurious death notification for thread " 4731 + thread.asBinder()); 4732 } 4733 } 4734 4735 /** 4736 * If a stack trace dump file is configured, dump process stack traces. 4737 * @param clearTraces causes the dump file to be erased prior to the new 4738 * traces being written, if true; when false, the new traces will be 4739 * appended to any existing file content. 4740 * @param firstPids of dalvik VM processes to dump stack traces for first 4741 * @param lastPids of dalvik VM processes to dump stack traces for last 4742 * @param nativeProcs optional list of native process names to dump stack crawls 4743 * @return file containing stack traces, or null if no dump file is configured 4744 */ 4745 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4746 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4747 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4748 if (tracesPath == null || tracesPath.length() == 0) { 4749 return null; 4750 } 4751 4752 File tracesFile = new File(tracesPath); 4753 try { 4754 File tracesDir = tracesFile.getParentFile(); 4755 if (!tracesDir.exists()) { 4756 tracesDir.mkdirs(); 4757 if (!SELinux.restorecon(tracesDir)) { 4758 return null; 4759 } 4760 } 4761 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4762 4763 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4764 tracesFile.createNewFile(); 4765 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4766 } catch (IOException e) { 4767 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4768 return null; 4769 } 4770 4771 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4772 return tracesFile; 4773 } 4774 4775 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4776 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4777 // Use a FileObserver to detect when traces finish writing. 4778 // The order of traces is considered important to maintain for legibility. 4779 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4780 @Override 4781 public synchronized void onEvent(int event, String path) { notify(); } 4782 }; 4783 4784 try { 4785 observer.startWatching(); 4786 4787 // First collect all of the stacks of the most important pids. 4788 if (firstPids != null) { 4789 try { 4790 int num = firstPids.size(); 4791 for (int i = 0; i < num; i++) { 4792 synchronized (observer) { 4793 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4794 observer.wait(200); // Wait for write-close, give up after 200msec 4795 } 4796 } 4797 } catch (InterruptedException e) { 4798 Slog.wtf(TAG, e); 4799 } 4800 } 4801 4802 // Next collect the stacks of the native pids 4803 if (nativeProcs != null) { 4804 int[] pids = Process.getPidsForCommands(nativeProcs); 4805 if (pids != null) { 4806 for (int pid : pids) { 4807 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4808 } 4809 } 4810 } 4811 4812 // Lastly, measure CPU usage. 4813 if (processCpuTracker != null) { 4814 processCpuTracker.init(); 4815 System.gc(); 4816 processCpuTracker.update(); 4817 try { 4818 synchronized (processCpuTracker) { 4819 processCpuTracker.wait(500); // measure over 1/2 second. 4820 } 4821 } catch (InterruptedException e) { 4822 } 4823 processCpuTracker.update(); 4824 4825 // We'll take the stack crawls of just the top apps using CPU. 4826 final int N = processCpuTracker.countWorkingStats(); 4827 int numProcs = 0; 4828 for (int i=0; i<N && numProcs<5; i++) { 4829 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4830 if (lastPids.indexOfKey(stats.pid) >= 0) { 4831 numProcs++; 4832 try { 4833 synchronized (observer) { 4834 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4835 observer.wait(200); // Wait for write-close, give up after 200msec 4836 } 4837 } catch (InterruptedException e) { 4838 Slog.wtf(TAG, e); 4839 } 4840 4841 } 4842 } 4843 } 4844 } finally { 4845 observer.stopWatching(); 4846 } 4847 } 4848 4849 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4850 if (true || IS_USER_BUILD) { 4851 return; 4852 } 4853 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4854 if (tracesPath == null || tracesPath.length() == 0) { 4855 return; 4856 } 4857 4858 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4859 StrictMode.allowThreadDiskWrites(); 4860 try { 4861 final File tracesFile = new File(tracesPath); 4862 final File tracesDir = tracesFile.getParentFile(); 4863 final File tracesTmp = new File(tracesDir, "__tmp__"); 4864 try { 4865 if (!tracesDir.exists()) { 4866 tracesDir.mkdirs(); 4867 if (!SELinux.restorecon(tracesDir.getPath())) { 4868 return; 4869 } 4870 } 4871 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4872 4873 if (tracesFile.exists()) { 4874 tracesTmp.delete(); 4875 tracesFile.renameTo(tracesTmp); 4876 } 4877 StringBuilder sb = new StringBuilder(); 4878 Time tobj = new Time(); 4879 tobj.set(System.currentTimeMillis()); 4880 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4881 sb.append(": "); 4882 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4883 sb.append(" since "); 4884 sb.append(msg); 4885 FileOutputStream fos = new FileOutputStream(tracesFile); 4886 fos.write(sb.toString().getBytes()); 4887 if (app == null) { 4888 fos.write("\n*** No application process!".getBytes()); 4889 } 4890 fos.close(); 4891 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4892 } catch (IOException e) { 4893 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4894 return; 4895 } 4896 4897 if (app != null) { 4898 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4899 firstPids.add(app.pid); 4900 dumpStackTraces(tracesPath, firstPids, null, null, null); 4901 } 4902 4903 File lastTracesFile = null; 4904 File curTracesFile = null; 4905 for (int i=9; i>=0; i--) { 4906 String name = String.format(Locale.US, "slow%02d.txt", i); 4907 curTracesFile = new File(tracesDir, name); 4908 if (curTracesFile.exists()) { 4909 if (lastTracesFile != null) { 4910 curTracesFile.renameTo(lastTracesFile); 4911 } else { 4912 curTracesFile.delete(); 4913 } 4914 } 4915 lastTracesFile = curTracesFile; 4916 } 4917 tracesFile.renameTo(curTracesFile); 4918 if (tracesTmp.exists()) { 4919 tracesTmp.renameTo(tracesFile); 4920 } 4921 } finally { 4922 StrictMode.setThreadPolicy(oldPolicy); 4923 } 4924 } 4925 4926 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4927 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4928 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4929 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4930 4931 if (mController != null) { 4932 try { 4933 // 0 == continue, -1 = kill process immediately 4934 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4935 if (res < 0 && app.pid != MY_PID) { 4936 app.kill("anr", true); 4937 } 4938 } catch (RemoteException e) { 4939 mController = null; 4940 Watchdog.getInstance().setActivityController(null); 4941 } 4942 } 4943 4944 long anrTime = SystemClock.uptimeMillis(); 4945 if (MONITOR_CPU_USAGE) { 4946 updateCpuStatsNow(); 4947 } 4948 4949 synchronized (this) { 4950 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4951 if (mShuttingDown) { 4952 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4953 return; 4954 } else if (app.notResponding) { 4955 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4956 return; 4957 } else if (app.crashing) { 4958 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4959 return; 4960 } 4961 4962 // In case we come through here for the same app before completing 4963 // this one, mark as anring now so we will bail out. 4964 app.notResponding = true; 4965 4966 // Log the ANR to the event log. 4967 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4968 app.processName, app.info.flags, annotation); 4969 4970 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4971 firstPids.add(app.pid); 4972 4973 int parentPid = app.pid; 4974 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4975 if (parentPid != app.pid) firstPids.add(parentPid); 4976 4977 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4978 4979 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4980 ProcessRecord r = mLruProcesses.get(i); 4981 if (r != null && r.thread != null) { 4982 int pid = r.pid; 4983 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4984 if (r.persistent) { 4985 firstPids.add(pid); 4986 } else { 4987 lastPids.put(pid, Boolean.TRUE); 4988 } 4989 } 4990 } 4991 } 4992 } 4993 4994 // Log the ANR to the main log. 4995 StringBuilder info = new StringBuilder(); 4996 info.setLength(0); 4997 info.append("ANR in ").append(app.processName); 4998 if (activity != null && activity.shortComponentName != null) { 4999 info.append(" (").append(activity.shortComponentName).append(")"); 5000 } 5001 info.append("\n"); 5002 info.append("PID: ").append(app.pid).append("\n"); 5003 if (annotation != null) { 5004 info.append("Reason: ").append(annotation).append("\n"); 5005 } 5006 if (parent != null && parent != activity) { 5007 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5008 } 5009 5010 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5011 5012 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5013 NATIVE_STACKS_OF_INTEREST); 5014 5015 String cpuInfo = null; 5016 if (MONITOR_CPU_USAGE) { 5017 updateCpuStatsNow(); 5018 synchronized (mProcessCpuTracker) { 5019 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5020 } 5021 info.append(processCpuTracker.printCurrentLoad()); 5022 info.append(cpuInfo); 5023 } 5024 5025 info.append(processCpuTracker.printCurrentState(anrTime)); 5026 5027 Slog.e(TAG, info.toString()); 5028 if (tracesFile == null) { 5029 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5030 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5031 } 5032 5033 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5034 cpuInfo, tracesFile, null); 5035 5036 if (mController != null) { 5037 try { 5038 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5039 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5040 if (res != 0) { 5041 if (res < 0 && app.pid != MY_PID) { 5042 app.kill("anr", true); 5043 } else { 5044 synchronized (this) { 5045 mServices.scheduleServiceTimeoutLocked(app); 5046 } 5047 } 5048 return; 5049 } 5050 } catch (RemoteException e) { 5051 mController = null; 5052 Watchdog.getInstance().setActivityController(null); 5053 } 5054 } 5055 5056 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5057 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5058 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5059 5060 synchronized (this) { 5061 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5062 5063 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5064 app.kill("bg anr", true); 5065 return; 5066 } 5067 5068 // Set the app's notResponding state, and look up the errorReportReceiver 5069 makeAppNotRespondingLocked(app, 5070 activity != null ? activity.shortComponentName : null, 5071 annotation != null ? "ANR " + annotation : "ANR", 5072 info.toString()); 5073 5074 // Bring up the infamous App Not Responding dialog 5075 Message msg = Message.obtain(); 5076 HashMap<String, Object> map = new HashMap<String, Object>(); 5077 msg.what = SHOW_NOT_RESPONDING_MSG; 5078 msg.obj = map; 5079 msg.arg1 = aboveSystem ? 1 : 0; 5080 map.put("app", app); 5081 if (activity != null) { 5082 map.put("activity", activity); 5083 } 5084 5085 mHandler.sendMessage(msg); 5086 } 5087 } 5088 5089 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5090 if (!mLaunchWarningShown) { 5091 mLaunchWarningShown = true; 5092 mHandler.post(new Runnable() { 5093 @Override 5094 public void run() { 5095 synchronized (ActivityManagerService.this) { 5096 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5097 d.show(); 5098 mHandler.postDelayed(new Runnable() { 5099 @Override 5100 public void run() { 5101 synchronized (ActivityManagerService.this) { 5102 d.dismiss(); 5103 mLaunchWarningShown = false; 5104 } 5105 } 5106 }, 4000); 5107 } 5108 } 5109 }); 5110 } 5111 } 5112 5113 @Override 5114 public boolean clearApplicationUserData(final String packageName, 5115 final IPackageDataObserver observer, int userId) { 5116 enforceNotIsolatedCaller("clearApplicationUserData"); 5117 int uid = Binder.getCallingUid(); 5118 int pid = Binder.getCallingPid(); 5119 userId = handleIncomingUser(pid, uid, 5120 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5121 long callingId = Binder.clearCallingIdentity(); 5122 try { 5123 IPackageManager pm = AppGlobals.getPackageManager(); 5124 int pkgUid = -1; 5125 synchronized(this) { 5126 try { 5127 pkgUid = pm.getPackageUid(packageName, userId); 5128 } catch (RemoteException e) { 5129 } 5130 if (pkgUid == -1) { 5131 Slog.w(TAG, "Invalid packageName: " + packageName); 5132 if (observer != null) { 5133 try { 5134 observer.onRemoveCompleted(packageName, false); 5135 } catch (RemoteException e) { 5136 Slog.i(TAG, "Observer no longer exists."); 5137 } 5138 } 5139 return false; 5140 } 5141 if (uid == pkgUid || checkComponentPermission( 5142 android.Manifest.permission.CLEAR_APP_USER_DATA, 5143 pid, uid, -1, true) 5144 == PackageManager.PERMISSION_GRANTED) { 5145 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5146 } else { 5147 throw new SecurityException("PID " + pid + " does not have permission " 5148 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5149 + " of package " + packageName); 5150 } 5151 5152 // Remove all tasks match the cleared application package and user 5153 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5154 final TaskRecord tr = mRecentTasks.get(i); 5155 final String taskPackageName = 5156 tr.getBaseIntent().getComponent().getPackageName(); 5157 if (tr.userId != userId) continue; 5158 if (!taskPackageName.equals(packageName)) continue; 5159 removeTaskByIdLocked(tr.taskId, false); 5160 } 5161 } 5162 5163 try { 5164 // Clear application user data 5165 pm.clearApplicationUserData(packageName, observer, userId); 5166 5167 synchronized(this) { 5168 // Remove all permissions granted from/to this package 5169 removeUriPermissionsForPackageLocked(packageName, userId, true); 5170 } 5171 5172 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5173 Uri.fromParts("package", packageName, null)); 5174 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5175 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5176 null, null, 0, null, null, null, false, false, userId); 5177 } catch (RemoteException e) { 5178 } 5179 } finally { 5180 Binder.restoreCallingIdentity(callingId); 5181 } 5182 return true; 5183 } 5184 5185 @Override 5186 public void killBackgroundProcesses(final String packageName, int userId) { 5187 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5188 != PackageManager.PERMISSION_GRANTED && 5189 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5190 != PackageManager.PERMISSION_GRANTED) { 5191 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5192 + Binder.getCallingPid() 5193 + ", uid=" + Binder.getCallingUid() 5194 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5195 Slog.w(TAG, msg); 5196 throw new SecurityException(msg); 5197 } 5198 5199 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5200 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5201 long callingId = Binder.clearCallingIdentity(); 5202 try { 5203 IPackageManager pm = AppGlobals.getPackageManager(); 5204 synchronized(this) { 5205 int appId = -1; 5206 try { 5207 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5208 } catch (RemoteException e) { 5209 } 5210 if (appId == -1) { 5211 Slog.w(TAG, "Invalid packageName: " + packageName); 5212 return; 5213 } 5214 killPackageProcessesLocked(packageName, appId, userId, 5215 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5216 } 5217 } finally { 5218 Binder.restoreCallingIdentity(callingId); 5219 } 5220 } 5221 5222 @Override 5223 public void killAllBackgroundProcesses() { 5224 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5225 != PackageManager.PERMISSION_GRANTED) { 5226 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5227 + Binder.getCallingPid() 5228 + ", uid=" + Binder.getCallingUid() 5229 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5230 Slog.w(TAG, msg); 5231 throw new SecurityException(msg); 5232 } 5233 5234 long callingId = Binder.clearCallingIdentity(); 5235 try { 5236 synchronized(this) { 5237 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5238 final int NP = mProcessNames.getMap().size(); 5239 for (int ip=0; ip<NP; ip++) { 5240 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5241 final int NA = apps.size(); 5242 for (int ia=0; ia<NA; ia++) { 5243 ProcessRecord app = apps.valueAt(ia); 5244 if (app.persistent) { 5245 // we don't kill persistent processes 5246 continue; 5247 } 5248 if (app.removed) { 5249 procs.add(app); 5250 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5251 app.removed = true; 5252 procs.add(app); 5253 } 5254 } 5255 } 5256 5257 int N = procs.size(); 5258 for (int i=0; i<N; i++) { 5259 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5260 } 5261 mAllowLowerMemLevel = true; 5262 updateOomAdjLocked(); 5263 doLowMemReportIfNeededLocked(null); 5264 } 5265 } finally { 5266 Binder.restoreCallingIdentity(callingId); 5267 } 5268 } 5269 5270 @Override 5271 public void forceStopPackage(final String packageName, int userId) { 5272 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5273 != PackageManager.PERMISSION_GRANTED) { 5274 String msg = "Permission Denial: forceStopPackage() from pid=" 5275 + Binder.getCallingPid() 5276 + ", uid=" + Binder.getCallingUid() 5277 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5278 Slog.w(TAG, msg); 5279 throw new SecurityException(msg); 5280 } 5281 final int callingPid = Binder.getCallingPid(); 5282 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5283 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5284 long callingId = Binder.clearCallingIdentity(); 5285 try { 5286 IPackageManager pm = AppGlobals.getPackageManager(); 5287 synchronized(this) { 5288 int[] users = userId == UserHandle.USER_ALL 5289 ? getUsersLocked() : new int[] { userId }; 5290 for (int user : users) { 5291 int pkgUid = -1; 5292 try { 5293 pkgUid = pm.getPackageUid(packageName, user); 5294 } catch (RemoteException e) { 5295 } 5296 if (pkgUid == -1) { 5297 Slog.w(TAG, "Invalid packageName: " + packageName); 5298 continue; 5299 } 5300 try { 5301 pm.setPackageStoppedState(packageName, true, user); 5302 } catch (RemoteException e) { 5303 } catch (IllegalArgumentException e) { 5304 Slog.w(TAG, "Failed trying to unstop package " 5305 + packageName + ": " + e); 5306 } 5307 if (isUserRunningLocked(user, false)) { 5308 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5309 } 5310 } 5311 } 5312 } finally { 5313 Binder.restoreCallingIdentity(callingId); 5314 } 5315 } 5316 5317 @Override 5318 public void addPackageDependency(String packageName) { 5319 synchronized (this) { 5320 int callingPid = Binder.getCallingPid(); 5321 if (callingPid == Process.myPid()) { 5322 // Yeah, um, no. 5323 return; 5324 } 5325 ProcessRecord proc; 5326 synchronized (mPidsSelfLocked) { 5327 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5328 } 5329 if (proc != null) { 5330 if (proc.pkgDeps == null) { 5331 proc.pkgDeps = new ArraySet<String>(1); 5332 } 5333 proc.pkgDeps.add(packageName); 5334 } 5335 } 5336 } 5337 5338 /* 5339 * The pkg name and app id have to be specified. 5340 */ 5341 @Override 5342 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5343 if (pkg == null) { 5344 return; 5345 } 5346 // Make sure the uid is valid. 5347 if (appid < 0) { 5348 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5349 return; 5350 } 5351 int callerUid = Binder.getCallingUid(); 5352 // Only the system server can kill an application 5353 if (callerUid == Process.SYSTEM_UID) { 5354 // Post an aysnc message to kill the application 5355 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5356 msg.arg1 = appid; 5357 msg.arg2 = 0; 5358 Bundle bundle = new Bundle(); 5359 bundle.putString("pkg", pkg); 5360 bundle.putString("reason", reason); 5361 msg.obj = bundle; 5362 mHandler.sendMessage(msg); 5363 } else { 5364 throw new SecurityException(callerUid + " cannot kill pkg: " + 5365 pkg); 5366 } 5367 } 5368 5369 @Override 5370 public void closeSystemDialogs(String reason) { 5371 enforceNotIsolatedCaller("closeSystemDialogs"); 5372 5373 final int pid = Binder.getCallingPid(); 5374 final int uid = Binder.getCallingUid(); 5375 final long origId = Binder.clearCallingIdentity(); 5376 try { 5377 synchronized (this) { 5378 // Only allow this from foreground processes, so that background 5379 // applications can't abuse it to prevent system UI from being shown. 5380 if (uid >= Process.FIRST_APPLICATION_UID) { 5381 ProcessRecord proc; 5382 synchronized (mPidsSelfLocked) { 5383 proc = mPidsSelfLocked.get(pid); 5384 } 5385 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5386 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5387 + " from background process " + proc); 5388 return; 5389 } 5390 } 5391 closeSystemDialogsLocked(reason); 5392 } 5393 } finally { 5394 Binder.restoreCallingIdentity(origId); 5395 } 5396 } 5397 5398 void closeSystemDialogsLocked(String reason) { 5399 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5400 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5401 | Intent.FLAG_RECEIVER_FOREGROUND); 5402 if (reason != null) { 5403 intent.putExtra("reason", reason); 5404 } 5405 mWindowManager.closeSystemDialogs(reason); 5406 5407 mStackSupervisor.closeSystemDialogsLocked(); 5408 5409 broadcastIntentLocked(null, null, intent, null, 5410 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5411 Process.SYSTEM_UID, UserHandle.USER_ALL); 5412 } 5413 5414 @Override 5415 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5416 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5417 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5418 for (int i=pids.length-1; i>=0; i--) { 5419 ProcessRecord proc; 5420 int oomAdj; 5421 synchronized (this) { 5422 synchronized (mPidsSelfLocked) { 5423 proc = mPidsSelfLocked.get(pids[i]); 5424 oomAdj = proc != null ? proc.setAdj : 0; 5425 } 5426 } 5427 infos[i] = new Debug.MemoryInfo(); 5428 Debug.getMemoryInfo(pids[i], infos[i]); 5429 if (proc != null) { 5430 synchronized (this) { 5431 if (proc.thread != null && proc.setAdj == oomAdj) { 5432 // Record this for posterity if the process has been stable. 5433 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5434 infos[i].getTotalUss(), false, proc.pkgList); 5435 } 5436 } 5437 } 5438 } 5439 return infos; 5440 } 5441 5442 @Override 5443 public long[] getProcessPss(int[] pids) { 5444 enforceNotIsolatedCaller("getProcessPss"); 5445 long[] pss = new long[pids.length]; 5446 for (int i=pids.length-1; i>=0; i--) { 5447 ProcessRecord proc; 5448 int oomAdj; 5449 synchronized (this) { 5450 synchronized (mPidsSelfLocked) { 5451 proc = mPidsSelfLocked.get(pids[i]); 5452 oomAdj = proc != null ? proc.setAdj : 0; 5453 } 5454 } 5455 long[] tmpUss = new long[1]; 5456 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5457 if (proc != null) { 5458 synchronized (this) { 5459 if (proc.thread != null && proc.setAdj == oomAdj) { 5460 // Record this for posterity if the process has been stable. 5461 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5462 } 5463 } 5464 } 5465 } 5466 return pss; 5467 } 5468 5469 @Override 5470 public void killApplicationProcess(String processName, int uid) { 5471 if (processName == null) { 5472 return; 5473 } 5474 5475 int callerUid = Binder.getCallingUid(); 5476 // Only the system server can kill an application 5477 if (callerUid == Process.SYSTEM_UID) { 5478 synchronized (this) { 5479 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5480 if (app != null && app.thread != null) { 5481 try { 5482 app.thread.scheduleSuicide(); 5483 } catch (RemoteException e) { 5484 // If the other end already died, then our work here is done. 5485 } 5486 } else { 5487 Slog.w(TAG, "Process/uid not found attempting kill of " 5488 + processName + " / " + uid); 5489 } 5490 } 5491 } else { 5492 throw new SecurityException(callerUid + " cannot kill app process: " + 5493 processName); 5494 } 5495 } 5496 5497 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5498 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5499 false, true, false, false, UserHandle.getUserId(uid), reason); 5500 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5501 Uri.fromParts("package", packageName, null)); 5502 if (!mProcessesReady) { 5503 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5504 | Intent.FLAG_RECEIVER_FOREGROUND); 5505 } 5506 intent.putExtra(Intent.EXTRA_UID, uid); 5507 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5508 broadcastIntentLocked(null, null, intent, 5509 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5510 false, false, 5511 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5512 } 5513 5514 private void forceStopUserLocked(int userId, String reason) { 5515 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5516 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5517 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5518 | Intent.FLAG_RECEIVER_FOREGROUND); 5519 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5520 broadcastIntentLocked(null, null, intent, 5521 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5522 false, false, 5523 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5524 } 5525 5526 private final boolean killPackageProcessesLocked(String packageName, int appId, 5527 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5528 boolean doit, boolean evenPersistent, String reason) { 5529 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5530 5531 // Remove all processes this package may have touched: all with the 5532 // same UID (except for the system or root user), and all whose name 5533 // matches the package name. 5534 final int NP = mProcessNames.getMap().size(); 5535 for (int ip=0; ip<NP; ip++) { 5536 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5537 final int NA = apps.size(); 5538 for (int ia=0; ia<NA; ia++) { 5539 ProcessRecord app = apps.valueAt(ia); 5540 if (app.persistent && !evenPersistent) { 5541 // we don't kill persistent processes 5542 continue; 5543 } 5544 if (app.removed) { 5545 if (doit) { 5546 procs.add(app); 5547 } 5548 continue; 5549 } 5550 5551 // Skip process if it doesn't meet our oom adj requirement. 5552 if (app.setAdj < minOomAdj) { 5553 continue; 5554 } 5555 5556 // If no package is specified, we call all processes under the 5557 // give user id. 5558 if (packageName == null) { 5559 if (app.userId != userId) { 5560 continue; 5561 } 5562 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5563 continue; 5564 } 5565 // Package has been specified, we want to hit all processes 5566 // that match it. We need to qualify this by the processes 5567 // that are running under the specified app and user ID. 5568 } else { 5569 final boolean isDep = app.pkgDeps != null 5570 && app.pkgDeps.contains(packageName); 5571 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5572 continue; 5573 } 5574 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5575 continue; 5576 } 5577 if (!app.pkgList.containsKey(packageName) && !isDep) { 5578 continue; 5579 } 5580 } 5581 5582 // Process has passed all conditions, kill it! 5583 if (!doit) { 5584 return true; 5585 } 5586 app.removed = true; 5587 procs.add(app); 5588 } 5589 } 5590 5591 int N = procs.size(); 5592 for (int i=0; i<N; i++) { 5593 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5594 } 5595 updateOomAdjLocked(); 5596 return N > 0; 5597 } 5598 5599 private final boolean forceStopPackageLocked(String name, int appId, 5600 boolean callerWillRestart, boolean purgeCache, boolean doit, 5601 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5602 int i; 5603 int N; 5604 5605 if (userId == UserHandle.USER_ALL && name == null) { 5606 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5607 } 5608 5609 if (appId < 0 && name != null) { 5610 try { 5611 appId = UserHandle.getAppId( 5612 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5613 } catch (RemoteException e) { 5614 } 5615 } 5616 5617 if (doit) { 5618 if (name != null) { 5619 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5620 + " user=" + userId + ": " + reason); 5621 } else { 5622 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5623 } 5624 5625 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5626 for (int ip=pmap.size()-1; ip>=0; ip--) { 5627 SparseArray<Long> ba = pmap.valueAt(ip); 5628 for (i=ba.size()-1; i>=0; i--) { 5629 boolean remove = false; 5630 final int entUid = ba.keyAt(i); 5631 if (name != null) { 5632 if (userId == UserHandle.USER_ALL) { 5633 if (UserHandle.getAppId(entUid) == appId) { 5634 remove = true; 5635 } 5636 } else { 5637 if (entUid == UserHandle.getUid(userId, appId)) { 5638 remove = true; 5639 } 5640 } 5641 } else if (UserHandle.getUserId(entUid) == userId) { 5642 remove = true; 5643 } 5644 if (remove) { 5645 ba.removeAt(i); 5646 } 5647 } 5648 if (ba.size() == 0) { 5649 pmap.removeAt(ip); 5650 } 5651 } 5652 } 5653 5654 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5655 -100, callerWillRestart, true, doit, evenPersistent, 5656 name == null ? ("stop user " + userId) : ("stop " + name)); 5657 5658 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5659 if (!doit) { 5660 return true; 5661 } 5662 didSomething = true; 5663 } 5664 5665 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5666 if (!doit) { 5667 return true; 5668 } 5669 didSomething = true; 5670 } 5671 5672 if (name == null) { 5673 // Remove all sticky broadcasts from this user. 5674 mStickyBroadcasts.remove(userId); 5675 } 5676 5677 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5678 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5679 userId, providers)) { 5680 if (!doit) { 5681 return true; 5682 } 5683 didSomething = true; 5684 } 5685 N = providers.size(); 5686 for (i=0; i<N; i++) { 5687 removeDyingProviderLocked(null, providers.get(i), true); 5688 } 5689 5690 // Remove transient permissions granted from/to this package/user 5691 removeUriPermissionsForPackageLocked(name, userId, false); 5692 5693 if (name == null || uninstalling) { 5694 // Remove pending intents. For now we only do this when force 5695 // stopping users, because we have some problems when doing this 5696 // for packages -- app widgets are not currently cleaned up for 5697 // such packages, so they can be left with bad pending intents. 5698 if (mIntentSenderRecords.size() > 0) { 5699 Iterator<WeakReference<PendingIntentRecord>> it 5700 = mIntentSenderRecords.values().iterator(); 5701 while (it.hasNext()) { 5702 WeakReference<PendingIntentRecord> wpir = it.next(); 5703 if (wpir == null) { 5704 it.remove(); 5705 continue; 5706 } 5707 PendingIntentRecord pir = wpir.get(); 5708 if (pir == null) { 5709 it.remove(); 5710 continue; 5711 } 5712 if (name == null) { 5713 // Stopping user, remove all objects for the user. 5714 if (pir.key.userId != userId) { 5715 // Not the same user, skip it. 5716 continue; 5717 } 5718 } else { 5719 if (UserHandle.getAppId(pir.uid) != appId) { 5720 // Different app id, skip it. 5721 continue; 5722 } 5723 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5724 // Different user, skip it. 5725 continue; 5726 } 5727 if (!pir.key.packageName.equals(name)) { 5728 // Different package, skip it. 5729 continue; 5730 } 5731 } 5732 if (!doit) { 5733 return true; 5734 } 5735 didSomething = true; 5736 it.remove(); 5737 pir.canceled = true; 5738 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5739 pir.key.activity.pendingResults.remove(pir.ref); 5740 } 5741 } 5742 } 5743 } 5744 5745 if (doit) { 5746 if (purgeCache && name != null) { 5747 AttributeCache ac = AttributeCache.instance(); 5748 if (ac != null) { 5749 ac.removePackage(name); 5750 } 5751 } 5752 if (mBooted) { 5753 mStackSupervisor.resumeTopActivitiesLocked(); 5754 mStackSupervisor.scheduleIdleLocked(); 5755 } 5756 } 5757 5758 return didSomething; 5759 } 5760 5761 private final boolean removeProcessLocked(ProcessRecord app, 5762 boolean callerWillRestart, boolean allowRestart, String reason) { 5763 final String name = app.processName; 5764 final int uid = app.uid; 5765 if (DEBUG_PROCESSES) Slog.d( 5766 TAG, "Force removing proc " + app.toShortString() + " (" + name 5767 + "/" + uid + ")"); 5768 5769 mProcessNames.remove(name, uid); 5770 mIsolatedProcesses.remove(app.uid); 5771 if (mHeavyWeightProcess == app) { 5772 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5773 mHeavyWeightProcess.userId, 0)); 5774 mHeavyWeightProcess = null; 5775 } 5776 boolean needRestart = false; 5777 if (app.pid > 0 && app.pid != MY_PID) { 5778 int pid = app.pid; 5779 synchronized (mPidsSelfLocked) { 5780 mPidsSelfLocked.remove(pid); 5781 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5782 } 5783 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5784 if (app.isolated) { 5785 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5786 } 5787 app.kill(reason, true); 5788 handleAppDiedLocked(app, true, allowRestart); 5789 removeLruProcessLocked(app); 5790 5791 if (app.persistent && !app.isolated) { 5792 if (!callerWillRestart) { 5793 addAppLocked(app.info, false, null /* ABI override */); 5794 } else { 5795 needRestart = true; 5796 } 5797 } 5798 } else { 5799 mRemovedProcesses.add(app); 5800 } 5801 5802 return needRestart; 5803 } 5804 5805 private final void processStartTimedOutLocked(ProcessRecord app) { 5806 final int pid = app.pid; 5807 boolean gone = false; 5808 synchronized (mPidsSelfLocked) { 5809 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5810 if (knownApp != null && knownApp.thread == null) { 5811 mPidsSelfLocked.remove(pid); 5812 gone = true; 5813 } 5814 } 5815 5816 if (gone) { 5817 Slog.w(TAG, "Process " + app + " failed to attach"); 5818 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5819 pid, app.uid, app.processName); 5820 mProcessNames.remove(app.processName, app.uid); 5821 mIsolatedProcesses.remove(app.uid); 5822 if (mHeavyWeightProcess == app) { 5823 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5824 mHeavyWeightProcess.userId, 0)); 5825 mHeavyWeightProcess = null; 5826 } 5827 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5828 if (app.isolated) { 5829 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5830 } 5831 // Take care of any launching providers waiting for this process. 5832 checkAppInLaunchingProvidersLocked(app, true); 5833 // Take care of any services that are waiting for the process. 5834 mServices.processStartTimedOutLocked(app); 5835 app.kill("start timeout", true); 5836 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5837 Slog.w(TAG, "Unattached app died before backup, skipping"); 5838 try { 5839 IBackupManager bm = IBackupManager.Stub.asInterface( 5840 ServiceManager.getService(Context.BACKUP_SERVICE)); 5841 bm.agentDisconnected(app.info.packageName); 5842 } catch (RemoteException e) { 5843 // Can't happen; the backup manager is local 5844 } 5845 } 5846 if (isPendingBroadcastProcessLocked(pid)) { 5847 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5848 skipPendingBroadcastLocked(pid); 5849 } 5850 } else { 5851 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5852 } 5853 } 5854 5855 private final boolean attachApplicationLocked(IApplicationThread thread, 5856 int pid) { 5857 5858 // Find the application record that is being attached... either via 5859 // the pid if we are running in multiple processes, or just pull the 5860 // next app record if we are emulating process with anonymous threads. 5861 ProcessRecord app; 5862 if (pid != MY_PID && pid >= 0) { 5863 synchronized (mPidsSelfLocked) { 5864 app = mPidsSelfLocked.get(pid); 5865 } 5866 } else { 5867 app = null; 5868 } 5869 5870 if (app == null) { 5871 Slog.w(TAG, "No pending application record for pid " + pid 5872 + " (IApplicationThread " + thread + "); dropping process"); 5873 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5874 if (pid > 0 && pid != MY_PID) { 5875 Process.killProcessQuiet(pid); 5876 //TODO: Process.killProcessGroup(app.info.uid, pid); 5877 } else { 5878 try { 5879 thread.scheduleExit(); 5880 } catch (Exception e) { 5881 // Ignore exceptions. 5882 } 5883 } 5884 return false; 5885 } 5886 5887 // If this application record is still attached to a previous 5888 // process, clean it up now. 5889 if (app.thread != null) { 5890 handleAppDiedLocked(app, true, true); 5891 } 5892 5893 // Tell the process all about itself. 5894 5895 if (localLOGV) Slog.v( 5896 TAG, "Binding process pid " + pid + " to record " + app); 5897 5898 final String processName = app.processName; 5899 try { 5900 AppDeathRecipient adr = new AppDeathRecipient( 5901 app, pid, thread); 5902 thread.asBinder().linkToDeath(adr, 0); 5903 app.deathRecipient = adr; 5904 } catch (RemoteException e) { 5905 app.resetPackageList(mProcessStats); 5906 startProcessLocked(app, "link fail", processName); 5907 return false; 5908 } 5909 5910 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5911 5912 app.makeActive(thread, mProcessStats); 5913 app.curAdj = app.setAdj = -100; 5914 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5915 app.forcingToForeground = null; 5916 updateProcessForegroundLocked(app, false, false); 5917 app.hasShownUi = false; 5918 app.debugging = false; 5919 app.cached = false; 5920 app.killedByAm = false; 5921 5922 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5923 5924 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5925 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5926 5927 if (!normalMode) { 5928 Slog.i(TAG, "Launching preboot mode app: " + app); 5929 } 5930 5931 if (localLOGV) Slog.v( 5932 TAG, "New app record " + app 5933 + " thread=" + thread.asBinder() + " pid=" + pid); 5934 try { 5935 int testMode = IApplicationThread.DEBUG_OFF; 5936 if (mDebugApp != null && mDebugApp.equals(processName)) { 5937 testMode = mWaitForDebugger 5938 ? IApplicationThread.DEBUG_WAIT 5939 : IApplicationThread.DEBUG_ON; 5940 app.debugging = true; 5941 if (mDebugTransient) { 5942 mDebugApp = mOrigDebugApp; 5943 mWaitForDebugger = mOrigWaitForDebugger; 5944 } 5945 } 5946 String profileFile = app.instrumentationProfileFile; 5947 ParcelFileDescriptor profileFd = null; 5948 int samplingInterval = 0; 5949 boolean profileAutoStop = false; 5950 if (mProfileApp != null && mProfileApp.equals(processName)) { 5951 mProfileProc = app; 5952 profileFile = mProfileFile; 5953 profileFd = mProfileFd; 5954 samplingInterval = mSamplingInterval; 5955 profileAutoStop = mAutoStopProfiler; 5956 } 5957 boolean enableOpenGlTrace = false; 5958 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5959 enableOpenGlTrace = true; 5960 mOpenGlTraceApp = null; 5961 } 5962 5963 // If the app is being launched for restore or full backup, set it up specially 5964 boolean isRestrictedBackupMode = false; 5965 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5966 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5967 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5968 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5969 } 5970 5971 ensurePackageDexOpt(app.instrumentationInfo != null 5972 ? app.instrumentationInfo.packageName 5973 : app.info.packageName); 5974 if (app.instrumentationClass != null) { 5975 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5976 } 5977 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5978 + processName + " with config " + mConfiguration); 5979 ApplicationInfo appInfo = app.instrumentationInfo != null 5980 ? app.instrumentationInfo : app.info; 5981 app.compat = compatibilityInfoForPackageLocked(appInfo); 5982 if (profileFd != null) { 5983 profileFd = profileFd.dup(); 5984 } 5985 ProfilerInfo profilerInfo = profileFile == null ? null 5986 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5987 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5988 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5989 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5990 isRestrictedBackupMode || !normalMode, app.persistent, 5991 new Configuration(mConfiguration), app.compat, 5992 getCommonServicesLocked(app.isolated), 5993 mCoreSettingsObserver.getCoreSettingsLocked()); 5994 updateLruProcessLocked(app, false, null); 5995 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5996 } catch (Exception e) { 5997 // todo: Yikes! What should we do? For now we will try to 5998 // start another process, but that could easily get us in 5999 // an infinite loop of restarting processes... 6000 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6001 6002 app.resetPackageList(mProcessStats); 6003 app.unlinkDeathRecipient(); 6004 startProcessLocked(app, "bind fail", processName); 6005 return false; 6006 } 6007 6008 // Remove this record from the list of starting applications. 6009 mPersistentStartingProcesses.remove(app); 6010 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6011 "Attach application locked removing on hold: " + app); 6012 mProcessesOnHold.remove(app); 6013 6014 boolean badApp = false; 6015 boolean didSomething = false; 6016 6017 // See if the top visible activity is waiting to run in this process... 6018 if (normalMode) { 6019 try { 6020 if (mStackSupervisor.attachApplicationLocked(app)) { 6021 didSomething = true; 6022 } 6023 } catch (Exception e) { 6024 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6025 badApp = true; 6026 } 6027 } 6028 6029 // Find any services that should be running in this process... 6030 if (!badApp) { 6031 try { 6032 didSomething |= mServices.attachApplicationLocked(app, processName); 6033 } catch (Exception e) { 6034 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6035 badApp = true; 6036 } 6037 } 6038 6039 // Check if a next-broadcast receiver is in this process... 6040 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6041 try { 6042 didSomething |= sendPendingBroadcastsLocked(app); 6043 } catch (Exception e) { 6044 // If the app died trying to launch the receiver we declare it 'bad' 6045 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6046 badApp = true; 6047 } 6048 } 6049 6050 // Check whether the next backup agent is in this process... 6051 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6052 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6053 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6054 try { 6055 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6056 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6057 mBackupTarget.backupMode); 6058 } catch (Exception e) { 6059 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6060 badApp = true; 6061 } 6062 } 6063 6064 if (badApp) { 6065 app.kill("error during init", true); 6066 handleAppDiedLocked(app, false, true); 6067 return false; 6068 } 6069 6070 if (!didSomething) { 6071 updateOomAdjLocked(); 6072 } 6073 6074 return true; 6075 } 6076 6077 @Override 6078 public final void attachApplication(IApplicationThread thread) { 6079 synchronized (this) { 6080 int callingPid = Binder.getCallingPid(); 6081 final long origId = Binder.clearCallingIdentity(); 6082 attachApplicationLocked(thread, callingPid); 6083 Binder.restoreCallingIdentity(origId); 6084 } 6085 } 6086 6087 @Override 6088 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6089 final long origId = Binder.clearCallingIdentity(); 6090 synchronized (this) { 6091 ActivityStack stack = ActivityRecord.getStackLocked(token); 6092 if (stack != null) { 6093 ActivityRecord r = 6094 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6095 if (stopProfiling) { 6096 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6097 try { 6098 mProfileFd.close(); 6099 } catch (IOException e) { 6100 } 6101 clearProfilerLocked(); 6102 } 6103 } 6104 } 6105 } 6106 Binder.restoreCallingIdentity(origId); 6107 } 6108 6109 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6110 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6111 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6112 } 6113 6114 void enableScreenAfterBoot() { 6115 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6116 SystemClock.uptimeMillis()); 6117 mWindowManager.enableScreenAfterBoot(); 6118 6119 synchronized (this) { 6120 updateEventDispatchingLocked(); 6121 } 6122 } 6123 6124 @Override 6125 public void showBootMessage(final CharSequence msg, final boolean always) { 6126 enforceNotIsolatedCaller("showBootMessage"); 6127 mWindowManager.showBootMessage(msg, always); 6128 } 6129 6130 @Override 6131 public void keyguardWaitingForActivityDrawn() { 6132 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6133 final long token = Binder.clearCallingIdentity(); 6134 try { 6135 synchronized (this) { 6136 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6137 mWindowManager.keyguardWaitingForActivityDrawn(); 6138 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6139 mLockScreenShown = LOCK_SCREEN_LEAVING; 6140 updateSleepIfNeededLocked(); 6141 } 6142 } 6143 } finally { 6144 Binder.restoreCallingIdentity(token); 6145 } 6146 } 6147 6148 final void finishBooting() { 6149 synchronized (this) { 6150 if (!mBootAnimationComplete) { 6151 mCallFinishBooting = true; 6152 return; 6153 } 6154 mCallFinishBooting = false; 6155 } 6156 6157 ArraySet<String> completedIsas = new ArraySet<String>(); 6158 for (String abi : Build.SUPPORTED_ABIS) { 6159 Process.establishZygoteConnectionForAbi(abi); 6160 final String instructionSet = VMRuntime.getInstructionSet(abi); 6161 if (!completedIsas.contains(instructionSet)) { 6162 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6163 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6164 } 6165 completedIsas.add(instructionSet); 6166 } 6167 } 6168 6169 IntentFilter pkgFilter = new IntentFilter(); 6170 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6171 pkgFilter.addDataScheme("package"); 6172 mContext.registerReceiver(new BroadcastReceiver() { 6173 @Override 6174 public void onReceive(Context context, Intent intent) { 6175 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6176 if (pkgs != null) { 6177 for (String pkg : pkgs) { 6178 synchronized (ActivityManagerService.this) { 6179 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6180 0, "finished booting")) { 6181 setResultCode(Activity.RESULT_OK); 6182 return; 6183 } 6184 } 6185 } 6186 } 6187 } 6188 }, pkgFilter); 6189 6190 // Let system services know. 6191 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6192 6193 synchronized (this) { 6194 // Ensure that any processes we had put on hold are now started 6195 // up. 6196 final int NP = mProcessesOnHold.size(); 6197 if (NP > 0) { 6198 ArrayList<ProcessRecord> procs = 6199 new ArrayList<ProcessRecord>(mProcessesOnHold); 6200 for (int ip=0; ip<NP; ip++) { 6201 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6202 + procs.get(ip)); 6203 startProcessLocked(procs.get(ip), "on-hold", null); 6204 } 6205 } 6206 6207 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6208 // Start looking for apps that are abusing wake locks. 6209 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6210 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6211 // Tell anyone interested that we are done booting! 6212 SystemProperties.set("sys.boot_completed", "1"); 6213 6214 // And trigger dev.bootcomplete if we are not showing encryption progress 6215 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6216 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6217 SystemProperties.set("dev.bootcomplete", "1"); 6218 } 6219 for (int i=0; i<mStartedUsers.size(); i++) { 6220 UserStartedState uss = mStartedUsers.valueAt(i); 6221 if (uss.mState == UserStartedState.STATE_BOOTING) { 6222 uss.mState = UserStartedState.STATE_RUNNING; 6223 final int userId = mStartedUsers.keyAt(i); 6224 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6225 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6226 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6227 broadcastIntentLocked(null, null, intent, null, 6228 new IIntentReceiver.Stub() { 6229 @Override 6230 public void performReceive(Intent intent, int resultCode, 6231 String data, Bundle extras, boolean ordered, 6232 boolean sticky, int sendingUser) { 6233 synchronized (ActivityManagerService.this) { 6234 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6235 true, false); 6236 } 6237 } 6238 }, 6239 0, null, null, 6240 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6241 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6242 userId); 6243 } 6244 } 6245 scheduleStartProfilesLocked(); 6246 } 6247 } 6248 } 6249 6250 @Override 6251 public void bootAnimationComplete() { 6252 final boolean callFinishBooting; 6253 synchronized (this) { 6254 callFinishBooting = mCallFinishBooting; 6255 mBootAnimationComplete = true; 6256 } 6257 if (callFinishBooting) { 6258 finishBooting(); 6259 } 6260 } 6261 6262 @Override 6263 public void systemBackupRestored() { 6264 synchronized (this) { 6265 if (mSystemReady) { 6266 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6267 } else { 6268 Slog.w(TAG, "System backup restored before system is ready"); 6269 } 6270 } 6271 } 6272 6273 final void ensureBootCompleted() { 6274 boolean booting; 6275 boolean enableScreen; 6276 synchronized (this) { 6277 booting = mBooting; 6278 mBooting = false; 6279 enableScreen = !mBooted; 6280 mBooted = true; 6281 } 6282 6283 if (booting) { 6284 finishBooting(); 6285 } 6286 6287 if (enableScreen) { 6288 enableScreenAfterBoot(); 6289 } 6290 } 6291 6292 @Override 6293 public final void activityResumed(IBinder token) { 6294 final long origId = Binder.clearCallingIdentity(); 6295 synchronized(this) { 6296 ActivityStack stack = ActivityRecord.getStackLocked(token); 6297 if (stack != null) { 6298 ActivityRecord.activityResumedLocked(token); 6299 } 6300 } 6301 Binder.restoreCallingIdentity(origId); 6302 } 6303 6304 @Override 6305 public final void activityPaused(IBinder token) { 6306 final long origId = Binder.clearCallingIdentity(); 6307 synchronized(this) { 6308 ActivityStack stack = ActivityRecord.getStackLocked(token); 6309 if (stack != null) { 6310 stack.activityPausedLocked(token, false); 6311 } 6312 } 6313 Binder.restoreCallingIdentity(origId); 6314 } 6315 6316 @Override 6317 public final void activityStopped(IBinder token, Bundle icicle, 6318 PersistableBundle persistentState, CharSequence description) { 6319 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6320 6321 // Refuse possible leaked file descriptors 6322 if (icicle != null && icicle.hasFileDescriptors()) { 6323 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6324 } 6325 6326 final long origId = Binder.clearCallingIdentity(); 6327 6328 synchronized (this) { 6329 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6330 if (r != null) { 6331 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6332 } 6333 } 6334 6335 trimApplications(); 6336 6337 Binder.restoreCallingIdentity(origId); 6338 } 6339 6340 @Override 6341 public final void activityDestroyed(IBinder token) { 6342 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6343 synchronized (this) { 6344 ActivityStack stack = ActivityRecord.getStackLocked(token); 6345 if (stack != null) { 6346 stack.activityDestroyedLocked(token); 6347 } 6348 } 6349 } 6350 6351 @Override 6352 public final void backgroundResourcesReleased(IBinder token) { 6353 final long origId = Binder.clearCallingIdentity(); 6354 try { 6355 synchronized (this) { 6356 ActivityStack stack = ActivityRecord.getStackLocked(token); 6357 if (stack != null) { 6358 stack.backgroundResourcesReleased(); 6359 } 6360 } 6361 } finally { 6362 Binder.restoreCallingIdentity(origId); 6363 } 6364 } 6365 6366 @Override 6367 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6368 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6369 } 6370 6371 @Override 6372 public final void notifyEnterAnimationComplete(IBinder token) { 6373 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6374 } 6375 6376 @Override 6377 public String getCallingPackage(IBinder token) { 6378 synchronized (this) { 6379 ActivityRecord r = getCallingRecordLocked(token); 6380 return r != null ? r.info.packageName : null; 6381 } 6382 } 6383 6384 @Override 6385 public ComponentName getCallingActivity(IBinder token) { 6386 synchronized (this) { 6387 ActivityRecord r = getCallingRecordLocked(token); 6388 return r != null ? r.intent.getComponent() : null; 6389 } 6390 } 6391 6392 private ActivityRecord getCallingRecordLocked(IBinder token) { 6393 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6394 if (r == null) { 6395 return null; 6396 } 6397 return r.resultTo; 6398 } 6399 6400 @Override 6401 public ComponentName getActivityClassForToken(IBinder token) { 6402 synchronized(this) { 6403 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6404 if (r == null) { 6405 return null; 6406 } 6407 return r.intent.getComponent(); 6408 } 6409 } 6410 6411 @Override 6412 public String getPackageForToken(IBinder token) { 6413 synchronized(this) { 6414 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6415 if (r == null) { 6416 return null; 6417 } 6418 return r.packageName; 6419 } 6420 } 6421 6422 @Override 6423 public IIntentSender getIntentSender(int type, 6424 String packageName, IBinder token, String resultWho, 6425 int requestCode, Intent[] intents, String[] resolvedTypes, 6426 int flags, Bundle options, int userId) { 6427 enforceNotIsolatedCaller("getIntentSender"); 6428 // Refuse possible leaked file descriptors 6429 if (intents != null) { 6430 if (intents.length < 1) { 6431 throw new IllegalArgumentException("Intents array length must be >= 1"); 6432 } 6433 for (int i=0; i<intents.length; i++) { 6434 Intent intent = intents[i]; 6435 if (intent != null) { 6436 if (intent.hasFileDescriptors()) { 6437 throw new IllegalArgumentException("File descriptors passed in Intent"); 6438 } 6439 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6440 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6441 throw new IllegalArgumentException( 6442 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6443 } 6444 intents[i] = new Intent(intent); 6445 } 6446 } 6447 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6448 throw new IllegalArgumentException( 6449 "Intent array length does not match resolvedTypes length"); 6450 } 6451 } 6452 if (options != null) { 6453 if (options.hasFileDescriptors()) { 6454 throw new IllegalArgumentException("File descriptors passed in options"); 6455 } 6456 } 6457 6458 synchronized(this) { 6459 int callingUid = Binder.getCallingUid(); 6460 int origUserId = userId; 6461 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6462 type == ActivityManager.INTENT_SENDER_BROADCAST, 6463 ALLOW_NON_FULL, "getIntentSender", null); 6464 if (origUserId == UserHandle.USER_CURRENT) { 6465 // We don't want to evaluate this until the pending intent is 6466 // actually executed. However, we do want to always do the 6467 // security checking for it above. 6468 userId = UserHandle.USER_CURRENT; 6469 } 6470 try { 6471 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6472 int uid = AppGlobals.getPackageManager() 6473 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6474 if (!UserHandle.isSameApp(callingUid, uid)) { 6475 String msg = "Permission Denial: getIntentSender() from pid=" 6476 + Binder.getCallingPid() 6477 + ", uid=" + Binder.getCallingUid() 6478 + ", (need uid=" + uid + ")" 6479 + " is not allowed to send as package " + packageName; 6480 Slog.w(TAG, msg); 6481 throw new SecurityException(msg); 6482 } 6483 } 6484 6485 return getIntentSenderLocked(type, packageName, callingUid, userId, 6486 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6487 6488 } catch (RemoteException e) { 6489 throw new SecurityException(e); 6490 } 6491 } 6492 } 6493 6494 IIntentSender getIntentSenderLocked(int type, String packageName, 6495 int callingUid, int userId, IBinder token, String resultWho, 6496 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6497 Bundle options) { 6498 if (DEBUG_MU) 6499 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6500 ActivityRecord activity = null; 6501 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6502 activity = ActivityRecord.isInStackLocked(token); 6503 if (activity == null) { 6504 return null; 6505 } 6506 if (activity.finishing) { 6507 return null; 6508 } 6509 } 6510 6511 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6512 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6513 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6514 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6515 |PendingIntent.FLAG_UPDATE_CURRENT); 6516 6517 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6518 type, packageName, activity, resultWho, 6519 requestCode, intents, resolvedTypes, flags, options, userId); 6520 WeakReference<PendingIntentRecord> ref; 6521 ref = mIntentSenderRecords.get(key); 6522 PendingIntentRecord rec = ref != null ? ref.get() : null; 6523 if (rec != null) { 6524 if (!cancelCurrent) { 6525 if (updateCurrent) { 6526 if (rec.key.requestIntent != null) { 6527 rec.key.requestIntent.replaceExtras(intents != null ? 6528 intents[intents.length - 1] : null); 6529 } 6530 if (intents != null) { 6531 intents[intents.length-1] = rec.key.requestIntent; 6532 rec.key.allIntents = intents; 6533 rec.key.allResolvedTypes = resolvedTypes; 6534 } else { 6535 rec.key.allIntents = null; 6536 rec.key.allResolvedTypes = null; 6537 } 6538 } 6539 return rec; 6540 } 6541 rec.canceled = true; 6542 mIntentSenderRecords.remove(key); 6543 } 6544 if (noCreate) { 6545 return rec; 6546 } 6547 rec = new PendingIntentRecord(this, key, callingUid); 6548 mIntentSenderRecords.put(key, rec.ref); 6549 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6550 if (activity.pendingResults == null) { 6551 activity.pendingResults 6552 = new HashSet<WeakReference<PendingIntentRecord>>(); 6553 } 6554 activity.pendingResults.add(rec.ref); 6555 } 6556 return rec; 6557 } 6558 6559 @Override 6560 public void cancelIntentSender(IIntentSender sender) { 6561 if (!(sender instanceof PendingIntentRecord)) { 6562 return; 6563 } 6564 synchronized(this) { 6565 PendingIntentRecord rec = (PendingIntentRecord)sender; 6566 try { 6567 int uid = AppGlobals.getPackageManager() 6568 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6569 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6570 String msg = "Permission Denial: cancelIntentSender() from pid=" 6571 + Binder.getCallingPid() 6572 + ", uid=" + Binder.getCallingUid() 6573 + " is not allowed to cancel packges " 6574 + rec.key.packageName; 6575 Slog.w(TAG, msg); 6576 throw new SecurityException(msg); 6577 } 6578 } catch (RemoteException e) { 6579 throw new SecurityException(e); 6580 } 6581 cancelIntentSenderLocked(rec, true); 6582 } 6583 } 6584 6585 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6586 rec.canceled = true; 6587 mIntentSenderRecords.remove(rec.key); 6588 if (cleanActivity && rec.key.activity != null) { 6589 rec.key.activity.pendingResults.remove(rec.ref); 6590 } 6591 } 6592 6593 @Override 6594 public String getPackageForIntentSender(IIntentSender pendingResult) { 6595 if (!(pendingResult instanceof PendingIntentRecord)) { 6596 return null; 6597 } 6598 try { 6599 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6600 return res.key.packageName; 6601 } catch (ClassCastException e) { 6602 } 6603 return null; 6604 } 6605 6606 @Override 6607 public int getUidForIntentSender(IIntentSender sender) { 6608 if (sender instanceof PendingIntentRecord) { 6609 try { 6610 PendingIntentRecord res = (PendingIntentRecord)sender; 6611 return res.uid; 6612 } catch (ClassCastException e) { 6613 } 6614 } 6615 return -1; 6616 } 6617 6618 @Override 6619 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6620 if (!(pendingResult instanceof PendingIntentRecord)) { 6621 return false; 6622 } 6623 try { 6624 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6625 if (res.key.allIntents == null) { 6626 return false; 6627 } 6628 for (int i=0; i<res.key.allIntents.length; i++) { 6629 Intent intent = res.key.allIntents[i]; 6630 if (intent.getPackage() != null && intent.getComponent() != null) { 6631 return false; 6632 } 6633 } 6634 return true; 6635 } catch (ClassCastException e) { 6636 } 6637 return false; 6638 } 6639 6640 @Override 6641 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6642 if (!(pendingResult instanceof PendingIntentRecord)) { 6643 return false; 6644 } 6645 try { 6646 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6647 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6648 return true; 6649 } 6650 return false; 6651 } catch (ClassCastException e) { 6652 } 6653 return false; 6654 } 6655 6656 @Override 6657 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6658 if (!(pendingResult instanceof PendingIntentRecord)) { 6659 return null; 6660 } 6661 try { 6662 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6663 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6664 } catch (ClassCastException e) { 6665 } 6666 return null; 6667 } 6668 6669 @Override 6670 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6671 if (!(pendingResult instanceof PendingIntentRecord)) { 6672 return null; 6673 } 6674 try { 6675 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6676 Intent intent = res.key.requestIntent; 6677 if (intent != null) { 6678 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6679 || res.lastTagPrefix.equals(prefix))) { 6680 return res.lastTag; 6681 } 6682 res.lastTagPrefix = prefix; 6683 StringBuilder sb = new StringBuilder(128); 6684 if (prefix != null) { 6685 sb.append(prefix); 6686 } 6687 if (intent.getAction() != null) { 6688 sb.append(intent.getAction()); 6689 } else if (intent.getComponent() != null) { 6690 intent.getComponent().appendShortString(sb); 6691 } else { 6692 sb.append("?"); 6693 } 6694 return res.lastTag = sb.toString(); 6695 } 6696 } catch (ClassCastException e) { 6697 } 6698 return null; 6699 } 6700 6701 @Override 6702 public void setProcessLimit(int max) { 6703 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6704 "setProcessLimit()"); 6705 synchronized (this) { 6706 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6707 mProcessLimitOverride = max; 6708 } 6709 trimApplications(); 6710 } 6711 6712 @Override 6713 public int getProcessLimit() { 6714 synchronized (this) { 6715 return mProcessLimitOverride; 6716 } 6717 } 6718 6719 void foregroundTokenDied(ForegroundToken token) { 6720 synchronized (ActivityManagerService.this) { 6721 synchronized (mPidsSelfLocked) { 6722 ForegroundToken cur 6723 = mForegroundProcesses.get(token.pid); 6724 if (cur != token) { 6725 return; 6726 } 6727 mForegroundProcesses.remove(token.pid); 6728 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6729 if (pr == null) { 6730 return; 6731 } 6732 pr.forcingToForeground = null; 6733 updateProcessForegroundLocked(pr, false, false); 6734 } 6735 updateOomAdjLocked(); 6736 } 6737 } 6738 6739 @Override 6740 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6741 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6742 "setProcessForeground()"); 6743 synchronized(this) { 6744 boolean changed = false; 6745 6746 synchronized (mPidsSelfLocked) { 6747 ProcessRecord pr = mPidsSelfLocked.get(pid); 6748 if (pr == null && isForeground) { 6749 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6750 return; 6751 } 6752 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6753 if (oldToken != null) { 6754 oldToken.token.unlinkToDeath(oldToken, 0); 6755 mForegroundProcesses.remove(pid); 6756 if (pr != null) { 6757 pr.forcingToForeground = null; 6758 } 6759 changed = true; 6760 } 6761 if (isForeground && token != null) { 6762 ForegroundToken newToken = new ForegroundToken() { 6763 @Override 6764 public void binderDied() { 6765 foregroundTokenDied(this); 6766 } 6767 }; 6768 newToken.pid = pid; 6769 newToken.token = token; 6770 try { 6771 token.linkToDeath(newToken, 0); 6772 mForegroundProcesses.put(pid, newToken); 6773 pr.forcingToForeground = token; 6774 changed = true; 6775 } catch (RemoteException e) { 6776 // If the process died while doing this, we will later 6777 // do the cleanup with the process death link. 6778 } 6779 } 6780 } 6781 6782 if (changed) { 6783 updateOomAdjLocked(); 6784 } 6785 } 6786 } 6787 6788 // ========================================================= 6789 // PERMISSIONS 6790 // ========================================================= 6791 6792 static class PermissionController extends IPermissionController.Stub { 6793 ActivityManagerService mActivityManagerService; 6794 PermissionController(ActivityManagerService activityManagerService) { 6795 mActivityManagerService = activityManagerService; 6796 } 6797 6798 @Override 6799 public boolean checkPermission(String permission, int pid, int uid) { 6800 return mActivityManagerService.checkPermission(permission, pid, 6801 uid) == PackageManager.PERMISSION_GRANTED; 6802 } 6803 } 6804 6805 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6806 @Override 6807 public int checkComponentPermission(String permission, int pid, int uid, 6808 int owningUid, boolean exported) { 6809 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6810 owningUid, exported); 6811 } 6812 6813 @Override 6814 public Object getAMSLock() { 6815 return ActivityManagerService.this; 6816 } 6817 } 6818 6819 /** 6820 * This can be called with or without the global lock held. 6821 */ 6822 int checkComponentPermission(String permission, int pid, int uid, 6823 int owningUid, boolean exported) { 6824 if (pid == MY_PID) { 6825 return PackageManager.PERMISSION_GRANTED; 6826 } 6827 return ActivityManager.checkComponentPermission(permission, uid, 6828 owningUid, exported); 6829 } 6830 6831 /** 6832 * As the only public entry point for permissions checking, this method 6833 * can enforce the semantic that requesting a check on a null global 6834 * permission is automatically denied. (Internally a null permission 6835 * string is used when calling {@link #checkComponentPermission} in cases 6836 * when only uid-based security is needed.) 6837 * 6838 * This can be called with or without the global lock held. 6839 */ 6840 @Override 6841 public int checkPermission(String permission, int pid, int uid) { 6842 if (permission == null) { 6843 return PackageManager.PERMISSION_DENIED; 6844 } 6845 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6846 } 6847 6848 @Override 6849 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6850 if (permission == null) { 6851 return PackageManager.PERMISSION_DENIED; 6852 } 6853 6854 // We might be performing an operation on behalf of an indirect binder 6855 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6856 // client identity accordingly before proceeding. 6857 Identity tlsIdentity = sCallerIdentity.get(); 6858 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6859 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6860 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6861 uid = tlsIdentity.uid; 6862 pid = tlsIdentity.pid; 6863 } 6864 6865 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6866 } 6867 6868 /** 6869 * Binder IPC calls go through the public entry point. 6870 * This can be called with or without the global lock held. 6871 */ 6872 int checkCallingPermission(String permission) { 6873 return checkPermission(permission, 6874 Binder.getCallingPid(), 6875 UserHandle.getAppId(Binder.getCallingUid())); 6876 } 6877 6878 /** 6879 * This can be called with or without the global lock held. 6880 */ 6881 void enforceCallingPermission(String permission, String func) { 6882 if (checkCallingPermission(permission) 6883 == PackageManager.PERMISSION_GRANTED) { 6884 return; 6885 } 6886 6887 String msg = "Permission Denial: " + func + " from pid=" 6888 + Binder.getCallingPid() 6889 + ", uid=" + Binder.getCallingUid() 6890 + " requires " + permission; 6891 Slog.w(TAG, msg); 6892 throw new SecurityException(msg); 6893 } 6894 6895 /** 6896 * Determine if UID is holding permissions required to access {@link Uri} in 6897 * the given {@link ProviderInfo}. Final permission checking is always done 6898 * in {@link ContentProvider}. 6899 */ 6900 private final boolean checkHoldingPermissionsLocked( 6901 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6902 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6903 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6904 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6905 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6906 != PERMISSION_GRANTED) { 6907 return false; 6908 } 6909 } 6910 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6911 } 6912 6913 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6914 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6915 if (pi.applicationInfo.uid == uid) { 6916 return true; 6917 } else if (!pi.exported) { 6918 return false; 6919 } 6920 6921 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6922 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6923 try { 6924 // check if target holds top-level <provider> permissions 6925 if (!readMet && pi.readPermission != null && considerUidPermissions 6926 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6927 readMet = true; 6928 } 6929 if (!writeMet && pi.writePermission != null && considerUidPermissions 6930 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6931 writeMet = true; 6932 } 6933 6934 // track if unprotected read/write is allowed; any denied 6935 // <path-permission> below removes this ability 6936 boolean allowDefaultRead = pi.readPermission == null; 6937 boolean allowDefaultWrite = pi.writePermission == null; 6938 6939 // check if target holds any <path-permission> that match uri 6940 final PathPermission[] pps = pi.pathPermissions; 6941 if (pps != null) { 6942 final String path = grantUri.uri.getPath(); 6943 int i = pps.length; 6944 while (i > 0 && (!readMet || !writeMet)) { 6945 i--; 6946 PathPermission pp = pps[i]; 6947 if (pp.match(path)) { 6948 if (!readMet) { 6949 final String pprperm = pp.getReadPermission(); 6950 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6951 + pprperm + " for " + pp.getPath() 6952 + ": match=" + pp.match(path) 6953 + " check=" + pm.checkUidPermission(pprperm, uid)); 6954 if (pprperm != null) { 6955 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6956 == PERMISSION_GRANTED) { 6957 readMet = true; 6958 } else { 6959 allowDefaultRead = false; 6960 } 6961 } 6962 } 6963 if (!writeMet) { 6964 final String ppwperm = pp.getWritePermission(); 6965 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6966 + ppwperm + " for " + pp.getPath() 6967 + ": match=" + pp.match(path) 6968 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6969 if (ppwperm != null) { 6970 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6971 == PERMISSION_GRANTED) { 6972 writeMet = true; 6973 } else { 6974 allowDefaultWrite = false; 6975 } 6976 } 6977 } 6978 } 6979 } 6980 } 6981 6982 // grant unprotected <provider> read/write, if not blocked by 6983 // <path-permission> above 6984 if (allowDefaultRead) readMet = true; 6985 if (allowDefaultWrite) writeMet = true; 6986 6987 } catch (RemoteException e) { 6988 return false; 6989 } 6990 6991 return readMet && writeMet; 6992 } 6993 6994 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6995 ProviderInfo pi = null; 6996 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6997 if (cpr != null) { 6998 pi = cpr.info; 6999 } else { 7000 try { 7001 pi = AppGlobals.getPackageManager().resolveContentProvider( 7002 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7003 } catch (RemoteException ex) { 7004 } 7005 } 7006 return pi; 7007 } 7008 7009 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7010 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7011 if (targetUris != null) { 7012 return targetUris.get(grantUri); 7013 } 7014 return null; 7015 } 7016 7017 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7018 String targetPkg, int targetUid, GrantUri grantUri) { 7019 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7020 if (targetUris == null) { 7021 targetUris = Maps.newArrayMap(); 7022 mGrantedUriPermissions.put(targetUid, targetUris); 7023 } 7024 7025 UriPermission perm = targetUris.get(grantUri); 7026 if (perm == null) { 7027 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7028 targetUris.put(grantUri, perm); 7029 } 7030 7031 return perm; 7032 } 7033 7034 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7035 final int modeFlags) { 7036 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7037 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7038 : UriPermission.STRENGTH_OWNED; 7039 7040 // Root gets to do everything. 7041 if (uid == 0) { 7042 return true; 7043 } 7044 7045 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7046 if (perms == null) return false; 7047 7048 // First look for exact match 7049 final UriPermission exactPerm = perms.get(grantUri); 7050 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7051 return true; 7052 } 7053 7054 // No exact match, look for prefixes 7055 final int N = perms.size(); 7056 for (int i = 0; i < N; i++) { 7057 final UriPermission perm = perms.valueAt(i); 7058 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7059 && perm.getStrength(modeFlags) >= minStrength) { 7060 return true; 7061 } 7062 } 7063 7064 return false; 7065 } 7066 7067 /** 7068 * @param uri This uri must NOT contain an embedded userId. 7069 * @param userId The userId in which the uri is to be resolved. 7070 */ 7071 @Override 7072 public int checkUriPermission(Uri uri, int pid, int uid, 7073 final int modeFlags, int userId, IBinder callerToken) { 7074 enforceNotIsolatedCaller("checkUriPermission"); 7075 7076 // Another redirected-binder-call permissions check as in 7077 // {@link checkPermissionWithToken}. 7078 Identity tlsIdentity = sCallerIdentity.get(); 7079 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7080 uid = tlsIdentity.uid; 7081 pid = tlsIdentity.pid; 7082 } 7083 7084 // Our own process gets to do everything. 7085 if (pid == MY_PID) { 7086 return PackageManager.PERMISSION_GRANTED; 7087 } 7088 synchronized (this) { 7089 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7090 ? PackageManager.PERMISSION_GRANTED 7091 : PackageManager.PERMISSION_DENIED; 7092 } 7093 } 7094 7095 /** 7096 * Check if the targetPkg can be granted permission to access uri by 7097 * the callingUid using the given modeFlags. Throws a security exception 7098 * if callingUid is not allowed to do this. Returns the uid of the target 7099 * if the URI permission grant should be performed; returns -1 if it is not 7100 * needed (for example targetPkg already has permission to access the URI). 7101 * If you already know the uid of the target, you can supply it in 7102 * lastTargetUid else set that to -1. 7103 */ 7104 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7105 final int modeFlags, int lastTargetUid) { 7106 if (!Intent.isAccessUriMode(modeFlags)) { 7107 return -1; 7108 } 7109 7110 if (targetPkg != null) { 7111 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7112 "Checking grant " + targetPkg + " permission to " + grantUri); 7113 } 7114 7115 final IPackageManager pm = AppGlobals.getPackageManager(); 7116 7117 // If this is not a content: uri, we can't do anything with it. 7118 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7119 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7120 "Can't grant URI permission for non-content URI: " + grantUri); 7121 return -1; 7122 } 7123 7124 final String authority = grantUri.uri.getAuthority(); 7125 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7126 if (pi == null) { 7127 Slog.w(TAG, "No content provider found for permission check: " + 7128 grantUri.uri.toSafeString()); 7129 return -1; 7130 } 7131 7132 int targetUid = lastTargetUid; 7133 if (targetUid < 0 && targetPkg != null) { 7134 try { 7135 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7136 if (targetUid < 0) { 7137 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7138 "Can't grant URI permission no uid for: " + targetPkg); 7139 return -1; 7140 } 7141 } catch (RemoteException ex) { 7142 return -1; 7143 } 7144 } 7145 7146 if (targetUid >= 0) { 7147 // First... does the target actually need this permission? 7148 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7149 // No need to grant the target this permission. 7150 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7151 "Target " + targetPkg + " already has full permission to " + grantUri); 7152 return -1; 7153 } 7154 } else { 7155 // First... there is no target package, so can anyone access it? 7156 boolean allowed = pi.exported; 7157 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7158 if (pi.readPermission != null) { 7159 allowed = false; 7160 } 7161 } 7162 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7163 if (pi.writePermission != null) { 7164 allowed = false; 7165 } 7166 } 7167 if (allowed) { 7168 return -1; 7169 } 7170 } 7171 7172 /* There is a special cross user grant if: 7173 * - The target is on another user. 7174 * - Apps on the current user can access the uri without any uid permissions. 7175 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7176 * grant uri permissions. 7177 */ 7178 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7179 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7180 modeFlags, false /*without considering the uid permissions*/); 7181 7182 // Second... is the provider allowing granting of URI permissions? 7183 if (!specialCrossUserGrant) { 7184 if (!pi.grantUriPermissions) { 7185 throw new SecurityException("Provider " + pi.packageName 7186 + "/" + pi.name 7187 + " does not allow granting of Uri permissions (uri " 7188 + grantUri + ")"); 7189 } 7190 if (pi.uriPermissionPatterns != null) { 7191 final int N = pi.uriPermissionPatterns.length; 7192 boolean allowed = false; 7193 for (int i=0; i<N; i++) { 7194 if (pi.uriPermissionPatterns[i] != null 7195 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7196 allowed = true; 7197 break; 7198 } 7199 } 7200 if (!allowed) { 7201 throw new SecurityException("Provider " + pi.packageName 7202 + "/" + pi.name 7203 + " does not allow granting of permission to path of Uri " 7204 + grantUri); 7205 } 7206 } 7207 } 7208 7209 // Third... does the caller itself have permission to access 7210 // this uri? 7211 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7212 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7213 // Require they hold a strong enough Uri permission 7214 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7215 throw new SecurityException("Uid " + callingUid 7216 + " does not have permission to uri " + grantUri); 7217 } 7218 } 7219 } 7220 return targetUid; 7221 } 7222 7223 /** 7224 * @param uri This uri must NOT contain an embedded userId. 7225 * @param userId The userId in which the uri is to be resolved. 7226 */ 7227 @Override 7228 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7229 final int modeFlags, int userId) { 7230 enforceNotIsolatedCaller("checkGrantUriPermission"); 7231 synchronized(this) { 7232 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7233 new GrantUri(userId, uri, false), modeFlags, -1); 7234 } 7235 } 7236 7237 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7238 final int modeFlags, UriPermissionOwner owner) { 7239 if (!Intent.isAccessUriMode(modeFlags)) { 7240 return; 7241 } 7242 7243 // So here we are: the caller has the assumed permission 7244 // to the uri, and the target doesn't. Let's now give this to 7245 // the target. 7246 7247 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7248 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7249 7250 final String authority = grantUri.uri.getAuthority(); 7251 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7252 if (pi == null) { 7253 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7254 return; 7255 } 7256 7257 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7258 grantUri.prefix = true; 7259 } 7260 final UriPermission perm = findOrCreateUriPermissionLocked( 7261 pi.packageName, targetPkg, targetUid, grantUri); 7262 perm.grantModes(modeFlags, owner); 7263 } 7264 7265 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7266 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7267 if (targetPkg == null) { 7268 throw new NullPointerException("targetPkg"); 7269 } 7270 int targetUid; 7271 final IPackageManager pm = AppGlobals.getPackageManager(); 7272 try { 7273 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7274 } catch (RemoteException ex) { 7275 return; 7276 } 7277 7278 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7279 targetUid); 7280 if (targetUid < 0) { 7281 return; 7282 } 7283 7284 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7285 owner); 7286 } 7287 7288 static class NeededUriGrants extends ArrayList<GrantUri> { 7289 final String targetPkg; 7290 final int targetUid; 7291 final int flags; 7292 7293 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7294 this.targetPkg = targetPkg; 7295 this.targetUid = targetUid; 7296 this.flags = flags; 7297 } 7298 } 7299 7300 /** 7301 * Like checkGrantUriPermissionLocked, but takes an Intent. 7302 */ 7303 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7304 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7305 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7306 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7307 + " clip=" + (intent != null ? intent.getClipData() : null) 7308 + " from " + intent + "; flags=0x" 7309 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7310 7311 if (targetPkg == null) { 7312 throw new NullPointerException("targetPkg"); 7313 } 7314 7315 if (intent == null) { 7316 return null; 7317 } 7318 Uri data = intent.getData(); 7319 ClipData clip = intent.getClipData(); 7320 if (data == null && clip == null) { 7321 return null; 7322 } 7323 // Default userId for uris in the intent (if they don't specify it themselves) 7324 int contentUserHint = intent.getContentUserHint(); 7325 if (contentUserHint == UserHandle.USER_CURRENT) { 7326 contentUserHint = UserHandle.getUserId(callingUid); 7327 } 7328 final IPackageManager pm = AppGlobals.getPackageManager(); 7329 int targetUid; 7330 if (needed != null) { 7331 targetUid = needed.targetUid; 7332 } else { 7333 try { 7334 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7335 } catch (RemoteException ex) { 7336 return null; 7337 } 7338 if (targetUid < 0) { 7339 if (DEBUG_URI_PERMISSION) { 7340 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7341 + " on user " + targetUserId); 7342 } 7343 return null; 7344 } 7345 } 7346 if (data != null) { 7347 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7348 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7349 targetUid); 7350 if (targetUid > 0) { 7351 if (needed == null) { 7352 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7353 } 7354 needed.add(grantUri); 7355 } 7356 } 7357 if (clip != null) { 7358 for (int i=0; i<clip.getItemCount(); i++) { 7359 Uri uri = clip.getItemAt(i).getUri(); 7360 if (uri != null) { 7361 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7362 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7363 targetUid); 7364 if (targetUid > 0) { 7365 if (needed == null) { 7366 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7367 } 7368 needed.add(grantUri); 7369 } 7370 } else { 7371 Intent clipIntent = clip.getItemAt(i).getIntent(); 7372 if (clipIntent != null) { 7373 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7374 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7375 if (newNeeded != null) { 7376 needed = newNeeded; 7377 } 7378 } 7379 } 7380 } 7381 } 7382 7383 return needed; 7384 } 7385 7386 /** 7387 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7388 */ 7389 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7390 UriPermissionOwner owner) { 7391 if (needed != null) { 7392 for (int i=0; i<needed.size(); i++) { 7393 GrantUri grantUri = needed.get(i); 7394 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7395 grantUri, needed.flags, owner); 7396 } 7397 } 7398 } 7399 7400 void grantUriPermissionFromIntentLocked(int callingUid, 7401 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7402 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7403 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7404 if (needed == null) { 7405 return; 7406 } 7407 7408 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7409 } 7410 7411 /** 7412 * @param uri This uri must NOT contain an embedded userId. 7413 * @param userId The userId in which the uri is to be resolved. 7414 */ 7415 @Override 7416 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7417 final int modeFlags, int userId) { 7418 enforceNotIsolatedCaller("grantUriPermission"); 7419 GrantUri grantUri = new GrantUri(userId, uri, false); 7420 synchronized(this) { 7421 final ProcessRecord r = getRecordForAppLocked(caller); 7422 if (r == null) { 7423 throw new SecurityException("Unable to find app for caller " 7424 + caller 7425 + " when granting permission to uri " + grantUri); 7426 } 7427 if (targetPkg == null) { 7428 throw new IllegalArgumentException("null target"); 7429 } 7430 if (grantUri == null) { 7431 throw new IllegalArgumentException("null uri"); 7432 } 7433 7434 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7435 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7436 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7437 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7438 7439 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7440 UserHandle.getUserId(r.uid)); 7441 } 7442 } 7443 7444 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7445 if (perm.modeFlags == 0) { 7446 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7447 perm.targetUid); 7448 if (perms != null) { 7449 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7450 "Removing " + perm.targetUid + " permission to " + perm.uri); 7451 7452 perms.remove(perm.uri); 7453 if (perms.isEmpty()) { 7454 mGrantedUriPermissions.remove(perm.targetUid); 7455 } 7456 } 7457 } 7458 } 7459 7460 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7461 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7462 7463 final IPackageManager pm = AppGlobals.getPackageManager(); 7464 final String authority = grantUri.uri.getAuthority(); 7465 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7466 if (pi == null) { 7467 Slog.w(TAG, "No content provider found for permission revoke: " 7468 + grantUri.toSafeString()); 7469 return; 7470 } 7471 7472 // Does the caller have this permission on the URI? 7473 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7474 // If they don't have direct access to the URI, then revoke any 7475 // ownerless URI permissions that have been granted to them. 7476 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7477 if (perms != null) { 7478 boolean persistChanged = false; 7479 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7480 final UriPermission perm = it.next(); 7481 if (perm.uri.sourceUserId == grantUri.sourceUserId 7482 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7483 if (DEBUG_URI_PERMISSION) 7484 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7485 " permission to " + perm.uri); 7486 persistChanged |= perm.revokeModes( 7487 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7488 if (perm.modeFlags == 0) { 7489 it.remove(); 7490 } 7491 } 7492 } 7493 if (perms.isEmpty()) { 7494 mGrantedUriPermissions.remove(callingUid); 7495 } 7496 if (persistChanged) { 7497 schedulePersistUriGrants(); 7498 } 7499 } 7500 return; 7501 } 7502 7503 boolean persistChanged = false; 7504 7505 // Go through all of the permissions and remove any that match. 7506 int N = mGrantedUriPermissions.size(); 7507 for (int i = 0; i < N; i++) { 7508 final int targetUid = mGrantedUriPermissions.keyAt(i); 7509 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7510 7511 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7512 final UriPermission perm = it.next(); 7513 if (perm.uri.sourceUserId == grantUri.sourceUserId 7514 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7515 if (DEBUG_URI_PERMISSION) 7516 Slog.v(TAG, 7517 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7518 persistChanged |= perm.revokeModes( 7519 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7520 if (perm.modeFlags == 0) { 7521 it.remove(); 7522 } 7523 } 7524 } 7525 7526 if (perms.isEmpty()) { 7527 mGrantedUriPermissions.remove(targetUid); 7528 N--; 7529 i--; 7530 } 7531 } 7532 7533 if (persistChanged) { 7534 schedulePersistUriGrants(); 7535 } 7536 } 7537 7538 /** 7539 * @param uri This uri must NOT contain an embedded userId. 7540 * @param userId The userId in which the uri is to be resolved. 7541 */ 7542 @Override 7543 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7544 int userId) { 7545 enforceNotIsolatedCaller("revokeUriPermission"); 7546 synchronized(this) { 7547 final ProcessRecord r = getRecordForAppLocked(caller); 7548 if (r == null) { 7549 throw new SecurityException("Unable to find app for caller " 7550 + caller 7551 + " when revoking permission to uri " + uri); 7552 } 7553 if (uri == null) { 7554 Slog.w(TAG, "revokeUriPermission: null uri"); 7555 return; 7556 } 7557 7558 if (!Intent.isAccessUriMode(modeFlags)) { 7559 return; 7560 } 7561 7562 final IPackageManager pm = AppGlobals.getPackageManager(); 7563 final String authority = uri.getAuthority(); 7564 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7565 if (pi == null) { 7566 Slog.w(TAG, "No content provider found for permission revoke: " 7567 + uri.toSafeString()); 7568 return; 7569 } 7570 7571 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7572 } 7573 } 7574 7575 /** 7576 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7577 * given package. 7578 * 7579 * @param packageName Package name to match, or {@code null} to apply to all 7580 * packages. 7581 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7582 * to all users. 7583 * @param persistable If persistable grants should be removed. 7584 */ 7585 private void removeUriPermissionsForPackageLocked( 7586 String packageName, int userHandle, boolean persistable) { 7587 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7588 throw new IllegalArgumentException("Must narrow by either package or user"); 7589 } 7590 7591 boolean persistChanged = false; 7592 7593 int N = mGrantedUriPermissions.size(); 7594 for (int i = 0; i < N; i++) { 7595 final int targetUid = mGrantedUriPermissions.keyAt(i); 7596 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7597 7598 // Only inspect grants matching user 7599 if (userHandle == UserHandle.USER_ALL 7600 || userHandle == UserHandle.getUserId(targetUid)) { 7601 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7602 final UriPermission perm = it.next(); 7603 7604 // Only inspect grants matching package 7605 if (packageName == null || perm.sourcePkg.equals(packageName) 7606 || perm.targetPkg.equals(packageName)) { 7607 persistChanged |= perm.revokeModes(persistable 7608 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7609 7610 // Only remove when no modes remain; any persisted grants 7611 // will keep this alive. 7612 if (perm.modeFlags == 0) { 7613 it.remove(); 7614 } 7615 } 7616 } 7617 7618 if (perms.isEmpty()) { 7619 mGrantedUriPermissions.remove(targetUid); 7620 N--; 7621 i--; 7622 } 7623 } 7624 } 7625 7626 if (persistChanged) { 7627 schedulePersistUriGrants(); 7628 } 7629 } 7630 7631 @Override 7632 public IBinder newUriPermissionOwner(String name) { 7633 enforceNotIsolatedCaller("newUriPermissionOwner"); 7634 synchronized(this) { 7635 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7636 return owner.getExternalTokenLocked(); 7637 } 7638 } 7639 7640 /** 7641 * @param uri This uri must NOT contain an embedded userId. 7642 * @param sourceUserId The userId in which the uri is to be resolved. 7643 * @param targetUserId The userId of the app that receives the grant. 7644 */ 7645 @Override 7646 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7647 final int modeFlags, int sourceUserId, int targetUserId) { 7648 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7649 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7650 synchronized(this) { 7651 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7652 if (owner == null) { 7653 throw new IllegalArgumentException("Unknown owner: " + token); 7654 } 7655 if (fromUid != Binder.getCallingUid()) { 7656 if (Binder.getCallingUid() != Process.myUid()) { 7657 // Only system code can grant URI permissions on behalf 7658 // of other users. 7659 throw new SecurityException("nice try"); 7660 } 7661 } 7662 if (targetPkg == null) { 7663 throw new IllegalArgumentException("null target"); 7664 } 7665 if (uri == null) { 7666 throw new IllegalArgumentException("null uri"); 7667 } 7668 7669 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7670 modeFlags, owner, targetUserId); 7671 } 7672 } 7673 7674 /** 7675 * @param uri This uri must NOT contain an embedded userId. 7676 * @param userId The userId in which the uri is to be resolved. 7677 */ 7678 @Override 7679 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7680 synchronized(this) { 7681 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7682 if (owner == null) { 7683 throw new IllegalArgumentException("Unknown owner: " + token); 7684 } 7685 7686 if (uri == null) { 7687 owner.removeUriPermissionsLocked(mode); 7688 } else { 7689 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7690 } 7691 } 7692 } 7693 7694 private void schedulePersistUriGrants() { 7695 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7696 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7697 10 * DateUtils.SECOND_IN_MILLIS); 7698 } 7699 } 7700 7701 private void writeGrantedUriPermissions() { 7702 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7703 7704 // Snapshot permissions so we can persist without lock 7705 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7706 synchronized (this) { 7707 final int size = mGrantedUriPermissions.size(); 7708 for (int i = 0; i < size; i++) { 7709 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7710 for (UriPermission perm : perms.values()) { 7711 if (perm.persistedModeFlags != 0) { 7712 persist.add(perm.snapshot()); 7713 } 7714 } 7715 } 7716 } 7717 7718 FileOutputStream fos = null; 7719 try { 7720 fos = mGrantFile.startWrite(); 7721 7722 XmlSerializer out = new FastXmlSerializer(); 7723 out.setOutput(fos, "utf-8"); 7724 out.startDocument(null, true); 7725 out.startTag(null, TAG_URI_GRANTS); 7726 for (UriPermission.Snapshot perm : persist) { 7727 out.startTag(null, TAG_URI_GRANT); 7728 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7729 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7730 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7731 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7732 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7733 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7734 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7735 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7736 out.endTag(null, TAG_URI_GRANT); 7737 } 7738 out.endTag(null, TAG_URI_GRANTS); 7739 out.endDocument(); 7740 7741 mGrantFile.finishWrite(fos); 7742 } catch (IOException e) { 7743 if (fos != null) { 7744 mGrantFile.failWrite(fos); 7745 } 7746 } 7747 } 7748 7749 private void readGrantedUriPermissionsLocked() { 7750 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7751 7752 final long now = System.currentTimeMillis(); 7753 7754 FileInputStream fis = null; 7755 try { 7756 fis = mGrantFile.openRead(); 7757 final XmlPullParser in = Xml.newPullParser(); 7758 in.setInput(fis, null); 7759 7760 int type; 7761 while ((type = in.next()) != END_DOCUMENT) { 7762 final String tag = in.getName(); 7763 if (type == START_TAG) { 7764 if (TAG_URI_GRANT.equals(tag)) { 7765 final int sourceUserId; 7766 final int targetUserId; 7767 final int userHandle = readIntAttribute(in, 7768 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7769 if (userHandle != UserHandle.USER_NULL) { 7770 // For backwards compatibility. 7771 sourceUserId = userHandle; 7772 targetUserId = userHandle; 7773 } else { 7774 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7775 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7776 } 7777 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7778 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7779 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7780 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7781 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7782 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7783 7784 // Sanity check that provider still belongs to source package 7785 final ProviderInfo pi = getProviderInfoLocked( 7786 uri.getAuthority(), sourceUserId); 7787 if (pi != null && sourcePkg.equals(pi.packageName)) { 7788 int targetUid = -1; 7789 try { 7790 targetUid = AppGlobals.getPackageManager() 7791 .getPackageUid(targetPkg, targetUserId); 7792 } catch (RemoteException e) { 7793 } 7794 if (targetUid != -1) { 7795 final UriPermission perm = findOrCreateUriPermissionLocked( 7796 sourcePkg, targetPkg, targetUid, 7797 new GrantUri(sourceUserId, uri, prefix)); 7798 perm.initPersistedModes(modeFlags, createdTime); 7799 } 7800 } else { 7801 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7802 + " but instead found " + pi); 7803 } 7804 } 7805 } 7806 } 7807 } catch (FileNotFoundException e) { 7808 // Missing grants is okay 7809 } catch (IOException e) { 7810 Slog.wtf(TAG, "Failed reading Uri grants", e); 7811 } catch (XmlPullParserException e) { 7812 Slog.wtf(TAG, "Failed reading Uri grants", e); 7813 } finally { 7814 IoUtils.closeQuietly(fis); 7815 } 7816 } 7817 7818 /** 7819 * @param uri This uri must NOT contain an embedded userId. 7820 * @param userId The userId in which the uri is to be resolved. 7821 */ 7822 @Override 7823 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7824 enforceNotIsolatedCaller("takePersistableUriPermission"); 7825 7826 Preconditions.checkFlagsArgument(modeFlags, 7827 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7828 7829 synchronized (this) { 7830 final int callingUid = Binder.getCallingUid(); 7831 boolean persistChanged = false; 7832 GrantUri grantUri = new GrantUri(userId, uri, false); 7833 7834 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7835 new GrantUri(userId, uri, false)); 7836 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7837 new GrantUri(userId, uri, true)); 7838 7839 final boolean exactValid = (exactPerm != null) 7840 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7841 final boolean prefixValid = (prefixPerm != null) 7842 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7843 7844 if (!(exactValid || prefixValid)) { 7845 throw new SecurityException("No persistable permission grants found for UID " 7846 + callingUid + " and Uri " + grantUri.toSafeString()); 7847 } 7848 7849 if (exactValid) { 7850 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7851 } 7852 if (prefixValid) { 7853 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7854 } 7855 7856 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7857 7858 if (persistChanged) { 7859 schedulePersistUriGrants(); 7860 } 7861 } 7862 } 7863 7864 /** 7865 * @param uri This uri must NOT contain an embedded userId. 7866 * @param userId The userId in which the uri is to be resolved. 7867 */ 7868 @Override 7869 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7870 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7871 7872 Preconditions.checkFlagsArgument(modeFlags, 7873 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7874 7875 synchronized (this) { 7876 final int callingUid = Binder.getCallingUid(); 7877 boolean persistChanged = false; 7878 7879 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7880 new GrantUri(userId, uri, false)); 7881 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7882 new GrantUri(userId, uri, true)); 7883 if (exactPerm == null && prefixPerm == null) { 7884 throw new SecurityException("No permission grants found for UID " + callingUid 7885 + " and Uri " + uri.toSafeString()); 7886 } 7887 7888 if (exactPerm != null) { 7889 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7890 removeUriPermissionIfNeededLocked(exactPerm); 7891 } 7892 if (prefixPerm != null) { 7893 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7894 removeUriPermissionIfNeededLocked(prefixPerm); 7895 } 7896 7897 if (persistChanged) { 7898 schedulePersistUriGrants(); 7899 } 7900 } 7901 } 7902 7903 /** 7904 * Prune any older {@link UriPermission} for the given UID until outstanding 7905 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7906 * 7907 * @return if any mutations occured that require persisting. 7908 */ 7909 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7910 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7911 if (perms == null) return false; 7912 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7913 7914 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7915 for (UriPermission perm : perms.values()) { 7916 if (perm.persistedModeFlags != 0) { 7917 persisted.add(perm); 7918 } 7919 } 7920 7921 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7922 if (trimCount <= 0) return false; 7923 7924 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7925 for (int i = 0; i < trimCount; i++) { 7926 final UriPermission perm = persisted.get(i); 7927 7928 if (DEBUG_URI_PERMISSION) { 7929 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7930 } 7931 7932 perm.releasePersistableModes(~0); 7933 removeUriPermissionIfNeededLocked(perm); 7934 } 7935 7936 return true; 7937 } 7938 7939 @Override 7940 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7941 String packageName, boolean incoming) { 7942 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7943 Preconditions.checkNotNull(packageName, "packageName"); 7944 7945 final int callingUid = Binder.getCallingUid(); 7946 final IPackageManager pm = AppGlobals.getPackageManager(); 7947 try { 7948 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7949 if (packageUid != callingUid) { 7950 throw new SecurityException( 7951 "Package " + packageName + " does not belong to calling UID " + callingUid); 7952 } 7953 } catch (RemoteException e) { 7954 throw new SecurityException("Failed to verify package name ownership"); 7955 } 7956 7957 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7958 synchronized (this) { 7959 if (incoming) { 7960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7961 callingUid); 7962 if (perms == null) { 7963 Slog.w(TAG, "No permission grants found for " + packageName); 7964 } else { 7965 for (UriPermission perm : perms.values()) { 7966 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7967 result.add(perm.buildPersistedPublicApiObject()); 7968 } 7969 } 7970 } 7971 } else { 7972 final int size = mGrantedUriPermissions.size(); 7973 for (int i = 0; i < size; i++) { 7974 final ArrayMap<GrantUri, UriPermission> perms = 7975 mGrantedUriPermissions.valueAt(i); 7976 for (UriPermission perm : perms.values()) { 7977 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7978 result.add(perm.buildPersistedPublicApiObject()); 7979 } 7980 } 7981 } 7982 } 7983 } 7984 return new ParceledListSlice<android.content.UriPermission>(result); 7985 } 7986 7987 @Override 7988 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7989 synchronized (this) { 7990 ProcessRecord app = 7991 who != null ? getRecordForAppLocked(who) : null; 7992 if (app == null) return; 7993 7994 Message msg = Message.obtain(); 7995 msg.what = WAIT_FOR_DEBUGGER_MSG; 7996 msg.obj = app; 7997 msg.arg1 = waiting ? 1 : 0; 7998 mHandler.sendMessage(msg); 7999 } 8000 } 8001 8002 @Override 8003 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8004 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8005 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8006 outInfo.availMem = Process.getFreeMemory(); 8007 outInfo.totalMem = Process.getTotalMemory(); 8008 outInfo.threshold = homeAppMem; 8009 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8010 outInfo.hiddenAppThreshold = cachedAppMem; 8011 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8012 ProcessList.SERVICE_ADJ); 8013 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8014 ProcessList.VISIBLE_APP_ADJ); 8015 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8016 ProcessList.FOREGROUND_APP_ADJ); 8017 } 8018 8019 // ========================================================= 8020 // TASK MANAGEMENT 8021 // ========================================================= 8022 8023 @Override 8024 public List<IAppTask> getAppTasks(String callingPackage) { 8025 int callingUid = Binder.getCallingUid(); 8026 long ident = Binder.clearCallingIdentity(); 8027 8028 synchronized(this) { 8029 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8030 try { 8031 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8032 8033 final int N = mRecentTasks.size(); 8034 for (int i = 0; i < N; i++) { 8035 TaskRecord tr = mRecentTasks.get(i); 8036 // Skip tasks that do not match the caller. We don't need to verify 8037 // callingPackage, because we are also limiting to callingUid and know 8038 // that will limit to the correct security sandbox. 8039 if (tr.effectiveUid != callingUid) { 8040 continue; 8041 } 8042 Intent intent = tr.getBaseIntent(); 8043 if (intent == null || 8044 !callingPackage.equals(intent.getComponent().getPackageName())) { 8045 continue; 8046 } 8047 ActivityManager.RecentTaskInfo taskInfo = 8048 createRecentTaskInfoFromTaskRecord(tr); 8049 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8050 list.add(taskImpl); 8051 } 8052 } finally { 8053 Binder.restoreCallingIdentity(ident); 8054 } 8055 return list; 8056 } 8057 } 8058 8059 @Override 8060 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8061 final int callingUid = Binder.getCallingUid(); 8062 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8063 8064 synchronized(this) { 8065 if (localLOGV) Slog.v( 8066 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8067 8068 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8069 callingUid); 8070 8071 // TODO: Improve with MRU list from all ActivityStacks. 8072 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8073 } 8074 8075 return list; 8076 } 8077 8078 /** 8079 * Creates a new RecentTaskInfo from a TaskRecord. 8080 */ 8081 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8082 // Update the task description to reflect any changes in the task stack 8083 tr.updateTaskDescription(); 8084 8085 // Compose the recent task info 8086 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8087 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8088 rti.persistentId = tr.taskId; 8089 rti.baseIntent = new Intent(tr.getBaseIntent()); 8090 rti.origActivity = tr.origActivity; 8091 rti.description = tr.lastDescription; 8092 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8093 rti.userId = tr.userId; 8094 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8095 rti.firstActiveTime = tr.firstActiveTime; 8096 rti.lastActiveTime = tr.lastActiveTime; 8097 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8098 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8099 return rti; 8100 } 8101 8102 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8103 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8104 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8105 if (!allowed) { 8106 if (checkPermission(android.Manifest.permission.GET_TASKS, 8107 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8108 // Temporary compatibility: some existing apps on the system image may 8109 // still be requesting the old permission and not switched to the new 8110 // one; if so, we'll still allow them full access. This means we need 8111 // to see if they are holding the old permission and are a system app. 8112 try { 8113 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8114 allowed = true; 8115 Slog.w(TAG, caller + ": caller " + callingUid 8116 + " is using old GET_TASKS but privileged; allowing"); 8117 } 8118 } catch (RemoteException e) { 8119 } 8120 } 8121 } 8122 if (!allowed) { 8123 Slog.w(TAG, caller + ": caller " + callingUid 8124 + " does not hold GET_TASKS; limiting output"); 8125 } 8126 return allowed; 8127 } 8128 8129 @Override 8130 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8131 final int callingUid = Binder.getCallingUid(); 8132 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8133 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8134 8135 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8136 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8137 synchronized (this) { 8138 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8139 callingUid); 8140 final boolean detailed = checkCallingPermission( 8141 android.Manifest.permission.GET_DETAILED_TASKS) 8142 == PackageManager.PERMISSION_GRANTED; 8143 8144 final int N = mRecentTasks.size(); 8145 ArrayList<ActivityManager.RecentTaskInfo> res 8146 = new ArrayList<ActivityManager.RecentTaskInfo>( 8147 maxNum < N ? maxNum : N); 8148 8149 final Set<Integer> includedUsers; 8150 if (includeProfiles) { 8151 includedUsers = getProfileIdsLocked(userId); 8152 } else { 8153 includedUsers = new HashSet<Integer>(); 8154 } 8155 includedUsers.add(Integer.valueOf(userId)); 8156 8157 for (int i=0; i<N && maxNum > 0; i++) { 8158 TaskRecord tr = mRecentTasks.get(i); 8159 // Only add calling user or related users recent tasks 8160 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8161 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8162 continue; 8163 } 8164 8165 // Return the entry if desired by the caller. We always return 8166 // the first entry, because callers always expect this to be the 8167 // foreground app. We may filter others if the caller has 8168 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8169 // we should exclude the entry. 8170 8171 if (i == 0 8172 || withExcluded 8173 || (tr.intent == null) 8174 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8175 == 0)) { 8176 if (!allowed) { 8177 // If the caller doesn't have the GET_TASKS permission, then only 8178 // allow them to see a small subset of tasks -- their own and home. 8179 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8180 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8181 continue; 8182 } 8183 } 8184 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8185 if (tr.stack != null && tr.stack.isHomeStack()) { 8186 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8187 continue; 8188 } 8189 } 8190 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8191 // Don't include auto remove tasks that are finished or finishing. 8192 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8193 + tr); 8194 continue; 8195 } 8196 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8197 && !tr.isAvailable) { 8198 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8199 continue; 8200 } 8201 8202 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8203 if (!detailed) { 8204 rti.baseIntent.replaceExtras((Bundle)null); 8205 } 8206 8207 res.add(rti); 8208 maxNum--; 8209 } 8210 } 8211 return res; 8212 } 8213 } 8214 8215 TaskRecord recentTaskForIdLocked(int id) { 8216 final int N = mRecentTasks.size(); 8217 for (int i=0; i<N; i++) { 8218 TaskRecord tr = mRecentTasks.get(i); 8219 if (tr.taskId == id) { 8220 return tr; 8221 } 8222 } 8223 return null; 8224 } 8225 8226 @Override 8227 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8228 synchronized (this) { 8229 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8230 "getTaskThumbnail()"); 8231 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8232 if (tr != null) { 8233 return tr.getTaskThumbnailLocked(); 8234 } 8235 } 8236 return null; 8237 } 8238 8239 @Override 8240 public int addAppTask(IBinder activityToken, Intent intent, 8241 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8242 final int callingUid = Binder.getCallingUid(); 8243 final long callingIdent = Binder.clearCallingIdentity(); 8244 8245 try { 8246 synchronized (this) { 8247 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8248 if (r == null) { 8249 throw new IllegalArgumentException("Activity does not exist; token=" 8250 + activityToken); 8251 } 8252 ComponentName comp = intent.getComponent(); 8253 if (comp == null) { 8254 throw new IllegalArgumentException("Intent " + intent 8255 + " must specify explicit component"); 8256 } 8257 if (thumbnail.getWidth() != mThumbnailWidth 8258 || thumbnail.getHeight() != mThumbnailHeight) { 8259 throw new IllegalArgumentException("Bad thumbnail size: got " 8260 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8261 + mThumbnailWidth + "x" + mThumbnailHeight); 8262 } 8263 if (intent.getSelector() != null) { 8264 intent.setSelector(null); 8265 } 8266 if (intent.getSourceBounds() != null) { 8267 intent.setSourceBounds(null); 8268 } 8269 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8270 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8271 // The caller has added this as an auto-remove task... that makes no 8272 // sense, so turn off auto-remove. 8273 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8274 } 8275 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8276 // Must be a new task. 8277 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8278 } 8279 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8280 mLastAddedTaskActivity = null; 8281 } 8282 ActivityInfo ainfo = mLastAddedTaskActivity; 8283 if (ainfo == null) { 8284 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8285 comp, 0, UserHandle.getUserId(callingUid)); 8286 if (ainfo.applicationInfo.uid != callingUid) { 8287 throw new SecurityException( 8288 "Can't add task for another application: target uid=" 8289 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8290 } 8291 } 8292 8293 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8294 intent, description); 8295 8296 int trimIdx = trimRecentsForTaskLocked(task, false); 8297 if (trimIdx >= 0) { 8298 // If this would have caused a trim, then we'll abort because that 8299 // means it would be added at the end of the list but then just removed. 8300 return INVALID_TASK_ID; 8301 } 8302 8303 final int N = mRecentTasks.size(); 8304 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8305 final TaskRecord tr = mRecentTasks.remove(N - 1); 8306 tr.removedFromRecents(); 8307 } 8308 8309 task.inRecents = true; 8310 mRecentTasks.add(task); 8311 r.task.stack.addTask(task, false, false); 8312 8313 task.setLastThumbnail(thumbnail); 8314 task.freeLastThumbnail(); 8315 8316 return task.taskId; 8317 } 8318 } finally { 8319 Binder.restoreCallingIdentity(callingIdent); 8320 } 8321 } 8322 8323 @Override 8324 public Point getAppTaskThumbnailSize() { 8325 synchronized (this) { 8326 return new Point(mThumbnailWidth, mThumbnailHeight); 8327 } 8328 } 8329 8330 @Override 8331 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8332 synchronized (this) { 8333 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8334 if (r != null) { 8335 r.setTaskDescription(td); 8336 r.task.updateTaskDescription(); 8337 } 8338 } 8339 } 8340 8341 @Override 8342 public Bitmap getTaskDescriptionIcon(String filename) { 8343 if (!FileUtils.isValidExtFilename(filename) 8344 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8345 throw new IllegalArgumentException("Bad filename: " + filename); 8346 } 8347 return mTaskPersister.getTaskDescriptionIcon(filename); 8348 } 8349 8350 @Override 8351 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8352 throws RemoteException { 8353 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8354 opts.getCustomInPlaceResId() == 0) { 8355 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8356 "with valid animation"); 8357 } 8358 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8359 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8360 opts.getCustomInPlaceResId()); 8361 mWindowManager.executeAppTransition(); 8362 } 8363 8364 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8365 mRecentTasks.remove(tr); 8366 tr.removedFromRecents(); 8367 ComponentName component = tr.getBaseIntent().getComponent(); 8368 if (component == null) { 8369 Slog.w(TAG, "No component for base intent of task: " + tr); 8370 return; 8371 } 8372 8373 if (!killProcess) { 8374 return; 8375 } 8376 8377 // Determine if the process(es) for this task should be killed. 8378 final String pkg = component.getPackageName(); 8379 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8380 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8381 for (int i = 0; i < pmap.size(); i++) { 8382 8383 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8384 for (int j = 0; j < uids.size(); j++) { 8385 ProcessRecord proc = uids.valueAt(j); 8386 if (proc.userId != tr.userId) { 8387 // Don't kill process for a different user. 8388 continue; 8389 } 8390 if (proc == mHomeProcess) { 8391 // Don't kill the home process along with tasks from the same package. 8392 continue; 8393 } 8394 if (!proc.pkgList.containsKey(pkg)) { 8395 // Don't kill process that is not associated with this task. 8396 continue; 8397 } 8398 8399 for (int k = 0; k < proc.activities.size(); k++) { 8400 TaskRecord otherTask = proc.activities.get(k).task; 8401 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8402 // Don't kill process(es) that has an activity in a different task that is 8403 // also in recents. 8404 return; 8405 } 8406 } 8407 8408 // Add process to kill list. 8409 procsToKill.add(proc); 8410 } 8411 } 8412 8413 // Find any running services associated with this app and stop if needed. 8414 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8415 8416 // Kill the running processes. 8417 for (int i = 0; i < procsToKill.size(); i++) { 8418 ProcessRecord pr = procsToKill.get(i); 8419 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8420 pr.kill("remove task", true); 8421 } else { 8422 pr.waitingToKill = "remove task"; 8423 } 8424 } 8425 } 8426 8427 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8428 // Remove all tasks with activities in the specified package from the list of recent tasks 8429 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8430 TaskRecord tr = mRecentTasks.get(i); 8431 if (tr.userId != userId) continue; 8432 8433 ComponentName cn = tr.intent.getComponent(); 8434 if (cn != null && cn.getPackageName().equals(packageName)) { 8435 // If the package name matches, remove the task. 8436 removeTaskByIdLocked(tr.taskId, true); 8437 } 8438 } 8439 } 8440 8441 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8442 final IPackageManager pm = AppGlobals.getPackageManager(); 8443 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8444 8445 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8446 TaskRecord tr = mRecentTasks.get(i); 8447 if (tr.userId != userId) continue; 8448 8449 ComponentName cn = tr.intent.getComponent(); 8450 if (cn != null && cn.getPackageName().equals(packageName)) { 8451 // Skip if component still exists in the package. 8452 if (componentsKnownToExist.contains(cn)) continue; 8453 8454 try { 8455 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8456 if (info != null) { 8457 componentsKnownToExist.add(cn); 8458 } else { 8459 removeTaskByIdLocked(tr.taskId, false); 8460 } 8461 } catch (RemoteException e) { 8462 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8463 } 8464 } 8465 } 8466 } 8467 8468 /** 8469 * Removes the task with the specified task id. 8470 * 8471 * @param taskId Identifier of the task to be removed. 8472 * @param killProcess Kill any process associated with the task if possible. 8473 * @return Returns true if the given task was found and removed. 8474 */ 8475 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8476 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8477 if (tr != null) { 8478 tr.removeTaskActivitiesLocked(); 8479 cleanUpRemovedTaskLocked(tr, killProcess); 8480 if (tr.isPersistable) { 8481 notifyTaskPersisterLocked(null, true); 8482 } 8483 return true; 8484 } 8485 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8486 return false; 8487 } 8488 8489 @Override 8490 public boolean removeTask(int taskId) { 8491 synchronized (this) { 8492 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8493 "removeTask()"); 8494 long ident = Binder.clearCallingIdentity(); 8495 try { 8496 return removeTaskByIdLocked(taskId, true); 8497 } finally { 8498 Binder.restoreCallingIdentity(ident); 8499 } 8500 } 8501 } 8502 8503 /** 8504 * TODO: Add mController hook 8505 */ 8506 @Override 8507 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8508 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8509 "moveTaskToFront()"); 8510 8511 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8512 synchronized(this) { 8513 moveTaskToFrontLocked(taskId, flags, options); 8514 } 8515 } 8516 8517 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8518 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8519 Binder.getCallingUid(), -1, -1, "Task to front")) { 8520 ActivityOptions.abort(options); 8521 return; 8522 } 8523 final long origId = Binder.clearCallingIdentity(); 8524 try { 8525 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8526 if (task == null) { 8527 Slog.d(TAG, "Could not find task for id: "+ taskId); 8528 return; 8529 } 8530 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8531 mStackSupervisor.showLockTaskToast(); 8532 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8533 return; 8534 } 8535 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8536 if (prev != null && prev.isRecentsActivity()) { 8537 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8538 } 8539 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8540 } finally { 8541 Binder.restoreCallingIdentity(origId); 8542 } 8543 ActivityOptions.abort(options); 8544 } 8545 8546 @Override 8547 public void moveTaskToBack(int taskId) { 8548 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8549 "moveTaskToBack()"); 8550 8551 synchronized(this) { 8552 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8553 if (tr != null) { 8554 if (tr == mStackSupervisor.mLockTaskModeTask) { 8555 mStackSupervisor.showLockTaskToast(); 8556 return; 8557 } 8558 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8559 ActivityStack stack = tr.stack; 8560 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8561 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8562 Binder.getCallingUid(), -1, -1, "Task to back")) { 8563 return; 8564 } 8565 } 8566 final long origId = Binder.clearCallingIdentity(); 8567 try { 8568 stack.moveTaskToBackLocked(taskId, null); 8569 } finally { 8570 Binder.restoreCallingIdentity(origId); 8571 } 8572 } 8573 } 8574 } 8575 8576 /** 8577 * Moves an activity, and all of the other activities within the same task, to the bottom 8578 * of the history stack. The activity's order within the task is unchanged. 8579 * 8580 * @param token A reference to the activity we wish to move 8581 * @param nonRoot If false then this only works if the activity is the root 8582 * of a task; if true it will work for any activity in a task. 8583 * @return Returns true if the move completed, false if not. 8584 */ 8585 @Override 8586 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8587 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8588 synchronized(this) { 8589 final long origId = Binder.clearCallingIdentity(); 8590 try { 8591 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8592 if (taskId >= 0) { 8593 if ((mStackSupervisor.mLockTaskModeTask != null) 8594 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8595 mStackSupervisor.showLockTaskToast(); 8596 return false; 8597 } 8598 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8599 } 8600 } finally { 8601 Binder.restoreCallingIdentity(origId); 8602 } 8603 } 8604 return false; 8605 } 8606 8607 @Override 8608 public void moveTaskBackwards(int task) { 8609 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8610 "moveTaskBackwards()"); 8611 8612 synchronized(this) { 8613 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8614 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8615 return; 8616 } 8617 final long origId = Binder.clearCallingIdentity(); 8618 moveTaskBackwardsLocked(task); 8619 Binder.restoreCallingIdentity(origId); 8620 } 8621 } 8622 8623 private final void moveTaskBackwardsLocked(int task) { 8624 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8625 } 8626 8627 @Override 8628 public IBinder getHomeActivityToken() throws RemoteException { 8629 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8630 "getHomeActivityToken()"); 8631 synchronized (this) { 8632 return mStackSupervisor.getHomeActivityToken(); 8633 } 8634 } 8635 8636 @Override 8637 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8638 IActivityContainerCallback callback) throws RemoteException { 8639 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8640 "createActivityContainer()"); 8641 synchronized (this) { 8642 if (parentActivityToken == null) { 8643 throw new IllegalArgumentException("parent token must not be null"); 8644 } 8645 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8646 if (r == null) { 8647 return null; 8648 } 8649 if (callback == null) { 8650 throw new IllegalArgumentException("callback must not be null"); 8651 } 8652 return mStackSupervisor.createActivityContainer(r, callback); 8653 } 8654 } 8655 8656 @Override 8657 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8658 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8659 "deleteActivityContainer()"); 8660 synchronized (this) { 8661 mStackSupervisor.deleteActivityContainer(container); 8662 } 8663 } 8664 8665 @Override 8666 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8667 throws RemoteException { 8668 synchronized (this) { 8669 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8670 if (stack != null) { 8671 return stack.mActivityContainer; 8672 } 8673 return null; 8674 } 8675 } 8676 8677 @Override 8678 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8679 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8680 "moveTaskToStack()"); 8681 if (stackId == HOME_STACK_ID) { 8682 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8683 new RuntimeException("here").fillInStackTrace()); 8684 } 8685 synchronized (this) { 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8689 + stackId + " toTop=" + toTop); 8690 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8691 } finally { 8692 Binder.restoreCallingIdentity(ident); 8693 } 8694 } 8695 } 8696 8697 @Override 8698 public void resizeStack(int stackBoxId, Rect bounds) { 8699 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8700 "resizeStackBox()"); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 mWindowManager.resizeStack(stackBoxId, bounds); 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public List<StackInfo> getAllStackInfos() { 8711 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8712 "getAllStackInfos()"); 8713 long ident = Binder.clearCallingIdentity(); 8714 try { 8715 synchronized (this) { 8716 return mStackSupervisor.getAllStackInfosLocked(); 8717 } 8718 } finally { 8719 Binder.restoreCallingIdentity(ident); 8720 } 8721 } 8722 8723 @Override 8724 public StackInfo getStackInfo(int stackId) { 8725 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8726 "getStackInfo()"); 8727 long ident = Binder.clearCallingIdentity(); 8728 try { 8729 synchronized (this) { 8730 return mStackSupervisor.getStackInfoLocked(stackId); 8731 } 8732 } finally { 8733 Binder.restoreCallingIdentity(ident); 8734 } 8735 } 8736 8737 @Override 8738 public boolean isInHomeStack(int taskId) { 8739 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8740 "getStackInfo()"); 8741 long ident = Binder.clearCallingIdentity(); 8742 try { 8743 synchronized (this) { 8744 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8745 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8746 } 8747 } finally { 8748 Binder.restoreCallingIdentity(ident); 8749 } 8750 } 8751 8752 @Override 8753 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8754 synchronized(this) { 8755 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8756 } 8757 } 8758 8759 private boolean isLockTaskAuthorized(String pkg) { 8760 final DevicePolicyManager dpm = (DevicePolicyManager) 8761 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8762 try { 8763 int uid = mContext.getPackageManager().getPackageUid(pkg, 8764 Binder.getCallingUserHandle().getIdentifier()); 8765 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8766 } catch (NameNotFoundException e) { 8767 return false; 8768 } 8769 } 8770 8771 void startLockTaskMode(TaskRecord task) { 8772 final String pkg; 8773 synchronized (this) { 8774 pkg = task.intent.getComponent().getPackageName(); 8775 } 8776 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8777 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8778 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8779 StatusBarManagerInternal.class); 8780 if (statusBarManager != null) { 8781 statusBarManager.showScreenPinningRequest(); 8782 } 8783 return; 8784 } 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 // Since we lost lock on task, make sure it is still there. 8789 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8790 if (task != null) { 8791 if (!isSystemInitiated 8792 && ((mStackSupervisor.getFocusedStack() == null) 8793 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8794 throw new IllegalArgumentException("Invalid task, not in foreground"); 8795 } 8796 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8797 } 8798 } 8799 } finally { 8800 Binder.restoreCallingIdentity(ident); 8801 } 8802 } 8803 8804 @Override 8805 public void startLockTaskMode(int taskId) { 8806 final TaskRecord task; 8807 long ident = Binder.clearCallingIdentity(); 8808 try { 8809 synchronized (this) { 8810 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8811 } 8812 } finally { 8813 Binder.restoreCallingIdentity(ident); 8814 } 8815 if (task != null) { 8816 startLockTaskMode(task); 8817 } 8818 } 8819 8820 @Override 8821 public void startLockTaskMode(IBinder token) { 8822 final TaskRecord task; 8823 long ident = Binder.clearCallingIdentity(); 8824 try { 8825 synchronized (this) { 8826 final ActivityRecord r = ActivityRecord.forToken(token); 8827 if (r == null) { 8828 return; 8829 } 8830 task = r.task; 8831 } 8832 } finally { 8833 Binder.restoreCallingIdentity(ident); 8834 } 8835 if (task != null) { 8836 startLockTaskMode(task); 8837 } 8838 } 8839 8840 @Override 8841 public void startLockTaskModeOnCurrent() throws RemoteException { 8842 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8843 "startLockTaskModeOnCurrent"); 8844 long ident = Binder.clearCallingIdentity(); 8845 try { 8846 ActivityRecord r = null; 8847 synchronized (this) { 8848 r = mStackSupervisor.topRunningActivityLocked(); 8849 } 8850 startLockTaskMode(r.task); 8851 } finally { 8852 Binder.restoreCallingIdentity(ident); 8853 } 8854 } 8855 8856 @Override 8857 public void stopLockTaskMode() { 8858 // Verify that the user matches the package of the intent for the TaskRecord 8859 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8860 // and stopLockTaskMode. 8861 final int callingUid = Binder.getCallingUid(); 8862 if (callingUid != Process.SYSTEM_UID) { 8863 try { 8864 String pkg = 8865 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8866 int uid = mContext.getPackageManager().getPackageUid(pkg, 8867 Binder.getCallingUserHandle().getIdentifier()); 8868 if (uid != callingUid) { 8869 throw new SecurityException("Invalid uid, expected " + uid); 8870 } 8871 } catch (NameNotFoundException e) { 8872 Log.d(TAG, "stopLockTaskMode " + e); 8873 return; 8874 } 8875 } 8876 long ident = Binder.clearCallingIdentity(); 8877 try { 8878 Log.d(TAG, "stopLockTaskMode"); 8879 // Stop lock task 8880 synchronized (this) { 8881 mStackSupervisor.setLockTaskModeLocked(null, false); 8882 } 8883 } finally { 8884 Binder.restoreCallingIdentity(ident); 8885 } 8886 } 8887 8888 @Override 8889 public void stopLockTaskModeOnCurrent() throws RemoteException { 8890 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8891 "stopLockTaskModeOnCurrent"); 8892 long ident = Binder.clearCallingIdentity(); 8893 try { 8894 stopLockTaskMode(); 8895 } finally { 8896 Binder.restoreCallingIdentity(ident); 8897 } 8898 } 8899 8900 @Override 8901 public boolean isInLockTaskMode() { 8902 synchronized (this) { 8903 return mStackSupervisor.isInLockTaskMode(); 8904 } 8905 } 8906 8907 // ========================================================= 8908 // CONTENT PROVIDERS 8909 // ========================================================= 8910 8911 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8912 List<ProviderInfo> providers = null; 8913 try { 8914 providers = AppGlobals.getPackageManager(). 8915 queryContentProviders(app.processName, app.uid, 8916 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8917 } catch (RemoteException ex) { 8918 } 8919 if (DEBUG_MU) 8920 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8921 int userId = app.userId; 8922 if (providers != null) { 8923 int N = providers.size(); 8924 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8925 for (int i=0; i<N; i++) { 8926 ProviderInfo cpi = 8927 (ProviderInfo)providers.get(i); 8928 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8929 cpi.name, cpi.flags); 8930 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8931 // This is a singleton provider, but a user besides the 8932 // default user is asking to initialize a process it runs 8933 // in... well, no, it doesn't actually run in this process, 8934 // it runs in the process of the default user. Get rid of it. 8935 providers.remove(i); 8936 N--; 8937 i--; 8938 continue; 8939 } 8940 8941 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8942 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8943 if (cpr == null) { 8944 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8945 mProviderMap.putProviderByClass(comp, cpr); 8946 } 8947 if (DEBUG_MU) 8948 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8949 app.pubProviders.put(cpi.name, cpr); 8950 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8951 // Don't add this if it is a platform component that is marked 8952 // to run in multiple processes, because this is actually 8953 // part of the framework so doesn't make sense to track as a 8954 // separate apk in the process. 8955 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8956 mProcessStats); 8957 } 8958 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8959 } 8960 } 8961 return providers; 8962 } 8963 8964 /** 8965 * Check if {@link ProcessRecord} has a possible chance at accessing the 8966 * given {@link ProviderInfo}. Final permission checking is always done 8967 * in {@link ContentProvider}. 8968 */ 8969 private final String checkContentProviderPermissionLocked( 8970 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8971 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8972 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8973 boolean checkedGrants = false; 8974 if (checkUser) { 8975 // Looking for cross-user grants before enforcing the typical cross-users permissions 8976 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8977 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8978 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8979 return null; 8980 } 8981 checkedGrants = true; 8982 } 8983 userId = handleIncomingUser(callingPid, callingUid, userId, 8984 false, ALLOW_NON_FULL, 8985 "checkContentProviderPermissionLocked " + cpi.authority, null); 8986 if (userId != tmpTargetUserId) { 8987 // When we actually went to determine the final targer user ID, this ended 8988 // up different than our initial check for the authority. This is because 8989 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8990 // SELF. So we need to re-check the grants again. 8991 checkedGrants = false; 8992 } 8993 } 8994 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8995 cpi.applicationInfo.uid, cpi.exported) 8996 == PackageManager.PERMISSION_GRANTED) { 8997 return null; 8998 } 8999 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9000 cpi.applicationInfo.uid, cpi.exported) 9001 == PackageManager.PERMISSION_GRANTED) { 9002 return null; 9003 } 9004 9005 PathPermission[] pps = cpi.pathPermissions; 9006 if (pps != null) { 9007 int i = pps.length; 9008 while (i > 0) { 9009 i--; 9010 PathPermission pp = pps[i]; 9011 String pprperm = pp.getReadPermission(); 9012 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9013 cpi.applicationInfo.uid, cpi.exported) 9014 == PackageManager.PERMISSION_GRANTED) { 9015 return null; 9016 } 9017 String ppwperm = pp.getWritePermission(); 9018 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9019 cpi.applicationInfo.uid, cpi.exported) 9020 == PackageManager.PERMISSION_GRANTED) { 9021 return null; 9022 } 9023 } 9024 } 9025 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9026 return null; 9027 } 9028 9029 String msg; 9030 if (!cpi.exported) { 9031 msg = "Permission Denial: opening provider " + cpi.name 9032 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9033 + ", uid=" + callingUid + ") that is not exported from uid " 9034 + cpi.applicationInfo.uid; 9035 } else { 9036 msg = "Permission Denial: opening provider " + cpi.name 9037 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9038 + ", uid=" + callingUid + ") requires " 9039 + cpi.readPermission + " or " + cpi.writePermission; 9040 } 9041 Slog.w(TAG, msg); 9042 return msg; 9043 } 9044 9045 /** 9046 * Returns if the ContentProvider has granted a uri to callingUid 9047 */ 9048 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9049 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9050 if (perms != null) { 9051 for (int i=perms.size()-1; i>=0; i--) { 9052 GrantUri grantUri = perms.keyAt(i); 9053 if (grantUri.sourceUserId == userId || !checkUser) { 9054 if (matchesProvider(grantUri.uri, cpi)) { 9055 return true; 9056 } 9057 } 9058 } 9059 } 9060 return false; 9061 } 9062 9063 /** 9064 * Returns true if the uri authority is one of the authorities specified in the provider. 9065 */ 9066 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9067 String uriAuth = uri.getAuthority(); 9068 String cpiAuth = cpi.authority; 9069 if (cpiAuth.indexOf(';') == -1) { 9070 return cpiAuth.equals(uriAuth); 9071 } 9072 String[] cpiAuths = cpiAuth.split(";"); 9073 int length = cpiAuths.length; 9074 for (int i = 0; i < length; i++) { 9075 if (cpiAuths[i].equals(uriAuth)) return true; 9076 } 9077 return false; 9078 } 9079 9080 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9081 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9082 if (r != null) { 9083 for (int i=0; i<r.conProviders.size(); i++) { 9084 ContentProviderConnection conn = r.conProviders.get(i); 9085 if (conn.provider == cpr) { 9086 if (DEBUG_PROVIDER) Slog.v(TAG, 9087 "Adding provider requested by " 9088 + r.processName + " from process " 9089 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9090 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9091 if (stable) { 9092 conn.stableCount++; 9093 conn.numStableIncs++; 9094 } else { 9095 conn.unstableCount++; 9096 conn.numUnstableIncs++; 9097 } 9098 return conn; 9099 } 9100 } 9101 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9102 if (stable) { 9103 conn.stableCount = 1; 9104 conn.numStableIncs = 1; 9105 } else { 9106 conn.unstableCount = 1; 9107 conn.numUnstableIncs = 1; 9108 } 9109 cpr.connections.add(conn); 9110 r.conProviders.add(conn); 9111 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9112 return conn; 9113 } 9114 cpr.addExternalProcessHandleLocked(externalProcessToken); 9115 return null; 9116 } 9117 9118 boolean decProviderCountLocked(ContentProviderConnection conn, 9119 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9120 if (conn != null) { 9121 cpr = conn.provider; 9122 if (DEBUG_PROVIDER) Slog.v(TAG, 9123 "Removing provider requested by " 9124 + conn.client.processName + " from process " 9125 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9126 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9127 if (stable) { 9128 conn.stableCount--; 9129 } else { 9130 conn.unstableCount--; 9131 } 9132 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9133 cpr.connections.remove(conn); 9134 conn.client.conProviders.remove(conn); 9135 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9136 return true; 9137 } 9138 return false; 9139 } 9140 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9141 return false; 9142 } 9143 9144 private void checkTime(long startTime, String where) { 9145 long now = SystemClock.elapsedRealtime(); 9146 if ((now-startTime) > 1000) { 9147 // If we are taking more than a second, log about it. 9148 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9149 } 9150 } 9151 9152 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9153 String name, IBinder token, boolean stable, int userId) { 9154 ContentProviderRecord cpr; 9155 ContentProviderConnection conn = null; 9156 ProviderInfo cpi = null; 9157 9158 synchronized(this) { 9159 long startTime = SystemClock.elapsedRealtime(); 9160 9161 ProcessRecord r = null; 9162 if (caller != null) { 9163 r = getRecordForAppLocked(caller); 9164 if (r == null) { 9165 throw new SecurityException( 9166 "Unable to find app for caller " + caller 9167 + " (pid=" + Binder.getCallingPid() 9168 + ") when getting content provider " + name); 9169 } 9170 } 9171 9172 boolean checkCrossUser = true; 9173 9174 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9175 9176 // First check if this content provider has been published... 9177 cpr = mProviderMap.getProviderByName(name, userId); 9178 // If that didn't work, check if it exists for user 0 and then 9179 // verify that it's a singleton provider before using it. 9180 if (cpr == null && userId != UserHandle.USER_OWNER) { 9181 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9182 if (cpr != null) { 9183 cpi = cpr.info; 9184 if (isSingleton(cpi.processName, cpi.applicationInfo, 9185 cpi.name, cpi.flags) 9186 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9187 userId = UserHandle.USER_OWNER; 9188 checkCrossUser = false; 9189 } else { 9190 cpr = null; 9191 cpi = null; 9192 } 9193 } 9194 } 9195 9196 boolean providerRunning = cpr != null; 9197 if (providerRunning) { 9198 cpi = cpr.info; 9199 String msg; 9200 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9201 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9202 != null) { 9203 throw new SecurityException(msg); 9204 } 9205 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9206 9207 if (r != null && cpr.canRunHere(r)) { 9208 // This provider has been published or is in the process 9209 // of being published... but it is also allowed to run 9210 // in the caller's process, so don't make a connection 9211 // and just let the caller instantiate its own instance. 9212 ContentProviderHolder holder = cpr.newHolder(null); 9213 // don't give caller the provider object, it needs 9214 // to make its own. 9215 holder.provider = null; 9216 return holder; 9217 } 9218 9219 final long origId = Binder.clearCallingIdentity(); 9220 9221 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9222 9223 // In this case the provider instance already exists, so we can 9224 // return it right away. 9225 conn = incProviderCountLocked(r, cpr, token, stable); 9226 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9227 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9228 // If this is a perceptible app accessing the provider, 9229 // make sure to count it as being accessed and thus 9230 // back up on the LRU list. This is good because 9231 // content providers are often expensive to start. 9232 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9233 updateLruProcessLocked(cpr.proc, false, null); 9234 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9235 } 9236 } 9237 9238 if (cpr.proc != null) { 9239 if (false) { 9240 if (cpr.name.flattenToShortString().equals( 9241 "com.android.providers.calendar/.CalendarProvider2")) { 9242 Slog.v(TAG, "****************** KILLING " 9243 + cpr.name.flattenToShortString()); 9244 Process.killProcess(cpr.proc.pid); 9245 } 9246 } 9247 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9248 boolean success = updateOomAdjLocked(cpr.proc); 9249 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9250 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9251 // NOTE: there is still a race here where a signal could be 9252 // pending on the process even though we managed to update its 9253 // adj level. Not sure what to do about this, but at least 9254 // the race is now smaller. 9255 if (!success) { 9256 // Uh oh... it looks like the provider's process 9257 // has been killed on us. We need to wait for a new 9258 // process to be started, and make sure its death 9259 // doesn't kill our process. 9260 Slog.i(TAG, 9261 "Existing provider " + cpr.name.flattenToShortString() 9262 + " is crashing; detaching " + r); 9263 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9264 checkTime(startTime, "getContentProviderImpl: before appDied"); 9265 appDiedLocked(cpr.proc); 9266 checkTime(startTime, "getContentProviderImpl: after appDied"); 9267 if (!lastRef) { 9268 // This wasn't the last ref our process had on 9269 // the provider... we have now been killed, bail. 9270 return null; 9271 } 9272 providerRunning = false; 9273 conn = null; 9274 } 9275 } 9276 9277 Binder.restoreCallingIdentity(origId); 9278 } 9279 9280 boolean singleton; 9281 if (!providerRunning) { 9282 try { 9283 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9284 cpi = AppGlobals.getPackageManager(). 9285 resolveContentProvider(name, 9286 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9287 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9288 } catch (RemoteException ex) { 9289 } 9290 if (cpi == null) { 9291 return null; 9292 } 9293 // If the provider is a singleton AND 9294 // (it's a call within the same user || the provider is a 9295 // privileged app) 9296 // Then allow connecting to the singleton provider 9297 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9298 cpi.name, cpi.flags) 9299 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9300 if (singleton) { 9301 userId = UserHandle.USER_OWNER; 9302 } 9303 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9304 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9305 9306 String msg; 9307 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9308 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9309 != null) { 9310 throw new SecurityException(msg); 9311 } 9312 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9313 9314 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9315 && !cpi.processName.equals("system")) { 9316 // If this content provider does not run in the system 9317 // process, and the system is not yet ready to run other 9318 // processes, then fail fast instead of hanging. 9319 throw new IllegalArgumentException( 9320 "Attempt to launch content provider before system ready"); 9321 } 9322 9323 // Make sure that the user who owns this provider is running. If not, 9324 // we don't want to allow it to run. 9325 if (!isUserRunningLocked(userId, false)) { 9326 Slog.w(TAG, "Unable to launch app " 9327 + cpi.applicationInfo.packageName + "/" 9328 + cpi.applicationInfo.uid + " for provider " 9329 + name + ": user " + userId + " is stopped"); 9330 return null; 9331 } 9332 9333 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9334 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9335 cpr = mProviderMap.getProviderByClass(comp, userId); 9336 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9337 final boolean firstClass = cpr == null; 9338 if (firstClass) { 9339 final long ident = Binder.clearCallingIdentity(); 9340 try { 9341 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9342 ApplicationInfo ai = 9343 AppGlobals.getPackageManager(). 9344 getApplicationInfo( 9345 cpi.applicationInfo.packageName, 9346 STOCK_PM_FLAGS, userId); 9347 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9348 if (ai == null) { 9349 Slog.w(TAG, "No package info for content provider " 9350 + cpi.name); 9351 return null; 9352 } 9353 ai = getAppInfoForUser(ai, userId); 9354 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9355 } catch (RemoteException ex) { 9356 // pm is in same process, this will never happen. 9357 } finally { 9358 Binder.restoreCallingIdentity(ident); 9359 } 9360 } 9361 9362 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9363 9364 if (r != null && cpr.canRunHere(r)) { 9365 // If this is a multiprocess provider, then just return its 9366 // info and allow the caller to instantiate it. Only do 9367 // this if the provider is the same user as the caller's 9368 // process, or can run as root (so can be in any process). 9369 return cpr.newHolder(null); 9370 } 9371 9372 if (DEBUG_PROVIDER) { 9373 RuntimeException e = new RuntimeException("here"); 9374 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9375 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9376 } 9377 9378 // This is single process, and our app is now connecting to it. 9379 // See if we are already in the process of launching this 9380 // provider. 9381 final int N = mLaunchingProviders.size(); 9382 int i; 9383 for (i=0; i<N; i++) { 9384 if (mLaunchingProviders.get(i) == cpr) { 9385 break; 9386 } 9387 } 9388 9389 // If the provider is not already being launched, then get it 9390 // started. 9391 if (i >= N) { 9392 final long origId = Binder.clearCallingIdentity(); 9393 9394 try { 9395 // Content provider is now in use, its package can't be stopped. 9396 try { 9397 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9398 AppGlobals.getPackageManager().setPackageStoppedState( 9399 cpr.appInfo.packageName, false, userId); 9400 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9401 } catch (RemoteException e) { 9402 } catch (IllegalArgumentException e) { 9403 Slog.w(TAG, "Failed trying to unstop package " 9404 + cpr.appInfo.packageName + ": " + e); 9405 } 9406 9407 // Use existing process if already started 9408 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9409 ProcessRecord proc = getProcessRecordLocked( 9410 cpi.processName, cpr.appInfo.uid, false); 9411 if (proc != null && proc.thread != null) { 9412 if (DEBUG_PROVIDER) { 9413 Slog.d(TAG, "Installing in existing process " + proc); 9414 } 9415 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9416 proc.pubProviders.put(cpi.name, cpr); 9417 try { 9418 proc.thread.scheduleInstallProvider(cpi); 9419 } catch (RemoteException e) { 9420 } 9421 } else { 9422 checkTime(startTime, "getContentProviderImpl: before start process"); 9423 proc = startProcessLocked(cpi.processName, 9424 cpr.appInfo, false, 0, "content provider", 9425 new ComponentName(cpi.applicationInfo.packageName, 9426 cpi.name), false, false, false); 9427 checkTime(startTime, "getContentProviderImpl: after start process"); 9428 if (proc == null) { 9429 Slog.w(TAG, "Unable to launch app " 9430 + cpi.applicationInfo.packageName + "/" 9431 + cpi.applicationInfo.uid + " for provider " 9432 + name + ": process is bad"); 9433 return null; 9434 } 9435 } 9436 cpr.launchingApp = proc; 9437 mLaunchingProviders.add(cpr); 9438 } finally { 9439 Binder.restoreCallingIdentity(origId); 9440 } 9441 } 9442 9443 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9444 9445 // Make sure the provider is published (the same provider class 9446 // may be published under multiple names). 9447 if (firstClass) { 9448 mProviderMap.putProviderByClass(comp, cpr); 9449 } 9450 9451 mProviderMap.putProviderByName(name, cpr); 9452 conn = incProviderCountLocked(r, cpr, token, stable); 9453 if (conn != null) { 9454 conn.waiting = true; 9455 } 9456 } 9457 checkTime(startTime, "getContentProviderImpl: done!"); 9458 } 9459 9460 // Wait for the provider to be published... 9461 synchronized (cpr) { 9462 while (cpr.provider == null) { 9463 if (cpr.launchingApp == null) { 9464 Slog.w(TAG, "Unable to launch app " 9465 + cpi.applicationInfo.packageName + "/" 9466 + cpi.applicationInfo.uid + " for provider " 9467 + name + ": launching app became null"); 9468 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9469 UserHandle.getUserId(cpi.applicationInfo.uid), 9470 cpi.applicationInfo.packageName, 9471 cpi.applicationInfo.uid, name); 9472 return null; 9473 } 9474 try { 9475 if (DEBUG_MU) { 9476 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9477 + cpr.launchingApp); 9478 } 9479 if (conn != null) { 9480 conn.waiting = true; 9481 } 9482 cpr.wait(); 9483 } catch (InterruptedException ex) { 9484 } finally { 9485 if (conn != null) { 9486 conn.waiting = false; 9487 } 9488 } 9489 } 9490 } 9491 return cpr != null ? cpr.newHolder(conn) : null; 9492 } 9493 9494 @Override 9495 public final ContentProviderHolder getContentProvider( 9496 IApplicationThread caller, String name, int userId, boolean stable) { 9497 enforceNotIsolatedCaller("getContentProvider"); 9498 if (caller == null) { 9499 String msg = "null IApplicationThread when getting content provider " 9500 + name; 9501 Slog.w(TAG, msg); 9502 throw new SecurityException(msg); 9503 } 9504 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9505 // with cross-user grant. 9506 return getContentProviderImpl(caller, name, null, stable, userId); 9507 } 9508 9509 public ContentProviderHolder getContentProviderExternal( 9510 String name, int userId, IBinder token) { 9511 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9512 "Do not have permission in call getContentProviderExternal()"); 9513 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9514 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9515 return getContentProviderExternalUnchecked(name, token, userId); 9516 } 9517 9518 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9519 IBinder token, int userId) { 9520 return getContentProviderImpl(null, name, token, true, userId); 9521 } 9522 9523 /** 9524 * Drop a content provider from a ProcessRecord's bookkeeping 9525 */ 9526 public void removeContentProvider(IBinder connection, boolean stable) { 9527 enforceNotIsolatedCaller("removeContentProvider"); 9528 long ident = Binder.clearCallingIdentity(); 9529 try { 9530 synchronized (this) { 9531 ContentProviderConnection conn; 9532 try { 9533 conn = (ContentProviderConnection)connection; 9534 } catch (ClassCastException e) { 9535 String msg ="removeContentProvider: " + connection 9536 + " not a ContentProviderConnection"; 9537 Slog.w(TAG, msg); 9538 throw new IllegalArgumentException(msg); 9539 } 9540 if (conn == null) { 9541 throw new NullPointerException("connection is null"); 9542 } 9543 if (decProviderCountLocked(conn, null, null, stable)) { 9544 updateOomAdjLocked(); 9545 } 9546 } 9547 } finally { 9548 Binder.restoreCallingIdentity(ident); 9549 } 9550 } 9551 9552 public void removeContentProviderExternal(String name, IBinder token) { 9553 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9554 "Do not have permission in call removeContentProviderExternal()"); 9555 int userId = UserHandle.getCallingUserId(); 9556 long ident = Binder.clearCallingIdentity(); 9557 try { 9558 removeContentProviderExternalUnchecked(name, token, userId); 9559 } finally { 9560 Binder.restoreCallingIdentity(ident); 9561 } 9562 } 9563 9564 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9565 synchronized (this) { 9566 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9567 if(cpr == null) { 9568 //remove from mProvidersByClass 9569 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9570 return; 9571 } 9572 9573 //update content provider record entry info 9574 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9575 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9576 if (localCpr.hasExternalProcessHandles()) { 9577 if (localCpr.removeExternalProcessHandleLocked(token)) { 9578 updateOomAdjLocked(); 9579 } else { 9580 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9581 + " with no external reference for token: " 9582 + token + "."); 9583 } 9584 } else { 9585 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9586 + " with no external references."); 9587 } 9588 } 9589 } 9590 9591 public final void publishContentProviders(IApplicationThread caller, 9592 List<ContentProviderHolder> providers) { 9593 if (providers == null) { 9594 return; 9595 } 9596 9597 enforceNotIsolatedCaller("publishContentProviders"); 9598 synchronized (this) { 9599 final ProcessRecord r = getRecordForAppLocked(caller); 9600 if (DEBUG_MU) 9601 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9602 if (r == null) { 9603 throw new SecurityException( 9604 "Unable to find app for caller " + caller 9605 + " (pid=" + Binder.getCallingPid() 9606 + ") when publishing content providers"); 9607 } 9608 9609 final long origId = Binder.clearCallingIdentity(); 9610 9611 final int N = providers.size(); 9612 for (int i=0; i<N; i++) { 9613 ContentProviderHolder src = providers.get(i); 9614 if (src == null || src.info == null || src.provider == null) { 9615 continue; 9616 } 9617 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9618 if (DEBUG_MU) 9619 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9620 if (dst != null) { 9621 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9622 mProviderMap.putProviderByClass(comp, dst); 9623 String names[] = dst.info.authority.split(";"); 9624 for (int j = 0; j < names.length; j++) { 9625 mProviderMap.putProviderByName(names[j], dst); 9626 } 9627 9628 int NL = mLaunchingProviders.size(); 9629 int j; 9630 for (j=0; j<NL; j++) { 9631 if (mLaunchingProviders.get(j) == dst) { 9632 mLaunchingProviders.remove(j); 9633 j--; 9634 NL--; 9635 } 9636 } 9637 synchronized (dst) { 9638 dst.provider = src.provider; 9639 dst.proc = r; 9640 dst.notifyAll(); 9641 } 9642 updateOomAdjLocked(r); 9643 } 9644 } 9645 9646 Binder.restoreCallingIdentity(origId); 9647 } 9648 } 9649 9650 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9651 ContentProviderConnection conn; 9652 try { 9653 conn = (ContentProviderConnection)connection; 9654 } catch (ClassCastException e) { 9655 String msg ="refContentProvider: " + connection 9656 + " not a ContentProviderConnection"; 9657 Slog.w(TAG, msg); 9658 throw new IllegalArgumentException(msg); 9659 } 9660 if (conn == null) { 9661 throw new NullPointerException("connection is null"); 9662 } 9663 9664 synchronized (this) { 9665 if (stable > 0) { 9666 conn.numStableIncs += stable; 9667 } 9668 stable = conn.stableCount + stable; 9669 if (stable < 0) { 9670 throw new IllegalStateException("stableCount < 0: " + stable); 9671 } 9672 9673 if (unstable > 0) { 9674 conn.numUnstableIncs += unstable; 9675 } 9676 unstable = conn.unstableCount + unstable; 9677 if (unstable < 0) { 9678 throw new IllegalStateException("unstableCount < 0: " + unstable); 9679 } 9680 9681 if ((stable+unstable) <= 0) { 9682 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9683 + stable + " unstable=" + unstable); 9684 } 9685 conn.stableCount = stable; 9686 conn.unstableCount = unstable; 9687 return !conn.dead; 9688 } 9689 } 9690 9691 public void unstableProviderDied(IBinder connection) { 9692 ContentProviderConnection conn; 9693 try { 9694 conn = (ContentProviderConnection)connection; 9695 } catch (ClassCastException e) { 9696 String msg ="refContentProvider: " + connection 9697 + " not a ContentProviderConnection"; 9698 Slog.w(TAG, msg); 9699 throw new IllegalArgumentException(msg); 9700 } 9701 if (conn == null) { 9702 throw new NullPointerException("connection is null"); 9703 } 9704 9705 // Safely retrieve the content provider associated with the connection. 9706 IContentProvider provider; 9707 synchronized (this) { 9708 provider = conn.provider.provider; 9709 } 9710 9711 if (provider == null) { 9712 // Um, yeah, we're way ahead of you. 9713 return; 9714 } 9715 9716 // Make sure the caller is being honest with us. 9717 if (provider.asBinder().pingBinder()) { 9718 // Er, no, still looks good to us. 9719 synchronized (this) { 9720 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9721 + " says " + conn + " died, but we don't agree"); 9722 return; 9723 } 9724 } 9725 9726 // Well look at that! It's dead! 9727 synchronized (this) { 9728 if (conn.provider.provider != provider) { 9729 // But something changed... good enough. 9730 return; 9731 } 9732 9733 ProcessRecord proc = conn.provider.proc; 9734 if (proc == null || proc.thread == null) { 9735 // Seems like the process is already cleaned up. 9736 return; 9737 } 9738 9739 // As far as we're concerned, this is just like receiving a 9740 // death notification... just a bit prematurely. 9741 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9742 + ") early provider death"); 9743 final long ident = Binder.clearCallingIdentity(); 9744 try { 9745 appDiedLocked(proc); 9746 } finally { 9747 Binder.restoreCallingIdentity(ident); 9748 } 9749 } 9750 } 9751 9752 @Override 9753 public void appNotRespondingViaProvider(IBinder connection) { 9754 enforceCallingPermission( 9755 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9756 9757 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9758 if (conn == null) { 9759 Slog.w(TAG, "ContentProviderConnection is null"); 9760 return; 9761 } 9762 9763 final ProcessRecord host = conn.provider.proc; 9764 if (host == null) { 9765 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9766 return; 9767 } 9768 9769 final long token = Binder.clearCallingIdentity(); 9770 try { 9771 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9772 } finally { 9773 Binder.restoreCallingIdentity(token); 9774 } 9775 } 9776 9777 public final void installSystemProviders() { 9778 List<ProviderInfo> providers; 9779 synchronized (this) { 9780 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9781 providers = generateApplicationProvidersLocked(app); 9782 if (providers != null) { 9783 for (int i=providers.size()-1; i>=0; i--) { 9784 ProviderInfo pi = (ProviderInfo)providers.get(i); 9785 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9786 Slog.w(TAG, "Not installing system proc provider " + pi.name 9787 + ": not system .apk"); 9788 providers.remove(i); 9789 } 9790 } 9791 } 9792 } 9793 if (providers != null) { 9794 mSystemThread.installSystemProviders(providers); 9795 } 9796 9797 mCoreSettingsObserver = new CoreSettingsObserver(this); 9798 9799 //mUsageStatsService.monitorPackages(); 9800 } 9801 9802 /** 9803 * Allows apps to retrieve the MIME type of a URI. 9804 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9805 * users, then it does not need permission to access the ContentProvider. 9806 * Either, it needs cross-user uri grants. 9807 * 9808 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9809 * 9810 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9811 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9812 */ 9813 public String getProviderMimeType(Uri uri, int userId) { 9814 enforceNotIsolatedCaller("getProviderMimeType"); 9815 final String name = uri.getAuthority(); 9816 int callingUid = Binder.getCallingUid(); 9817 int callingPid = Binder.getCallingPid(); 9818 long ident = 0; 9819 boolean clearedIdentity = false; 9820 userId = unsafeConvertIncomingUser(userId); 9821 if (canClearIdentity(callingPid, callingUid, userId)) { 9822 clearedIdentity = true; 9823 ident = Binder.clearCallingIdentity(); 9824 } 9825 ContentProviderHolder holder = null; 9826 try { 9827 holder = getContentProviderExternalUnchecked(name, null, userId); 9828 if (holder != null) { 9829 return holder.provider.getType(uri); 9830 } 9831 } catch (RemoteException e) { 9832 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9833 return null; 9834 } finally { 9835 // We need to clear the identity to call removeContentProviderExternalUnchecked 9836 if (!clearedIdentity) { 9837 ident = Binder.clearCallingIdentity(); 9838 } 9839 try { 9840 if (holder != null) { 9841 removeContentProviderExternalUnchecked(name, null, userId); 9842 } 9843 } finally { 9844 Binder.restoreCallingIdentity(ident); 9845 } 9846 } 9847 9848 return null; 9849 } 9850 9851 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9852 if (UserHandle.getUserId(callingUid) == userId) { 9853 return true; 9854 } 9855 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9856 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9857 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9858 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9859 return true; 9860 } 9861 return false; 9862 } 9863 9864 // ========================================================= 9865 // GLOBAL MANAGEMENT 9866 // ========================================================= 9867 9868 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9869 boolean isolated, int isolatedUid) { 9870 String proc = customProcess != null ? customProcess : info.processName; 9871 BatteryStatsImpl.Uid.Proc ps = null; 9872 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9873 int uid = info.uid; 9874 if (isolated) { 9875 if (isolatedUid == 0) { 9876 int userId = UserHandle.getUserId(uid); 9877 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9878 while (true) { 9879 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9880 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9881 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9882 } 9883 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9884 mNextIsolatedProcessUid++; 9885 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9886 // No process for this uid, use it. 9887 break; 9888 } 9889 stepsLeft--; 9890 if (stepsLeft <= 0) { 9891 return null; 9892 } 9893 } 9894 } else { 9895 // Special case for startIsolatedProcess (internal only), where 9896 // the uid of the isolated process is specified by the caller. 9897 uid = isolatedUid; 9898 } 9899 } 9900 return new ProcessRecord(stats, info, proc, uid); 9901 } 9902 9903 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9904 String abiOverride) { 9905 ProcessRecord app; 9906 if (!isolated) { 9907 app = getProcessRecordLocked(info.processName, info.uid, true); 9908 } else { 9909 app = null; 9910 } 9911 9912 if (app == null) { 9913 app = newProcessRecordLocked(info, null, isolated, 0); 9914 mProcessNames.put(info.processName, app.uid, app); 9915 if (isolated) { 9916 mIsolatedProcesses.put(app.uid, app); 9917 } 9918 updateLruProcessLocked(app, false, null); 9919 updateOomAdjLocked(); 9920 } 9921 9922 // This package really, really can not be stopped. 9923 try { 9924 AppGlobals.getPackageManager().setPackageStoppedState( 9925 info.packageName, false, UserHandle.getUserId(app.uid)); 9926 } catch (RemoteException e) { 9927 } catch (IllegalArgumentException e) { 9928 Slog.w(TAG, "Failed trying to unstop package " 9929 + info.packageName + ": " + e); 9930 } 9931 9932 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9933 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9934 app.persistent = true; 9935 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9936 } 9937 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9938 mPersistentStartingProcesses.add(app); 9939 startProcessLocked(app, "added application", app.processName, abiOverride, 9940 null /* entryPoint */, null /* entryPointArgs */); 9941 } 9942 9943 return app; 9944 } 9945 9946 public void unhandledBack() { 9947 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9948 "unhandledBack()"); 9949 9950 synchronized(this) { 9951 final long origId = Binder.clearCallingIdentity(); 9952 try { 9953 getFocusedStack().unhandledBackLocked(); 9954 } finally { 9955 Binder.restoreCallingIdentity(origId); 9956 } 9957 } 9958 } 9959 9960 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9961 enforceNotIsolatedCaller("openContentUri"); 9962 final int userId = UserHandle.getCallingUserId(); 9963 String name = uri.getAuthority(); 9964 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9965 ParcelFileDescriptor pfd = null; 9966 if (cph != null) { 9967 // We record the binder invoker's uid in thread-local storage before 9968 // going to the content provider to open the file. Later, in the code 9969 // that handles all permissions checks, we look for this uid and use 9970 // that rather than the Activity Manager's own uid. The effect is that 9971 // we do the check against the caller's permissions even though it looks 9972 // to the content provider like the Activity Manager itself is making 9973 // the request. 9974 Binder token = new Binder(); 9975 sCallerIdentity.set(new Identity( 9976 token, Binder.getCallingPid(), Binder.getCallingUid())); 9977 try { 9978 pfd = cph.provider.openFile(null, uri, "r", null, token); 9979 } catch (FileNotFoundException e) { 9980 // do nothing; pfd will be returned null 9981 } finally { 9982 // Ensure that whatever happens, we clean up the identity state 9983 sCallerIdentity.remove(); 9984 } 9985 9986 // We've got the fd now, so we're done with the provider. 9987 removeContentProviderExternalUnchecked(name, null, userId); 9988 } else { 9989 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9990 } 9991 return pfd; 9992 } 9993 9994 // Actually is sleeping or shutting down or whatever else in the future 9995 // is an inactive state. 9996 public boolean isSleepingOrShuttingDown() { 9997 return isSleeping() || mShuttingDown; 9998 } 9999 10000 public boolean isSleeping() { 10001 return mSleeping; 10002 } 10003 10004 void onWakefulnessChanged(int wakefulness) { 10005 synchronized(this) { 10006 mWakefulness = wakefulness; 10007 updateSleepIfNeededLocked(); 10008 } 10009 } 10010 10011 void finishRunningVoiceLocked() { 10012 if (mRunningVoice) { 10013 mRunningVoice = false; 10014 updateSleepIfNeededLocked(); 10015 } 10016 } 10017 10018 void updateSleepIfNeededLocked() { 10019 if (mSleeping && !shouldSleepLocked()) { 10020 mSleeping = false; 10021 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10022 } else if (!mSleeping && shouldSleepLocked()) { 10023 mSleeping = true; 10024 mStackSupervisor.goingToSleepLocked(); 10025 10026 // Initialize the wake times of all processes. 10027 checkExcessivePowerUsageLocked(false); 10028 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10029 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10030 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10031 } 10032 } 10033 10034 private boolean shouldSleepLocked() { 10035 // Resume applications while running a voice interactor. 10036 if (mRunningVoice) { 10037 return false; 10038 } 10039 10040 switch (mWakefulness) { 10041 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10042 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10043 // If we're interactive but applications are already paused then defer 10044 // resuming them until the lock screen is hidden. 10045 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10046 case PowerManagerInternal.WAKEFULNESS_DOZING: 10047 // If we're dozing then pause applications whenever the lock screen is shown. 10048 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10049 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10050 default: 10051 // If we're asleep then pause applications unconditionally. 10052 return true; 10053 } 10054 } 10055 10056 /** Pokes the task persister. */ 10057 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10058 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10059 // Never persist the home stack. 10060 return; 10061 } 10062 mTaskPersister.wakeup(task, flush); 10063 } 10064 10065 /** Notifies all listeners when the task stack has changed. */ 10066 void notifyTaskStackChangedLocked() { 10067 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10068 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10069 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10070 } 10071 10072 @Override 10073 public boolean shutdown(int timeout) { 10074 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10075 != PackageManager.PERMISSION_GRANTED) { 10076 throw new SecurityException("Requires permission " 10077 + android.Manifest.permission.SHUTDOWN); 10078 } 10079 10080 boolean timedout = false; 10081 10082 synchronized(this) { 10083 mShuttingDown = true; 10084 updateEventDispatchingLocked(); 10085 timedout = mStackSupervisor.shutdownLocked(timeout); 10086 } 10087 10088 mAppOpsService.shutdown(); 10089 if (mUsageStatsService != null) { 10090 mUsageStatsService.prepareShutdown(); 10091 } 10092 mBatteryStatsService.shutdown(); 10093 synchronized (this) { 10094 mProcessStats.shutdownLocked(); 10095 notifyTaskPersisterLocked(null, true); 10096 } 10097 10098 return timedout; 10099 } 10100 10101 public final void activitySlept(IBinder token) { 10102 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10103 10104 final long origId = Binder.clearCallingIdentity(); 10105 10106 synchronized (this) { 10107 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10108 if (r != null) { 10109 mStackSupervisor.activitySleptLocked(r); 10110 } 10111 } 10112 10113 Binder.restoreCallingIdentity(origId); 10114 } 10115 10116 private String lockScreenShownToString() { 10117 switch (mLockScreenShown) { 10118 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10119 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10120 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10121 default: return "Unknown=" + mLockScreenShown; 10122 } 10123 } 10124 10125 void logLockScreen(String msg) { 10126 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10127 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10128 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10129 + " mSleeping=" + mSleeping); 10130 } 10131 10132 void startRunningVoiceLocked() { 10133 if (!mRunningVoice) { 10134 mRunningVoice = true; 10135 updateSleepIfNeededLocked(); 10136 } 10137 } 10138 10139 private void updateEventDispatchingLocked() { 10140 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10141 } 10142 10143 public void setLockScreenShown(boolean shown) { 10144 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10145 != PackageManager.PERMISSION_GRANTED) { 10146 throw new SecurityException("Requires permission " 10147 + android.Manifest.permission.DEVICE_POWER); 10148 } 10149 10150 synchronized(this) { 10151 long ident = Binder.clearCallingIdentity(); 10152 try { 10153 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10154 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10155 updateSleepIfNeededLocked(); 10156 } finally { 10157 Binder.restoreCallingIdentity(ident); 10158 } 10159 } 10160 } 10161 10162 @Override 10163 public void stopAppSwitches() { 10164 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10165 != PackageManager.PERMISSION_GRANTED) { 10166 throw new SecurityException("Requires permission " 10167 + android.Manifest.permission.STOP_APP_SWITCHES); 10168 } 10169 10170 synchronized(this) { 10171 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10172 + APP_SWITCH_DELAY_TIME; 10173 mDidAppSwitch = false; 10174 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10175 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10176 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10177 } 10178 } 10179 10180 public void resumeAppSwitches() { 10181 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10182 != PackageManager.PERMISSION_GRANTED) { 10183 throw new SecurityException("Requires permission " 10184 + android.Manifest.permission.STOP_APP_SWITCHES); 10185 } 10186 10187 synchronized(this) { 10188 // Note that we don't execute any pending app switches... we will 10189 // let those wait until either the timeout, or the next start 10190 // activity request. 10191 mAppSwitchesAllowedTime = 0; 10192 } 10193 } 10194 10195 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10196 int callingPid, int callingUid, String name) { 10197 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10198 return true; 10199 } 10200 10201 int perm = checkComponentPermission( 10202 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10203 sourceUid, -1, true); 10204 if (perm == PackageManager.PERMISSION_GRANTED) { 10205 return true; 10206 } 10207 10208 // If the actual IPC caller is different from the logical source, then 10209 // also see if they are allowed to control app switches. 10210 if (callingUid != -1 && callingUid != sourceUid) { 10211 perm = checkComponentPermission( 10212 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10213 callingUid, -1, true); 10214 if (perm == PackageManager.PERMISSION_GRANTED) { 10215 return true; 10216 } 10217 } 10218 10219 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10220 return false; 10221 } 10222 10223 public void setDebugApp(String packageName, boolean waitForDebugger, 10224 boolean persistent) { 10225 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10226 "setDebugApp()"); 10227 10228 long ident = Binder.clearCallingIdentity(); 10229 try { 10230 // Note that this is not really thread safe if there are multiple 10231 // callers into it at the same time, but that's not a situation we 10232 // care about. 10233 if (persistent) { 10234 final ContentResolver resolver = mContext.getContentResolver(); 10235 Settings.Global.putString( 10236 resolver, Settings.Global.DEBUG_APP, 10237 packageName); 10238 Settings.Global.putInt( 10239 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10240 waitForDebugger ? 1 : 0); 10241 } 10242 10243 synchronized (this) { 10244 if (!persistent) { 10245 mOrigDebugApp = mDebugApp; 10246 mOrigWaitForDebugger = mWaitForDebugger; 10247 } 10248 mDebugApp = packageName; 10249 mWaitForDebugger = waitForDebugger; 10250 mDebugTransient = !persistent; 10251 if (packageName != null) { 10252 forceStopPackageLocked(packageName, -1, false, false, true, true, 10253 false, UserHandle.USER_ALL, "set debug app"); 10254 } 10255 } 10256 } finally { 10257 Binder.restoreCallingIdentity(ident); 10258 } 10259 } 10260 10261 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10262 synchronized (this) { 10263 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10264 if (!isDebuggable) { 10265 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10266 throw new SecurityException("Process not debuggable: " + app.packageName); 10267 } 10268 } 10269 10270 mOpenGlTraceApp = processName; 10271 } 10272 } 10273 10274 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10275 synchronized (this) { 10276 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10277 if (!isDebuggable) { 10278 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10279 throw new SecurityException("Process not debuggable: " + app.packageName); 10280 } 10281 } 10282 mProfileApp = processName; 10283 mProfileFile = profilerInfo.profileFile; 10284 if (mProfileFd != null) { 10285 try { 10286 mProfileFd.close(); 10287 } catch (IOException e) { 10288 } 10289 mProfileFd = null; 10290 } 10291 mProfileFd = profilerInfo.profileFd; 10292 mSamplingInterval = profilerInfo.samplingInterval; 10293 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10294 mProfileType = 0; 10295 } 10296 } 10297 10298 @Override 10299 public void setAlwaysFinish(boolean enabled) { 10300 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10301 "setAlwaysFinish()"); 10302 10303 Settings.Global.putInt( 10304 mContext.getContentResolver(), 10305 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10306 10307 synchronized (this) { 10308 mAlwaysFinishActivities = enabled; 10309 } 10310 } 10311 10312 @Override 10313 public void setActivityController(IActivityController controller) { 10314 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10315 "setActivityController()"); 10316 synchronized (this) { 10317 mController = controller; 10318 Watchdog.getInstance().setActivityController(controller); 10319 } 10320 } 10321 10322 @Override 10323 public void setUserIsMonkey(boolean userIsMonkey) { 10324 synchronized (this) { 10325 synchronized (mPidsSelfLocked) { 10326 final int callingPid = Binder.getCallingPid(); 10327 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10328 if (precessRecord == null) { 10329 throw new SecurityException("Unknown process: " + callingPid); 10330 } 10331 if (precessRecord.instrumentationUiAutomationConnection == null) { 10332 throw new SecurityException("Only an instrumentation process " 10333 + "with a UiAutomation can call setUserIsMonkey"); 10334 } 10335 } 10336 mUserIsMonkey = userIsMonkey; 10337 } 10338 } 10339 10340 @Override 10341 public boolean isUserAMonkey() { 10342 synchronized (this) { 10343 // If there is a controller also implies the user is a monkey. 10344 return (mUserIsMonkey || mController != null); 10345 } 10346 } 10347 10348 public void requestBugReport() { 10349 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10350 SystemProperties.set("ctl.start", "bugreport"); 10351 } 10352 10353 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10354 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10355 } 10356 10357 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10358 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10359 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10360 } 10361 return KEY_DISPATCHING_TIMEOUT; 10362 } 10363 10364 @Override 10365 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10366 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10367 != PackageManager.PERMISSION_GRANTED) { 10368 throw new SecurityException("Requires permission " 10369 + android.Manifest.permission.FILTER_EVENTS); 10370 } 10371 ProcessRecord proc; 10372 long timeout; 10373 synchronized (this) { 10374 synchronized (mPidsSelfLocked) { 10375 proc = mPidsSelfLocked.get(pid); 10376 } 10377 timeout = getInputDispatchingTimeoutLocked(proc); 10378 } 10379 10380 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10381 return -1; 10382 } 10383 10384 return timeout; 10385 } 10386 10387 /** 10388 * Handle input dispatching timeouts. 10389 * Returns whether input dispatching should be aborted or not. 10390 */ 10391 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10392 final ActivityRecord activity, final ActivityRecord parent, 10393 final boolean aboveSystem, String reason) { 10394 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10395 != PackageManager.PERMISSION_GRANTED) { 10396 throw new SecurityException("Requires permission " 10397 + android.Manifest.permission.FILTER_EVENTS); 10398 } 10399 10400 final String annotation; 10401 if (reason == null) { 10402 annotation = "Input dispatching timed out"; 10403 } else { 10404 annotation = "Input dispatching timed out (" + reason + ")"; 10405 } 10406 10407 if (proc != null) { 10408 synchronized (this) { 10409 if (proc.debugging) { 10410 return false; 10411 } 10412 10413 if (mDidDexOpt) { 10414 // Give more time since we were dexopting. 10415 mDidDexOpt = false; 10416 return false; 10417 } 10418 10419 if (proc.instrumentationClass != null) { 10420 Bundle info = new Bundle(); 10421 info.putString("shortMsg", "keyDispatchingTimedOut"); 10422 info.putString("longMsg", annotation); 10423 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10424 return true; 10425 } 10426 } 10427 mHandler.post(new Runnable() { 10428 @Override 10429 public void run() { 10430 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10431 } 10432 }); 10433 } 10434 10435 return true; 10436 } 10437 10438 public Bundle getAssistContextExtras(int requestType) { 10439 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10440 UserHandle.getCallingUserId()); 10441 if (pae == null) { 10442 return null; 10443 } 10444 synchronized (pae) { 10445 while (!pae.haveResult) { 10446 try { 10447 pae.wait(); 10448 } catch (InterruptedException e) { 10449 } 10450 } 10451 if (pae.result != null) { 10452 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10453 } 10454 } 10455 synchronized (this) { 10456 mPendingAssistExtras.remove(pae); 10457 mHandler.removeCallbacks(pae); 10458 } 10459 return pae.extras; 10460 } 10461 10462 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10463 int userHandle) { 10464 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10465 "getAssistContextExtras()"); 10466 PendingAssistExtras pae; 10467 Bundle extras = new Bundle(); 10468 synchronized (this) { 10469 ActivityRecord activity = getFocusedStack().mResumedActivity; 10470 if (activity == null) { 10471 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10472 return null; 10473 } 10474 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10475 if (activity.app == null || activity.app.thread == null) { 10476 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10477 return null; 10478 } 10479 if (activity.app.pid == Binder.getCallingPid()) { 10480 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10481 return null; 10482 } 10483 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10484 try { 10485 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10486 requestType); 10487 mPendingAssistExtras.add(pae); 10488 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10489 } catch (RemoteException e) { 10490 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10491 return null; 10492 } 10493 return pae; 10494 } 10495 } 10496 10497 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10498 PendingAssistExtras pae = (PendingAssistExtras)token; 10499 synchronized (pae) { 10500 pae.result = extras; 10501 pae.haveResult = true; 10502 pae.notifyAll(); 10503 if (pae.intent == null) { 10504 // Caller is just waiting for the result. 10505 return; 10506 } 10507 } 10508 10509 // We are now ready to launch the assist activity. 10510 synchronized (this) { 10511 boolean exists = mPendingAssistExtras.remove(pae); 10512 mHandler.removeCallbacks(pae); 10513 if (!exists) { 10514 // Timed out. 10515 return; 10516 } 10517 } 10518 pae.intent.replaceExtras(extras); 10519 if (pae.hint != null) { 10520 pae.intent.putExtra(pae.hint, true); 10521 } 10522 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10523 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10524 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10525 closeSystemDialogs("assist"); 10526 try { 10527 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10528 } catch (ActivityNotFoundException e) { 10529 Slog.w(TAG, "No activity to handle assist action.", e); 10530 } 10531 } 10532 10533 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10534 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10535 } 10536 10537 public void registerProcessObserver(IProcessObserver observer) { 10538 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10539 "registerProcessObserver()"); 10540 synchronized (this) { 10541 mProcessObservers.register(observer); 10542 } 10543 } 10544 10545 @Override 10546 public void unregisterProcessObserver(IProcessObserver observer) { 10547 synchronized (this) { 10548 mProcessObservers.unregister(observer); 10549 } 10550 } 10551 10552 @Override 10553 public boolean convertFromTranslucent(IBinder token) { 10554 final long origId = Binder.clearCallingIdentity(); 10555 try { 10556 synchronized (this) { 10557 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10558 if (r == null) { 10559 return false; 10560 } 10561 final boolean translucentChanged = r.changeWindowTranslucency(true); 10562 if (translucentChanged) { 10563 r.task.stack.releaseBackgroundResources(); 10564 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10565 } 10566 mWindowManager.setAppFullscreen(token, true); 10567 return translucentChanged; 10568 } 10569 } finally { 10570 Binder.restoreCallingIdentity(origId); 10571 } 10572 } 10573 10574 @Override 10575 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10576 final long origId = Binder.clearCallingIdentity(); 10577 try { 10578 synchronized (this) { 10579 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10580 if (r == null) { 10581 return false; 10582 } 10583 int index = r.task.mActivities.lastIndexOf(r); 10584 if (index > 0) { 10585 ActivityRecord under = r.task.mActivities.get(index - 1); 10586 under.returningOptions = options; 10587 } 10588 final boolean translucentChanged = r.changeWindowTranslucency(false); 10589 if (translucentChanged) { 10590 r.task.stack.convertToTranslucent(r); 10591 } 10592 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10593 mWindowManager.setAppFullscreen(token, false); 10594 return translucentChanged; 10595 } 10596 } finally { 10597 Binder.restoreCallingIdentity(origId); 10598 } 10599 } 10600 10601 @Override 10602 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10603 final long origId = Binder.clearCallingIdentity(); 10604 try { 10605 synchronized (this) { 10606 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10607 if (r != null) { 10608 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10609 } 10610 } 10611 return false; 10612 } finally { 10613 Binder.restoreCallingIdentity(origId); 10614 } 10615 } 10616 10617 @Override 10618 public boolean isBackgroundVisibleBehind(IBinder token) { 10619 final long origId = Binder.clearCallingIdentity(); 10620 try { 10621 synchronized (this) { 10622 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10623 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10624 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10625 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10626 return visible; 10627 } 10628 } finally { 10629 Binder.restoreCallingIdentity(origId); 10630 } 10631 } 10632 10633 @Override 10634 public ActivityOptions getActivityOptions(IBinder token) { 10635 final long origId = Binder.clearCallingIdentity(); 10636 try { 10637 synchronized (this) { 10638 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10639 if (r != null) { 10640 final ActivityOptions activityOptions = r.pendingOptions; 10641 r.pendingOptions = null; 10642 return activityOptions; 10643 } 10644 return null; 10645 } 10646 } finally { 10647 Binder.restoreCallingIdentity(origId); 10648 } 10649 } 10650 10651 @Override 10652 public void setImmersive(IBinder token, boolean immersive) { 10653 synchronized(this) { 10654 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10655 if (r == null) { 10656 throw new IllegalArgumentException(); 10657 } 10658 r.immersive = immersive; 10659 10660 // update associated state if we're frontmost 10661 if (r == mFocusedActivity) { 10662 if (DEBUG_IMMERSIVE) { 10663 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10664 } 10665 applyUpdateLockStateLocked(r); 10666 } 10667 } 10668 } 10669 10670 @Override 10671 public boolean isImmersive(IBinder token) { 10672 synchronized (this) { 10673 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10674 if (r == null) { 10675 throw new IllegalArgumentException(); 10676 } 10677 return r.immersive; 10678 } 10679 } 10680 10681 public boolean isTopActivityImmersive() { 10682 enforceNotIsolatedCaller("startActivity"); 10683 synchronized (this) { 10684 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10685 return (r != null) ? r.immersive : false; 10686 } 10687 } 10688 10689 @Override 10690 public boolean isTopOfTask(IBinder token) { 10691 synchronized (this) { 10692 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10693 if (r == null) { 10694 throw new IllegalArgumentException(); 10695 } 10696 return r.task.getTopActivity() == r; 10697 } 10698 } 10699 10700 public final void enterSafeMode() { 10701 synchronized(this) { 10702 // It only makes sense to do this before the system is ready 10703 // and started launching other packages. 10704 if (!mSystemReady) { 10705 try { 10706 AppGlobals.getPackageManager().enterSafeMode(); 10707 } catch (RemoteException e) { 10708 } 10709 } 10710 10711 mSafeMode = true; 10712 } 10713 } 10714 10715 public final void showSafeModeOverlay() { 10716 View v = LayoutInflater.from(mContext).inflate( 10717 com.android.internal.R.layout.safe_mode, null); 10718 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10719 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10720 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10721 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10722 lp.gravity = Gravity.BOTTOM | Gravity.START; 10723 lp.format = v.getBackground().getOpacity(); 10724 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10725 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10726 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10727 ((WindowManager)mContext.getSystemService( 10728 Context.WINDOW_SERVICE)).addView(v, lp); 10729 } 10730 10731 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10732 if (!(sender instanceof PendingIntentRecord)) { 10733 return; 10734 } 10735 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10736 synchronized (stats) { 10737 if (mBatteryStatsService.isOnBattery()) { 10738 mBatteryStatsService.enforceCallingPermission(); 10739 PendingIntentRecord rec = (PendingIntentRecord)sender; 10740 int MY_UID = Binder.getCallingUid(); 10741 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10742 BatteryStatsImpl.Uid.Pkg pkg = 10743 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10744 sourcePkg != null ? sourcePkg : rec.key.packageName); 10745 pkg.incWakeupsLocked(); 10746 } 10747 } 10748 } 10749 10750 public boolean killPids(int[] pids, String pReason, boolean secure) { 10751 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10752 throw new SecurityException("killPids only available to the system"); 10753 } 10754 String reason = (pReason == null) ? "Unknown" : pReason; 10755 // XXX Note: don't acquire main activity lock here, because the window 10756 // manager calls in with its locks held. 10757 10758 boolean killed = false; 10759 synchronized (mPidsSelfLocked) { 10760 int[] types = new int[pids.length]; 10761 int worstType = 0; 10762 for (int i=0; i<pids.length; i++) { 10763 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10764 if (proc != null) { 10765 int type = proc.setAdj; 10766 types[i] = type; 10767 if (type > worstType) { 10768 worstType = type; 10769 } 10770 } 10771 } 10772 10773 // If the worst oom_adj is somewhere in the cached proc LRU range, 10774 // then constrain it so we will kill all cached procs. 10775 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10776 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10777 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10778 } 10779 10780 // If this is not a secure call, don't let it kill processes that 10781 // are important. 10782 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10783 worstType = ProcessList.SERVICE_ADJ; 10784 } 10785 10786 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10787 for (int i=0; i<pids.length; i++) { 10788 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10789 if (proc == null) { 10790 continue; 10791 } 10792 int adj = proc.setAdj; 10793 if (adj >= worstType && !proc.killedByAm) { 10794 proc.kill(reason, true); 10795 killed = true; 10796 } 10797 } 10798 } 10799 return killed; 10800 } 10801 10802 @Override 10803 public void killUid(int uid, String reason) { 10804 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10805 throw new SecurityException("killUid only available to the system"); 10806 } 10807 synchronized (this) { 10808 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10809 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10810 reason != null ? reason : "kill uid"); 10811 } 10812 } 10813 10814 @Override 10815 public boolean killProcessesBelowForeground(String reason) { 10816 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10817 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10818 } 10819 10820 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10821 } 10822 10823 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10824 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10825 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10826 } 10827 10828 boolean killed = false; 10829 synchronized (mPidsSelfLocked) { 10830 final int size = mPidsSelfLocked.size(); 10831 for (int i = 0; i < size; i++) { 10832 final int pid = mPidsSelfLocked.keyAt(i); 10833 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10834 if (proc == null) continue; 10835 10836 final int adj = proc.setAdj; 10837 if (adj > belowAdj && !proc.killedByAm) { 10838 proc.kill(reason, true); 10839 killed = true; 10840 } 10841 } 10842 } 10843 return killed; 10844 } 10845 10846 @Override 10847 public void hang(final IBinder who, boolean allowRestart) { 10848 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10849 != PackageManager.PERMISSION_GRANTED) { 10850 throw new SecurityException("Requires permission " 10851 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10852 } 10853 10854 final IBinder.DeathRecipient death = new DeathRecipient() { 10855 @Override 10856 public void binderDied() { 10857 synchronized (this) { 10858 notifyAll(); 10859 } 10860 } 10861 }; 10862 10863 try { 10864 who.linkToDeath(death, 0); 10865 } catch (RemoteException e) { 10866 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10867 return; 10868 } 10869 10870 synchronized (this) { 10871 Watchdog.getInstance().setAllowRestart(allowRestart); 10872 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10873 synchronized (death) { 10874 while (who.isBinderAlive()) { 10875 try { 10876 death.wait(); 10877 } catch (InterruptedException e) { 10878 } 10879 } 10880 } 10881 Watchdog.getInstance().setAllowRestart(true); 10882 } 10883 } 10884 10885 @Override 10886 public void restart() { 10887 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10888 != PackageManager.PERMISSION_GRANTED) { 10889 throw new SecurityException("Requires permission " 10890 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10891 } 10892 10893 Log.i(TAG, "Sending shutdown broadcast..."); 10894 10895 BroadcastReceiver br = new BroadcastReceiver() { 10896 @Override public void onReceive(Context context, Intent intent) { 10897 // Now the broadcast is done, finish up the low-level shutdown. 10898 Log.i(TAG, "Shutting down activity manager..."); 10899 shutdown(10000); 10900 Log.i(TAG, "Shutdown complete, restarting!"); 10901 Process.killProcess(Process.myPid()); 10902 System.exit(10); 10903 } 10904 }; 10905 10906 // First send the high-level shut down broadcast. 10907 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10908 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10909 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10910 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10911 mContext.sendOrderedBroadcastAsUser(intent, 10912 UserHandle.ALL, null, br, mHandler, 0, null, null); 10913 */ 10914 br.onReceive(mContext, intent); 10915 } 10916 10917 private long getLowRamTimeSinceIdle(long now) { 10918 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10919 } 10920 10921 @Override 10922 public void performIdleMaintenance() { 10923 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10924 != PackageManager.PERMISSION_GRANTED) { 10925 throw new SecurityException("Requires permission " 10926 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10927 } 10928 10929 synchronized (this) { 10930 final long now = SystemClock.uptimeMillis(); 10931 final long timeSinceLastIdle = now - mLastIdleTime; 10932 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10933 mLastIdleTime = now; 10934 mLowRamTimeSinceLastIdle = 0; 10935 if (mLowRamStartTime != 0) { 10936 mLowRamStartTime = now; 10937 } 10938 10939 StringBuilder sb = new StringBuilder(128); 10940 sb.append("Idle maintenance over "); 10941 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10942 sb.append(" low RAM for "); 10943 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10944 Slog.i(TAG, sb.toString()); 10945 10946 // If at least 1/3 of our time since the last idle period has been spent 10947 // with RAM low, then we want to kill processes. 10948 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10949 10950 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10951 ProcessRecord proc = mLruProcesses.get(i); 10952 if (proc.notCachedSinceIdle) { 10953 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10954 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10955 if (doKilling && proc.initialIdlePss != 0 10956 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10957 sb = new StringBuilder(128); 10958 sb.append("Kill"); 10959 sb.append(proc.processName); 10960 sb.append(" in idle maint: pss="); 10961 sb.append(proc.lastPss); 10962 sb.append(", initialPss="); 10963 sb.append(proc.initialIdlePss); 10964 sb.append(", period="); 10965 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10966 sb.append(", lowRamPeriod="); 10967 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10968 Slog.wtfQuiet(TAG, sb.toString()); 10969 proc.kill("idle maint (pss " + proc.lastPss 10970 + " from " + proc.initialIdlePss + ")", true); 10971 } 10972 } 10973 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10974 proc.notCachedSinceIdle = true; 10975 proc.initialIdlePss = 0; 10976 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10977 mTestPssMode, isSleeping(), now); 10978 } 10979 } 10980 10981 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10982 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10983 } 10984 } 10985 10986 private void retrieveSettings() { 10987 final ContentResolver resolver = mContext.getContentResolver(); 10988 String debugApp = Settings.Global.getString( 10989 resolver, Settings.Global.DEBUG_APP); 10990 boolean waitForDebugger = Settings.Global.getInt( 10991 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10992 boolean alwaysFinishActivities = Settings.Global.getInt( 10993 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10994 boolean forceRtl = Settings.Global.getInt( 10995 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10996 // Transfer any global setting for forcing RTL layout, into a System Property 10997 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10998 10999 Configuration configuration = new Configuration(); 11000 Settings.System.getConfiguration(resolver, configuration); 11001 if (forceRtl) { 11002 // This will take care of setting the correct layout direction flags 11003 configuration.setLayoutDirection(configuration.locale); 11004 } 11005 11006 synchronized (this) { 11007 mDebugApp = mOrigDebugApp = debugApp; 11008 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11009 mAlwaysFinishActivities = alwaysFinishActivities; 11010 // This happens before any activities are started, so we can 11011 // change mConfiguration in-place. 11012 updateConfigurationLocked(configuration, null, false, true); 11013 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11014 } 11015 } 11016 11017 /** Loads resources after the current configuration has been set. */ 11018 private void loadResourcesOnSystemReady() { 11019 final Resources res = mContext.getResources(); 11020 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11021 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11022 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11023 } 11024 11025 public boolean testIsSystemReady() { 11026 // no need to synchronize(this) just to read & return the value 11027 return mSystemReady; 11028 } 11029 11030 private static File getCalledPreBootReceiversFile() { 11031 File dataDir = Environment.getDataDirectory(); 11032 File systemDir = new File(dataDir, "system"); 11033 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11034 return fname; 11035 } 11036 11037 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11038 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11039 File file = getCalledPreBootReceiversFile(); 11040 FileInputStream fis = null; 11041 try { 11042 fis = new FileInputStream(file); 11043 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11044 int fvers = dis.readInt(); 11045 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11046 String vers = dis.readUTF(); 11047 String codename = dis.readUTF(); 11048 String build = dis.readUTF(); 11049 if (android.os.Build.VERSION.RELEASE.equals(vers) 11050 && android.os.Build.VERSION.CODENAME.equals(codename) 11051 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11052 int num = dis.readInt(); 11053 while (num > 0) { 11054 num--; 11055 String pkg = dis.readUTF(); 11056 String cls = dis.readUTF(); 11057 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11058 } 11059 } 11060 } 11061 } catch (FileNotFoundException e) { 11062 } catch (IOException e) { 11063 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11064 } finally { 11065 if (fis != null) { 11066 try { 11067 fis.close(); 11068 } catch (IOException e) { 11069 } 11070 } 11071 } 11072 return lastDoneReceivers; 11073 } 11074 11075 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11076 File file = getCalledPreBootReceiversFile(); 11077 FileOutputStream fos = null; 11078 DataOutputStream dos = null; 11079 try { 11080 fos = new FileOutputStream(file); 11081 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11082 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11083 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11084 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11085 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11086 dos.writeInt(list.size()); 11087 for (int i=0; i<list.size(); i++) { 11088 dos.writeUTF(list.get(i).getPackageName()); 11089 dos.writeUTF(list.get(i).getClassName()); 11090 } 11091 } catch (IOException e) { 11092 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11093 file.delete(); 11094 } finally { 11095 FileUtils.sync(fos); 11096 if (dos != null) { 11097 try { 11098 dos.close(); 11099 } catch (IOException e) { 11100 // TODO Auto-generated catch block 11101 e.printStackTrace(); 11102 } 11103 } 11104 } 11105 } 11106 11107 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11108 ArrayList<ComponentName> doneReceivers, int userId) { 11109 boolean waitingUpdate = false; 11110 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11111 List<ResolveInfo> ris = null; 11112 try { 11113 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11114 intent, null, 0, userId); 11115 } catch (RemoteException e) { 11116 } 11117 if (ris != null) { 11118 for (int i=ris.size()-1; i>=0; i--) { 11119 if ((ris.get(i).activityInfo.applicationInfo.flags 11120 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11121 ris.remove(i); 11122 } 11123 } 11124 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11125 11126 // For User 0, load the version number. When delivering to a new user, deliver 11127 // to all receivers. 11128 if (userId == UserHandle.USER_OWNER) { 11129 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11130 for (int i=0; i<ris.size(); i++) { 11131 ActivityInfo ai = ris.get(i).activityInfo; 11132 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11133 if (lastDoneReceivers.contains(comp)) { 11134 // We already did the pre boot receiver for this app with the current 11135 // platform version, so don't do it again... 11136 ris.remove(i); 11137 i--; 11138 // ...however, do keep it as one that has been done, so we don't 11139 // forget about it when rewriting the file of last done receivers. 11140 doneReceivers.add(comp); 11141 } 11142 } 11143 } 11144 11145 // If primary user, send broadcast to all available users, else just to userId 11146 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11147 : new int[] { userId }; 11148 for (int i = 0; i < ris.size(); i++) { 11149 ActivityInfo ai = ris.get(i).activityInfo; 11150 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11151 doneReceivers.add(comp); 11152 intent.setComponent(comp); 11153 for (int j=0; j<users.length; j++) { 11154 IIntentReceiver finisher = null; 11155 // On last receiver and user, set up a completion callback 11156 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11157 finisher = new IIntentReceiver.Stub() { 11158 public void performReceive(Intent intent, int resultCode, 11159 String data, Bundle extras, boolean ordered, 11160 boolean sticky, int sendingUser) { 11161 // The raw IIntentReceiver interface is called 11162 // with the AM lock held, so redispatch to 11163 // execute our code without the lock. 11164 mHandler.post(onFinishCallback); 11165 } 11166 }; 11167 } 11168 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11169 + " for user " + users[j]); 11170 broadcastIntentLocked(null, null, intent, null, finisher, 11171 0, null, null, null, AppOpsManager.OP_NONE, 11172 true, false, MY_PID, Process.SYSTEM_UID, 11173 users[j]); 11174 if (finisher != null) { 11175 waitingUpdate = true; 11176 } 11177 } 11178 } 11179 } 11180 11181 return waitingUpdate; 11182 } 11183 11184 public void systemReady(final Runnable goingCallback) { 11185 synchronized(this) { 11186 if (mSystemReady) { 11187 // If we're done calling all the receivers, run the next "boot phase" passed in 11188 // by the SystemServer 11189 if (goingCallback != null) { 11190 goingCallback.run(); 11191 } 11192 return; 11193 } 11194 11195 // Make sure we have the current profile info, since it is needed for 11196 // security checks. 11197 updateCurrentProfileIdsLocked(); 11198 11199 if (mRecentTasks == null) { 11200 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11201 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11202 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11203 mTaskPersister.startPersisting(); 11204 } 11205 11206 // Check to see if there are any update receivers to run. 11207 if (!mDidUpdate) { 11208 if (mWaitingUpdate) { 11209 return; 11210 } 11211 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11212 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11213 public void run() { 11214 synchronized (ActivityManagerService.this) { 11215 mDidUpdate = true; 11216 } 11217 writeLastDonePreBootReceivers(doneReceivers); 11218 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11219 false); 11220 systemReady(goingCallback); 11221 } 11222 }, doneReceivers, UserHandle.USER_OWNER); 11223 11224 if (mWaitingUpdate) { 11225 return; 11226 } 11227 mDidUpdate = true; 11228 } 11229 11230 mAppOpsService.systemReady(); 11231 mSystemReady = true; 11232 } 11233 11234 ArrayList<ProcessRecord> procsToKill = null; 11235 synchronized(mPidsSelfLocked) { 11236 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11237 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11238 if (!isAllowedWhileBooting(proc.info)){ 11239 if (procsToKill == null) { 11240 procsToKill = new ArrayList<ProcessRecord>(); 11241 } 11242 procsToKill.add(proc); 11243 } 11244 } 11245 } 11246 11247 synchronized(this) { 11248 if (procsToKill != null) { 11249 for (int i=procsToKill.size()-1; i>=0; i--) { 11250 ProcessRecord proc = procsToKill.get(i); 11251 Slog.i(TAG, "Removing system update proc: " + proc); 11252 removeProcessLocked(proc, true, false, "system update done"); 11253 } 11254 } 11255 11256 // Now that we have cleaned up any update processes, we 11257 // are ready to start launching real processes and know that 11258 // we won't trample on them any more. 11259 mProcessesReady = true; 11260 } 11261 11262 Slog.i(TAG, "System now ready"); 11263 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11264 SystemClock.uptimeMillis()); 11265 11266 synchronized(this) { 11267 // Make sure we have no pre-ready processes sitting around. 11268 11269 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11270 ResolveInfo ri = mContext.getPackageManager() 11271 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11272 STOCK_PM_FLAGS); 11273 CharSequence errorMsg = null; 11274 if (ri != null) { 11275 ActivityInfo ai = ri.activityInfo; 11276 ApplicationInfo app = ai.applicationInfo; 11277 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11278 mTopAction = Intent.ACTION_FACTORY_TEST; 11279 mTopData = null; 11280 mTopComponent = new ComponentName(app.packageName, 11281 ai.name); 11282 } else { 11283 errorMsg = mContext.getResources().getText( 11284 com.android.internal.R.string.factorytest_not_system); 11285 } 11286 } else { 11287 errorMsg = mContext.getResources().getText( 11288 com.android.internal.R.string.factorytest_no_action); 11289 } 11290 if (errorMsg != null) { 11291 mTopAction = null; 11292 mTopData = null; 11293 mTopComponent = null; 11294 Message msg = Message.obtain(); 11295 msg.what = SHOW_FACTORY_ERROR_MSG; 11296 msg.getData().putCharSequence("msg", errorMsg); 11297 mHandler.sendMessage(msg); 11298 } 11299 } 11300 } 11301 11302 retrieveSettings(); 11303 loadResourcesOnSystemReady(); 11304 11305 synchronized (this) { 11306 readGrantedUriPermissionsLocked(); 11307 } 11308 11309 if (goingCallback != null) goingCallback.run(); 11310 11311 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11312 Integer.toString(mCurrentUserId), mCurrentUserId); 11313 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11314 Integer.toString(mCurrentUserId), mCurrentUserId); 11315 mSystemServiceManager.startUser(mCurrentUserId); 11316 11317 synchronized (this) { 11318 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11319 try { 11320 List apps = AppGlobals.getPackageManager(). 11321 getPersistentApplications(STOCK_PM_FLAGS); 11322 if (apps != null) { 11323 int N = apps.size(); 11324 int i; 11325 for (i=0; i<N; i++) { 11326 ApplicationInfo info 11327 = (ApplicationInfo)apps.get(i); 11328 if (info != null && 11329 !info.packageName.equals("android")) { 11330 addAppLocked(info, false, null /* ABI override */); 11331 } 11332 } 11333 } 11334 } catch (RemoteException ex) { 11335 // pm is in same process, this will never happen. 11336 } 11337 } 11338 11339 // Start up initial activity. 11340 mBooting = true; 11341 startHomeActivityLocked(mCurrentUserId); 11342 11343 try { 11344 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11345 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11346 + " data partition or your device will be unstable."); 11347 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11348 } 11349 } catch (RemoteException e) { 11350 } 11351 11352 if (!Build.isFingerprintConsistent()) { 11353 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11354 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11355 } 11356 11357 long ident = Binder.clearCallingIdentity(); 11358 try { 11359 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11360 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11361 | Intent.FLAG_RECEIVER_FOREGROUND); 11362 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11363 broadcastIntentLocked(null, null, intent, 11364 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11365 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11366 intent = new Intent(Intent.ACTION_USER_STARTING); 11367 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11368 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11369 broadcastIntentLocked(null, null, intent, 11370 null, new IIntentReceiver.Stub() { 11371 @Override 11372 public void performReceive(Intent intent, int resultCode, String data, 11373 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11374 throws RemoteException { 11375 } 11376 }, 0, null, null, 11377 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11378 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11379 } catch (Throwable t) { 11380 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11381 } finally { 11382 Binder.restoreCallingIdentity(ident); 11383 } 11384 mStackSupervisor.resumeTopActivitiesLocked(); 11385 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11386 } 11387 } 11388 11389 private boolean makeAppCrashingLocked(ProcessRecord app, 11390 String shortMsg, String longMsg, String stackTrace) { 11391 app.crashing = true; 11392 app.crashingReport = generateProcessError(app, 11393 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11394 startAppProblemLocked(app); 11395 app.stopFreezingAllLocked(); 11396 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11397 } 11398 11399 private void makeAppNotRespondingLocked(ProcessRecord app, 11400 String activity, String shortMsg, String longMsg) { 11401 app.notResponding = true; 11402 app.notRespondingReport = generateProcessError(app, 11403 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11404 activity, shortMsg, longMsg, null); 11405 startAppProblemLocked(app); 11406 app.stopFreezingAllLocked(); 11407 } 11408 11409 /** 11410 * Generate a process error record, suitable for attachment to a ProcessRecord. 11411 * 11412 * @param app The ProcessRecord in which the error occurred. 11413 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11414 * ActivityManager.AppErrorStateInfo 11415 * @param activity The activity associated with the crash, if known. 11416 * @param shortMsg Short message describing the crash. 11417 * @param longMsg Long message describing the crash. 11418 * @param stackTrace Full crash stack trace, may be null. 11419 * 11420 * @return Returns a fully-formed AppErrorStateInfo record. 11421 */ 11422 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11423 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11424 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11425 11426 report.condition = condition; 11427 report.processName = app.processName; 11428 report.pid = app.pid; 11429 report.uid = app.info.uid; 11430 report.tag = activity; 11431 report.shortMsg = shortMsg; 11432 report.longMsg = longMsg; 11433 report.stackTrace = stackTrace; 11434 11435 return report; 11436 } 11437 11438 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11439 synchronized (this) { 11440 app.crashing = false; 11441 app.crashingReport = null; 11442 app.notResponding = false; 11443 app.notRespondingReport = null; 11444 if (app.anrDialog == fromDialog) { 11445 app.anrDialog = null; 11446 } 11447 if (app.waitDialog == fromDialog) { 11448 app.waitDialog = null; 11449 } 11450 if (app.pid > 0 && app.pid != MY_PID) { 11451 handleAppCrashLocked(app, null, null, null); 11452 app.kill("user request after error", true); 11453 } 11454 } 11455 } 11456 11457 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11458 String stackTrace) { 11459 long now = SystemClock.uptimeMillis(); 11460 11461 Long crashTime; 11462 if (!app.isolated) { 11463 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11464 } else { 11465 crashTime = null; 11466 } 11467 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11468 // This process loses! 11469 Slog.w(TAG, "Process " + app.info.processName 11470 + " has crashed too many times: killing!"); 11471 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11472 app.userId, app.info.processName, app.uid); 11473 mStackSupervisor.handleAppCrashLocked(app); 11474 if (!app.persistent) { 11475 // We don't want to start this process again until the user 11476 // explicitly does so... but for persistent process, we really 11477 // need to keep it running. If a persistent process is actually 11478 // repeatedly crashing, then badness for everyone. 11479 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11480 app.info.processName); 11481 if (!app.isolated) { 11482 // XXX We don't have a way to mark isolated processes 11483 // as bad, since they don't have a peristent identity. 11484 mBadProcesses.put(app.info.processName, app.uid, 11485 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11486 mProcessCrashTimes.remove(app.info.processName, app.uid); 11487 } 11488 app.bad = true; 11489 app.removed = true; 11490 // Don't let services in this process be restarted and potentially 11491 // annoy the user repeatedly. Unless it is persistent, since those 11492 // processes run critical code. 11493 removeProcessLocked(app, false, false, "crash"); 11494 mStackSupervisor.resumeTopActivitiesLocked(); 11495 return false; 11496 } 11497 mStackSupervisor.resumeTopActivitiesLocked(); 11498 } else { 11499 mStackSupervisor.finishTopRunningActivityLocked(app); 11500 } 11501 11502 // Bump up the crash count of any services currently running in the proc. 11503 for (int i=app.services.size()-1; i>=0; i--) { 11504 // Any services running in the application need to be placed 11505 // back in the pending list. 11506 ServiceRecord sr = app.services.valueAt(i); 11507 sr.crashCount++; 11508 } 11509 11510 // If the crashing process is what we consider to be the "home process" and it has been 11511 // replaced by a third-party app, clear the package preferred activities from packages 11512 // with a home activity running in the process to prevent a repeatedly crashing app 11513 // from blocking the user to manually clear the list. 11514 final ArrayList<ActivityRecord> activities = app.activities; 11515 if (app == mHomeProcess && activities.size() > 0 11516 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11517 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11518 final ActivityRecord r = activities.get(activityNdx); 11519 if (r.isHomeActivity()) { 11520 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11521 try { 11522 ActivityThread.getPackageManager() 11523 .clearPackagePreferredActivities(r.packageName); 11524 } catch (RemoteException c) { 11525 // pm is in same process, this will never happen. 11526 } 11527 } 11528 } 11529 } 11530 11531 if (!app.isolated) { 11532 // XXX Can't keep track of crash times for isolated processes, 11533 // because they don't have a perisistent identity. 11534 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11535 } 11536 11537 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11538 return true; 11539 } 11540 11541 void startAppProblemLocked(ProcessRecord app) { 11542 // If this app is not running under the current user, then we 11543 // can't give it a report button because that would require 11544 // launching the report UI under a different user. 11545 app.errorReportReceiver = null; 11546 11547 for (int userId : mCurrentProfileIds) { 11548 if (app.userId == userId) { 11549 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11550 mContext, app.info.packageName, app.info.flags); 11551 } 11552 } 11553 skipCurrentReceiverLocked(app); 11554 } 11555 11556 void skipCurrentReceiverLocked(ProcessRecord app) { 11557 for (BroadcastQueue queue : mBroadcastQueues) { 11558 queue.skipCurrentReceiverLocked(app); 11559 } 11560 } 11561 11562 /** 11563 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11564 * The application process will exit immediately after this call returns. 11565 * @param app object of the crashing app, null for the system server 11566 * @param crashInfo describing the exception 11567 */ 11568 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11569 ProcessRecord r = findAppProcess(app, "Crash"); 11570 final String processName = app == null ? "system_server" 11571 : (r == null ? "unknown" : r.processName); 11572 11573 handleApplicationCrashInner("crash", r, processName, crashInfo); 11574 } 11575 11576 /* Native crash reporting uses this inner version because it needs to be somewhat 11577 * decoupled from the AM-managed cleanup lifecycle 11578 */ 11579 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11580 ApplicationErrorReport.CrashInfo crashInfo) { 11581 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11582 UserHandle.getUserId(Binder.getCallingUid()), processName, 11583 r == null ? -1 : r.info.flags, 11584 crashInfo.exceptionClassName, 11585 crashInfo.exceptionMessage, 11586 crashInfo.throwFileName, 11587 crashInfo.throwLineNumber); 11588 11589 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11590 11591 crashApplication(r, crashInfo); 11592 } 11593 11594 public void handleApplicationStrictModeViolation( 11595 IBinder app, 11596 int violationMask, 11597 StrictMode.ViolationInfo info) { 11598 ProcessRecord r = findAppProcess(app, "StrictMode"); 11599 if (r == null) { 11600 return; 11601 } 11602 11603 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11604 Integer stackFingerprint = info.hashCode(); 11605 boolean logIt = true; 11606 synchronized (mAlreadyLoggedViolatedStacks) { 11607 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11608 logIt = false; 11609 // TODO: sub-sample into EventLog for these, with 11610 // the info.durationMillis? Then we'd get 11611 // the relative pain numbers, without logging all 11612 // the stack traces repeatedly. We'd want to do 11613 // likewise in the client code, which also does 11614 // dup suppression, before the Binder call. 11615 } else { 11616 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11617 mAlreadyLoggedViolatedStacks.clear(); 11618 } 11619 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11620 } 11621 } 11622 if (logIt) { 11623 logStrictModeViolationToDropBox(r, info); 11624 } 11625 } 11626 11627 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11628 AppErrorResult result = new AppErrorResult(); 11629 synchronized (this) { 11630 final long origId = Binder.clearCallingIdentity(); 11631 11632 Message msg = Message.obtain(); 11633 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11634 HashMap<String, Object> data = new HashMap<String, Object>(); 11635 data.put("result", result); 11636 data.put("app", r); 11637 data.put("violationMask", violationMask); 11638 data.put("info", info); 11639 msg.obj = data; 11640 mHandler.sendMessage(msg); 11641 11642 Binder.restoreCallingIdentity(origId); 11643 } 11644 int res = result.get(); 11645 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11646 } 11647 } 11648 11649 // Depending on the policy in effect, there could be a bunch of 11650 // these in quick succession so we try to batch these together to 11651 // minimize disk writes, number of dropbox entries, and maximize 11652 // compression, by having more fewer, larger records. 11653 private void logStrictModeViolationToDropBox( 11654 ProcessRecord process, 11655 StrictMode.ViolationInfo info) { 11656 if (info == null) { 11657 return; 11658 } 11659 final boolean isSystemApp = process == null || 11660 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11661 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11662 final String processName = process == null ? "unknown" : process.processName; 11663 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11664 final DropBoxManager dbox = (DropBoxManager) 11665 mContext.getSystemService(Context.DROPBOX_SERVICE); 11666 11667 // Exit early if the dropbox isn't configured to accept this report type. 11668 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11669 11670 boolean bufferWasEmpty; 11671 boolean needsFlush; 11672 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11673 synchronized (sb) { 11674 bufferWasEmpty = sb.length() == 0; 11675 appendDropBoxProcessHeaders(process, processName, sb); 11676 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11677 sb.append("System-App: ").append(isSystemApp).append("\n"); 11678 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11679 if (info.violationNumThisLoop != 0) { 11680 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11681 } 11682 if (info.numAnimationsRunning != 0) { 11683 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11684 } 11685 if (info.broadcastIntentAction != null) { 11686 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11687 } 11688 if (info.durationMillis != -1) { 11689 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11690 } 11691 if (info.numInstances != -1) { 11692 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11693 } 11694 if (info.tags != null) { 11695 for (String tag : info.tags) { 11696 sb.append("Span-Tag: ").append(tag).append("\n"); 11697 } 11698 } 11699 sb.append("\n"); 11700 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11701 sb.append(info.crashInfo.stackTrace); 11702 } 11703 sb.append("\n"); 11704 11705 // Only buffer up to ~64k. Various logging bits truncate 11706 // things at 128k. 11707 needsFlush = (sb.length() > 64 * 1024); 11708 } 11709 11710 // Flush immediately if the buffer's grown too large, or this 11711 // is a non-system app. Non-system apps are isolated with a 11712 // different tag & policy and not batched. 11713 // 11714 // Batching is useful during internal testing with 11715 // StrictMode settings turned up high. Without batching, 11716 // thousands of separate files could be created on boot. 11717 if (!isSystemApp || needsFlush) { 11718 new Thread("Error dump: " + dropboxTag) { 11719 @Override 11720 public void run() { 11721 String report; 11722 synchronized (sb) { 11723 report = sb.toString(); 11724 sb.delete(0, sb.length()); 11725 sb.trimToSize(); 11726 } 11727 if (report.length() != 0) { 11728 dbox.addText(dropboxTag, report); 11729 } 11730 } 11731 }.start(); 11732 return; 11733 } 11734 11735 // System app batching: 11736 if (!bufferWasEmpty) { 11737 // An existing dropbox-writing thread is outstanding, so 11738 // we don't need to start it up. The existing thread will 11739 // catch the buffer appends we just did. 11740 return; 11741 } 11742 11743 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11744 // (After this point, we shouldn't access AMS internal data structures.) 11745 new Thread("Error dump: " + dropboxTag) { 11746 @Override 11747 public void run() { 11748 // 5 second sleep to let stacks arrive and be batched together 11749 try { 11750 Thread.sleep(5000); // 5 seconds 11751 } catch (InterruptedException e) {} 11752 11753 String errorReport; 11754 synchronized (mStrictModeBuffer) { 11755 errorReport = mStrictModeBuffer.toString(); 11756 if (errorReport.length() == 0) { 11757 return; 11758 } 11759 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11760 mStrictModeBuffer.trimToSize(); 11761 } 11762 dbox.addText(dropboxTag, errorReport); 11763 } 11764 }.start(); 11765 } 11766 11767 /** 11768 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11769 * @param app object of the crashing app, null for the system server 11770 * @param tag reported by the caller 11771 * @param system whether this wtf is coming from the system 11772 * @param crashInfo describing the context of the error 11773 * @return true if the process should exit immediately (WTF is fatal) 11774 */ 11775 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11776 final ApplicationErrorReport.CrashInfo crashInfo) { 11777 final int callingUid = Binder.getCallingUid(); 11778 final int callingPid = Binder.getCallingPid(); 11779 11780 if (system) { 11781 // If this is coming from the system, we could very well have low-level 11782 // system locks held, so we want to do this all asynchronously. And we 11783 // never want this to become fatal, so there is that too. 11784 mHandler.post(new Runnable() { 11785 @Override public void run() { 11786 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11787 } 11788 }); 11789 return false; 11790 } 11791 11792 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11793 crashInfo); 11794 11795 if (r != null && r.pid != Process.myPid() && 11796 Settings.Global.getInt(mContext.getContentResolver(), 11797 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11798 crashApplication(r, crashInfo); 11799 return true; 11800 } else { 11801 return false; 11802 } 11803 } 11804 11805 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11806 final ApplicationErrorReport.CrashInfo crashInfo) { 11807 final ProcessRecord r = findAppProcess(app, "WTF"); 11808 final String processName = app == null ? "system_server" 11809 : (r == null ? "unknown" : r.processName); 11810 11811 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11812 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11813 11814 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11815 11816 return r; 11817 } 11818 11819 /** 11820 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11821 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11822 */ 11823 private ProcessRecord findAppProcess(IBinder app, String reason) { 11824 if (app == null) { 11825 return null; 11826 } 11827 11828 synchronized (this) { 11829 final int NP = mProcessNames.getMap().size(); 11830 for (int ip=0; ip<NP; ip++) { 11831 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11832 final int NA = apps.size(); 11833 for (int ia=0; ia<NA; ia++) { 11834 ProcessRecord p = apps.valueAt(ia); 11835 if (p.thread != null && p.thread.asBinder() == app) { 11836 return p; 11837 } 11838 } 11839 } 11840 11841 Slog.w(TAG, "Can't find mystery application for " + reason 11842 + " from pid=" + Binder.getCallingPid() 11843 + " uid=" + Binder.getCallingUid() + ": " + app); 11844 return null; 11845 } 11846 } 11847 11848 /** 11849 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11850 * to append various headers to the dropbox log text. 11851 */ 11852 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11853 StringBuilder sb) { 11854 // Watchdog thread ends up invoking this function (with 11855 // a null ProcessRecord) to add the stack file to dropbox. 11856 // Do not acquire a lock on this (am) in such cases, as it 11857 // could cause a potential deadlock, if and when watchdog 11858 // is invoked due to unavailability of lock on am and it 11859 // would prevent watchdog from killing system_server. 11860 if (process == null) { 11861 sb.append("Process: ").append(processName).append("\n"); 11862 return; 11863 } 11864 // Note: ProcessRecord 'process' is guarded by the service 11865 // instance. (notably process.pkgList, which could otherwise change 11866 // concurrently during execution of this method) 11867 synchronized (this) { 11868 sb.append("Process: ").append(processName).append("\n"); 11869 int flags = process.info.flags; 11870 IPackageManager pm = AppGlobals.getPackageManager(); 11871 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11872 for (int ip=0; ip<process.pkgList.size(); ip++) { 11873 String pkg = process.pkgList.keyAt(ip); 11874 sb.append("Package: ").append(pkg); 11875 try { 11876 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11877 if (pi != null) { 11878 sb.append(" v").append(pi.versionCode); 11879 if (pi.versionName != null) { 11880 sb.append(" (").append(pi.versionName).append(")"); 11881 } 11882 } 11883 } catch (RemoteException e) { 11884 Slog.e(TAG, "Error getting package info: " + pkg, e); 11885 } 11886 sb.append("\n"); 11887 } 11888 } 11889 } 11890 11891 private static String processClass(ProcessRecord process) { 11892 if (process == null || process.pid == MY_PID) { 11893 return "system_server"; 11894 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11895 return "system_app"; 11896 } else { 11897 return "data_app"; 11898 } 11899 } 11900 11901 /** 11902 * Write a description of an error (crash, WTF, ANR) to the drop box. 11903 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11904 * @param process which caused the error, null means the system server 11905 * @param activity which triggered the error, null if unknown 11906 * @param parent activity related to the error, null if unknown 11907 * @param subject line related to the error, null if absent 11908 * @param report in long form describing the error, null if absent 11909 * @param logFile to include in the report, null if none 11910 * @param crashInfo giving an application stack trace, null if absent 11911 */ 11912 public void addErrorToDropBox(String eventType, 11913 ProcessRecord process, String processName, ActivityRecord activity, 11914 ActivityRecord parent, String subject, 11915 final String report, final File logFile, 11916 final ApplicationErrorReport.CrashInfo crashInfo) { 11917 // NOTE -- this must never acquire the ActivityManagerService lock, 11918 // otherwise the watchdog may be prevented from resetting the system. 11919 11920 final String dropboxTag = processClass(process) + "_" + eventType; 11921 final DropBoxManager dbox = (DropBoxManager) 11922 mContext.getSystemService(Context.DROPBOX_SERVICE); 11923 11924 // Exit early if the dropbox isn't configured to accept this report type. 11925 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11926 11927 final StringBuilder sb = new StringBuilder(1024); 11928 appendDropBoxProcessHeaders(process, processName, sb); 11929 if (activity != null) { 11930 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11931 } 11932 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11933 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11934 } 11935 if (parent != null && parent != activity) { 11936 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11937 } 11938 if (subject != null) { 11939 sb.append("Subject: ").append(subject).append("\n"); 11940 } 11941 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11942 if (Debug.isDebuggerConnected()) { 11943 sb.append("Debugger: Connected\n"); 11944 } 11945 sb.append("\n"); 11946 11947 // Do the rest in a worker thread to avoid blocking the caller on I/O 11948 // (After this point, we shouldn't access AMS internal data structures.) 11949 Thread worker = new Thread("Error dump: " + dropboxTag) { 11950 @Override 11951 public void run() { 11952 if (report != null) { 11953 sb.append(report); 11954 } 11955 if (logFile != null) { 11956 try { 11957 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11958 "\n\n[[TRUNCATED]]")); 11959 } catch (IOException e) { 11960 Slog.e(TAG, "Error reading " + logFile, e); 11961 } 11962 } 11963 if (crashInfo != null && crashInfo.stackTrace != null) { 11964 sb.append(crashInfo.stackTrace); 11965 } 11966 11967 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11968 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11969 if (lines > 0) { 11970 sb.append("\n"); 11971 11972 // Merge several logcat streams, and take the last N lines 11973 InputStreamReader input = null; 11974 try { 11975 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11976 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11977 "-b", "crash", 11978 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11979 11980 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11981 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11982 input = new InputStreamReader(logcat.getInputStream()); 11983 11984 int num; 11985 char[] buf = new char[8192]; 11986 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11987 } catch (IOException e) { 11988 Slog.e(TAG, "Error running logcat", e); 11989 } finally { 11990 if (input != null) try { input.close(); } catch (IOException e) {} 11991 } 11992 } 11993 11994 dbox.addText(dropboxTag, sb.toString()); 11995 } 11996 }; 11997 11998 if (process == null) { 11999 // If process is null, we are being called from some internal code 12000 // and may be about to die -- run this synchronously. 12001 worker.run(); 12002 } else { 12003 worker.start(); 12004 } 12005 } 12006 12007 /** 12008 * Bring up the "unexpected error" dialog box for a crashing app. 12009 * Deal with edge cases (intercepts from instrumented applications, 12010 * ActivityController, error intent receivers, that sort of thing). 12011 * @param r the application crashing 12012 * @param crashInfo describing the failure 12013 */ 12014 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12015 long timeMillis = System.currentTimeMillis(); 12016 String shortMsg = crashInfo.exceptionClassName; 12017 String longMsg = crashInfo.exceptionMessage; 12018 String stackTrace = crashInfo.stackTrace; 12019 if (shortMsg != null && longMsg != null) { 12020 longMsg = shortMsg + ": " + longMsg; 12021 } else if (shortMsg != null) { 12022 longMsg = shortMsg; 12023 } 12024 12025 AppErrorResult result = new AppErrorResult(); 12026 synchronized (this) { 12027 if (mController != null) { 12028 try { 12029 String name = r != null ? r.processName : null; 12030 int pid = r != null ? r.pid : Binder.getCallingPid(); 12031 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12032 if (!mController.appCrashed(name, pid, 12033 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12034 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12035 && "Native crash".equals(crashInfo.exceptionClassName)) { 12036 Slog.w(TAG, "Skip killing native crashed app " + name 12037 + "(" + pid + ") during testing"); 12038 } else { 12039 Slog.w(TAG, "Force-killing crashed app " + name 12040 + " at watcher's request"); 12041 if (r != null) { 12042 r.kill("crash", true); 12043 } else { 12044 // Huh. 12045 Process.killProcess(pid); 12046 Process.killProcessGroup(uid, pid); 12047 } 12048 } 12049 return; 12050 } 12051 } catch (RemoteException e) { 12052 mController = null; 12053 Watchdog.getInstance().setActivityController(null); 12054 } 12055 } 12056 12057 final long origId = Binder.clearCallingIdentity(); 12058 12059 // If this process is running instrumentation, finish it. 12060 if (r != null && r.instrumentationClass != null) { 12061 Slog.w(TAG, "Error in app " + r.processName 12062 + " running instrumentation " + r.instrumentationClass + ":"); 12063 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12064 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12065 Bundle info = new Bundle(); 12066 info.putString("shortMsg", shortMsg); 12067 info.putString("longMsg", longMsg); 12068 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12069 Binder.restoreCallingIdentity(origId); 12070 return; 12071 } 12072 12073 // Log crash in battery stats. 12074 if (r != null) { 12075 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12076 } 12077 12078 // If we can't identify the process or it's already exceeded its crash quota, 12079 // quit right away without showing a crash dialog. 12080 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12081 Binder.restoreCallingIdentity(origId); 12082 return; 12083 } 12084 12085 Message msg = Message.obtain(); 12086 msg.what = SHOW_ERROR_MSG; 12087 HashMap data = new HashMap(); 12088 data.put("result", result); 12089 data.put("app", r); 12090 msg.obj = data; 12091 mHandler.sendMessage(msg); 12092 12093 Binder.restoreCallingIdentity(origId); 12094 } 12095 12096 int res = result.get(); 12097 12098 Intent appErrorIntent = null; 12099 synchronized (this) { 12100 if (r != null && !r.isolated) { 12101 // XXX Can't keep track of crash time for isolated processes, 12102 // since they don't have a persistent identity. 12103 mProcessCrashTimes.put(r.info.processName, r.uid, 12104 SystemClock.uptimeMillis()); 12105 } 12106 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12107 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12108 } 12109 } 12110 12111 if (appErrorIntent != null) { 12112 try { 12113 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12114 } catch (ActivityNotFoundException e) { 12115 Slog.w(TAG, "bug report receiver dissappeared", e); 12116 } 12117 } 12118 } 12119 12120 Intent createAppErrorIntentLocked(ProcessRecord r, 12121 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12122 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12123 if (report == null) { 12124 return null; 12125 } 12126 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12127 result.setComponent(r.errorReportReceiver); 12128 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12129 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12130 return result; 12131 } 12132 12133 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12134 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12135 if (r.errorReportReceiver == null) { 12136 return null; 12137 } 12138 12139 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12140 return null; 12141 } 12142 12143 ApplicationErrorReport report = new ApplicationErrorReport(); 12144 report.packageName = r.info.packageName; 12145 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12146 report.processName = r.processName; 12147 report.time = timeMillis; 12148 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12149 12150 if (r.crashing || r.forceCrashReport) { 12151 report.type = ApplicationErrorReport.TYPE_CRASH; 12152 report.crashInfo = crashInfo; 12153 } else if (r.notResponding) { 12154 report.type = ApplicationErrorReport.TYPE_ANR; 12155 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12156 12157 report.anrInfo.activity = r.notRespondingReport.tag; 12158 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12159 report.anrInfo.info = r.notRespondingReport.longMsg; 12160 } 12161 12162 return report; 12163 } 12164 12165 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12166 enforceNotIsolatedCaller("getProcessesInErrorState"); 12167 // assume our apps are happy - lazy create the list 12168 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12169 12170 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12171 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12172 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12173 12174 synchronized (this) { 12175 12176 // iterate across all processes 12177 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12178 ProcessRecord app = mLruProcesses.get(i); 12179 if (!allUsers && app.userId != userId) { 12180 continue; 12181 } 12182 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12183 // This one's in trouble, so we'll generate a report for it 12184 // crashes are higher priority (in case there's a crash *and* an anr) 12185 ActivityManager.ProcessErrorStateInfo report = null; 12186 if (app.crashing) { 12187 report = app.crashingReport; 12188 } else if (app.notResponding) { 12189 report = app.notRespondingReport; 12190 } 12191 12192 if (report != null) { 12193 if (errList == null) { 12194 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12195 } 12196 errList.add(report); 12197 } else { 12198 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12199 " crashing = " + app.crashing + 12200 " notResponding = " + app.notResponding); 12201 } 12202 } 12203 } 12204 } 12205 12206 return errList; 12207 } 12208 12209 static int procStateToImportance(int procState, int memAdj, 12210 ActivityManager.RunningAppProcessInfo currApp) { 12211 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12212 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12213 currApp.lru = memAdj; 12214 } else { 12215 currApp.lru = 0; 12216 } 12217 return imp; 12218 } 12219 12220 private void fillInProcMemInfo(ProcessRecord app, 12221 ActivityManager.RunningAppProcessInfo outInfo) { 12222 outInfo.pid = app.pid; 12223 outInfo.uid = app.info.uid; 12224 if (mHeavyWeightProcess == app) { 12225 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12226 } 12227 if (app.persistent) { 12228 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12229 } 12230 if (app.activities.size() > 0) { 12231 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12232 } 12233 outInfo.lastTrimLevel = app.trimMemoryLevel; 12234 int adj = app.curAdj; 12235 int procState = app.curProcState; 12236 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12237 outInfo.importanceReasonCode = app.adjTypeCode; 12238 outInfo.processState = app.curProcState; 12239 } 12240 12241 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12242 enforceNotIsolatedCaller("getRunningAppProcesses"); 12243 // Lazy instantiation of list 12244 List<ActivityManager.RunningAppProcessInfo> runList = null; 12245 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12246 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12247 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12248 synchronized (this) { 12249 // Iterate across all processes 12250 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12251 ProcessRecord app = mLruProcesses.get(i); 12252 if (!allUsers && app.userId != userId) { 12253 continue; 12254 } 12255 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12256 // Generate process state info for running application 12257 ActivityManager.RunningAppProcessInfo currApp = 12258 new ActivityManager.RunningAppProcessInfo(app.processName, 12259 app.pid, app.getPackageList()); 12260 fillInProcMemInfo(app, currApp); 12261 if (app.adjSource instanceof ProcessRecord) { 12262 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12263 currApp.importanceReasonImportance = 12264 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12265 app.adjSourceProcState); 12266 } else if (app.adjSource instanceof ActivityRecord) { 12267 ActivityRecord r = (ActivityRecord)app.adjSource; 12268 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12269 } 12270 if (app.adjTarget instanceof ComponentName) { 12271 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12272 } 12273 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12274 // + " lru=" + currApp.lru); 12275 if (runList == null) { 12276 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12277 } 12278 runList.add(currApp); 12279 } 12280 } 12281 } 12282 return runList; 12283 } 12284 12285 public List<ApplicationInfo> getRunningExternalApplications() { 12286 enforceNotIsolatedCaller("getRunningExternalApplications"); 12287 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12288 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12289 if (runningApps != null && runningApps.size() > 0) { 12290 Set<String> extList = new HashSet<String>(); 12291 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12292 if (app.pkgList != null) { 12293 for (String pkg : app.pkgList) { 12294 extList.add(pkg); 12295 } 12296 } 12297 } 12298 IPackageManager pm = AppGlobals.getPackageManager(); 12299 for (String pkg : extList) { 12300 try { 12301 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12302 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12303 retList.add(info); 12304 } 12305 } catch (RemoteException e) { 12306 } 12307 } 12308 } 12309 return retList; 12310 } 12311 12312 @Override 12313 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12314 enforceNotIsolatedCaller("getMyMemoryState"); 12315 synchronized (this) { 12316 ProcessRecord proc; 12317 synchronized (mPidsSelfLocked) { 12318 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12319 } 12320 fillInProcMemInfo(proc, outInfo); 12321 } 12322 } 12323 12324 @Override 12325 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12326 if (checkCallingPermission(android.Manifest.permission.DUMP) 12327 != PackageManager.PERMISSION_GRANTED) { 12328 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12329 + Binder.getCallingPid() 12330 + ", uid=" + Binder.getCallingUid() 12331 + " without permission " 12332 + android.Manifest.permission.DUMP); 12333 return; 12334 } 12335 12336 boolean dumpAll = false; 12337 boolean dumpClient = false; 12338 String dumpPackage = null; 12339 12340 int opti = 0; 12341 while (opti < args.length) { 12342 String opt = args[opti]; 12343 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12344 break; 12345 } 12346 opti++; 12347 if ("-a".equals(opt)) { 12348 dumpAll = true; 12349 } else if ("-c".equals(opt)) { 12350 dumpClient = true; 12351 } else if ("-p".equals(opt)) { 12352 if (opti < args.length) { 12353 dumpPackage = args[opti]; 12354 opti++; 12355 } else { 12356 pw.println("Error: -p option requires package argument"); 12357 return; 12358 } 12359 dumpClient = true; 12360 } else if ("-h".equals(opt)) { 12361 pw.println("Activity manager dump options:"); 12362 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12363 pw.println(" cmd may be one of:"); 12364 pw.println(" a[ctivities]: activity stack state"); 12365 pw.println(" r[recents]: recent activities state"); 12366 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12367 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12368 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12369 pw.println(" o[om]: out of memory management"); 12370 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12371 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12372 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12373 pw.println(" as[sociations]: tracked app associations"); 12374 pw.println(" service [COMP_SPEC]: service client-side state"); 12375 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12376 pw.println(" all: dump all activities"); 12377 pw.println(" top: dump the top activity"); 12378 pw.println(" write: write all pending state to storage"); 12379 pw.println(" track-associations: enable association tracking"); 12380 pw.println(" untrack-associations: disable and clear association tracking"); 12381 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12382 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12383 pw.println(" a partial substring in a component name, a"); 12384 pw.println(" hex object identifier."); 12385 pw.println(" -a: include all available server state."); 12386 pw.println(" -c: include client state."); 12387 pw.println(" -p: limit output to given package."); 12388 return; 12389 } else { 12390 pw.println("Unknown argument: " + opt + "; use -h for help"); 12391 } 12392 } 12393 12394 long origId = Binder.clearCallingIdentity(); 12395 boolean more = false; 12396 // Is the caller requesting to dump a particular piece of data? 12397 if (opti < args.length) { 12398 String cmd = args[opti]; 12399 opti++; 12400 if ("activities".equals(cmd) || "a".equals(cmd)) { 12401 synchronized (this) { 12402 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12403 } 12404 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12405 synchronized (this) { 12406 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12407 } 12408 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12409 String[] newArgs; 12410 String name; 12411 if (opti >= args.length) { 12412 name = null; 12413 newArgs = EMPTY_STRING_ARRAY; 12414 } else { 12415 dumpPackage = args[opti]; 12416 opti++; 12417 newArgs = new String[args.length - opti]; 12418 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12419 args.length - opti); 12420 } 12421 synchronized (this) { 12422 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12423 } 12424 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12425 String[] newArgs; 12426 String name; 12427 if (opti >= args.length) { 12428 name = null; 12429 newArgs = EMPTY_STRING_ARRAY; 12430 } else { 12431 dumpPackage = args[opti]; 12432 opti++; 12433 newArgs = new String[args.length - opti]; 12434 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12435 args.length - opti); 12436 } 12437 synchronized (this) { 12438 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12439 } 12440 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12441 String[] newArgs; 12442 String name; 12443 if (opti >= args.length) { 12444 name = null; 12445 newArgs = EMPTY_STRING_ARRAY; 12446 } else { 12447 dumpPackage = args[opti]; 12448 opti++; 12449 newArgs = new String[args.length - opti]; 12450 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12451 args.length - opti); 12452 } 12453 synchronized (this) { 12454 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12455 } 12456 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12457 synchronized (this) { 12458 dumpOomLocked(fd, pw, args, opti, true); 12459 } 12460 } else if ("provider".equals(cmd)) { 12461 String[] newArgs; 12462 String name; 12463 if (opti >= args.length) { 12464 name = null; 12465 newArgs = EMPTY_STRING_ARRAY; 12466 } else { 12467 name = args[opti]; 12468 opti++; 12469 newArgs = new String[args.length - opti]; 12470 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12471 } 12472 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12473 pw.println("No providers match: " + name); 12474 pw.println("Use -h for help."); 12475 } 12476 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12477 synchronized (this) { 12478 dumpProvidersLocked(fd, pw, args, opti, true, null); 12479 } 12480 } else if ("service".equals(cmd)) { 12481 String[] newArgs; 12482 String name; 12483 if (opti >= args.length) { 12484 name = null; 12485 newArgs = EMPTY_STRING_ARRAY; 12486 } else { 12487 name = args[opti]; 12488 opti++; 12489 newArgs = new String[args.length - opti]; 12490 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12491 args.length - opti); 12492 } 12493 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12494 pw.println("No services match: " + name); 12495 pw.println("Use -h for help."); 12496 } 12497 } else if ("package".equals(cmd)) { 12498 String[] newArgs; 12499 if (opti >= args.length) { 12500 pw.println("package: no package name specified"); 12501 pw.println("Use -h for help."); 12502 } else { 12503 dumpPackage = args[opti]; 12504 opti++; 12505 newArgs = new String[args.length - opti]; 12506 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12507 args.length - opti); 12508 args = newArgs; 12509 opti = 0; 12510 more = true; 12511 } 12512 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12513 synchronized (this) { 12514 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12515 } 12516 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12517 synchronized (this) { 12518 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12519 } 12520 } else if ("write".equals(cmd)) { 12521 mTaskPersister.flush(); 12522 pw.println("All tasks persisted."); 12523 return; 12524 } else if ("track-associations".equals(cmd)) { 12525 synchronized (this) { 12526 if (!mTrackingAssociations) { 12527 mTrackingAssociations = true; 12528 pw.println("Association tracking started."); 12529 } else { 12530 pw.println("Association tracking already enabled."); 12531 } 12532 } 12533 return; 12534 } else if ("untrack-associations".equals(cmd)) { 12535 synchronized (this) { 12536 if (mTrackingAssociations) { 12537 mTrackingAssociations = false; 12538 mAssociations.clear(); 12539 pw.println("Association tracking stopped."); 12540 } else { 12541 pw.println("Association tracking not running."); 12542 } 12543 } 12544 return; 12545 } else { 12546 // Dumping a single activity? 12547 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12548 pw.println("Bad activity command, or no activities match: " + cmd); 12549 pw.println("Use -h for help."); 12550 } 12551 } 12552 if (!more) { 12553 Binder.restoreCallingIdentity(origId); 12554 return; 12555 } 12556 } 12557 12558 // No piece of data specified, dump everything. 12559 synchronized (this) { 12560 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12561 pw.println(); 12562 if (dumpAll) { 12563 pw.println("-------------------------------------------------------------------------------"); 12564 } 12565 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12566 pw.println(); 12567 if (dumpAll) { 12568 pw.println("-------------------------------------------------------------------------------"); 12569 } 12570 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12571 pw.println(); 12572 if (dumpAll) { 12573 pw.println("-------------------------------------------------------------------------------"); 12574 } 12575 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12576 pw.println(); 12577 if (dumpAll) { 12578 pw.println("-------------------------------------------------------------------------------"); 12579 } 12580 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12581 pw.println(); 12582 if (dumpAll) { 12583 pw.println("-------------------------------------------------------------------------------"); 12584 } 12585 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12586 if (mAssociations.size() > 0) { 12587 pw.println(); 12588 if (dumpAll) { 12589 pw.println("-------------------------------------------------------------------------------"); 12590 } 12591 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12592 } 12593 pw.println(); 12594 if (dumpAll) { 12595 pw.println("-------------------------------------------------------------------------------"); 12596 } 12597 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12598 } 12599 Binder.restoreCallingIdentity(origId); 12600 } 12601 12602 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12603 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12604 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12605 12606 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12607 dumpPackage); 12608 boolean needSep = printedAnything; 12609 12610 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12611 dumpPackage, needSep, " mFocusedActivity: "); 12612 if (printed) { 12613 printedAnything = true; 12614 needSep = false; 12615 } 12616 12617 if (dumpPackage == null) { 12618 if (needSep) { 12619 pw.println(); 12620 } 12621 needSep = true; 12622 printedAnything = true; 12623 mStackSupervisor.dump(pw, " "); 12624 } 12625 12626 if (!printedAnything) { 12627 pw.println(" (nothing)"); 12628 } 12629 } 12630 12631 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12632 int opti, boolean dumpAll, String dumpPackage) { 12633 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12634 12635 boolean printedAnything = false; 12636 12637 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12638 boolean printedHeader = false; 12639 12640 final int N = mRecentTasks.size(); 12641 for (int i=0; i<N; i++) { 12642 TaskRecord tr = mRecentTasks.get(i); 12643 if (dumpPackage != null) { 12644 if (tr.realActivity == null || 12645 !dumpPackage.equals(tr.realActivity)) { 12646 continue; 12647 } 12648 } 12649 if (!printedHeader) { 12650 pw.println(" Recent tasks:"); 12651 printedHeader = true; 12652 printedAnything = true; 12653 } 12654 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12655 pw.println(tr); 12656 if (dumpAll) { 12657 mRecentTasks.get(i).dump(pw, " "); 12658 } 12659 } 12660 } 12661 12662 if (!printedAnything) { 12663 pw.println(" (nothing)"); 12664 } 12665 } 12666 12667 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12668 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12669 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12670 12671 int dumpUid = 0; 12672 if (dumpPackage != null) { 12673 IPackageManager pm = AppGlobals.getPackageManager(); 12674 try { 12675 dumpUid = pm.getPackageUid(dumpPackage, 0); 12676 } catch (RemoteException e) { 12677 } 12678 } 12679 12680 boolean printedAnything = false; 12681 12682 final long now = SystemClock.uptimeMillis(); 12683 12684 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12685 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12686 = mAssociations.valueAt(i1); 12687 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12688 SparseArray<ArrayMap<String, Association>> sourceUids 12689 = targetComponents.valueAt(i2); 12690 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12691 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12692 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12693 Association ass = sourceProcesses.valueAt(i4); 12694 if (dumpPackage != null) { 12695 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12696 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12697 continue; 12698 } 12699 } 12700 printedAnything = true; 12701 pw.print(" "); 12702 pw.print(ass.mTargetProcess); 12703 pw.print("/"); 12704 UserHandle.formatUid(pw, ass.mTargetUid); 12705 pw.print(" <- "); 12706 pw.print(ass.mSourceProcess); 12707 pw.print("/"); 12708 UserHandle.formatUid(pw, ass.mSourceUid); 12709 pw.println(); 12710 pw.print(" via "); 12711 pw.print(ass.mTargetComponent.flattenToShortString()); 12712 pw.println(); 12713 pw.print(" "); 12714 long dur = ass.mTime; 12715 if (ass.mNesting > 0) { 12716 dur += now - ass.mStartTime; 12717 } 12718 TimeUtils.formatDuration(dur, pw); 12719 pw.print(" ("); 12720 pw.print(ass.mCount); 12721 pw.println(" times)"); 12722 if (ass.mNesting > 0) { 12723 pw.print(" "); 12724 pw.print(" Currently active: "); 12725 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12726 pw.println(); 12727 } 12728 } 12729 } 12730 } 12731 12732 } 12733 12734 if (!printedAnything) { 12735 pw.println(" (nothing)"); 12736 } 12737 } 12738 12739 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12740 int opti, boolean dumpAll, String dumpPackage) { 12741 boolean needSep = false; 12742 boolean printedAnything = false; 12743 int numPers = 0; 12744 12745 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12746 12747 if (dumpAll) { 12748 final int NP = mProcessNames.getMap().size(); 12749 for (int ip=0; ip<NP; ip++) { 12750 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12751 final int NA = procs.size(); 12752 for (int ia=0; ia<NA; ia++) { 12753 ProcessRecord r = procs.valueAt(ia); 12754 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12755 continue; 12756 } 12757 if (!needSep) { 12758 pw.println(" All known processes:"); 12759 needSep = true; 12760 printedAnything = true; 12761 } 12762 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12763 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12764 pw.print(" "); pw.println(r); 12765 r.dump(pw, " "); 12766 if (r.persistent) { 12767 numPers++; 12768 } 12769 } 12770 } 12771 } 12772 12773 if (mIsolatedProcesses.size() > 0) { 12774 boolean printed = false; 12775 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12776 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12777 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12778 continue; 12779 } 12780 if (!printed) { 12781 if (needSep) { 12782 pw.println(); 12783 } 12784 pw.println(" Isolated process list (sorted by uid):"); 12785 printedAnything = true; 12786 printed = true; 12787 needSep = true; 12788 } 12789 pw.println(String.format("%sIsolated #%2d: %s", 12790 " ", i, r.toString())); 12791 } 12792 } 12793 12794 if (mLruProcesses.size() > 0) { 12795 if (needSep) { 12796 pw.println(); 12797 } 12798 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12799 pw.print(" total, non-act at "); 12800 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12801 pw.print(", non-svc at "); 12802 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12803 pw.println("):"); 12804 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12805 needSep = true; 12806 printedAnything = true; 12807 } 12808 12809 if (dumpAll || dumpPackage != null) { 12810 synchronized (mPidsSelfLocked) { 12811 boolean printed = false; 12812 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12813 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12814 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12815 continue; 12816 } 12817 if (!printed) { 12818 if (needSep) pw.println(); 12819 needSep = true; 12820 pw.println(" PID mappings:"); 12821 printed = true; 12822 printedAnything = true; 12823 } 12824 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12825 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12826 } 12827 } 12828 } 12829 12830 if (mForegroundProcesses.size() > 0) { 12831 synchronized (mPidsSelfLocked) { 12832 boolean printed = false; 12833 for (int i=0; i<mForegroundProcesses.size(); i++) { 12834 ProcessRecord r = mPidsSelfLocked.get( 12835 mForegroundProcesses.valueAt(i).pid); 12836 if (dumpPackage != null && (r == null 12837 || !r.pkgList.containsKey(dumpPackage))) { 12838 continue; 12839 } 12840 if (!printed) { 12841 if (needSep) pw.println(); 12842 needSep = true; 12843 pw.println(" Foreground Processes:"); 12844 printed = true; 12845 printedAnything = true; 12846 } 12847 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12848 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12849 } 12850 } 12851 } 12852 12853 if (mPersistentStartingProcesses.size() > 0) { 12854 if (needSep) pw.println(); 12855 needSep = true; 12856 printedAnything = true; 12857 pw.println(" Persisent processes that are starting:"); 12858 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12859 "Starting Norm", "Restarting PERS", dumpPackage); 12860 } 12861 12862 if (mRemovedProcesses.size() > 0) { 12863 if (needSep) pw.println(); 12864 needSep = true; 12865 printedAnything = true; 12866 pw.println(" Processes that are being removed:"); 12867 dumpProcessList(pw, this, mRemovedProcesses, " ", 12868 "Removed Norm", "Removed PERS", dumpPackage); 12869 } 12870 12871 if (mProcessesOnHold.size() > 0) { 12872 if (needSep) pw.println(); 12873 needSep = true; 12874 printedAnything = true; 12875 pw.println(" Processes that are on old until the system is ready:"); 12876 dumpProcessList(pw, this, mProcessesOnHold, " ", 12877 "OnHold Norm", "OnHold PERS", dumpPackage); 12878 } 12879 12880 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12881 12882 if (mProcessCrashTimes.getMap().size() > 0) { 12883 boolean printed = false; 12884 long now = SystemClock.uptimeMillis(); 12885 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12886 final int NP = pmap.size(); 12887 for (int ip=0; ip<NP; ip++) { 12888 String pname = pmap.keyAt(ip); 12889 SparseArray<Long> uids = pmap.valueAt(ip); 12890 final int N = uids.size(); 12891 for (int i=0; i<N; i++) { 12892 int puid = uids.keyAt(i); 12893 ProcessRecord r = mProcessNames.get(pname, puid); 12894 if (dumpPackage != null && (r == null 12895 || !r.pkgList.containsKey(dumpPackage))) { 12896 continue; 12897 } 12898 if (!printed) { 12899 if (needSep) pw.println(); 12900 needSep = true; 12901 pw.println(" Time since processes crashed:"); 12902 printed = true; 12903 printedAnything = true; 12904 } 12905 pw.print(" Process "); pw.print(pname); 12906 pw.print(" uid "); pw.print(puid); 12907 pw.print(": last crashed "); 12908 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12909 pw.println(" ago"); 12910 } 12911 } 12912 } 12913 12914 if (mBadProcesses.getMap().size() > 0) { 12915 boolean printed = false; 12916 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12917 final int NP = pmap.size(); 12918 for (int ip=0; ip<NP; ip++) { 12919 String pname = pmap.keyAt(ip); 12920 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12921 final int N = uids.size(); 12922 for (int i=0; i<N; i++) { 12923 int puid = uids.keyAt(i); 12924 ProcessRecord r = mProcessNames.get(pname, puid); 12925 if (dumpPackage != null && (r == null 12926 || !r.pkgList.containsKey(dumpPackage))) { 12927 continue; 12928 } 12929 if (!printed) { 12930 if (needSep) pw.println(); 12931 needSep = true; 12932 pw.println(" Bad processes:"); 12933 printedAnything = true; 12934 } 12935 BadProcessInfo info = uids.valueAt(i); 12936 pw.print(" Bad process "); pw.print(pname); 12937 pw.print(" uid "); pw.print(puid); 12938 pw.print(": crashed at time "); pw.println(info.time); 12939 if (info.shortMsg != null) { 12940 pw.print(" Short msg: "); pw.println(info.shortMsg); 12941 } 12942 if (info.longMsg != null) { 12943 pw.print(" Long msg: "); pw.println(info.longMsg); 12944 } 12945 if (info.stack != null) { 12946 pw.println(" Stack:"); 12947 int lastPos = 0; 12948 for (int pos=0; pos<info.stack.length(); pos++) { 12949 if (info.stack.charAt(pos) == '\n') { 12950 pw.print(" "); 12951 pw.write(info.stack, lastPos, pos-lastPos); 12952 pw.println(); 12953 lastPos = pos+1; 12954 } 12955 } 12956 if (lastPos < info.stack.length()) { 12957 pw.print(" "); 12958 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12959 pw.println(); 12960 } 12961 } 12962 } 12963 } 12964 } 12965 12966 if (dumpPackage == null) { 12967 pw.println(); 12968 needSep = false; 12969 pw.println(" mStartedUsers:"); 12970 for (int i=0; i<mStartedUsers.size(); i++) { 12971 UserStartedState uss = mStartedUsers.valueAt(i); 12972 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12973 pw.print(": "); uss.dump("", pw); 12974 } 12975 pw.print(" mStartedUserArray: ["); 12976 for (int i=0; i<mStartedUserArray.length; i++) { 12977 if (i > 0) pw.print(", "); 12978 pw.print(mStartedUserArray[i]); 12979 } 12980 pw.println("]"); 12981 pw.print(" mUserLru: ["); 12982 for (int i=0; i<mUserLru.size(); i++) { 12983 if (i > 0) pw.print(", "); 12984 pw.print(mUserLru.get(i)); 12985 } 12986 pw.println("]"); 12987 if (dumpAll) { 12988 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12989 } 12990 synchronized (mUserProfileGroupIdsSelfLocked) { 12991 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12992 pw.println(" mUserProfileGroupIds:"); 12993 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12994 pw.print(" User #"); 12995 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12996 pw.print(" -> profile #"); 12997 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12998 } 12999 } 13000 } 13001 } 13002 if (mHomeProcess != null && (dumpPackage == null 13003 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13004 if (needSep) { 13005 pw.println(); 13006 needSep = false; 13007 } 13008 pw.println(" mHomeProcess: " + mHomeProcess); 13009 } 13010 if (mPreviousProcess != null && (dumpPackage == null 13011 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13012 if (needSep) { 13013 pw.println(); 13014 needSep = false; 13015 } 13016 pw.println(" mPreviousProcess: " + mPreviousProcess); 13017 } 13018 if (dumpAll) { 13019 StringBuilder sb = new StringBuilder(128); 13020 sb.append(" mPreviousProcessVisibleTime: "); 13021 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13022 pw.println(sb); 13023 } 13024 if (mHeavyWeightProcess != null && (dumpPackage == null 13025 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13026 if (needSep) { 13027 pw.println(); 13028 needSep = false; 13029 } 13030 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13031 } 13032 if (dumpPackage == null) { 13033 pw.println(" mConfiguration: " + mConfiguration); 13034 } 13035 if (dumpAll) { 13036 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13037 if (mCompatModePackages.getPackages().size() > 0) { 13038 boolean printed = false; 13039 for (Map.Entry<String, Integer> entry 13040 : mCompatModePackages.getPackages().entrySet()) { 13041 String pkg = entry.getKey(); 13042 int mode = entry.getValue(); 13043 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13044 continue; 13045 } 13046 if (!printed) { 13047 pw.println(" mScreenCompatPackages:"); 13048 printed = true; 13049 } 13050 pw.print(" "); pw.print(pkg); pw.print(": "); 13051 pw.print(mode); pw.println(); 13052 } 13053 } 13054 } 13055 if (dumpPackage == null) { 13056 pw.println(" mWakefulness=" 13057 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13058 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13059 + lockScreenShownToString()); 13060 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13061 + " mTestPssMode=" + mTestPssMode); 13062 } 13063 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13064 || mOrigWaitForDebugger) { 13065 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13066 || dumpPackage.equals(mOrigDebugApp)) { 13067 if (needSep) { 13068 pw.println(); 13069 needSep = false; 13070 } 13071 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13072 + " mDebugTransient=" + mDebugTransient 13073 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13074 } 13075 } 13076 if (mOpenGlTraceApp != null) { 13077 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13078 if (needSep) { 13079 pw.println(); 13080 needSep = false; 13081 } 13082 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13083 } 13084 } 13085 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13086 || mProfileFd != null) { 13087 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13088 if (needSep) { 13089 pw.println(); 13090 needSep = false; 13091 } 13092 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13093 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13094 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13095 + mAutoStopProfiler); 13096 pw.println(" mProfileType=" + mProfileType); 13097 } 13098 } 13099 if (dumpPackage == null) { 13100 if (mAlwaysFinishActivities || mController != null) { 13101 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13102 + " mController=" + mController); 13103 } 13104 if (dumpAll) { 13105 pw.println(" Total persistent processes: " + numPers); 13106 pw.println(" mProcessesReady=" + mProcessesReady 13107 + " mSystemReady=" + mSystemReady 13108 + " mBooted=" + mBooted 13109 + " mFactoryTest=" + mFactoryTest); 13110 pw.println(" mBooting=" + mBooting 13111 + " mCallFinishBooting=" + mCallFinishBooting 13112 + " mBootAnimationComplete=" + mBootAnimationComplete); 13113 pw.print(" mLastPowerCheckRealtime="); 13114 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13115 pw.println(""); 13116 pw.print(" mLastPowerCheckUptime="); 13117 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13118 pw.println(""); 13119 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13120 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13121 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13122 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13123 + " (" + mLruProcesses.size() + " total)" 13124 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13125 + " mNumServiceProcs=" + mNumServiceProcs 13126 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13127 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13128 + " mLastMemoryLevel" + mLastMemoryLevel 13129 + " mLastNumProcesses" + mLastNumProcesses); 13130 long now = SystemClock.uptimeMillis(); 13131 pw.print(" mLastIdleTime="); 13132 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13133 pw.print(" mLowRamSinceLastIdle="); 13134 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13135 pw.println(); 13136 } 13137 } 13138 13139 if (!printedAnything) { 13140 pw.println(" (nothing)"); 13141 } 13142 } 13143 13144 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13145 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13146 if (mProcessesToGc.size() > 0) { 13147 boolean printed = false; 13148 long now = SystemClock.uptimeMillis(); 13149 for (int i=0; i<mProcessesToGc.size(); i++) { 13150 ProcessRecord proc = mProcessesToGc.get(i); 13151 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13152 continue; 13153 } 13154 if (!printed) { 13155 if (needSep) pw.println(); 13156 needSep = true; 13157 pw.println(" Processes that are waiting to GC:"); 13158 printed = true; 13159 } 13160 pw.print(" Process "); pw.println(proc); 13161 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13162 pw.print(", last gced="); 13163 pw.print(now-proc.lastRequestedGc); 13164 pw.print(" ms ago, last lowMem="); 13165 pw.print(now-proc.lastLowMemory); 13166 pw.println(" ms ago"); 13167 13168 } 13169 } 13170 return needSep; 13171 } 13172 13173 void printOomLevel(PrintWriter pw, String name, int adj) { 13174 pw.print(" "); 13175 if (adj >= 0) { 13176 pw.print(' '); 13177 if (adj < 10) pw.print(' '); 13178 } else { 13179 if (adj > -10) pw.print(' '); 13180 } 13181 pw.print(adj); 13182 pw.print(": "); 13183 pw.print(name); 13184 pw.print(" ("); 13185 pw.print(mProcessList.getMemLevel(adj)/1024); 13186 pw.println(" kB)"); 13187 } 13188 13189 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13190 int opti, boolean dumpAll) { 13191 boolean needSep = false; 13192 13193 if (mLruProcesses.size() > 0) { 13194 if (needSep) pw.println(); 13195 needSep = true; 13196 pw.println(" OOM levels:"); 13197 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13198 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13199 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13200 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13201 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13202 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13203 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13204 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13205 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13206 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13207 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13208 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13209 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13210 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13211 13212 if (needSep) pw.println(); 13213 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13214 pw.print(" total, non-act at "); 13215 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13216 pw.print(", non-svc at "); 13217 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13218 pw.println("):"); 13219 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13220 needSep = true; 13221 } 13222 13223 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13224 13225 pw.println(); 13226 pw.println(" mHomeProcess: " + mHomeProcess); 13227 pw.println(" mPreviousProcess: " + mPreviousProcess); 13228 if (mHeavyWeightProcess != null) { 13229 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13230 } 13231 13232 return true; 13233 } 13234 13235 /** 13236 * There are three ways to call this: 13237 * - no provider specified: dump all the providers 13238 * - a flattened component name that matched an existing provider was specified as the 13239 * first arg: dump that one provider 13240 * - the first arg isn't the flattened component name of an existing provider: 13241 * dump all providers whose component contains the first arg as a substring 13242 */ 13243 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13244 int opti, boolean dumpAll) { 13245 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13246 } 13247 13248 static class ItemMatcher { 13249 ArrayList<ComponentName> components; 13250 ArrayList<String> strings; 13251 ArrayList<Integer> objects; 13252 boolean all; 13253 13254 ItemMatcher() { 13255 all = true; 13256 } 13257 13258 void build(String name) { 13259 ComponentName componentName = ComponentName.unflattenFromString(name); 13260 if (componentName != null) { 13261 if (components == null) { 13262 components = new ArrayList<ComponentName>(); 13263 } 13264 components.add(componentName); 13265 all = false; 13266 } else { 13267 int objectId = 0; 13268 // Not a '/' separated full component name; maybe an object ID? 13269 try { 13270 objectId = Integer.parseInt(name, 16); 13271 if (objects == null) { 13272 objects = new ArrayList<Integer>(); 13273 } 13274 objects.add(objectId); 13275 all = false; 13276 } catch (RuntimeException e) { 13277 // Not an integer; just do string match. 13278 if (strings == null) { 13279 strings = new ArrayList<String>(); 13280 } 13281 strings.add(name); 13282 all = false; 13283 } 13284 } 13285 } 13286 13287 int build(String[] args, int opti) { 13288 for (; opti<args.length; opti++) { 13289 String name = args[opti]; 13290 if ("--".equals(name)) { 13291 return opti+1; 13292 } 13293 build(name); 13294 } 13295 return opti; 13296 } 13297 13298 boolean match(Object object, ComponentName comp) { 13299 if (all) { 13300 return true; 13301 } 13302 if (components != null) { 13303 for (int i=0; i<components.size(); i++) { 13304 if (components.get(i).equals(comp)) { 13305 return true; 13306 } 13307 } 13308 } 13309 if (objects != null) { 13310 for (int i=0; i<objects.size(); i++) { 13311 if (System.identityHashCode(object) == objects.get(i)) { 13312 return true; 13313 } 13314 } 13315 } 13316 if (strings != null) { 13317 String flat = comp.flattenToString(); 13318 for (int i=0; i<strings.size(); i++) { 13319 if (flat.contains(strings.get(i))) { 13320 return true; 13321 } 13322 } 13323 } 13324 return false; 13325 } 13326 } 13327 13328 /** 13329 * There are three things that cmd can be: 13330 * - a flattened component name that matches an existing activity 13331 * - the cmd arg isn't the flattened component name of an existing activity: 13332 * dump all activity whose component contains the cmd as a substring 13333 * - A hex number of the ActivityRecord object instance. 13334 */ 13335 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13336 int opti, boolean dumpAll) { 13337 ArrayList<ActivityRecord> activities; 13338 13339 synchronized (this) { 13340 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13341 } 13342 13343 if (activities.size() <= 0) { 13344 return false; 13345 } 13346 13347 String[] newArgs = new String[args.length - opti]; 13348 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13349 13350 TaskRecord lastTask = null; 13351 boolean needSep = false; 13352 for (int i=activities.size()-1; i>=0; i--) { 13353 ActivityRecord r = activities.get(i); 13354 if (needSep) { 13355 pw.println(); 13356 } 13357 needSep = true; 13358 synchronized (this) { 13359 if (lastTask != r.task) { 13360 lastTask = r.task; 13361 pw.print("TASK "); pw.print(lastTask.affinity); 13362 pw.print(" id="); pw.println(lastTask.taskId); 13363 if (dumpAll) { 13364 lastTask.dump(pw, " "); 13365 } 13366 } 13367 } 13368 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13369 } 13370 return true; 13371 } 13372 13373 /** 13374 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13375 * there is a thread associated with the activity. 13376 */ 13377 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13378 final ActivityRecord r, String[] args, boolean dumpAll) { 13379 String innerPrefix = prefix + " "; 13380 synchronized (this) { 13381 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13382 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13383 pw.print(" pid="); 13384 if (r.app != null) pw.println(r.app.pid); 13385 else pw.println("(not running)"); 13386 if (dumpAll) { 13387 r.dump(pw, innerPrefix); 13388 } 13389 } 13390 if (r.app != null && r.app.thread != null) { 13391 // flush anything that is already in the PrintWriter since the thread is going 13392 // to write to the file descriptor directly 13393 pw.flush(); 13394 try { 13395 TransferPipe tp = new TransferPipe(); 13396 try { 13397 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13398 r.appToken, innerPrefix, args); 13399 tp.go(fd); 13400 } finally { 13401 tp.kill(); 13402 } 13403 } catch (IOException e) { 13404 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13405 } catch (RemoteException e) { 13406 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13407 } 13408 } 13409 } 13410 13411 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13412 int opti, boolean dumpAll, String dumpPackage) { 13413 boolean needSep = false; 13414 boolean onlyHistory = false; 13415 boolean printedAnything = false; 13416 13417 if ("history".equals(dumpPackage)) { 13418 if (opti < args.length && "-s".equals(args[opti])) { 13419 dumpAll = false; 13420 } 13421 onlyHistory = true; 13422 dumpPackage = null; 13423 } 13424 13425 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13426 if (!onlyHistory && dumpAll) { 13427 if (mRegisteredReceivers.size() > 0) { 13428 boolean printed = false; 13429 Iterator it = mRegisteredReceivers.values().iterator(); 13430 while (it.hasNext()) { 13431 ReceiverList r = (ReceiverList)it.next(); 13432 if (dumpPackage != null && (r.app == null || 13433 !dumpPackage.equals(r.app.info.packageName))) { 13434 continue; 13435 } 13436 if (!printed) { 13437 pw.println(" Registered Receivers:"); 13438 needSep = true; 13439 printed = true; 13440 printedAnything = true; 13441 } 13442 pw.print(" * "); pw.println(r); 13443 r.dump(pw, " "); 13444 } 13445 } 13446 13447 if (mReceiverResolver.dump(pw, needSep ? 13448 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13449 " ", dumpPackage, false, false)) { 13450 needSep = true; 13451 printedAnything = true; 13452 } 13453 } 13454 13455 for (BroadcastQueue q : mBroadcastQueues) { 13456 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13457 printedAnything |= needSep; 13458 } 13459 13460 needSep = true; 13461 13462 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13463 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13464 if (needSep) { 13465 pw.println(); 13466 } 13467 needSep = true; 13468 printedAnything = true; 13469 pw.print(" Sticky broadcasts for user "); 13470 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13471 StringBuilder sb = new StringBuilder(128); 13472 for (Map.Entry<String, ArrayList<Intent>> ent 13473 : mStickyBroadcasts.valueAt(user).entrySet()) { 13474 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13475 if (dumpAll) { 13476 pw.println(":"); 13477 ArrayList<Intent> intents = ent.getValue(); 13478 final int N = intents.size(); 13479 for (int i=0; i<N; i++) { 13480 sb.setLength(0); 13481 sb.append(" Intent: "); 13482 intents.get(i).toShortString(sb, false, true, false, false); 13483 pw.println(sb.toString()); 13484 Bundle bundle = intents.get(i).getExtras(); 13485 if (bundle != null) { 13486 pw.print(" "); 13487 pw.println(bundle.toString()); 13488 } 13489 } 13490 } else { 13491 pw.println(""); 13492 } 13493 } 13494 } 13495 } 13496 13497 if (!onlyHistory && dumpAll) { 13498 pw.println(); 13499 for (BroadcastQueue queue : mBroadcastQueues) { 13500 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13501 + queue.mBroadcastsScheduled); 13502 } 13503 pw.println(" mHandler:"); 13504 mHandler.dump(new PrintWriterPrinter(pw), " "); 13505 needSep = true; 13506 printedAnything = true; 13507 } 13508 13509 if (!printedAnything) { 13510 pw.println(" (nothing)"); 13511 } 13512 } 13513 13514 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13515 int opti, boolean dumpAll, String dumpPackage) { 13516 boolean needSep; 13517 boolean printedAnything = false; 13518 13519 ItemMatcher matcher = new ItemMatcher(); 13520 matcher.build(args, opti); 13521 13522 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13523 13524 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13525 printedAnything |= needSep; 13526 13527 if (mLaunchingProviders.size() > 0) { 13528 boolean printed = false; 13529 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13530 ContentProviderRecord r = mLaunchingProviders.get(i); 13531 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13532 continue; 13533 } 13534 if (!printed) { 13535 if (needSep) pw.println(); 13536 needSep = true; 13537 pw.println(" Launching content providers:"); 13538 printed = true; 13539 printedAnything = true; 13540 } 13541 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13542 pw.println(r); 13543 } 13544 } 13545 13546 if (mGrantedUriPermissions.size() > 0) { 13547 boolean printed = false; 13548 int dumpUid = -2; 13549 if (dumpPackage != null) { 13550 try { 13551 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13552 } catch (NameNotFoundException e) { 13553 dumpUid = -1; 13554 } 13555 } 13556 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13557 int uid = mGrantedUriPermissions.keyAt(i); 13558 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13559 continue; 13560 } 13561 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13562 if (!printed) { 13563 if (needSep) pw.println(); 13564 needSep = true; 13565 pw.println(" Granted Uri Permissions:"); 13566 printed = true; 13567 printedAnything = true; 13568 } 13569 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13570 for (UriPermission perm : perms.values()) { 13571 pw.print(" "); pw.println(perm); 13572 if (dumpAll) { 13573 perm.dump(pw, " "); 13574 } 13575 } 13576 } 13577 } 13578 13579 if (!printedAnything) { 13580 pw.println(" (nothing)"); 13581 } 13582 } 13583 13584 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13585 int opti, boolean dumpAll, String dumpPackage) { 13586 boolean printed = false; 13587 13588 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13589 13590 if (mIntentSenderRecords.size() > 0) { 13591 Iterator<WeakReference<PendingIntentRecord>> it 13592 = mIntentSenderRecords.values().iterator(); 13593 while (it.hasNext()) { 13594 WeakReference<PendingIntentRecord> ref = it.next(); 13595 PendingIntentRecord rec = ref != null ? ref.get(): null; 13596 if (dumpPackage != null && (rec == null 13597 || !dumpPackage.equals(rec.key.packageName))) { 13598 continue; 13599 } 13600 printed = true; 13601 if (rec != null) { 13602 pw.print(" * "); pw.println(rec); 13603 if (dumpAll) { 13604 rec.dump(pw, " "); 13605 } 13606 } else { 13607 pw.print(" * "); pw.println(ref); 13608 } 13609 } 13610 } 13611 13612 if (!printed) { 13613 pw.println(" (nothing)"); 13614 } 13615 } 13616 13617 private static final int dumpProcessList(PrintWriter pw, 13618 ActivityManagerService service, List list, 13619 String prefix, String normalLabel, String persistentLabel, 13620 String dumpPackage) { 13621 int numPers = 0; 13622 final int N = list.size()-1; 13623 for (int i=N; i>=0; i--) { 13624 ProcessRecord r = (ProcessRecord)list.get(i); 13625 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13626 continue; 13627 } 13628 pw.println(String.format("%s%s #%2d: %s", 13629 prefix, (r.persistent ? persistentLabel : normalLabel), 13630 i, r.toString())); 13631 if (r.persistent) { 13632 numPers++; 13633 } 13634 } 13635 return numPers; 13636 } 13637 13638 private static final boolean dumpProcessOomList(PrintWriter pw, 13639 ActivityManagerService service, List<ProcessRecord> origList, 13640 String prefix, String normalLabel, String persistentLabel, 13641 boolean inclDetails, String dumpPackage) { 13642 13643 ArrayList<Pair<ProcessRecord, Integer>> list 13644 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13645 for (int i=0; i<origList.size(); i++) { 13646 ProcessRecord r = origList.get(i); 13647 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13648 continue; 13649 } 13650 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13651 } 13652 13653 if (list.size() <= 0) { 13654 return false; 13655 } 13656 13657 Comparator<Pair<ProcessRecord, Integer>> comparator 13658 = new Comparator<Pair<ProcessRecord, Integer>>() { 13659 @Override 13660 public int compare(Pair<ProcessRecord, Integer> object1, 13661 Pair<ProcessRecord, Integer> object2) { 13662 if (object1.first.setAdj != object2.first.setAdj) { 13663 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13664 } 13665 if (object1.second.intValue() != object2.second.intValue()) { 13666 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13667 } 13668 return 0; 13669 } 13670 }; 13671 13672 Collections.sort(list, comparator); 13673 13674 final long curRealtime = SystemClock.elapsedRealtime(); 13675 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13676 final long curUptime = SystemClock.uptimeMillis(); 13677 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13678 13679 for (int i=list.size()-1; i>=0; i--) { 13680 ProcessRecord r = list.get(i).first; 13681 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13682 char schedGroup; 13683 switch (r.setSchedGroup) { 13684 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13685 schedGroup = 'B'; 13686 break; 13687 case Process.THREAD_GROUP_DEFAULT: 13688 schedGroup = 'F'; 13689 break; 13690 default: 13691 schedGroup = '?'; 13692 break; 13693 } 13694 char foreground; 13695 if (r.foregroundActivities) { 13696 foreground = 'A'; 13697 } else if (r.foregroundServices) { 13698 foreground = 'S'; 13699 } else { 13700 foreground = ' '; 13701 } 13702 String procState = ProcessList.makeProcStateString(r.curProcState); 13703 pw.print(prefix); 13704 pw.print(r.persistent ? persistentLabel : normalLabel); 13705 pw.print(" #"); 13706 int num = (origList.size()-1)-list.get(i).second; 13707 if (num < 10) pw.print(' '); 13708 pw.print(num); 13709 pw.print(": "); 13710 pw.print(oomAdj); 13711 pw.print(' '); 13712 pw.print(schedGroup); 13713 pw.print('/'); 13714 pw.print(foreground); 13715 pw.print('/'); 13716 pw.print(procState); 13717 pw.print(" trm:"); 13718 if (r.trimMemoryLevel < 10) pw.print(' '); 13719 pw.print(r.trimMemoryLevel); 13720 pw.print(' '); 13721 pw.print(r.toShortString()); 13722 pw.print(" ("); 13723 pw.print(r.adjType); 13724 pw.println(')'); 13725 if (r.adjSource != null || r.adjTarget != null) { 13726 pw.print(prefix); 13727 pw.print(" "); 13728 if (r.adjTarget instanceof ComponentName) { 13729 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13730 } else if (r.adjTarget != null) { 13731 pw.print(r.adjTarget.toString()); 13732 } else { 13733 pw.print("{null}"); 13734 } 13735 pw.print("<="); 13736 if (r.adjSource instanceof ProcessRecord) { 13737 pw.print("Proc{"); 13738 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13739 pw.println("}"); 13740 } else if (r.adjSource != null) { 13741 pw.println(r.adjSource.toString()); 13742 } else { 13743 pw.println("{null}"); 13744 } 13745 } 13746 if (inclDetails) { 13747 pw.print(prefix); 13748 pw.print(" "); 13749 pw.print("oom: max="); pw.print(r.maxAdj); 13750 pw.print(" curRaw="); pw.print(r.curRawAdj); 13751 pw.print(" setRaw="); pw.print(r.setRawAdj); 13752 pw.print(" cur="); pw.print(r.curAdj); 13753 pw.print(" set="); pw.println(r.setAdj); 13754 pw.print(prefix); 13755 pw.print(" "); 13756 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13757 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13758 pw.print(" lastPss="); pw.print(r.lastPss); 13759 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13760 pw.print(prefix); 13761 pw.print(" "); 13762 pw.print("cached="); pw.print(r.cached); 13763 pw.print(" empty="); pw.print(r.empty); 13764 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13765 13766 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13767 if (r.lastWakeTime != 0) { 13768 long wtime; 13769 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13770 synchronized (stats) { 13771 wtime = stats.getProcessWakeTime(r.info.uid, 13772 r.pid, curRealtime); 13773 } 13774 long timeUsed = wtime - r.lastWakeTime; 13775 pw.print(prefix); 13776 pw.print(" "); 13777 pw.print("keep awake over "); 13778 TimeUtils.formatDuration(realtimeSince, pw); 13779 pw.print(" used "); 13780 TimeUtils.formatDuration(timeUsed, pw); 13781 pw.print(" ("); 13782 pw.print((timeUsed*100)/realtimeSince); 13783 pw.println("%)"); 13784 } 13785 if (r.lastCpuTime != 0) { 13786 long timeUsed = r.curCpuTime - r.lastCpuTime; 13787 pw.print(prefix); 13788 pw.print(" "); 13789 pw.print("run cpu over "); 13790 TimeUtils.formatDuration(uptimeSince, pw); 13791 pw.print(" used "); 13792 TimeUtils.formatDuration(timeUsed, pw); 13793 pw.print(" ("); 13794 pw.print((timeUsed*100)/uptimeSince); 13795 pw.println("%)"); 13796 } 13797 } 13798 } 13799 } 13800 return true; 13801 } 13802 13803 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13804 String[] args) { 13805 ArrayList<ProcessRecord> procs; 13806 synchronized (this) { 13807 if (args != null && args.length > start 13808 && args[start].charAt(0) != '-') { 13809 procs = new ArrayList<ProcessRecord>(); 13810 int pid = -1; 13811 try { 13812 pid = Integer.parseInt(args[start]); 13813 } catch (NumberFormatException e) { 13814 } 13815 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13816 ProcessRecord proc = mLruProcesses.get(i); 13817 if (proc.pid == pid) { 13818 procs.add(proc); 13819 } else if (allPkgs && proc.pkgList != null 13820 && proc.pkgList.containsKey(args[start])) { 13821 procs.add(proc); 13822 } else if (proc.processName.equals(args[start])) { 13823 procs.add(proc); 13824 } 13825 } 13826 if (procs.size() <= 0) { 13827 return null; 13828 } 13829 } else { 13830 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13831 } 13832 } 13833 return procs; 13834 } 13835 13836 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13837 PrintWriter pw, String[] args) { 13838 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13839 if (procs == null) { 13840 pw.println("No process found for: " + args[0]); 13841 return; 13842 } 13843 13844 long uptime = SystemClock.uptimeMillis(); 13845 long realtime = SystemClock.elapsedRealtime(); 13846 pw.println("Applications Graphics Acceleration Info:"); 13847 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13848 13849 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13850 ProcessRecord r = procs.get(i); 13851 if (r.thread != null) { 13852 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13853 pw.flush(); 13854 try { 13855 TransferPipe tp = new TransferPipe(); 13856 try { 13857 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13858 tp.go(fd); 13859 } finally { 13860 tp.kill(); 13861 } 13862 } catch (IOException e) { 13863 pw.println("Failure while dumping the app: " + r); 13864 pw.flush(); 13865 } catch (RemoteException e) { 13866 pw.println("Got a RemoteException while dumping the app " + r); 13867 pw.flush(); 13868 } 13869 } 13870 } 13871 } 13872 13873 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13874 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13875 if (procs == null) { 13876 pw.println("No process found for: " + args[0]); 13877 return; 13878 } 13879 13880 pw.println("Applications Database Info:"); 13881 13882 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13883 ProcessRecord r = procs.get(i); 13884 if (r.thread != null) { 13885 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13886 pw.flush(); 13887 try { 13888 TransferPipe tp = new TransferPipe(); 13889 try { 13890 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13891 tp.go(fd); 13892 } finally { 13893 tp.kill(); 13894 } 13895 } catch (IOException e) { 13896 pw.println("Failure while dumping the app: " + r); 13897 pw.flush(); 13898 } catch (RemoteException e) { 13899 pw.println("Got a RemoteException while dumping the app " + r); 13900 pw.flush(); 13901 } 13902 } 13903 } 13904 } 13905 13906 final static class MemItem { 13907 final boolean isProc; 13908 final String label; 13909 final String shortLabel; 13910 final long pss; 13911 final int id; 13912 final boolean hasActivities; 13913 ArrayList<MemItem> subitems; 13914 13915 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13916 boolean _hasActivities) { 13917 isProc = true; 13918 label = _label; 13919 shortLabel = _shortLabel; 13920 pss = _pss; 13921 id = _id; 13922 hasActivities = _hasActivities; 13923 } 13924 13925 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13926 isProc = false; 13927 label = _label; 13928 shortLabel = _shortLabel; 13929 pss = _pss; 13930 id = _id; 13931 hasActivities = false; 13932 } 13933 } 13934 13935 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13936 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13937 if (sort && !isCompact) { 13938 Collections.sort(items, new Comparator<MemItem>() { 13939 @Override 13940 public int compare(MemItem lhs, MemItem rhs) { 13941 if (lhs.pss < rhs.pss) { 13942 return 1; 13943 } else if (lhs.pss > rhs.pss) { 13944 return -1; 13945 } 13946 return 0; 13947 } 13948 }); 13949 } 13950 13951 for (int i=0; i<items.size(); i++) { 13952 MemItem mi = items.get(i); 13953 if (!isCompact) { 13954 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13955 } else if (mi.isProc) { 13956 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13957 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13958 pw.println(mi.hasActivities ? ",a" : ",e"); 13959 } else { 13960 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13961 pw.println(mi.pss); 13962 } 13963 if (mi.subitems != null) { 13964 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13965 true, isCompact); 13966 } 13967 } 13968 } 13969 13970 // These are in KB. 13971 static final long[] DUMP_MEM_BUCKETS = new long[] { 13972 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13973 120*1024, 160*1024, 200*1024, 13974 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13975 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13976 }; 13977 13978 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13979 boolean stackLike) { 13980 int start = label.lastIndexOf('.'); 13981 if (start >= 0) start++; 13982 else start = 0; 13983 int end = label.length(); 13984 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13985 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13986 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13987 out.append(bucket); 13988 out.append(stackLike ? "MB." : "MB "); 13989 out.append(label, start, end); 13990 return; 13991 } 13992 } 13993 out.append(memKB/1024); 13994 out.append(stackLike ? "MB." : "MB "); 13995 out.append(label, start, end); 13996 } 13997 13998 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13999 ProcessList.NATIVE_ADJ, 14000 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 14001 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14002 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14003 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14004 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14005 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14006 }; 14007 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14008 "Native", 14009 "System", "Persistent", "Persistent Service", "Foreground", 14010 "Visible", "Perceptible", 14011 "Heavy Weight", "Backup", 14012 "A Services", "Home", 14013 "Previous", "B Services", "Cached" 14014 }; 14015 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14016 "native", 14017 "sys", "pers", "persvc", "fore", 14018 "vis", "percept", 14019 "heavy", "backup", 14020 "servicea", "home", 14021 "prev", "serviceb", "cached" 14022 }; 14023 14024 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14025 long realtime, boolean isCheckinRequest, boolean isCompact) { 14026 if (isCheckinRequest || isCompact) { 14027 // short checkin version 14028 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14029 } else { 14030 pw.println("Applications Memory Usage (kB):"); 14031 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14032 } 14033 } 14034 14035 private static final int KSM_SHARED = 0; 14036 private static final int KSM_SHARING = 1; 14037 private static final int KSM_UNSHARED = 2; 14038 private static final int KSM_VOLATILE = 3; 14039 14040 private final long[] getKsmInfo() { 14041 long[] longOut = new long[4]; 14042 final int[] SINGLE_LONG_FORMAT = new int[] { 14043 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14044 }; 14045 long[] longTmp = new long[1]; 14046 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14047 SINGLE_LONG_FORMAT, null, longTmp, null); 14048 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14049 longTmp[0] = 0; 14050 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14051 SINGLE_LONG_FORMAT, null, longTmp, null); 14052 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14053 longTmp[0] = 0; 14054 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14055 SINGLE_LONG_FORMAT, null, longTmp, null); 14056 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14057 longTmp[0] = 0; 14058 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14059 SINGLE_LONG_FORMAT, null, longTmp, null); 14060 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14061 return longOut; 14062 } 14063 14064 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14065 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14066 boolean dumpDetails = false; 14067 boolean dumpFullDetails = false; 14068 boolean dumpDalvik = false; 14069 boolean oomOnly = false; 14070 boolean isCompact = false; 14071 boolean localOnly = false; 14072 boolean packages = false; 14073 14074 int opti = 0; 14075 while (opti < args.length) { 14076 String opt = args[opti]; 14077 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14078 break; 14079 } 14080 opti++; 14081 if ("-a".equals(opt)) { 14082 dumpDetails = true; 14083 dumpFullDetails = true; 14084 dumpDalvik = true; 14085 } else if ("-d".equals(opt)) { 14086 dumpDalvik = true; 14087 } else if ("-c".equals(opt)) { 14088 isCompact = true; 14089 } else if ("--oom".equals(opt)) { 14090 oomOnly = true; 14091 } else if ("--local".equals(opt)) { 14092 localOnly = true; 14093 } else if ("--package".equals(opt)) { 14094 packages = true; 14095 } else if ("-h".equals(opt)) { 14096 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14097 pw.println(" -a: include all available information for each process."); 14098 pw.println(" -d: include dalvik details when dumping process details."); 14099 pw.println(" -c: dump in a compact machine-parseable representation."); 14100 pw.println(" --oom: only show processes organized by oom adj."); 14101 pw.println(" --local: only collect details locally, don't call process."); 14102 pw.println(" --package: interpret process arg as package, dumping all"); 14103 pw.println(" processes that have loaded that package."); 14104 pw.println("If [process] is specified it can be the name or "); 14105 pw.println("pid of a specific process to dump."); 14106 return; 14107 } else { 14108 pw.println("Unknown argument: " + opt + "; use -h for help"); 14109 } 14110 } 14111 14112 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14113 long uptime = SystemClock.uptimeMillis(); 14114 long realtime = SystemClock.elapsedRealtime(); 14115 final long[] tmpLong = new long[1]; 14116 14117 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14118 if (procs == null) { 14119 // No Java processes. Maybe they want to print a native process. 14120 if (args != null && args.length > opti 14121 && args[opti].charAt(0) != '-') { 14122 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14123 = new ArrayList<ProcessCpuTracker.Stats>(); 14124 updateCpuStatsNow(); 14125 int findPid = -1; 14126 try { 14127 findPid = Integer.parseInt(args[opti]); 14128 } catch (NumberFormatException e) { 14129 } 14130 synchronized (mProcessCpuTracker) { 14131 final int N = mProcessCpuTracker.countStats(); 14132 for (int i=0; i<N; i++) { 14133 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14134 if (st.pid == findPid || (st.baseName != null 14135 && st.baseName.equals(args[opti]))) { 14136 nativeProcs.add(st); 14137 } 14138 } 14139 } 14140 if (nativeProcs.size() > 0) { 14141 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14142 isCompact); 14143 Debug.MemoryInfo mi = null; 14144 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14145 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14146 final int pid = r.pid; 14147 if (!isCheckinRequest && dumpDetails) { 14148 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14149 } 14150 if (mi == null) { 14151 mi = new Debug.MemoryInfo(); 14152 } 14153 if (dumpDetails || (!brief && !oomOnly)) { 14154 Debug.getMemoryInfo(pid, mi); 14155 } else { 14156 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14157 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14158 } 14159 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14160 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14161 if (isCheckinRequest) { 14162 pw.println(); 14163 } 14164 } 14165 return; 14166 } 14167 } 14168 pw.println("No process found for: " + args[opti]); 14169 return; 14170 } 14171 14172 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14173 dumpDetails = true; 14174 } 14175 14176 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14177 14178 String[] innerArgs = new String[args.length-opti]; 14179 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14180 14181 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14182 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14183 long nativePss = 0; 14184 long dalvikPss = 0; 14185 long otherPss = 0; 14186 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14187 14188 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14189 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14190 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14191 14192 long totalPss = 0; 14193 long cachedPss = 0; 14194 14195 Debug.MemoryInfo mi = null; 14196 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14197 final ProcessRecord r = procs.get(i); 14198 final IApplicationThread thread; 14199 final int pid; 14200 final int oomAdj; 14201 final boolean hasActivities; 14202 synchronized (this) { 14203 thread = r.thread; 14204 pid = r.pid; 14205 oomAdj = r.getSetAdjWithServices(); 14206 hasActivities = r.activities.size() > 0; 14207 } 14208 if (thread != null) { 14209 if (!isCheckinRequest && dumpDetails) { 14210 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14211 } 14212 if (mi == null) { 14213 mi = new Debug.MemoryInfo(); 14214 } 14215 if (dumpDetails || (!brief && !oomOnly)) { 14216 Debug.getMemoryInfo(pid, mi); 14217 } else { 14218 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14219 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14220 } 14221 if (dumpDetails) { 14222 if (localOnly) { 14223 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14224 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14225 if (isCheckinRequest) { 14226 pw.println(); 14227 } 14228 } else { 14229 try { 14230 pw.flush(); 14231 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14232 dumpDalvik, innerArgs); 14233 } catch (RemoteException e) { 14234 if (!isCheckinRequest) { 14235 pw.println("Got RemoteException!"); 14236 pw.flush(); 14237 } 14238 } 14239 } 14240 } 14241 14242 final long myTotalPss = mi.getTotalPss(); 14243 final long myTotalUss = mi.getTotalUss(); 14244 14245 synchronized (this) { 14246 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14247 // Record this for posterity if the process has been stable. 14248 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14249 } 14250 } 14251 14252 if (!isCheckinRequest && mi != null) { 14253 totalPss += myTotalPss; 14254 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14255 (hasActivities ? " / activities)" : ")"), 14256 r.processName, myTotalPss, pid, hasActivities); 14257 procMems.add(pssItem); 14258 procMemsMap.put(pid, pssItem); 14259 14260 nativePss += mi.nativePss; 14261 dalvikPss += mi.dalvikPss; 14262 otherPss += mi.otherPss; 14263 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14264 long mem = mi.getOtherPss(j); 14265 miscPss[j] += mem; 14266 otherPss -= mem; 14267 } 14268 14269 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14270 cachedPss += myTotalPss; 14271 } 14272 14273 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14274 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14275 || oomIndex == (oomPss.length-1)) { 14276 oomPss[oomIndex] += myTotalPss; 14277 if (oomProcs[oomIndex] == null) { 14278 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14279 } 14280 oomProcs[oomIndex].add(pssItem); 14281 break; 14282 } 14283 } 14284 } 14285 } 14286 } 14287 14288 long nativeProcTotalPss = 0; 14289 14290 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14291 // If we are showing aggregations, also look for native processes to 14292 // include so that our aggregations are more accurate. 14293 updateCpuStatsNow(); 14294 mi = null; 14295 synchronized (mProcessCpuTracker) { 14296 final int N = mProcessCpuTracker.countStats(); 14297 for (int i=0; i<N; i++) { 14298 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14299 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14300 if (mi == null) { 14301 mi = new Debug.MemoryInfo(); 14302 } 14303 if (!brief && !oomOnly) { 14304 Debug.getMemoryInfo(st.pid, mi); 14305 } else { 14306 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14307 mi.nativePrivateDirty = (int)tmpLong[0]; 14308 } 14309 14310 final long myTotalPss = mi.getTotalPss(); 14311 totalPss += myTotalPss; 14312 nativeProcTotalPss += myTotalPss; 14313 14314 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14315 st.name, myTotalPss, st.pid, false); 14316 procMems.add(pssItem); 14317 14318 nativePss += mi.nativePss; 14319 dalvikPss += mi.dalvikPss; 14320 otherPss += mi.otherPss; 14321 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14322 long mem = mi.getOtherPss(j); 14323 miscPss[j] += mem; 14324 otherPss -= mem; 14325 } 14326 oomPss[0] += myTotalPss; 14327 if (oomProcs[0] == null) { 14328 oomProcs[0] = new ArrayList<MemItem>(); 14329 } 14330 oomProcs[0].add(pssItem); 14331 } 14332 } 14333 } 14334 14335 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14336 14337 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14338 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14339 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14340 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14341 String label = Debug.MemoryInfo.getOtherLabel(j); 14342 catMems.add(new MemItem(label, label, miscPss[j], j)); 14343 } 14344 14345 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14346 for (int j=0; j<oomPss.length; j++) { 14347 if (oomPss[j] != 0) { 14348 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14349 : DUMP_MEM_OOM_LABEL[j]; 14350 MemItem item = new MemItem(label, label, oomPss[j], 14351 DUMP_MEM_OOM_ADJ[j]); 14352 item.subitems = oomProcs[j]; 14353 oomMems.add(item); 14354 } 14355 } 14356 14357 if (!brief && !oomOnly && !isCompact) { 14358 pw.println(); 14359 pw.println("Total PSS by process:"); 14360 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14361 pw.println(); 14362 } 14363 if (!isCompact) { 14364 pw.println("Total PSS by OOM adjustment:"); 14365 } 14366 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14367 if (!brief && !oomOnly) { 14368 PrintWriter out = categoryPw != null ? categoryPw : pw; 14369 if (!isCompact) { 14370 out.println(); 14371 out.println("Total PSS by category:"); 14372 } 14373 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14374 } 14375 if (!isCompact) { 14376 pw.println(); 14377 } 14378 MemInfoReader memInfo = new MemInfoReader(); 14379 memInfo.readMemInfo(); 14380 if (nativeProcTotalPss > 0) { 14381 synchronized (this) { 14382 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14383 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14384 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14385 } 14386 } 14387 if (!brief) { 14388 if (!isCompact) { 14389 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14390 pw.print(" kB (status "); 14391 switch (mLastMemoryLevel) { 14392 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14393 pw.println("normal)"); 14394 break; 14395 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14396 pw.println("moderate)"); 14397 break; 14398 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14399 pw.println("low)"); 14400 break; 14401 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14402 pw.println("critical)"); 14403 break; 14404 default: 14405 pw.print(mLastMemoryLevel); 14406 pw.println(")"); 14407 break; 14408 } 14409 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14410 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14411 pw.print(cachedPss); pw.print(" cached pss + "); 14412 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14413 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14414 } else { 14415 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14416 pw.print(cachedPss + memInfo.getCachedSizeKb() 14417 + memInfo.getFreeSizeKb()); pw.print(","); 14418 pw.println(totalPss - cachedPss); 14419 } 14420 } 14421 if (!isCompact) { 14422 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14423 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14424 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14425 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14426 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14427 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14428 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14429 } 14430 if (!brief) { 14431 if (memInfo.getZramTotalSizeKb() != 0) { 14432 if (!isCompact) { 14433 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14434 pw.print(" kB physical used for "); 14435 pw.print(memInfo.getSwapTotalSizeKb() 14436 - memInfo.getSwapFreeSizeKb()); 14437 pw.print(" kB in swap ("); 14438 pw.print(memInfo.getSwapTotalSizeKb()); 14439 pw.println(" kB total swap)"); 14440 } else { 14441 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14442 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14443 pw.println(memInfo.getSwapFreeSizeKb()); 14444 } 14445 } 14446 final long[] ksm = getKsmInfo(); 14447 if (!isCompact) { 14448 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14449 || ksm[KSM_VOLATILE] != 0) { 14450 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14451 pw.print(" kB saved from shared "); 14452 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14453 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14454 pw.print(" kB unshared; "); 14455 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14456 } 14457 pw.print(" Tuning: "); 14458 pw.print(ActivityManager.staticGetMemoryClass()); 14459 pw.print(" (large "); 14460 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14461 pw.print("), oom "); 14462 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14463 pw.print(" kB"); 14464 pw.print(", restore limit "); 14465 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14466 pw.print(" kB"); 14467 if (ActivityManager.isLowRamDeviceStatic()) { 14468 pw.print(" (low-ram)"); 14469 } 14470 if (ActivityManager.isHighEndGfx()) { 14471 pw.print(" (high-end-gfx)"); 14472 } 14473 pw.println(); 14474 } else { 14475 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14476 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14477 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14478 pw.print("tuning,"); 14479 pw.print(ActivityManager.staticGetMemoryClass()); 14480 pw.print(','); 14481 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14482 pw.print(','); 14483 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14484 if (ActivityManager.isLowRamDeviceStatic()) { 14485 pw.print(",low-ram"); 14486 } 14487 if (ActivityManager.isHighEndGfx()) { 14488 pw.print(",high-end-gfx"); 14489 } 14490 pw.println(); 14491 } 14492 } 14493 } 14494 } 14495 14496 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14497 long memtrack, String name) { 14498 sb.append(" "); 14499 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14500 sb.append(' '); 14501 sb.append(ProcessList.makeProcStateString(procState)); 14502 sb.append(' '); 14503 ProcessList.appendRamKb(sb, pss); 14504 sb.append(" kB: "); 14505 sb.append(name); 14506 if (memtrack > 0) { 14507 sb.append(" ("); 14508 sb.append(memtrack); 14509 sb.append(" kB memtrack)"); 14510 } 14511 } 14512 14513 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14514 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14515 sb.append(" (pid "); 14516 sb.append(mi.pid); 14517 sb.append(") "); 14518 sb.append(mi.adjType); 14519 sb.append('\n'); 14520 if (mi.adjReason != null) { 14521 sb.append(" "); 14522 sb.append(mi.adjReason); 14523 sb.append('\n'); 14524 } 14525 } 14526 14527 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14528 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14529 for (int i=0, N=memInfos.size(); i<N; i++) { 14530 ProcessMemInfo mi = memInfos.get(i); 14531 infoMap.put(mi.pid, mi); 14532 } 14533 updateCpuStatsNow(); 14534 long[] memtrackTmp = new long[1]; 14535 synchronized (mProcessCpuTracker) { 14536 final int N = mProcessCpuTracker.countStats(); 14537 for (int i=0; i<N; i++) { 14538 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14539 if (st.vsize > 0) { 14540 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14541 if (pss > 0) { 14542 if (infoMap.indexOfKey(st.pid) < 0) { 14543 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14544 ProcessList.NATIVE_ADJ, -1, "native", null); 14545 mi.pss = pss; 14546 mi.memtrack = memtrackTmp[0]; 14547 memInfos.add(mi); 14548 } 14549 } 14550 } 14551 } 14552 } 14553 14554 long totalPss = 0; 14555 long totalMemtrack = 0; 14556 for (int i=0, N=memInfos.size(); i<N; i++) { 14557 ProcessMemInfo mi = memInfos.get(i); 14558 if (mi.pss == 0) { 14559 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14560 mi.memtrack = memtrackTmp[0]; 14561 } 14562 totalPss += mi.pss; 14563 totalMemtrack += mi.memtrack; 14564 } 14565 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14566 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14567 if (lhs.oomAdj != rhs.oomAdj) { 14568 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14569 } 14570 if (lhs.pss != rhs.pss) { 14571 return lhs.pss < rhs.pss ? 1 : -1; 14572 } 14573 return 0; 14574 } 14575 }); 14576 14577 StringBuilder tag = new StringBuilder(128); 14578 StringBuilder stack = new StringBuilder(128); 14579 tag.append("Low on memory -- "); 14580 appendMemBucket(tag, totalPss, "total", false); 14581 appendMemBucket(stack, totalPss, "total", true); 14582 14583 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14584 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14585 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14586 14587 boolean firstLine = true; 14588 int lastOomAdj = Integer.MIN_VALUE; 14589 long extraNativeRam = 0; 14590 long extraNativeMemtrack = 0; 14591 long cachedPss = 0; 14592 for (int i=0, N=memInfos.size(); i<N; i++) { 14593 ProcessMemInfo mi = memInfos.get(i); 14594 14595 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14596 cachedPss += mi.pss; 14597 } 14598 14599 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14600 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14601 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14602 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14603 if (lastOomAdj != mi.oomAdj) { 14604 lastOomAdj = mi.oomAdj; 14605 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14606 tag.append(" / "); 14607 } 14608 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14609 if (firstLine) { 14610 stack.append(":"); 14611 firstLine = false; 14612 } 14613 stack.append("\n\t at "); 14614 } else { 14615 stack.append("$"); 14616 } 14617 } else { 14618 tag.append(" "); 14619 stack.append("$"); 14620 } 14621 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14622 appendMemBucket(tag, mi.pss, mi.name, false); 14623 } 14624 appendMemBucket(stack, mi.pss, mi.name, true); 14625 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14626 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14627 stack.append("("); 14628 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14629 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14630 stack.append(DUMP_MEM_OOM_LABEL[k]); 14631 stack.append(":"); 14632 stack.append(DUMP_MEM_OOM_ADJ[k]); 14633 } 14634 } 14635 stack.append(")"); 14636 } 14637 } 14638 14639 appendMemInfo(fullNativeBuilder, mi); 14640 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14641 // The short form only has native processes that are >= 512K. 14642 if (mi.pss >= 512) { 14643 appendMemInfo(shortNativeBuilder, mi); 14644 } else { 14645 extraNativeRam += mi.pss; 14646 extraNativeMemtrack += mi.memtrack; 14647 } 14648 } else { 14649 // Short form has all other details, but if we have collected RAM 14650 // from smaller native processes let's dump a summary of that. 14651 if (extraNativeRam > 0) { 14652 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14653 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14654 shortNativeBuilder.append('\n'); 14655 extraNativeRam = 0; 14656 } 14657 appendMemInfo(fullJavaBuilder, mi); 14658 } 14659 } 14660 14661 fullJavaBuilder.append(" "); 14662 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14663 fullJavaBuilder.append(" kB: TOTAL"); 14664 if (totalMemtrack > 0) { 14665 fullJavaBuilder.append(" ("); 14666 fullJavaBuilder.append(totalMemtrack); 14667 fullJavaBuilder.append(" kB memtrack)"); 14668 } else { 14669 } 14670 fullJavaBuilder.append("\n"); 14671 14672 MemInfoReader memInfo = new MemInfoReader(); 14673 memInfo.readMemInfo(); 14674 final long[] infos = memInfo.getRawInfo(); 14675 14676 StringBuilder memInfoBuilder = new StringBuilder(1024); 14677 Debug.getMemInfo(infos); 14678 memInfoBuilder.append(" MemInfo: "); 14679 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14680 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14681 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14682 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14683 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14684 memInfoBuilder.append(" "); 14685 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14686 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14687 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14688 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14689 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14690 memInfoBuilder.append(" ZRAM: "); 14691 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14692 memInfoBuilder.append(" kB RAM, "); 14693 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14694 memInfoBuilder.append(" kB swap total, "); 14695 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14696 memInfoBuilder.append(" kB swap free\n"); 14697 } 14698 final long[] ksm = getKsmInfo(); 14699 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14700 || ksm[KSM_VOLATILE] != 0) { 14701 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14702 memInfoBuilder.append(" kB saved from shared "); 14703 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14704 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14705 memInfoBuilder.append(" kB unshared; "); 14706 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14707 } 14708 memInfoBuilder.append(" Free RAM: "); 14709 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14710 + memInfo.getFreeSizeKb()); 14711 memInfoBuilder.append(" kB\n"); 14712 memInfoBuilder.append(" Used RAM: "); 14713 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14714 memInfoBuilder.append(" kB\n"); 14715 memInfoBuilder.append(" Lost RAM: "); 14716 memInfoBuilder.append(memInfo.getTotalSizeKb() 14717 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14718 - memInfo.getKernelUsedSizeKb()); 14719 memInfoBuilder.append(" kB\n"); 14720 Slog.i(TAG, "Low on memory:"); 14721 Slog.i(TAG, shortNativeBuilder.toString()); 14722 Slog.i(TAG, fullJavaBuilder.toString()); 14723 Slog.i(TAG, memInfoBuilder.toString()); 14724 14725 StringBuilder dropBuilder = new StringBuilder(1024); 14726 /* 14727 StringWriter oomSw = new StringWriter(); 14728 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14729 StringWriter catSw = new StringWriter(); 14730 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14731 String[] emptyArgs = new String[] { }; 14732 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14733 oomPw.flush(); 14734 String oomString = oomSw.toString(); 14735 */ 14736 dropBuilder.append("Low on memory:"); 14737 dropBuilder.append(stack); 14738 dropBuilder.append('\n'); 14739 dropBuilder.append(fullNativeBuilder); 14740 dropBuilder.append(fullJavaBuilder); 14741 dropBuilder.append('\n'); 14742 dropBuilder.append(memInfoBuilder); 14743 dropBuilder.append('\n'); 14744 /* 14745 dropBuilder.append(oomString); 14746 dropBuilder.append('\n'); 14747 */ 14748 StringWriter catSw = new StringWriter(); 14749 synchronized (ActivityManagerService.this) { 14750 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14751 String[] emptyArgs = new String[] { }; 14752 catPw.println(); 14753 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14754 catPw.println(); 14755 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14756 false, false, null); 14757 catPw.println(); 14758 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14759 catPw.flush(); 14760 } 14761 dropBuilder.append(catSw.toString()); 14762 addErrorToDropBox("lowmem", null, "system_server", null, 14763 null, tag.toString(), dropBuilder.toString(), null, null); 14764 //Slog.i(TAG, "Sent to dropbox:"); 14765 //Slog.i(TAG, dropBuilder.toString()); 14766 synchronized (ActivityManagerService.this) { 14767 long now = SystemClock.uptimeMillis(); 14768 if (mLastMemUsageReportTime < now) { 14769 mLastMemUsageReportTime = now; 14770 } 14771 } 14772 } 14773 14774 /** 14775 * Searches array of arguments for the specified string 14776 * @param args array of argument strings 14777 * @param value value to search for 14778 * @return true if the value is contained in the array 14779 */ 14780 private static boolean scanArgs(String[] args, String value) { 14781 if (args != null) { 14782 for (String arg : args) { 14783 if (value.equals(arg)) { 14784 return true; 14785 } 14786 } 14787 } 14788 return false; 14789 } 14790 14791 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14792 ContentProviderRecord cpr, boolean always) { 14793 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14794 14795 if (!inLaunching || always) { 14796 synchronized (cpr) { 14797 cpr.launchingApp = null; 14798 cpr.notifyAll(); 14799 } 14800 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14801 String names[] = cpr.info.authority.split(";"); 14802 for (int j = 0; j < names.length; j++) { 14803 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14804 } 14805 } 14806 14807 for (int i=0; i<cpr.connections.size(); i++) { 14808 ContentProviderConnection conn = cpr.connections.get(i); 14809 if (conn.waiting) { 14810 // If this connection is waiting for the provider, then we don't 14811 // need to mess with its process unless we are always removing 14812 // or for some reason the provider is not currently launching. 14813 if (inLaunching && !always) { 14814 continue; 14815 } 14816 } 14817 ProcessRecord capp = conn.client; 14818 conn.dead = true; 14819 if (conn.stableCount > 0) { 14820 if (!capp.persistent && capp.thread != null 14821 && capp.pid != 0 14822 && capp.pid != MY_PID) { 14823 capp.kill("depends on provider " 14824 + cpr.name.flattenToShortString() 14825 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14826 } 14827 } else if (capp.thread != null && conn.provider.provider != null) { 14828 try { 14829 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14830 } catch (RemoteException e) { 14831 } 14832 // In the protocol here, we don't expect the client to correctly 14833 // clean up this connection, we'll just remove it. 14834 cpr.connections.remove(i); 14835 if (conn.client.conProviders.remove(conn)) { 14836 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14837 } 14838 } 14839 } 14840 14841 if (inLaunching && always) { 14842 mLaunchingProviders.remove(cpr); 14843 } 14844 return inLaunching; 14845 } 14846 14847 /** 14848 * Main code for cleaning up a process when it has gone away. This is 14849 * called both as a result of the process dying, or directly when stopping 14850 * a process when running in single process mode. 14851 * 14852 * @return Returns true if the given process has been restarted, so the 14853 * app that was passed in must remain on the process lists. 14854 */ 14855 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14856 boolean restarting, boolean allowRestart, int index) { 14857 if (index >= 0) { 14858 removeLruProcessLocked(app); 14859 ProcessList.remove(app.pid); 14860 } 14861 14862 mProcessesToGc.remove(app); 14863 mPendingPssProcesses.remove(app); 14864 14865 // Dismiss any open dialogs. 14866 if (app.crashDialog != null && !app.forceCrashReport) { 14867 app.crashDialog.dismiss(); 14868 app.crashDialog = null; 14869 } 14870 if (app.anrDialog != null) { 14871 app.anrDialog.dismiss(); 14872 app.anrDialog = null; 14873 } 14874 if (app.waitDialog != null) { 14875 app.waitDialog.dismiss(); 14876 app.waitDialog = null; 14877 } 14878 14879 app.crashing = false; 14880 app.notResponding = false; 14881 14882 app.resetPackageList(mProcessStats); 14883 app.unlinkDeathRecipient(); 14884 app.makeInactive(mProcessStats); 14885 app.waitingToKill = null; 14886 app.forcingToForeground = null; 14887 updateProcessForegroundLocked(app, false, false); 14888 app.foregroundActivities = false; 14889 app.hasShownUi = false; 14890 app.treatLikeActivity = false; 14891 app.hasAboveClient = false; 14892 app.hasClientActivities = false; 14893 14894 mServices.killServicesLocked(app, allowRestart); 14895 14896 boolean restart = false; 14897 14898 // Remove published content providers. 14899 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14900 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14901 final boolean always = app.bad || !allowRestart; 14902 if (removeDyingProviderLocked(app, cpr, always) || always) { 14903 // We left the provider in the launching list, need to 14904 // restart it. 14905 restart = true; 14906 } 14907 14908 cpr.provider = null; 14909 cpr.proc = null; 14910 } 14911 app.pubProviders.clear(); 14912 14913 // Take care of any launching providers waiting for this process. 14914 if (checkAppInLaunchingProvidersLocked(app, false)) { 14915 restart = true; 14916 } 14917 14918 // Unregister from connected content providers. 14919 if (!app.conProviders.isEmpty()) { 14920 for (int i=0; i<app.conProviders.size(); i++) { 14921 ContentProviderConnection conn = app.conProviders.get(i); 14922 conn.provider.connections.remove(conn); 14923 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14924 conn.provider.name); 14925 } 14926 app.conProviders.clear(); 14927 } 14928 14929 // At this point there may be remaining entries in mLaunchingProviders 14930 // where we were the only one waiting, so they are no longer of use. 14931 // Look for these and clean up if found. 14932 // XXX Commented out for now. Trying to figure out a way to reproduce 14933 // the actual situation to identify what is actually going on. 14934 if (false) { 14935 for (int i=0; i<mLaunchingProviders.size(); i++) { 14936 ContentProviderRecord cpr = (ContentProviderRecord) 14937 mLaunchingProviders.get(i); 14938 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14939 synchronized (cpr) { 14940 cpr.launchingApp = null; 14941 cpr.notifyAll(); 14942 } 14943 } 14944 } 14945 } 14946 14947 skipCurrentReceiverLocked(app); 14948 14949 // Unregister any receivers. 14950 for (int i=app.receivers.size()-1; i>=0; i--) { 14951 removeReceiverLocked(app.receivers.valueAt(i)); 14952 } 14953 app.receivers.clear(); 14954 14955 // If the app is undergoing backup, tell the backup manager about it 14956 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14957 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14958 + mBackupTarget.appInfo + " died during backup"); 14959 try { 14960 IBackupManager bm = IBackupManager.Stub.asInterface( 14961 ServiceManager.getService(Context.BACKUP_SERVICE)); 14962 bm.agentDisconnected(app.info.packageName); 14963 } catch (RemoteException e) { 14964 // can't happen; backup manager is local 14965 } 14966 } 14967 14968 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14969 ProcessChangeItem item = mPendingProcessChanges.get(i); 14970 if (item.pid == app.pid) { 14971 mPendingProcessChanges.remove(i); 14972 mAvailProcessChanges.add(item); 14973 } 14974 } 14975 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14976 14977 // If the caller is restarting this app, then leave it in its 14978 // current lists and let the caller take care of it. 14979 if (restarting) { 14980 return false; 14981 } 14982 14983 if (!app.persistent || app.isolated) { 14984 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14985 "Removing non-persistent process during cleanup: " + app); 14986 mProcessNames.remove(app.processName, app.uid); 14987 mIsolatedProcesses.remove(app.uid); 14988 if (mHeavyWeightProcess == app) { 14989 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14990 mHeavyWeightProcess.userId, 0)); 14991 mHeavyWeightProcess = null; 14992 } 14993 } else if (!app.removed) { 14994 // This app is persistent, so we need to keep its record around. 14995 // If it is not already on the pending app list, add it there 14996 // and start a new process for it. 14997 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14998 mPersistentStartingProcesses.add(app); 14999 restart = true; 15000 } 15001 } 15002 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15003 "Clean-up removing on hold: " + app); 15004 mProcessesOnHold.remove(app); 15005 15006 if (app == mHomeProcess) { 15007 mHomeProcess = null; 15008 } 15009 if (app == mPreviousProcess) { 15010 mPreviousProcess = null; 15011 } 15012 15013 if (restart && !app.isolated) { 15014 // We have components that still need to be running in the 15015 // process, so re-launch it. 15016 if (index < 0) { 15017 ProcessList.remove(app.pid); 15018 } 15019 mProcessNames.put(app.processName, app.uid, app); 15020 startProcessLocked(app, "restart", app.processName); 15021 return true; 15022 } else if (app.pid > 0 && app.pid != MY_PID) { 15023 // Goodbye! 15024 boolean removed; 15025 synchronized (mPidsSelfLocked) { 15026 mPidsSelfLocked.remove(app.pid); 15027 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15028 } 15029 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15030 if (app.isolated) { 15031 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15032 } 15033 app.setPid(0); 15034 } 15035 return false; 15036 } 15037 15038 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15039 // Look through the content providers we are waiting to have launched, 15040 // and if any run in this process then either schedule a restart of 15041 // the process or kill the client waiting for it if this process has 15042 // gone bad. 15043 int NL = mLaunchingProviders.size(); 15044 boolean restart = false; 15045 for (int i=0; i<NL; i++) { 15046 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15047 if (cpr.launchingApp == app) { 15048 if (!alwaysBad && !app.bad) { 15049 restart = true; 15050 } else { 15051 removeDyingProviderLocked(app, cpr, true); 15052 // cpr should have been removed from mLaunchingProviders 15053 NL = mLaunchingProviders.size(); 15054 i--; 15055 } 15056 } 15057 } 15058 return restart; 15059 } 15060 15061 // ========================================================= 15062 // SERVICES 15063 // ========================================================= 15064 15065 @Override 15066 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15067 int flags) { 15068 enforceNotIsolatedCaller("getServices"); 15069 synchronized (this) { 15070 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15071 } 15072 } 15073 15074 @Override 15075 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15076 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15077 synchronized (this) { 15078 return mServices.getRunningServiceControlPanelLocked(name); 15079 } 15080 } 15081 15082 @Override 15083 public ComponentName startService(IApplicationThread caller, Intent service, 15084 String resolvedType, int userId) { 15085 enforceNotIsolatedCaller("startService"); 15086 // Refuse possible leaked file descriptors 15087 if (service != null && service.hasFileDescriptors() == true) { 15088 throw new IllegalArgumentException("File descriptors passed in Intent"); 15089 } 15090 15091 if (DEBUG_SERVICE) 15092 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15093 synchronized(this) { 15094 final int callingPid = Binder.getCallingPid(); 15095 final int callingUid = Binder.getCallingUid(); 15096 final long origId = Binder.clearCallingIdentity(); 15097 ComponentName res = mServices.startServiceLocked(caller, service, 15098 resolvedType, callingPid, callingUid, userId); 15099 Binder.restoreCallingIdentity(origId); 15100 return res; 15101 } 15102 } 15103 15104 ComponentName startServiceInPackage(int uid, 15105 Intent service, String resolvedType, int userId) { 15106 synchronized(this) { 15107 if (DEBUG_SERVICE) 15108 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15109 final long origId = Binder.clearCallingIdentity(); 15110 ComponentName res = mServices.startServiceLocked(null, service, 15111 resolvedType, -1, uid, userId); 15112 Binder.restoreCallingIdentity(origId); 15113 return res; 15114 } 15115 } 15116 15117 @Override 15118 public int stopService(IApplicationThread caller, Intent service, 15119 String resolvedType, int userId) { 15120 enforceNotIsolatedCaller("stopService"); 15121 // Refuse possible leaked file descriptors 15122 if (service != null && service.hasFileDescriptors() == true) { 15123 throw new IllegalArgumentException("File descriptors passed in Intent"); 15124 } 15125 15126 synchronized(this) { 15127 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15128 } 15129 } 15130 15131 @Override 15132 public IBinder peekService(Intent service, String resolvedType) { 15133 enforceNotIsolatedCaller("peekService"); 15134 // Refuse possible leaked file descriptors 15135 if (service != null && service.hasFileDescriptors() == true) { 15136 throw new IllegalArgumentException("File descriptors passed in Intent"); 15137 } 15138 synchronized(this) { 15139 return mServices.peekServiceLocked(service, resolvedType); 15140 } 15141 } 15142 15143 @Override 15144 public boolean stopServiceToken(ComponentName className, IBinder token, 15145 int startId) { 15146 synchronized(this) { 15147 return mServices.stopServiceTokenLocked(className, token, startId); 15148 } 15149 } 15150 15151 @Override 15152 public void setServiceForeground(ComponentName className, IBinder token, 15153 int id, Notification notification, boolean removeNotification) { 15154 synchronized(this) { 15155 mServices.setServiceForegroundLocked(className, token, id, notification, 15156 removeNotification); 15157 } 15158 } 15159 15160 @Override 15161 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15162 boolean requireFull, String name, String callerPackage) { 15163 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15164 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15165 } 15166 15167 int unsafeConvertIncomingUser(int userId) { 15168 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15169 ? mCurrentUserId : userId; 15170 } 15171 15172 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15173 int allowMode, String name, String callerPackage) { 15174 final int callingUserId = UserHandle.getUserId(callingUid); 15175 if (callingUserId == userId) { 15176 return userId; 15177 } 15178 15179 // Note that we may be accessing mCurrentUserId outside of a lock... 15180 // shouldn't be a big deal, if this is being called outside 15181 // of a locked context there is intrinsically a race with 15182 // the value the caller will receive and someone else changing it. 15183 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15184 // we will switch to the calling user if access to the current user fails. 15185 int targetUserId = unsafeConvertIncomingUser(userId); 15186 15187 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15188 final boolean allow; 15189 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15190 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15191 // If the caller has this permission, they always pass go. And collect $200. 15192 allow = true; 15193 } else if (allowMode == ALLOW_FULL_ONLY) { 15194 // We require full access, sucks to be you. 15195 allow = false; 15196 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15197 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15198 // If the caller does not have either permission, they are always doomed. 15199 allow = false; 15200 } else if (allowMode == ALLOW_NON_FULL) { 15201 // We are blanket allowing non-full access, you lucky caller! 15202 allow = true; 15203 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15204 // We may or may not allow this depending on whether the two users are 15205 // in the same profile. 15206 synchronized (mUserProfileGroupIdsSelfLocked) { 15207 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15208 UserInfo.NO_PROFILE_GROUP_ID); 15209 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15210 UserInfo.NO_PROFILE_GROUP_ID); 15211 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15212 && callingProfile == targetProfile; 15213 } 15214 } else { 15215 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15216 } 15217 if (!allow) { 15218 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15219 // In this case, they would like to just execute as their 15220 // owner user instead of failing. 15221 targetUserId = callingUserId; 15222 } else { 15223 StringBuilder builder = new StringBuilder(128); 15224 builder.append("Permission Denial: "); 15225 builder.append(name); 15226 if (callerPackage != null) { 15227 builder.append(" from "); 15228 builder.append(callerPackage); 15229 } 15230 builder.append(" asks to run as user "); 15231 builder.append(userId); 15232 builder.append(" but is calling from user "); 15233 builder.append(UserHandle.getUserId(callingUid)); 15234 builder.append("; this requires "); 15235 builder.append(INTERACT_ACROSS_USERS_FULL); 15236 if (allowMode != ALLOW_FULL_ONLY) { 15237 builder.append(" or "); 15238 builder.append(INTERACT_ACROSS_USERS); 15239 } 15240 String msg = builder.toString(); 15241 Slog.w(TAG, msg); 15242 throw new SecurityException(msg); 15243 } 15244 } 15245 } 15246 if (!allowAll && targetUserId < 0) { 15247 throw new IllegalArgumentException( 15248 "Call does not support special user #" + targetUserId); 15249 } 15250 // Check shell permission 15251 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15252 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15253 targetUserId)) { 15254 throw new SecurityException("Shell does not have permission to access user " 15255 + targetUserId + "\n " + Debug.getCallers(3)); 15256 } 15257 } 15258 return targetUserId; 15259 } 15260 15261 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15262 String className, int flags) { 15263 boolean result = false; 15264 // For apps that don't have pre-defined UIDs, check for permission 15265 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15266 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15267 if (ActivityManager.checkUidPermission( 15268 INTERACT_ACROSS_USERS, 15269 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15270 ComponentName comp = new ComponentName(aInfo.packageName, className); 15271 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15272 + " requests FLAG_SINGLE_USER, but app does not hold " 15273 + INTERACT_ACROSS_USERS; 15274 Slog.w(TAG, msg); 15275 throw new SecurityException(msg); 15276 } 15277 // Permission passed 15278 result = true; 15279 } 15280 } else if ("system".equals(componentProcessName)) { 15281 result = true; 15282 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15283 // Phone app and persistent apps are allowed to export singleuser providers. 15284 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15285 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15286 } 15287 if (DEBUG_MU) { 15288 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15289 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15290 } 15291 return result; 15292 } 15293 15294 /** 15295 * Checks to see if the caller is in the same app as the singleton 15296 * component, or the component is in a special app. It allows special apps 15297 * to export singleton components but prevents exporting singleton 15298 * components for regular apps. 15299 */ 15300 boolean isValidSingletonCall(int callingUid, int componentUid) { 15301 int componentAppId = UserHandle.getAppId(componentUid); 15302 return UserHandle.isSameApp(callingUid, componentUid) 15303 || componentAppId == Process.SYSTEM_UID 15304 || componentAppId == Process.PHONE_UID 15305 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15306 == PackageManager.PERMISSION_GRANTED; 15307 } 15308 15309 public int bindService(IApplicationThread caller, IBinder token, 15310 Intent service, String resolvedType, 15311 IServiceConnection connection, int flags, int userId) { 15312 enforceNotIsolatedCaller("bindService"); 15313 15314 // Refuse possible leaked file descriptors 15315 if (service != null && service.hasFileDescriptors() == true) { 15316 throw new IllegalArgumentException("File descriptors passed in Intent"); 15317 } 15318 15319 synchronized(this) { 15320 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15321 connection, flags, userId); 15322 } 15323 } 15324 15325 public boolean unbindService(IServiceConnection connection) { 15326 synchronized (this) { 15327 return mServices.unbindServiceLocked(connection); 15328 } 15329 } 15330 15331 public void publishService(IBinder token, Intent intent, IBinder service) { 15332 // Refuse possible leaked file descriptors 15333 if (intent != null && intent.hasFileDescriptors() == true) { 15334 throw new IllegalArgumentException("File descriptors passed in Intent"); 15335 } 15336 15337 synchronized(this) { 15338 if (!(token instanceof ServiceRecord)) { 15339 throw new IllegalArgumentException("Invalid service token"); 15340 } 15341 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15342 } 15343 } 15344 15345 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15346 // Refuse possible leaked file descriptors 15347 if (intent != null && intent.hasFileDescriptors() == true) { 15348 throw new IllegalArgumentException("File descriptors passed in Intent"); 15349 } 15350 15351 synchronized(this) { 15352 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15353 } 15354 } 15355 15356 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15357 synchronized(this) { 15358 if (!(token instanceof ServiceRecord)) { 15359 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 15360 throw new IllegalArgumentException("Invalid service token"); 15361 } 15362 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15363 } 15364 } 15365 15366 // ========================================================= 15367 // BACKUP AND RESTORE 15368 // ========================================================= 15369 15370 // Cause the target app to be launched if necessary and its backup agent 15371 // instantiated. The backup agent will invoke backupAgentCreated() on the 15372 // activity manager to announce its creation. 15373 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15374 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15375 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15376 15377 synchronized(this) { 15378 // !!! TODO: currently no check here that we're already bound 15379 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15380 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15381 synchronized (stats) { 15382 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15383 } 15384 15385 // Backup agent is now in use, its package can't be stopped. 15386 try { 15387 AppGlobals.getPackageManager().setPackageStoppedState( 15388 app.packageName, false, UserHandle.getUserId(app.uid)); 15389 } catch (RemoteException e) { 15390 } catch (IllegalArgumentException e) { 15391 Slog.w(TAG, "Failed trying to unstop package " 15392 + app.packageName + ": " + e); 15393 } 15394 15395 BackupRecord r = new BackupRecord(ss, app, backupMode); 15396 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15397 ? new ComponentName(app.packageName, app.backupAgentName) 15398 : new ComponentName("android", "FullBackupAgent"); 15399 // startProcessLocked() returns existing proc's record if it's already running 15400 ProcessRecord proc = startProcessLocked(app.processName, app, 15401 false, 0, "backup", hostingName, false, false, false); 15402 if (proc == null) { 15403 Slog.e(TAG, "Unable to start backup agent process " + r); 15404 return false; 15405 } 15406 15407 r.app = proc; 15408 mBackupTarget = r; 15409 mBackupAppName = app.packageName; 15410 15411 // Try not to kill the process during backup 15412 updateOomAdjLocked(proc); 15413 15414 // If the process is already attached, schedule the creation of the backup agent now. 15415 // If it is not yet live, this will be done when it attaches to the framework. 15416 if (proc.thread != null) { 15417 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15418 try { 15419 proc.thread.scheduleCreateBackupAgent(app, 15420 compatibilityInfoForPackageLocked(app), backupMode); 15421 } catch (RemoteException e) { 15422 // Will time out on the backup manager side 15423 } 15424 } else { 15425 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15426 } 15427 // Invariants: at this point, the target app process exists and the application 15428 // is either already running or in the process of coming up. mBackupTarget and 15429 // mBackupAppName describe the app, so that when it binds back to the AM we 15430 // know that it's scheduled for a backup-agent operation. 15431 } 15432 15433 return true; 15434 } 15435 15436 @Override 15437 public void clearPendingBackup() { 15438 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15439 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15440 15441 synchronized (this) { 15442 mBackupTarget = null; 15443 mBackupAppName = null; 15444 } 15445 } 15446 15447 // A backup agent has just come up 15448 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15449 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15450 + " = " + agent); 15451 15452 synchronized(this) { 15453 if (!agentPackageName.equals(mBackupAppName)) { 15454 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15455 return; 15456 } 15457 } 15458 15459 long oldIdent = Binder.clearCallingIdentity(); 15460 try { 15461 IBackupManager bm = IBackupManager.Stub.asInterface( 15462 ServiceManager.getService(Context.BACKUP_SERVICE)); 15463 bm.agentConnected(agentPackageName, agent); 15464 } catch (RemoteException e) { 15465 // can't happen; the backup manager service is local 15466 } catch (Exception e) { 15467 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15468 e.printStackTrace(); 15469 } finally { 15470 Binder.restoreCallingIdentity(oldIdent); 15471 } 15472 } 15473 15474 // done with this agent 15475 public void unbindBackupAgent(ApplicationInfo appInfo) { 15476 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15477 if (appInfo == null) { 15478 Slog.w(TAG, "unbind backup agent for null app"); 15479 return; 15480 } 15481 15482 synchronized(this) { 15483 try { 15484 if (mBackupAppName == null) { 15485 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15486 return; 15487 } 15488 15489 if (!mBackupAppName.equals(appInfo.packageName)) { 15490 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15491 return; 15492 } 15493 15494 // Not backing this app up any more; reset its OOM adjustment 15495 final ProcessRecord proc = mBackupTarget.app; 15496 updateOomAdjLocked(proc); 15497 15498 // If the app crashed during backup, 'thread' will be null here 15499 if (proc.thread != null) { 15500 try { 15501 proc.thread.scheduleDestroyBackupAgent(appInfo, 15502 compatibilityInfoForPackageLocked(appInfo)); 15503 } catch (Exception e) { 15504 Slog.e(TAG, "Exception when unbinding backup agent:"); 15505 e.printStackTrace(); 15506 } 15507 } 15508 } finally { 15509 mBackupTarget = null; 15510 mBackupAppName = null; 15511 } 15512 } 15513 } 15514 // ========================================================= 15515 // BROADCASTS 15516 // ========================================================= 15517 15518 private final List getStickiesLocked(String action, IntentFilter filter, 15519 List cur, int userId) { 15520 final ContentResolver resolver = mContext.getContentResolver(); 15521 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15522 if (stickies == null) { 15523 return cur; 15524 } 15525 final ArrayList<Intent> list = stickies.get(action); 15526 if (list == null) { 15527 return cur; 15528 } 15529 int N = list.size(); 15530 for (int i=0; i<N; i++) { 15531 Intent intent = list.get(i); 15532 if (filter.match(resolver, intent, true, TAG) >= 0) { 15533 if (cur == null) { 15534 cur = new ArrayList<Intent>(); 15535 } 15536 cur.add(intent); 15537 } 15538 } 15539 return cur; 15540 } 15541 15542 boolean isPendingBroadcastProcessLocked(int pid) { 15543 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15544 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15545 } 15546 15547 void skipPendingBroadcastLocked(int pid) { 15548 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15549 for (BroadcastQueue queue : mBroadcastQueues) { 15550 queue.skipPendingBroadcastLocked(pid); 15551 } 15552 } 15553 15554 // The app just attached; send any pending broadcasts that it should receive 15555 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15556 boolean didSomething = false; 15557 for (BroadcastQueue queue : mBroadcastQueues) { 15558 didSomething |= queue.sendPendingBroadcastsLocked(app); 15559 } 15560 return didSomething; 15561 } 15562 15563 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15564 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15565 enforceNotIsolatedCaller("registerReceiver"); 15566 int callingUid; 15567 int callingPid; 15568 synchronized(this) { 15569 ProcessRecord callerApp = null; 15570 if (caller != null) { 15571 callerApp = getRecordForAppLocked(caller); 15572 if (callerApp == null) { 15573 throw new SecurityException( 15574 "Unable to find app for caller " + caller 15575 + " (pid=" + Binder.getCallingPid() 15576 + ") when registering receiver " + receiver); 15577 } 15578 if (callerApp.info.uid != Process.SYSTEM_UID && 15579 !callerApp.pkgList.containsKey(callerPackage) && 15580 !"android".equals(callerPackage)) { 15581 throw new SecurityException("Given caller package " + callerPackage 15582 + " is not running in process " + callerApp); 15583 } 15584 callingUid = callerApp.info.uid; 15585 callingPid = callerApp.pid; 15586 } else { 15587 callerPackage = null; 15588 callingUid = Binder.getCallingUid(); 15589 callingPid = Binder.getCallingPid(); 15590 } 15591 15592 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15593 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15594 15595 List allSticky = null; 15596 15597 // Look for any matching sticky broadcasts... 15598 Iterator actions = filter.actionsIterator(); 15599 if (actions != null) { 15600 while (actions.hasNext()) { 15601 String action = (String)actions.next(); 15602 allSticky = getStickiesLocked(action, filter, allSticky, 15603 UserHandle.USER_ALL); 15604 allSticky = getStickiesLocked(action, filter, allSticky, 15605 UserHandle.getUserId(callingUid)); 15606 } 15607 } else { 15608 allSticky = getStickiesLocked(null, filter, allSticky, 15609 UserHandle.USER_ALL); 15610 allSticky = getStickiesLocked(null, filter, allSticky, 15611 UserHandle.getUserId(callingUid)); 15612 } 15613 15614 // The first sticky in the list is returned directly back to 15615 // the client. 15616 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15617 15618 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15619 + ": " + sticky); 15620 15621 if (receiver == null) { 15622 return sticky; 15623 } 15624 15625 ReceiverList rl 15626 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15627 if (rl == null) { 15628 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15629 userId, receiver); 15630 if (rl.app != null) { 15631 rl.app.receivers.add(rl); 15632 } else { 15633 try { 15634 receiver.asBinder().linkToDeath(rl, 0); 15635 } catch (RemoteException e) { 15636 return sticky; 15637 } 15638 rl.linkedToDeath = true; 15639 } 15640 mRegisteredReceivers.put(receiver.asBinder(), rl); 15641 } else if (rl.uid != callingUid) { 15642 throw new IllegalArgumentException( 15643 "Receiver requested to register for uid " + callingUid 15644 + " was previously registered for uid " + rl.uid); 15645 } else if (rl.pid != callingPid) { 15646 throw new IllegalArgumentException( 15647 "Receiver requested to register for pid " + callingPid 15648 + " was previously registered for pid " + rl.pid); 15649 } else if (rl.userId != userId) { 15650 throw new IllegalArgumentException( 15651 "Receiver requested to register for user " + userId 15652 + " was previously registered for user " + rl.userId); 15653 } 15654 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15655 permission, callingUid, userId); 15656 rl.add(bf); 15657 if (!bf.debugCheck()) { 15658 Slog.w(TAG, "==> For Dynamic broadast"); 15659 } 15660 mReceiverResolver.addFilter(bf); 15661 15662 // Enqueue broadcasts for all existing stickies that match 15663 // this filter. 15664 if (allSticky != null) { 15665 ArrayList receivers = new ArrayList(); 15666 receivers.add(bf); 15667 15668 int N = allSticky.size(); 15669 for (int i=0; i<N; i++) { 15670 Intent intent = (Intent)allSticky.get(i); 15671 BroadcastQueue queue = broadcastQueueForIntent(intent); 15672 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15673 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15674 null, null, false, true, true, -1); 15675 queue.enqueueParallelBroadcastLocked(r); 15676 queue.scheduleBroadcastsLocked(); 15677 } 15678 } 15679 15680 return sticky; 15681 } 15682 } 15683 15684 public void unregisterReceiver(IIntentReceiver receiver) { 15685 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15686 15687 final long origId = Binder.clearCallingIdentity(); 15688 try { 15689 boolean doTrim = false; 15690 15691 synchronized(this) { 15692 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15693 if (rl != null) { 15694 if (rl.curBroadcast != null) { 15695 BroadcastRecord r = rl.curBroadcast; 15696 final boolean doNext = finishReceiverLocked( 15697 receiver.asBinder(), r.resultCode, r.resultData, 15698 r.resultExtras, r.resultAbort); 15699 if (doNext) { 15700 doTrim = true; 15701 r.queue.processNextBroadcast(false); 15702 } 15703 } 15704 15705 if (rl.app != null) { 15706 rl.app.receivers.remove(rl); 15707 } 15708 removeReceiverLocked(rl); 15709 if (rl.linkedToDeath) { 15710 rl.linkedToDeath = false; 15711 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15712 } 15713 } 15714 } 15715 15716 // If we actually concluded any broadcasts, we might now be able 15717 // to trim the recipients' apps from our working set 15718 if (doTrim) { 15719 trimApplications(); 15720 return; 15721 } 15722 15723 } finally { 15724 Binder.restoreCallingIdentity(origId); 15725 } 15726 } 15727 15728 void removeReceiverLocked(ReceiverList rl) { 15729 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15730 int N = rl.size(); 15731 for (int i=0; i<N; i++) { 15732 mReceiverResolver.removeFilter(rl.get(i)); 15733 } 15734 } 15735 15736 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15737 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15738 ProcessRecord r = mLruProcesses.get(i); 15739 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15740 try { 15741 r.thread.dispatchPackageBroadcast(cmd, packages); 15742 } catch (RemoteException ex) { 15743 } 15744 } 15745 } 15746 } 15747 15748 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15749 int callingUid, int[] users) { 15750 List<ResolveInfo> receivers = null; 15751 try { 15752 HashSet<ComponentName> singleUserReceivers = null; 15753 boolean scannedFirstReceivers = false; 15754 for (int user : users) { 15755 // Skip users that have Shell restrictions 15756 if (callingUid == Process.SHELL_UID 15757 && getUserManagerLocked().hasUserRestriction( 15758 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15759 continue; 15760 } 15761 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15762 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15763 if (user != 0 && newReceivers != null) { 15764 // If this is not the primary user, we need to check for 15765 // any receivers that should be filtered out. 15766 for (int i=0; i<newReceivers.size(); i++) { 15767 ResolveInfo ri = newReceivers.get(i); 15768 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15769 newReceivers.remove(i); 15770 i--; 15771 } 15772 } 15773 } 15774 if (newReceivers != null && newReceivers.size() == 0) { 15775 newReceivers = null; 15776 } 15777 if (receivers == null) { 15778 receivers = newReceivers; 15779 } else if (newReceivers != null) { 15780 // We need to concatenate the additional receivers 15781 // found with what we have do far. This would be easy, 15782 // but we also need to de-dup any receivers that are 15783 // singleUser. 15784 if (!scannedFirstReceivers) { 15785 // Collect any single user receivers we had already retrieved. 15786 scannedFirstReceivers = true; 15787 for (int i=0; i<receivers.size(); i++) { 15788 ResolveInfo ri = receivers.get(i); 15789 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15790 ComponentName cn = new ComponentName( 15791 ri.activityInfo.packageName, ri.activityInfo.name); 15792 if (singleUserReceivers == null) { 15793 singleUserReceivers = new HashSet<ComponentName>(); 15794 } 15795 singleUserReceivers.add(cn); 15796 } 15797 } 15798 } 15799 // Add the new results to the existing results, tracking 15800 // and de-dupping single user receivers. 15801 for (int i=0; i<newReceivers.size(); i++) { 15802 ResolveInfo ri = newReceivers.get(i); 15803 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15804 ComponentName cn = new ComponentName( 15805 ri.activityInfo.packageName, ri.activityInfo.name); 15806 if (singleUserReceivers == null) { 15807 singleUserReceivers = new HashSet<ComponentName>(); 15808 } 15809 if (!singleUserReceivers.contains(cn)) { 15810 singleUserReceivers.add(cn); 15811 receivers.add(ri); 15812 } 15813 } else { 15814 receivers.add(ri); 15815 } 15816 } 15817 } 15818 } 15819 } catch (RemoteException ex) { 15820 // pm is in same process, this will never happen. 15821 } 15822 return receivers; 15823 } 15824 15825 private final int broadcastIntentLocked(ProcessRecord callerApp, 15826 String callerPackage, Intent intent, String resolvedType, 15827 IIntentReceiver resultTo, int resultCode, String resultData, 15828 Bundle map, String requiredPermission, int appOp, 15829 boolean ordered, boolean sticky, int callingPid, int callingUid, 15830 int userId) { 15831 intent = new Intent(intent); 15832 15833 // By default broadcasts do not go to stopped apps. 15834 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15835 15836 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15837 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15838 + " ordered=" + ordered + " userid=" + userId); 15839 if ((resultTo != null) && !ordered) { 15840 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15841 } 15842 15843 userId = handleIncomingUser(callingPid, callingUid, userId, 15844 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15845 15846 // Make sure that the user who is receiving this broadcast is running. 15847 // If not, we will just skip it. Make an exception for shutdown broadcasts 15848 // and upgrade steps. 15849 15850 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15851 if ((callingUid != Process.SYSTEM_UID 15852 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15853 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15854 Slog.w(TAG, "Skipping broadcast of " + intent 15855 + ": user " + userId + " is stopped"); 15856 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15857 } 15858 } 15859 15860 /* 15861 * Prevent non-system code (defined here to be non-persistent 15862 * processes) from sending protected broadcasts. 15863 */ 15864 int callingAppId = UserHandle.getAppId(callingUid); 15865 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15866 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15867 || callingAppId == Process.NFC_UID || callingUid == 0) { 15868 // Always okay. 15869 } else if (callerApp == null || !callerApp.persistent) { 15870 try { 15871 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15872 intent.getAction())) { 15873 String msg = "Permission Denial: not allowed to send broadcast " 15874 + intent.getAction() + " from pid=" 15875 + callingPid + ", uid=" + callingUid; 15876 Slog.w(TAG, msg); 15877 throw new SecurityException(msg); 15878 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15879 // Special case for compatibility: we don't want apps to send this, 15880 // but historically it has not been protected and apps may be using it 15881 // to poke their own app widget. So, instead of making it protected, 15882 // just limit it to the caller. 15883 if (callerApp == null) { 15884 String msg = "Permission Denial: not allowed to send broadcast " 15885 + intent.getAction() + " from unknown caller."; 15886 Slog.w(TAG, msg); 15887 throw new SecurityException(msg); 15888 } else if (intent.getComponent() != null) { 15889 // They are good enough to send to an explicit component... verify 15890 // it is being sent to the calling app. 15891 if (!intent.getComponent().getPackageName().equals( 15892 callerApp.info.packageName)) { 15893 String msg = "Permission Denial: not allowed to send broadcast " 15894 + intent.getAction() + " to " 15895 + intent.getComponent().getPackageName() + " from " 15896 + callerApp.info.packageName; 15897 Slog.w(TAG, msg); 15898 throw new SecurityException(msg); 15899 } 15900 } else { 15901 // Limit broadcast to their own package. 15902 intent.setPackage(callerApp.info.packageName); 15903 } 15904 } 15905 } catch (RemoteException e) { 15906 Slog.w(TAG, "Remote exception", e); 15907 return ActivityManager.BROADCAST_SUCCESS; 15908 } 15909 } 15910 15911 final String action = intent.getAction(); 15912 if (action != null) { 15913 switch (action) { 15914 case Intent.ACTION_UID_REMOVED: 15915 case Intent.ACTION_PACKAGE_REMOVED: 15916 case Intent.ACTION_PACKAGE_CHANGED: 15917 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15918 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15919 // Handle special intents: if this broadcast is from the package 15920 // manager about a package being removed, we need to remove all of 15921 // its activities from the history stack. 15922 if (checkComponentPermission( 15923 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15924 callingPid, callingUid, -1, true) 15925 != PackageManager.PERMISSION_GRANTED) { 15926 String msg = "Permission Denial: " + intent.getAction() 15927 + " broadcast from " + callerPackage + " (pid=" + callingPid 15928 + ", uid=" + callingUid + ")" 15929 + " requires " 15930 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15931 Slog.w(TAG, msg); 15932 throw new SecurityException(msg); 15933 } 15934 switch (action) { 15935 case Intent.ACTION_UID_REMOVED: 15936 final Bundle intentExtras = intent.getExtras(); 15937 final int uid = intentExtras != null 15938 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15939 if (uid >= 0) { 15940 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15941 synchronized (bs) { 15942 bs.removeUidStatsLocked(uid); 15943 } 15944 mAppOpsService.uidRemoved(uid); 15945 } 15946 break; 15947 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15948 // If resources are unavailable just force stop all those packages 15949 // and flush the attribute cache as well. 15950 String list[] = 15951 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15952 if (list != null && list.length > 0) { 15953 for (int i = 0; i < list.length; i++) { 15954 forceStopPackageLocked(list[i], -1, false, true, true, 15955 false, false, userId, "storage unmount"); 15956 } 15957 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15958 sendPackageBroadcastLocked( 15959 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15960 userId); 15961 } 15962 break; 15963 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15964 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15965 break; 15966 case Intent.ACTION_PACKAGE_REMOVED: 15967 case Intent.ACTION_PACKAGE_CHANGED: 15968 Uri data = intent.getData(); 15969 String ssp; 15970 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15971 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15972 boolean fullUninstall = removed && 15973 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15974 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15975 forceStopPackageLocked(ssp, UserHandle.getAppId( 15976 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15977 false, true, true, false, fullUninstall, userId, 15978 removed ? "pkg removed" : "pkg changed"); 15979 } 15980 if (removed) { 15981 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15982 new String[] {ssp}, userId); 15983 if (fullUninstall) { 15984 mAppOpsService.packageRemoved( 15985 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15986 15987 // Remove all permissions granted from/to this package 15988 removeUriPermissionsForPackageLocked(ssp, userId, true); 15989 15990 removeTasksByPackageNameLocked(ssp, userId); 15991 if (userId == UserHandle.USER_OWNER) { 15992 mTaskPersister.removeFromPackageCache(ssp); 15993 } 15994 } 15995 } else { 15996 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15997 if (userId == UserHandle.USER_OWNER) { 15998 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15999 } 16000 } 16001 } 16002 break; 16003 } 16004 break; 16005 case Intent.ACTION_PACKAGE_ADDED: 16006 // Special case for adding a package: by default turn on compatibility mode. 16007 Uri data = intent.getData(); 16008 String ssp; 16009 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16010 final boolean replacing = 16011 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16012 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16013 16014 if (replacing) { 16015 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16016 } 16017 if (userId == UserHandle.USER_OWNER) { 16018 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16019 } 16020 } 16021 break; 16022 case Intent.ACTION_TIMEZONE_CHANGED: 16023 // If this is the time zone changed action, queue up a message that will reset 16024 // the timezone of all currently running processes. This message will get 16025 // queued up before the broadcast happens. 16026 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16027 break; 16028 case Intent.ACTION_TIME_CHANGED: 16029 // If the user set the time, let all running processes know. 16030 final int is24Hour = 16031 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16032 : 0; 16033 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16034 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16035 synchronized (stats) { 16036 stats.noteCurrentTimeChangedLocked(); 16037 } 16038 break; 16039 case Intent.ACTION_CLEAR_DNS_CACHE: 16040 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16041 break; 16042 case Proxy.PROXY_CHANGE_ACTION: 16043 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16044 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16045 break; 16046 } 16047 } 16048 16049 // Add to the sticky list if requested. 16050 if (sticky) { 16051 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16052 callingPid, callingUid) 16053 != PackageManager.PERMISSION_GRANTED) { 16054 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16055 + callingPid + ", uid=" + callingUid 16056 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16057 Slog.w(TAG, msg); 16058 throw new SecurityException(msg); 16059 } 16060 if (requiredPermission != null) { 16061 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16062 + " and enforce permission " + requiredPermission); 16063 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16064 } 16065 if (intent.getComponent() != null) { 16066 throw new SecurityException( 16067 "Sticky broadcasts can't target a specific component"); 16068 } 16069 // We use userId directly here, since the "all" target is maintained 16070 // as a separate set of sticky broadcasts. 16071 if (userId != UserHandle.USER_ALL) { 16072 // But first, if this is not a broadcast to all users, then 16073 // make sure it doesn't conflict with an existing broadcast to 16074 // all users. 16075 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16076 UserHandle.USER_ALL); 16077 if (stickies != null) { 16078 ArrayList<Intent> list = stickies.get(intent.getAction()); 16079 if (list != null) { 16080 int N = list.size(); 16081 int i; 16082 for (i=0; i<N; i++) { 16083 if (intent.filterEquals(list.get(i))) { 16084 throw new IllegalArgumentException( 16085 "Sticky broadcast " + intent + " for user " 16086 + userId + " conflicts with existing global broadcast"); 16087 } 16088 } 16089 } 16090 } 16091 } 16092 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16093 if (stickies == null) { 16094 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16095 mStickyBroadcasts.put(userId, stickies); 16096 } 16097 ArrayList<Intent> list = stickies.get(intent.getAction()); 16098 if (list == null) { 16099 list = new ArrayList<Intent>(); 16100 stickies.put(intent.getAction(), list); 16101 } 16102 int N = list.size(); 16103 int i; 16104 for (i=0; i<N; i++) { 16105 if (intent.filterEquals(list.get(i))) { 16106 // This sticky already exists, replace it. 16107 list.set(i, new Intent(intent)); 16108 break; 16109 } 16110 } 16111 if (i >= N) { 16112 list.add(new Intent(intent)); 16113 } 16114 } 16115 16116 int[] users; 16117 if (userId == UserHandle.USER_ALL) { 16118 // Caller wants broadcast to go to all started users. 16119 users = mStartedUserArray; 16120 } else { 16121 // Caller wants broadcast to go to one specific user. 16122 users = new int[] {userId}; 16123 } 16124 16125 // Figure out who all will receive this broadcast. 16126 List receivers = null; 16127 List<BroadcastFilter> registeredReceivers = null; 16128 // Need to resolve the intent to interested receivers... 16129 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16130 == 0) { 16131 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16132 } 16133 if (intent.getComponent() == null) { 16134 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16135 // Query one target user at a time, excluding shell-restricted users 16136 UserManagerService ums = getUserManagerLocked(); 16137 for (int i = 0; i < users.length; i++) { 16138 if (ums.hasUserRestriction( 16139 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16140 continue; 16141 } 16142 List<BroadcastFilter> registeredReceiversForUser = 16143 mReceiverResolver.queryIntent(intent, 16144 resolvedType, false, users[i]); 16145 if (registeredReceivers == null) { 16146 registeredReceivers = registeredReceiversForUser; 16147 } else if (registeredReceiversForUser != null) { 16148 registeredReceivers.addAll(registeredReceiversForUser); 16149 } 16150 } 16151 } else { 16152 registeredReceivers = mReceiverResolver.queryIntent(intent, 16153 resolvedType, false, userId); 16154 } 16155 } 16156 16157 final boolean replacePending = 16158 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16159 16160 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16161 + " replacePending=" + replacePending); 16162 16163 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16164 if (!ordered && NR > 0) { 16165 // If we are not serializing this broadcast, then send the 16166 // registered receivers separately so they don't wait for the 16167 // components to be launched. 16168 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16169 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16170 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16171 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16172 ordered, sticky, false, userId); 16173 if (DEBUG_BROADCAST) Slog.v( 16174 TAG, "Enqueueing parallel broadcast " + r); 16175 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16176 if (!replaced) { 16177 queue.enqueueParallelBroadcastLocked(r); 16178 queue.scheduleBroadcastsLocked(); 16179 } 16180 registeredReceivers = null; 16181 NR = 0; 16182 } 16183 16184 // Merge into one list. 16185 int ir = 0; 16186 if (receivers != null) { 16187 // A special case for PACKAGE_ADDED: do not allow the package 16188 // being added to see this broadcast. This prevents them from 16189 // using this as a back door to get run as soon as they are 16190 // installed. Maybe in the future we want to have a special install 16191 // broadcast or such for apps, but we'd like to deliberately make 16192 // this decision. 16193 String skipPackages[] = null; 16194 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16195 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16196 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16197 Uri data = intent.getData(); 16198 if (data != null) { 16199 String pkgName = data.getSchemeSpecificPart(); 16200 if (pkgName != null) { 16201 skipPackages = new String[] { pkgName }; 16202 } 16203 } 16204 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16205 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16206 } 16207 if (skipPackages != null && (skipPackages.length > 0)) { 16208 for (String skipPackage : skipPackages) { 16209 if (skipPackage != null) { 16210 int NT = receivers.size(); 16211 for (int it=0; it<NT; it++) { 16212 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16213 if (curt.activityInfo.packageName.equals(skipPackage)) { 16214 receivers.remove(it); 16215 it--; 16216 NT--; 16217 } 16218 } 16219 } 16220 } 16221 } 16222 16223 int NT = receivers != null ? receivers.size() : 0; 16224 int it = 0; 16225 ResolveInfo curt = null; 16226 BroadcastFilter curr = null; 16227 while (it < NT && ir < NR) { 16228 if (curt == null) { 16229 curt = (ResolveInfo)receivers.get(it); 16230 } 16231 if (curr == null) { 16232 curr = registeredReceivers.get(ir); 16233 } 16234 if (curr.getPriority() >= curt.priority) { 16235 // Insert this broadcast record into the final list. 16236 receivers.add(it, curr); 16237 ir++; 16238 curr = null; 16239 it++; 16240 NT++; 16241 } else { 16242 // Skip to the next ResolveInfo in the final list. 16243 it++; 16244 curt = null; 16245 } 16246 } 16247 } 16248 while (ir < NR) { 16249 if (receivers == null) { 16250 receivers = new ArrayList(); 16251 } 16252 receivers.add(registeredReceivers.get(ir)); 16253 ir++; 16254 } 16255 16256 if ((receivers != null && receivers.size() > 0) 16257 || resultTo != null) { 16258 BroadcastQueue queue = broadcastQueueForIntent(intent); 16259 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16260 callerPackage, callingPid, callingUid, resolvedType, 16261 requiredPermission, appOp, receivers, resultTo, resultCode, 16262 resultData, map, ordered, sticky, false, userId); 16263 if (DEBUG_BROADCAST) Slog.v( 16264 TAG, "Enqueueing ordered broadcast " + r 16265 + ": prev had " + queue.mOrderedBroadcasts.size()); 16266 if (DEBUG_BROADCAST) { 16267 int seq = r.intent.getIntExtra("seq", -1); 16268 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16269 } 16270 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16271 if (!replaced) { 16272 queue.enqueueOrderedBroadcastLocked(r); 16273 queue.scheduleBroadcastsLocked(); 16274 } 16275 } 16276 16277 return ActivityManager.BROADCAST_SUCCESS; 16278 } 16279 16280 final Intent verifyBroadcastLocked(Intent intent) { 16281 // Refuse possible leaked file descriptors 16282 if (intent != null && intent.hasFileDescriptors() == true) { 16283 throw new IllegalArgumentException("File descriptors passed in Intent"); 16284 } 16285 16286 int flags = intent.getFlags(); 16287 16288 if (!mProcessesReady) { 16289 // if the caller really truly claims to know what they're doing, go 16290 // ahead and allow the broadcast without launching any receivers 16291 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16292 intent = new Intent(intent); 16293 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16294 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16295 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16296 + " before boot completion"); 16297 throw new IllegalStateException("Cannot broadcast before boot completed"); 16298 } 16299 } 16300 16301 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16302 throw new IllegalArgumentException( 16303 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16304 } 16305 16306 return intent; 16307 } 16308 16309 public final int broadcastIntent(IApplicationThread caller, 16310 Intent intent, String resolvedType, IIntentReceiver resultTo, 16311 int resultCode, String resultData, Bundle map, 16312 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16313 enforceNotIsolatedCaller("broadcastIntent"); 16314 synchronized(this) { 16315 intent = verifyBroadcastLocked(intent); 16316 16317 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16318 final int callingPid = Binder.getCallingPid(); 16319 final int callingUid = Binder.getCallingUid(); 16320 final long origId = Binder.clearCallingIdentity(); 16321 int res = broadcastIntentLocked(callerApp, 16322 callerApp != null ? callerApp.info.packageName : null, 16323 intent, resolvedType, resultTo, 16324 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16325 callingPid, callingUid, userId); 16326 Binder.restoreCallingIdentity(origId); 16327 return res; 16328 } 16329 } 16330 16331 int broadcastIntentInPackage(String packageName, int uid, 16332 Intent intent, String resolvedType, IIntentReceiver resultTo, 16333 int resultCode, String resultData, Bundle map, 16334 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16335 synchronized(this) { 16336 intent = verifyBroadcastLocked(intent); 16337 16338 final long origId = Binder.clearCallingIdentity(); 16339 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16340 resultTo, resultCode, resultData, map, requiredPermission, 16341 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16342 Binder.restoreCallingIdentity(origId); 16343 return res; 16344 } 16345 } 16346 16347 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16348 // Refuse possible leaked file descriptors 16349 if (intent != null && intent.hasFileDescriptors() == true) { 16350 throw new IllegalArgumentException("File descriptors passed in Intent"); 16351 } 16352 16353 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16354 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16355 16356 synchronized(this) { 16357 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16358 != PackageManager.PERMISSION_GRANTED) { 16359 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16360 + Binder.getCallingPid() 16361 + ", uid=" + Binder.getCallingUid() 16362 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16363 Slog.w(TAG, msg); 16364 throw new SecurityException(msg); 16365 } 16366 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16367 if (stickies != null) { 16368 ArrayList<Intent> list = stickies.get(intent.getAction()); 16369 if (list != null) { 16370 int N = list.size(); 16371 int i; 16372 for (i=0; i<N; i++) { 16373 if (intent.filterEquals(list.get(i))) { 16374 list.remove(i); 16375 break; 16376 } 16377 } 16378 if (list.size() <= 0) { 16379 stickies.remove(intent.getAction()); 16380 } 16381 } 16382 if (stickies.size() <= 0) { 16383 mStickyBroadcasts.remove(userId); 16384 } 16385 } 16386 } 16387 } 16388 16389 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16390 String resultData, Bundle resultExtras, boolean resultAbort) { 16391 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16392 if (r == null) { 16393 Slog.w(TAG, "finishReceiver called but not found on queue"); 16394 return false; 16395 } 16396 16397 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16398 } 16399 16400 void backgroundServicesFinishedLocked(int userId) { 16401 for (BroadcastQueue queue : mBroadcastQueues) { 16402 queue.backgroundServicesFinishedLocked(userId); 16403 } 16404 } 16405 16406 public void finishReceiver(IBinder who, int resultCode, String resultData, 16407 Bundle resultExtras, boolean resultAbort) { 16408 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16409 16410 // Refuse possible leaked file descriptors 16411 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16412 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16413 } 16414 16415 final long origId = Binder.clearCallingIdentity(); 16416 try { 16417 boolean doNext = false; 16418 BroadcastRecord r; 16419 16420 synchronized(this) { 16421 r = broadcastRecordForReceiverLocked(who); 16422 if (r != null) { 16423 doNext = r.queue.finishReceiverLocked(r, resultCode, 16424 resultData, resultExtras, resultAbort, true); 16425 } 16426 } 16427 16428 if (doNext) { 16429 r.queue.processNextBroadcast(false); 16430 } 16431 trimApplications(); 16432 } finally { 16433 Binder.restoreCallingIdentity(origId); 16434 } 16435 } 16436 16437 // ========================================================= 16438 // INSTRUMENTATION 16439 // ========================================================= 16440 16441 public boolean startInstrumentation(ComponentName className, 16442 String profileFile, int flags, Bundle arguments, 16443 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16444 int userId, String abiOverride) { 16445 enforceNotIsolatedCaller("startInstrumentation"); 16446 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16447 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16448 // Refuse possible leaked file descriptors 16449 if (arguments != null && arguments.hasFileDescriptors()) { 16450 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16451 } 16452 16453 synchronized(this) { 16454 InstrumentationInfo ii = null; 16455 ApplicationInfo ai = null; 16456 try { 16457 ii = mContext.getPackageManager().getInstrumentationInfo( 16458 className, STOCK_PM_FLAGS); 16459 ai = AppGlobals.getPackageManager().getApplicationInfo( 16460 ii.targetPackage, STOCK_PM_FLAGS, userId); 16461 } catch (PackageManager.NameNotFoundException e) { 16462 } catch (RemoteException e) { 16463 } 16464 if (ii == null) { 16465 reportStartInstrumentationFailure(watcher, className, 16466 "Unable to find instrumentation info for: " + className); 16467 return false; 16468 } 16469 if (ai == null) { 16470 reportStartInstrumentationFailure(watcher, className, 16471 "Unable to find instrumentation target package: " + ii.targetPackage); 16472 return false; 16473 } 16474 16475 int match = mContext.getPackageManager().checkSignatures( 16476 ii.targetPackage, ii.packageName); 16477 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16478 String msg = "Permission Denial: starting instrumentation " 16479 + className + " from pid=" 16480 + Binder.getCallingPid() 16481 + ", uid=" + Binder.getCallingPid() 16482 + " not allowed because package " + ii.packageName 16483 + " does not have a signature matching the target " 16484 + ii.targetPackage; 16485 reportStartInstrumentationFailure(watcher, className, msg); 16486 throw new SecurityException(msg); 16487 } 16488 16489 final long origId = Binder.clearCallingIdentity(); 16490 // Instrumentation can kill and relaunch even persistent processes 16491 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16492 "start instr"); 16493 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16494 app.instrumentationClass = className; 16495 app.instrumentationInfo = ai; 16496 app.instrumentationProfileFile = profileFile; 16497 app.instrumentationArguments = arguments; 16498 app.instrumentationWatcher = watcher; 16499 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16500 app.instrumentationResultClass = className; 16501 Binder.restoreCallingIdentity(origId); 16502 } 16503 16504 return true; 16505 } 16506 16507 /** 16508 * Report errors that occur while attempting to start Instrumentation. Always writes the 16509 * error to the logs, but if somebody is watching, send the report there too. This enables 16510 * the "am" command to report errors with more information. 16511 * 16512 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16513 * @param cn The component name of the instrumentation. 16514 * @param report The error report. 16515 */ 16516 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16517 ComponentName cn, String report) { 16518 Slog.w(TAG, report); 16519 try { 16520 if (watcher != null) { 16521 Bundle results = new Bundle(); 16522 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16523 results.putString("Error", report); 16524 watcher.instrumentationStatus(cn, -1, results); 16525 } 16526 } catch (RemoteException e) { 16527 Slog.w(TAG, e); 16528 } 16529 } 16530 16531 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16532 if (app.instrumentationWatcher != null) { 16533 try { 16534 // NOTE: IInstrumentationWatcher *must* be oneway here 16535 app.instrumentationWatcher.instrumentationFinished( 16536 app.instrumentationClass, 16537 resultCode, 16538 results); 16539 } catch (RemoteException e) { 16540 } 16541 } 16542 if (app.instrumentationUiAutomationConnection != null) { 16543 try { 16544 app.instrumentationUiAutomationConnection.shutdown(); 16545 } catch (RemoteException re) { 16546 /* ignore */ 16547 } 16548 // Only a UiAutomation can set this flag and now that 16549 // it is finished we make sure it is reset to its default. 16550 mUserIsMonkey = false; 16551 } 16552 app.instrumentationWatcher = null; 16553 app.instrumentationUiAutomationConnection = null; 16554 app.instrumentationClass = null; 16555 app.instrumentationInfo = null; 16556 app.instrumentationProfileFile = null; 16557 app.instrumentationArguments = null; 16558 16559 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16560 "finished inst"); 16561 } 16562 16563 public void finishInstrumentation(IApplicationThread target, 16564 int resultCode, Bundle results) { 16565 int userId = UserHandle.getCallingUserId(); 16566 // Refuse possible leaked file descriptors 16567 if (results != null && results.hasFileDescriptors()) { 16568 throw new IllegalArgumentException("File descriptors passed in Intent"); 16569 } 16570 16571 synchronized(this) { 16572 ProcessRecord app = getRecordForAppLocked(target); 16573 if (app == null) { 16574 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16575 return; 16576 } 16577 final long origId = Binder.clearCallingIdentity(); 16578 finishInstrumentationLocked(app, resultCode, results); 16579 Binder.restoreCallingIdentity(origId); 16580 } 16581 } 16582 16583 // ========================================================= 16584 // CONFIGURATION 16585 // ========================================================= 16586 16587 public ConfigurationInfo getDeviceConfigurationInfo() { 16588 ConfigurationInfo config = new ConfigurationInfo(); 16589 synchronized (this) { 16590 config.reqTouchScreen = mConfiguration.touchscreen; 16591 config.reqKeyboardType = mConfiguration.keyboard; 16592 config.reqNavigation = mConfiguration.navigation; 16593 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16594 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16595 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16596 } 16597 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16598 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16599 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16600 } 16601 config.reqGlEsVersion = GL_ES_VERSION; 16602 } 16603 return config; 16604 } 16605 16606 ActivityStack getFocusedStack() { 16607 return mStackSupervisor.getFocusedStack(); 16608 } 16609 16610 public Configuration getConfiguration() { 16611 Configuration ci; 16612 synchronized(this) { 16613 ci = new Configuration(mConfiguration); 16614 ci.userSetLocale = false; 16615 } 16616 return ci; 16617 } 16618 16619 public void updatePersistentConfiguration(Configuration values) { 16620 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16621 "updateConfiguration()"); 16622 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16623 "updateConfiguration()"); 16624 if (values == null) { 16625 throw new NullPointerException("Configuration must not be null"); 16626 } 16627 16628 synchronized(this) { 16629 final long origId = Binder.clearCallingIdentity(); 16630 updateConfigurationLocked(values, null, true, false); 16631 Binder.restoreCallingIdentity(origId); 16632 } 16633 } 16634 16635 public void updateConfiguration(Configuration values) { 16636 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16637 "updateConfiguration()"); 16638 16639 synchronized(this) { 16640 if (values == null && mWindowManager != null) { 16641 // sentinel: fetch the current configuration from the window manager 16642 values = mWindowManager.computeNewConfiguration(); 16643 } 16644 16645 if (mWindowManager != null) { 16646 mProcessList.applyDisplaySize(mWindowManager); 16647 } 16648 16649 final long origId = Binder.clearCallingIdentity(); 16650 if (values != null) { 16651 Settings.System.clearConfiguration(values); 16652 } 16653 updateConfigurationLocked(values, null, false, false); 16654 Binder.restoreCallingIdentity(origId); 16655 } 16656 } 16657 16658 /** 16659 * Do either or both things: (1) change the current configuration, and (2) 16660 * make sure the given activity is running with the (now) current 16661 * configuration. Returns true if the activity has been left running, or 16662 * false if <var>starting</var> is being destroyed to match the new 16663 * configuration. 16664 * @param persistent TODO 16665 */ 16666 boolean updateConfigurationLocked(Configuration values, 16667 ActivityRecord starting, boolean persistent, boolean initLocale) { 16668 int changes = 0; 16669 16670 if (values != null) { 16671 Configuration newConfig = new Configuration(mConfiguration); 16672 changes = newConfig.updateFrom(values); 16673 if (changes != 0) { 16674 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16675 Slog.i(TAG, "Updating configuration to: " + values); 16676 } 16677 16678 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16679 16680 if (values.locale != null && !initLocale) { 16681 saveLocaleLocked(values.locale, 16682 !values.locale.equals(mConfiguration.locale), 16683 values.userSetLocale); 16684 } 16685 16686 mConfigurationSeq++; 16687 if (mConfigurationSeq <= 0) { 16688 mConfigurationSeq = 1; 16689 } 16690 newConfig.seq = mConfigurationSeq; 16691 mConfiguration = newConfig; 16692 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16693 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16694 //mUsageStatsService.noteStartConfig(newConfig); 16695 16696 final Configuration configCopy = new Configuration(mConfiguration); 16697 16698 // TODO: If our config changes, should we auto dismiss any currently 16699 // showing dialogs? 16700 mShowDialogs = shouldShowDialogs(newConfig); 16701 16702 AttributeCache ac = AttributeCache.instance(); 16703 if (ac != null) { 16704 ac.updateConfiguration(configCopy); 16705 } 16706 16707 // Make sure all resources in our process are updated 16708 // right now, so that anyone who is going to retrieve 16709 // resource values after we return will be sure to get 16710 // the new ones. This is especially important during 16711 // boot, where the first config change needs to guarantee 16712 // all resources have that config before following boot 16713 // code is executed. 16714 mSystemThread.applyConfigurationToResources(configCopy); 16715 16716 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16717 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16718 msg.obj = new Configuration(configCopy); 16719 mHandler.sendMessage(msg); 16720 } 16721 16722 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16723 ProcessRecord app = mLruProcesses.get(i); 16724 try { 16725 if (app.thread != null) { 16726 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16727 + app.processName + " new config " + mConfiguration); 16728 app.thread.scheduleConfigurationChanged(configCopy); 16729 } 16730 } catch (Exception e) { 16731 } 16732 } 16733 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16734 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16735 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16736 | Intent.FLAG_RECEIVER_FOREGROUND); 16737 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16738 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16739 Process.SYSTEM_UID, UserHandle.USER_ALL); 16740 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16741 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16742 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16743 broadcastIntentLocked(null, null, intent, 16744 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16745 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16746 } 16747 } 16748 } 16749 16750 boolean kept = true; 16751 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16752 // mainStack is null during startup. 16753 if (mainStack != null) { 16754 if (changes != 0 && starting == null) { 16755 // If the configuration changed, and the caller is not already 16756 // in the process of starting an activity, then find the top 16757 // activity to check if its configuration needs to change. 16758 starting = mainStack.topRunningActivityLocked(null); 16759 } 16760 16761 if (starting != null) { 16762 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16763 // And we need to make sure at this point that all other activities 16764 // are made visible with the correct configuration. 16765 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16766 } 16767 } 16768 16769 if (values != null && mWindowManager != null) { 16770 mWindowManager.setNewConfiguration(mConfiguration); 16771 } 16772 16773 return kept; 16774 } 16775 16776 /** 16777 * Decide based on the configuration whether we should shouw the ANR, 16778 * crash, etc dialogs. The idea is that if there is no affordnace to 16779 * press the on-screen buttons, we shouldn't show the dialog. 16780 * 16781 * A thought: SystemUI might also want to get told about this, the Power 16782 * dialog / global actions also might want different behaviors. 16783 */ 16784 private static final boolean shouldShowDialogs(Configuration config) { 16785 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16786 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16787 } 16788 16789 /** 16790 * Save the locale. You must be inside a synchronized (this) block. 16791 */ 16792 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16793 if(isDiff) { 16794 SystemProperties.set("user.language", l.getLanguage()); 16795 SystemProperties.set("user.region", l.getCountry()); 16796 } 16797 16798 if(isPersist) { 16799 SystemProperties.set("persist.sys.language", l.getLanguage()); 16800 SystemProperties.set("persist.sys.country", l.getCountry()); 16801 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16802 16803 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16804 } 16805 } 16806 16807 @Override 16808 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16809 synchronized (this) { 16810 ActivityRecord srec = ActivityRecord.forToken(token); 16811 if (srec.task != null && srec.task.stack != null) { 16812 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16813 } 16814 } 16815 return false; 16816 } 16817 16818 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16819 Intent resultData) { 16820 16821 synchronized (this) { 16822 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16823 if (stack != null) { 16824 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16825 } 16826 return false; 16827 } 16828 } 16829 16830 public int getLaunchedFromUid(IBinder activityToken) { 16831 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16832 if (srec == null) { 16833 return -1; 16834 } 16835 return srec.launchedFromUid; 16836 } 16837 16838 public String getLaunchedFromPackage(IBinder activityToken) { 16839 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16840 if (srec == null) { 16841 return null; 16842 } 16843 return srec.launchedFromPackage; 16844 } 16845 16846 // ========================================================= 16847 // LIFETIME MANAGEMENT 16848 // ========================================================= 16849 16850 // Returns which broadcast queue the app is the current [or imminent] receiver 16851 // on, or 'null' if the app is not an active broadcast recipient. 16852 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16853 BroadcastRecord r = app.curReceiver; 16854 if (r != null) { 16855 return r.queue; 16856 } 16857 16858 // It's not the current receiver, but it might be starting up to become one 16859 synchronized (this) { 16860 for (BroadcastQueue queue : mBroadcastQueues) { 16861 r = queue.mPendingBroadcast; 16862 if (r != null && r.curApp == app) { 16863 // found it; report which queue it's in 16864 return queue; 16865 } 16866 } 16867 } 16868 16869 return null; 16870 } 16871 16872 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16873 ComponentName targetComponent, String targetProcess) { 16874 if (!mTrackingAssociations) { 16875 return null; 16876 } 16877 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16878 = mAssociations.get(targetUid); 16879 if (components == null) { 16880 components = new ArrayMap<>(); 16881 mAssociations.put(targetUid, components); 16882 } 16883 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16884 if (sourceUids == null) { 16885 sourceUids = new SparseArray<>(); 16886 components.put(targetComponent, sourceUids); 16887 } 16888 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16889 if (sourceProcesses == null) { 16890 sourceProcesses = new ArrayMap<>(); 16891 sourceUids.put(sourceUid, sourceProcesses); 16892 } 16893 Association ass = sourceProcesses.get(sourceProcess); 16894 if (ass == null) { 16895 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16896 targetProcess); 16897 sourceProcesses.put(sourceProcess, ass); 16898 } 16899 ass.mCount++; 16900 ass.mNesting++; 16901 if (ass.mNesting == 1) { 16902 ass.mStartTime = SystemClock.uptimeMillis(); 16903 } 16904 return ass; 16905 } 16906 16907 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16908 ComponentName targetComponent) { 16909 if (!mTrackingAssociations) { 16910 return; 16911 } 16912 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16913 = mAssociations.get(targetUid); 16914 if (components == null) { 16915 return; 16916 } 16917 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16918 if (sourceUids == null) { 16919 return; 16920 } 16921 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16922 if (sourceProcesses == null) { 16923 return; 16924 } 16925 Association ass = sourceProcesses.get(sourceProcess); 16926 if (ass == null || ass.mNesting <= 0) { 16927 return; 16928 } 16929 ass.mNesting--; 16930 if (ass.mNesting == 0) { 16931 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16932 } 16933 } 16934 16935 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16936 boolean doingAll, long now) { 16937 if (mAdjSeq == app.adjSeq) { 16938 // This adjustment has already been computed. 16939 return app.curRawAdj; 16940 } 16941 16942 if (app.thread == null) { 16943 app.adjSeq = mAdjSeq; 16944 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16945 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16946 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16947 } 16948 16949 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16950 app.adjSource = null; 16951 app.adjTarget = null; 16952 app.empty = false; 16953 app.cached = false; 16954 16955 final int activitiesSize = app.activities.size(); 16956 16957 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16958 // The max adjustment doesn't allow this app to be anything 16959 // below foreground, so it is not worth doing work for it. 16960 app.adjType = "fixed"; 16961 app.adjSeq = mAdjSeq; 16962 app.curRawAdj = app.maxAdj; 16963 app.foregroundActivities = false; 16964 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16965 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16966 // System processes can do UI, and when they do we want to have 16967 // them trim their memory after the user leaves the UI. To 16968 // facilitate this, here we need to determine whether or not it 16969 // is currently showing UI. 16970 app.systemNoUi = true; 16971 if (app == TOP_APP) { 16972 app.systemNoUi = false; 16973 } else if (activitiesSize > 0) { 16974 for (int j = 0; j < activitiesSize; j++) { 16975 final ActivityRecord r = app.activities.get(j); 16976 if (r.visible) { 16977 app.systemNoUi = false; 16978 } 16979 } 16980 } 16981 if (!app.systemNoUi) { 16982 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16983 } 16984 return (app.curAdj=app.maxAdj); 16985 } 16986 16987 app.systemNoUi = false; 16988 16989 // Determine the importance of the process, starting with most 16990 // important to least, and assign an appropriate OOM adjustment. 16991 int adj; 16992 int schedGroup; 16993 int procState; 16994 boolean foregroundActivities = false; 16995 BroadcastQueue queue; 16996 if (app == TOP_APP) { 16997 // The last app on the list is the foreground app. 16998 adj = ProcessList.FOREGROUND_APP_ADJ; 16999 schedGroup = Process.THREAD_GROUP_DEFAULT; 17000 app.adjType = "top-activity"; 17001 foregroundActivities = true; 17002 procState = ActivityManager.PROCESS_STATE_TOP; 17003 } else if (app.instrumentationClass != null) { 17004 // Don't want to kill running instrumentation. 17005 adj = ProcessList.FOREGROUND_APP_ADJ; 17006 schedGroup = Process.THREAD_GROUP_DEFAULT; 17007 app.adjType = "instrumentation"; 17008 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17009 } else if ((queue = isReceivingBroadcast(app)) != null) { 17010 // An app that is currently receiving a broadcast also 17011 // counts as being in the foreground for OOM killer purposes. 17012 // It's placed in a sched group based on the nature of the 17013 // broadcast as reflected by which queue it's active in. 17014 adj = ProcessList.FOREGROUND_APP_ADJ; 17015 schedGroup = (queue == mFgBroadcastQueue) 17016 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17017 app.adjType = "broadcast"; 17018 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17019 } else if (app.executingServices.size() > 0) { 17020 // An app that is currently executing a service callback also 17021 // counts as being in the foreground. 17022 adj = ProcessList.FOREGROUND_APP_ADJ; 17023 schedGroup = app.execServicesFg ? 17024 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17025 app.adjType = "exec-service"; 17026 procState = ActivityManager.PROCESS_STATE_SERVICE; 17027 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17028 } else { 17029 // As far as we know the process is empty. We may change our mind later. 17030 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17031 // At this point we don't actually know the adjustment. Use the cached adj 17032 // value that the caller wants us to. 17033 adj = cachedAdj; 17034 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17035 app.cached = true; 17036 app.empty = true; 17037 app.adjType = "cch-empty"; 17038 } 17039 17040 // Examine all activities if not already foreground. 17041 if (!foregroundActivities && activitiesSize > 0) { 17042 for (int j = 0; j < activitiesSize; j++) { 17043 final ActivityRecord r = app.activities.get(j); 17044 if (r.app != app) { 17045 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17046 + app + "?!?"); 17047 continue; 17048 } 17049 if (r.visible) { 17050 // App has a visible activity; only upgrade adjustment. 17051 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17052 adj = ProcessList.VISIBLE_APP_ADJ; 17053 app.adjType = "visible"; 17054 } 17055 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17056 procState = ActivityManager.PROCESS_STATE_TOP; 17057 } 17058 schedGroup = Process.THREAD_GROUP_DEFAULT; 17059 app.cached = false; 17060 app.empty = false; 17061 foregroundActivities = true; 17062 break; 17063 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17064 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17065 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17066 app.adjType = "pausing"; 17067 } 17068 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17069 procState = ActivityManager.PROCESS_STATE_TOP; 17070 } 17071 schedGroup = Process.THREAD_GROUP_DEFAULT; 17072 app.cached = false; 17073 app.empty = false; 17074 foregroundActivities = true; 17075 } else if (r.state == ActivityState.STOPPING) { 17076 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17077 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17078 app.adjType = "stopping"; 17079 } 17080 // For the process state, we will at this point consider the 17081 // process to be cached. It will be cached either as an activity 17082 // or empty depending on whether the activity is finishing. We do 17083 // this so that we can treat the process as cached for purposes of 17084 // memory trimming (determing current memory level, trim command to 17085 // send to process) since there can be an arbitrary number of stopping 17086 // processes and they should soon all go into the cached state. 17087 if (!r.finishing) { 17088 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17089 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17090 } 17091 } 17092 app.cached = false; 17093 app.empty = false; 17094 foregroundActivities = true; 17095 } else { 17096 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17097 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17098 app.adjType = "cch-act"; 17099 } 17100 } 17101 } 17102 } 17103 17104 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17105 if (app.foregroundServices) { 17106 // The user is aware of this app, so make it visible. 17107 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17108 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17109 app.cached = false; 17110 app.adjType = "fg-service"; 17111 schedGroup = Process.THREAD_GROUP_DEFAULT; 17112 } else if (app.forcingToForeground != null) { 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 = "force-fg"; 17118 app.adjSource = app.forcingToForeground; 17119 schedGroup = Process.THREAD_GROUP_DEFAULT; 17120 } 17121 } 17122 17123 if (app == mHeavyWeightProcess) { 17124 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17125 // We don't want to kill the current heavy-weight process. 17126 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17127 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17128 app.cached = false; 17129 app.adjType = "heavy"; 17130 } 17131 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17132 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17133 } 17134 } 17135 17136 if (app == mHomeProcess) { 17137 if (adj > ProcessList.HOME_APP_ADJ) { 17138 // This process is hosting what we currently consider to be the 17139 // home app, so we don't want to let it go into the background. 17140 adj = ProcessList.HOME_APP_ADJ; 17141 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17142 app.cached = false; 17143 app.adjType = "home"; 17144 } 17145 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17146 procState = ActivityManager.PROCESS_STATE_HOME; 17147 } 17148 } 17149 17150 if (app == mPreviousProcess && app.activities.size() > 0) { 17151 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17152 // This was the previous process that showed UI to the user. 17153 // We want to try to keep it around more aggressively, to give 17154 // a good experience around switching between two apps. 17155 adj = ProcessList.PREVIOUS_APP_ADJ; 17156 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17157 app.cached = false; 17158 app.adjType = "previous"; 17159 } 17160 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17161 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17162 } 17163 } 17164 17165 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17166 + " reason=" + app.adjType); 17167 17168 // By default, we use the computed adjustment. It may be changed if 17169 // there are applications dependent on our services or providers, but 17170 // this gives us a baseline and makes sure we don't get into an 17171 // infinite recursion. 17172 app.adjSeq = mAdjSeq; 17173 app.curRawAdj = adj; 17174 app.hasStartedServices = false; 17175 17176 if (mBackupTarget != null && app == mBackupTarget.app) { 17177 // If possible we want to avoid killing apps while they're being backed up 17178 if (adj > ProcessList.BACKUP_APP_ADJ) { 17179 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17180 adj = ProcessList.BACKUP_APP_ADJ; 17181 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17182 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17183 } 17184 app.adjType = "backup"; 17185 app.cached = false; 17186 } 17187 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17188 procState = ActivityManager.PROCESS_STATE_BACKUP; 17189 } 17190 } 17191 17192 boolean mayBeTop = false; 17193 17194 for (int is = app.services.size()-1; 17195 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17196 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17197 || procState > ActivityManager.PROCESS_STATE_TOP); 17198 is--) { 17199 ServiceRecord s = app.services.valueAt(is); 17200 if (s.startRequested) { 17201 app.hasStartedServices = true; 17202 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17203 procState = ActivityManager.PROCESS_STATE_SERVICE; 17204 } 17205 if (app.hasShownUi && app != mHomeProcess) { 17206 // If this process has shown some UI, let it immediately 17207 // go to the LRU list because it may be pretty heavy with 17208 // UI stuff. We'll tag it with a label just to help 17209 // debug and understand what is going on. 17210 if (adj > ProcessList.SERVICE_ADJ) { 17211 app.adjType = "cch-started-ui-services"; 17212 } 17213 } else { 17214 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17215 // This service has seen some activity within 17216 // recent memory, so we will keep its process ahead 17217 // of the background processes. 17218 if (adj > ProcessList.SERVICE_ADJ) { 17219 adj = ProcessList.SERVICE_ADJ; 17220 app.adjType = "started-services"; 17221 app.cached = false; 17222 } 17223 } 17224 // If we have let the service slide into the background 17225 // state, still have some text describing what it is doing 17226 // even though the service no longer has an impact. 17227 if (adj > ProcessList.SERVICE_ADJ) { 17228 app.adjType = "cch-started-services"; 17229 } 17230 } 17231 } 17232 for (int conni = s.connections.size()-1; 17233 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17234 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17235 || procState > ActivityManager.PROCESS_STATE_TOP); 17236 conni--) { 17237 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17238 for (int i = 0; 17239 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17240 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17241 || procState > ActivityManager.PROCESS_STATE_TOP); 17242 i++) { 17243 // XXX should compute this based on the max of 17244 // all connected clients. 17245 ConnectionRecord cr = clist.get(i); 17246 if (cr.binding.client == app) { 17247 // Binding to ourself is not interesting. 17248 continue; 17249 } 17250 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17251 ProcessRecord client = cr.binding.client; 17252 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17253 TOP_APP, doingAll, now); 17254 int clientProcState = client.curProcState; 17255 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17256 // If the other app is cached for any reason, for purposes here 17257 // we are going to consider it empty. The specific cached state 17258 // doesn't propagate except under certain conditions. 17259 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17260 } 17261 String adjType = null; 17262 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17263 // Not doing bind OOM management, so treat 17264 // this guy more like a started service. 17265 if (app.hasShownUi && app != mHomeProcess) { 17266 // If this process has shown some UI, let it immediately 17267 // go to the LRU list because it may be pretty heavy with 17268 // UI stuff. We'll tag it with a label just to help 17269 // debug and understand what is going on. 17270 if (adj > clientAdj) { 17271 adjType = "cch-bound-ui-services"; 17272 } 17273 app.cached = false; 17274 clientAdj = adj; 17275 clientProcState = procState; 17276 } else { 17277 if (now >= (s.lastActivity 17278 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17279 // This service has not seen activity within 17280 // recent memory, so allow it to drop to the 17281 // LRU list if there is no other reason to keep 17282 // it around. We'll also tag it with a label just 17283 // to help debug and undertand what is going on. 17284 if (adj > clientAdj) { 17285 adjType = "cch-bound-services"; 17286 } 17287 clientAdj = adj; 17288 } 17289 } 17290 } 17291 if (adj > clientAdj) { 17292 // If this process has recently shown UI, and 17293 // the process that is binding to it is less 17294 // important than being visible, then we don't 17295 // care about the binding as much as we care 17296 // about letting this process get into the LRU 17297 // list to be killed and restarted if needed for 17298 // memory. 17299 if (app.hasShownUi && app != mHomeProcess 17300 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17301 adjType = "cch-bound-ui-services"; 17302 } else { 17303 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17304 |Context.BIND_IMPORTANT)) != 0) { 17305 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17306 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17307 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17308 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17309 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17310 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17311 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17312 adj = clientAdj; 17313 } else { 17314 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17315 adj = ProcessList.VISIBLE_APP_ADJ; 17316 } 17317 } 17318 if (!client.cached) { 17319 app.cached = false; 17320 } 17321 adjType = "service"; 17322 } 17323 } 17324 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17325 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17326 schedGroup = Process.THREAD_GROUP_DEFAULT; 17327 } 17328 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17329 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17330 // Special handling of clients who are in the top state. 17331 // We *may* want to consider this process to be in the 17332 // top state as well, but only if there is not another 17333 // reason for it to be running. Being on the top is a 17334 // special state, meaning you are specifically running 17335 // for the current top app. If the process is already 17336 // running in the background for some other reason, it 17337 // is more important to continue considering it to be 17338 // in the background state. 17339 mayBeTop = true; 17340 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17341 } else { 17342 // Special handling for above-top states (persistent 17343 // processes). These should not bring the current process 17344 // into the top state, since they are not on top. Instead 17345 // give them the best state after that. 17346 clientProcState = 17347 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17348 } 17349 } 17350 } else { 17351 if (clientProcState < 17352 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17353 clientProcState = 17354 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17355 } 17356 } 17357 if (procState > clientProcState) { 17358 procState = clientProcState; 17359 } 17360 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17361 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17362 app.pendingUiClean = true; 17363 } 17364 if (adjType != null) { 17365 app.adjType = adjType; 17366 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17367 .REASON_SERVICE_IN_USE; 17368 app.adjSource = cr.binding.client; 17369 app.adjSourceProcState = clientProcState; 17370 app.adjTarget = s.name; 17371 } 17372 } 17373 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17374 app.treatLikeActivity = true; 17375 } 17376 final ActivityRecord a = cr.activity; 17377 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17378 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17379 (a.visible || a.state == ActivityState.RESUMED 17380 || a.state == ActivityState.PAUSING)) { 17381 adj = ProcessList.FOREGROUND_APP_ADJ; 17382 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17383 schedGroup = Process.THREAD_GROUP_DEFAULT; 17384 } 17385 app.cached = false; 17386 app.adjType = "service"; 17387 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17388 .REASON_SERVICE_IN_USE; 17389 app.adjSource = a; 17390 app.adjSourceProcState = procState; 17391 app.adjTarget = s.name; 17392 } 17393 } 17394 } 17395 } 17396 } 17397 17398 for (int provi = app.pubProviders.size()-1; 17399 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17400 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17401 || procState > ActivityManager.PROCESS_STATE_TOP); 17402 provi--) { 17403 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17404 for (int i = cpr.connections.size()-1; 17405 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17406 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17407 || procState > ActivityManager.PROCESS_STATE_TOP); 17408 i--) { 17409 ContentProviderConnection conn = cpr.connections.get(i); 17410 ProcessRecord client = conn.client; 17411 if (client == app) { 17412 // Being our own client is not interesting. 17413 continue; 17414 } 17415 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17416 int clientProcState = client.curProcState; 17417 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17418 // If the other app is cached for any reason, for purposes here 17419 // we are going to consider it empty. 17420 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17421 } 17422 if (adj > clientAdj) { 17423 if (app.hasShownUi && app != mHomeProcess 17424 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17425 app.adjType = "cch-ui-provider"; 17426 } else { 17427 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17428 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17429 app.adjType = "provider"; 17430 } 17431 app.cached &= client.cached; 17432 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17433 .REASON_PROVIDER_IN_USE; 17434 app.adjSource = client; 17435 app.adjSourceProcState = clientProcState; 17436 app.adjTarget = cpr.name; 17437 } 17438 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17439 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17440 // Special handling of clients who are in the top state. 17441 // We *may* want to consider this process to be in the 17442 // top state as well, but only if there is not another 17443 // reason for it to be running. Being on the top is a 17444 // special state, meaning you are specifically running 17445 // for the current top app. If the process is already 17446 // running in the background for some other reason, it 17447 // is more important to continue considering it to be 17448 // in the background state. 17449 mayBeTop = true; 17450 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17451 } else { 17452 // Special handling for above-top states (persistent 17453 // processes). These should not bring the current process 17454 // into the top state, since they are not on top. Instead 17455 // give them the best state after that. 17456 clientProcState = 17457 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17458 } 17459 } 17460 if (procState > clientProcState) { 17461 procState = clientProcState; 17462 } 17463 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17464 schedGroup = Process.THREAD_GROUP_DEFAULT; 17465 } 17466 } 17467 // If the provider has external (non-framework) process 17468 // dependencies, ensure that its adjustment is at least 17469 // FOREGROUND_APP_ADJ. 17470 if (cpr.hasExternalProcessHandles()) { 17471 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17472 adj = ProcessList.FOREGROUND_APP_ADJ; 17473 schedGroup = Process.THREAD_GROUP_DEFAULT; 17474 app.cached = false; 17475 app.adjType = "provider"; 17476 app.adjTarget = cpr.name; 17477 } 17478 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17479 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17480 } 17481 } 17482 } 17483 17484 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17485 // A client of one of our services or providers is in the top state. We 17486 // *may* want to be in the top state, but not if we are already running in 17487 // the background for some other reason. For the decision here, we are going 17488 // to pick out a few specific states that we want to remain in when a client 17489 // is top (states that tend to be longer-term) and otherwise allow it to go 17490 // to the top state. 17491 switch (procState) { 17492 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17493 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17494 case ActivityManager.PROCESS_STATE_SERVICE: 17495 // These all are longer-term states, so pull them up to the top 17496 // of the background states, but not all the way to the top state. 17497 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17498 break; 17499 default: 17500 // Otherwise, top is a better choice, so take it. 17501 procState = ActivityManager.PROCESS_STATE_TOP; 17502 break; 17503 } 17504 } 17505 17506 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17507 if (app.hasClientActivities) { 17508 // This is a cached process, but with client activities. Mark it so. 17509 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17510 app.adjType = "cch-client-act"; 17511 } else if (app.treatLikeActivity) { 17512 // This is a cached process, but somebody wants us to treat it like it has 17513 // an activity, okay! 17514 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17515 app.adjType = "cch-as-act"; 17516 } 17517 } 17518 17519 if (adj == ProcessList.SERVICE_ADJ) { 17520 if (doingAll) { 17521 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17522 mNewNumServiceProcs++; 17523 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17524 if (!app.serviceb) { 17525 // This service isn't far enough down on the LRU list to 17526 // normally be a B service, but if we are low on RAM and it 17527 // is large we want to force it down since we would prefer to 17528 // keep launcher over it. 17529 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17530 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17531 app.serviceHighRam = true; 17532 app.serviceb = true; 17533 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17534 } else { 17535 mNewNumAServiceProcs++; 17536 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17537 } 17538 } else { 17539 app.serviceHighRam = false; 17540 } 17541 } 17542 if (app.serviceb) { 17543 adj = ProcessList.SERVICE_B_ADJ; 17544 } 17545 } 17546 17547 app.curRawAdj = adj; 17548 17549 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17550 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17551 if (adj > app.maxAdj) { 17552 adj = app.maxAdj; 17553 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17554 schedGroup = Process.THREAD_GROUP_DEFAULT; 17555 } 17556 } 17557 17558 // Do final modification to adj. Everything we do between here and applying 17559 // the final setAdj must be done in this function, because we will also use 17560 // it when computing the final cached adj later. Note that we don't need to 17561 // worry about this for max adj above, since max adj will always be used to 17562 // keep it out of the cached vaues. 17563 app.curAdj = app.modifyRawOomAdj(adj); 17564 app.curSchedGroup = schedGroup; 17565 app.curProcState = procState; 17566 app.foregroundActivities = foregroundActivities; 17567 17568 return app.curRawAdj; 17569 } 17570 17571 /** 17572 * Record new PSS sample for a process. 17573 */ 17574 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17575 proc.lastPssTime = now; 17576 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17577 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17578 + ": " + pss + " lastPss=" + proc.lastPss 17579 + " state=" + ProcessList.makeProcStateString(procState)); 17580 if (proc.initialIdlePss == 0) { 17581 proc.initialIdlePss = pss; 17582 } 17583 proc.lastPss = pss; 17584 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17585 proc.lastCachedPss = pss; 17586 } 17587 } 17588 17589 /** 17590 * Schedule PSS collection of a process. 17591 */ 17592 void requestPssLocked(ProcessRecord proc, int procState) { 17593 if (mPendingPssProcesses.contains(proc)) { 17594 return; 17595 } 17596 if (mPendingPssProcesses.size() == 0) { 17597 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17598 } 17599 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17600 proc.pssProcState = procState; 17601 mPendingPssProcesses.add(proc); 17602 } 17603 17604 /** 17605 * Schedule PSS collection of all processes. 17606 */ 17607 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17608 if (!always) { 17609 if (now < (mLastFullPssTime + 17610 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17611 return; 17612 } 17613 } 17614 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17615 mLastFullPssTime = now; 17616 mFullPssPending = true; 17617 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17618 mPendingPssProcesses.clear(); 17619 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17620 ProcessRecord app = mLruProcesses.get(i); 17621 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17622 app.pssProcState = app.setProcState; 17623 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17624 mTestPssMode, isSleeping(), now); 17625 mPendingPssProcesses.add(app); 17626 } 17627 } 17628 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17629 } 17630 17631 public void setTestPssMode(boolean enabled) { 17632 synchronized (this) { 17633 mTestPssMode = enabled; 17634 if (enabled) { 17635 // Whenever we enable the mode, we want to take a snapshot all of current 17636 // process mem use. 17637 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17638 } 17639 } 17640 } 17641 17642 /** 17643 * Ask a given process to GC right now. 17644 */ 17645 final void performAppGcLocked(ProcessRecord app) { 17646 try { 17647 app.lastRequestedGc = SystemClock.uptimeMillis(); 17648 if (app.thread != null) { 17649 if (app.reportLowMemory) { 17650 app.reportLowMemory = false; 17651 app.thread.scheduleLowMemory(); 17652 } else { 17653 app.thread.processInBackground(); 17654 } 17655 } 17656 } catch (Exception e) { 17657 // whatever. 17658 } 17659 } 17660 17661 /** 17662 * Returns true if things are idle enough to perform GCs. 17663 */ 17664 private final boolean canGcNowLocked() { 17665 boolean processingBroadcasts = false; 17666 for (BroadcastQueue q : mBroadcastQueues) { 17667 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17668 processingBroadcasts = true; 17669 } 17670 } 17671 return !processingBroadcasts 17672 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17673 } 17674 17675 /** 17676 * Perform GCs on all processes that are waiting for it, but only 17677 * if things are idle. 17678 */ 17679 final void performAppGcsLocked() { 17680 final int N = mProcessesToGc.size(); 17681 if (N <= 0) { 17682 return; 17683 } 17684 if (canGcNowLocked()) { 17685 while (mProcessesToGc.size() > 0) { 17686 ProcessRecord proc = mProcessesToGc.remove(0); 17687 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17688 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17689 <= SystemClock.uptimeMillis()) { 17690 // To avoid spamming the system, we will GC processes one 17691 // at a time, waiting a few seconds between each. 17692 performAppGcLocked(proc); 17693 scheduleAppGcsLocked(); 17694 return; 17695 } else { 17696 // It hasn't been long enough since we last GCed this 17697 // process... put it in the list to wait for its time. 17698 addProcessToGcListLocked(proc); 17699 break; 17700 } 17701 } 17702 } 17703 17704 scheduleAppGcsLocked(); 17705 } 17706 } 17707 17708 /** 17709 * If all looks good, perform GCs on all processes waiting for them. 17710 */ 17711 final void performAppGcsIfAppropriateLocked() { 17712 if (canGcNowLocked()) { 17713 performAppGcsLocked(); 17714 return; 17715 } 17716 // Still not idle, wait some more. 17717 scheduleAppGcsLocked(); 17718 } 17719 17720 /** 17721 * Schedule the execution of all pending app GCs. 17722 */ 17723 final void scheduleAppGcsLocked() { 17724 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17725 17726 if (mProcessesToGc.size() > 0) { 17727 // Schedule a GC for the time to the next process. 17728 ProcessRecord proc = mProcessesToGc.get(0); 17729 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17730 17731 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17732 long now = SystemClock.uptimeMillis(); 17733 if (when < (now+GC_TIMEOUT)) { 17734 when = now + GC_TIMEOUT; 17735 } 17736 mHandler.sendMessageAtTime(msg, when); 17737 } 17738 } 17739 17740 /** 17741 * Add a process to the array of processes waiting to be GCed. Keeps the 17742 * list in sorted order by the last GC time. The process can't already be 17743 * on the list. 17744 */ 17745 final void addProcessToGcListLocked(ProcessRecord proc) { 17746 boolean added = false; 17747 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17748 if (mProcessesToGc.get(i).lastRequestedGc < 17749 proc.lastRequestedGc) { 17750 added = true; 17751 mProcessesToGc.add(i+1, proc); 17752 break; 17753 } 17754 } 17755 if (!added) { 17756 mProcessesToGc.add(0, proc); 17757 } 17758 } 17759 17760 /** 17761 * Set up to ask a process to GC itself. This will either do it 17762 * immediately, or put it on the list of processes to gc the next 17763 * time things are idle. 17764 */ 17765 final void scheduleAppGcLocked(ProcessRecord app) { 17766 long now = SystemClock.uptimeMillis(); 17767 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17768 return; 17769 } 17770 if (!mProcessesToGc.contains(app)) { 17771 addProcessToGcListLocked(app); 17772 scheduleAppGcsLocked(); 17773 } 17774 } 17775 17776 final void checkExcessivePowerUsageLocked(boolean doKills) { 17777 updateCpuStatsNow(); 17778 17779 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17780 boolean doWakeKills = doKills; 17781 boolean doCpuKills = doKills; 17782 if (mLastPowerCheckRealtime == 0) { 17783 doWakeKills = false; 17784 } 17785 if (mLastPowerCheckUptime == 0) { 17786 doCpuKills = false; 17787 } 17788 if (stats.isScreenOn()) { 17789 doWakeKills = false; 17790 } 17791 final long curRealtime = SystemClock.elapsedRealtime(); 17792 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17793 final long curUptime = SystemClock.uptimeMillis(); 17794 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17795 mLastPowerCheckRealtime = curRealtime; 17796 mLastPowerCheckUptime = curUptime; 17797 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17798 doWakeKills = false; 17799 } 17800 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17801 doCpuKills = false; 17802 } 17803 int i = mLruProcesses.size(); 17804 while (i > 0) { 17805 i--; 17806 ProcessRecord app = mLruProcesses.get(i); 17807 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17808 long wtime; 17809 synchronized (stats) { 17810 wtime = stats.getProcessWakeTime(app.info.uid, 17811 app.pid, curRealtime); 17812 } 17813 long wtimeUsed = wtime - app.lastWakeTime; 17814 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17815 if (DEBUG_POWER) { 17816 StringBuilder sb = new StringBuilder(128); 17817 sb.append("Wake for "); 17818 app.toShortString(sb); 17819 sb.append(": over "); 17820 TimeUtils.formatDuration(realtimeSince, sb); 17821 sb.append(" used "); 17822 TimeUtils.formatDuration(wtimeUsed, sb); 17823 sb.append(" ("); 17824 sb.append((wtimeUsed*100)/realtimeSince); 17825 sb.append("%)"); 17826 Slog.i(TAG, sb.toString()); 17827 sb.setLength(0); 17828 sb.append("CPU for "); 17829 app.toShortString(sb); 17830 sb.append(": over "); 17831 TimeUtils.formatDuration(uptimeSince, sb); 17832 sb.append(" used "); 17833 TimeUtils.formatDuration(cputimeUsed, sb); 17834 sb.append(" ("); 17835 sb.append((cputimeUsed*100)/uptimeSince); 17836 sb.append("%)"); 17837 Slog.i(TAG, sb.toString()); 17838 } 17839 // If a process has held a wake lock for more 17840 // than 50% of the time during this period, 17841 // that sounds bad. Kill! 17842 if (doWakeKills && realtimeSince > 0 17843 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17844 synchronized (stats) { 17845 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17846 realtimeSince, wtimeUsed); 17847 } 17848 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17849 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17850 } else if (doCpuKills && uptimeSince > 0 17851 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17852 synchronized (stats) { 17853 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17854 uptimeSince, cputimeUsed); 17855 } 17856 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17857 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17858 } else { 17859 app.lastWakeTime = wtime; 17860 app.lastCpuTime = app.curCpuTime; 17861 } 17862 } 17863 } 17864 } 17865 17866 private final boolean applyOomAdjLocked(ProcessRecord app, 17867 ProcessRecord TOP_APP, boolean doingAll, long now) { 17868 boolean success = true; 17869 17870 if (app.curRawAdj != app.setRawAdj) { 17871 app.setRawAdj = app.curRawAdj; 17872 } 17873 17874 int changes = 0; 17875 17876 if (app.curAdj != app.setAdj) { 17877 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17878 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17879 TAG, "Set " + app.pid + " " + app.processName + 17880 " adj " + app.curAdj + ": " + app.adjType); 17881 app.setAdj = app.curAdj; 17882 } 17883 17884 if (app.setSchedGroup != app.curSchedGroup) { 17885 app.setSchedGroup = app.curSchedGroup; 17886 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17887 "Setting process group of " + app.processName 17888 + " to " + app.curSchedGroup); 17889 if (app.waitingToKill != null && 17890 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17891 app.kill(app.waitingToKill, true); 17892 success = false; 17893 } else { 17894 if (true) { 17895 long oldId = Binder.clearCallingIdentity(); 17896 try { 17897 Process.setProcessGroup(app.pid, app.curSchedGroup); 17898 } catch (Exception e) { 17899 Slog.w(TAG, "Failed setting process group of " + app.pid 17900 + " to " + app.curSchedGroup); 17901 e.printStackTrace(); 17902 } finally { 17903 Binder.restoreCallingIdentity(oldId); 17904 } 17905 } else { 17906 if (app.thread != null) { 17907 try { 17908 app.thread.setSchedulingGroup(app.curSchedGroup); 17909 } catch (RemoteException e) { 17910 } 17911 } 17912 } 17913 Process.setSwappiness(app.pid, 17914 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17915 } 17916 } 17917 if (app.repForegroundActivities != app.foregroundActivities) { 17918 app.repForegroundActivities = app.foregroundActivities; 17919 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17920 } 17921 if (app.repProcState != app.curProcState) { 17922 app.repProcState = app.curProcState; 17923 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17924 if (app.thread != null) { 17925 try { 17926 if (false) { 17927 //RuntimeException h = new RuntimeException("here"); 17928 Slog.i(TAG, "Sending new process state " + app.repProcState 17929 + " to " + app /*, h*/); 17930 } 17931 app.thread.setProcessState(app.repProcState); 17932 } catch (RemoteException e) { 17933 } 17934 } 17935 } 17936 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17937 app.setProcState)) { 17938 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17939 // Experimental code to more aggressively collect pss while 17940 // running test... the problem is that this tends to collect 17941 // the data right when a process is transitioning between process 17942 // states, which well tend to give noisy data. 17943 long start = SystemClock.uptimeMillis(); 17944 long pss = Debug.getPss(app.pid, mTmpLong, null); 17945 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17946 mPendingPssProcesses.remove(app); 17947 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17948 + " to " + app.curProcState + ": " 17949 + (SystemClock.uptimeMillis()-start) + "ms"); 17950 } 17951 app.lastStateTime = now; 17952 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17953 mTestPssMode, isSleeping(), now); 17954 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17955 + ProcessList.makeProcStateString(app.setProcState) + " to " 17956 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17957 + (app.nextPssTime-now) + ": " + app); 17958 } else { 17959 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17960 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17961 mTestPssMode)))) { 17962 requestPssLocked(app, app.setProcState); 17963 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17964 mTestPssMode, isSleeping(), now); 17965 } else if (false && DEBUG_PSS) { 17966 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17967 } 17968 } 17969 if (app.setProcState != app.curProcState) { 17970 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17971 "Proc state change of " + app.processName 17972 + " to " + app.curProcState); 17973 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17974 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17975 if (setImportant && !curImportant) { 17976 // This app is no longer something we consider important enough to allow to 17977 // use arbitrary amounts of battery power. Note 17978 // its current wake lock time to later know to kill it if 17979 // it is not behaving well. 17980 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17981 synchronized (stats) { 17982 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17983 app.pid, SystemClock.elapsedRealtime()); 17984 } 17985 app.lastCpuTime = app.curCpuTime; 17986 17987 } 17988 app.setProcState = app.curProcState; 17989 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17990 app.notCachedSinceIdle = false; 17991 } 17992 if (!doingAll) { 17993 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17994 } else { 17995 app.procStateChanged = true; 17996 } 17997 } 17998 17999 if (changes != 0) { 18000 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 18001 int i = mPendingProcessChanges.size()-1; 18002 ProcessChangeItem item = null; 18003 while (i >= 0) { 18004 item = mPendingProcessChanges.get(i); 18005 if (item.pid == app.pid) { 18006 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18007 break; 18008 } 18009 i--; 18010 } 18011 if (i < 0) { 18012 // No existing item in pending changes; need a new one. 18013 final int NA = mAvailProcessChanges.size(); 18014 if (NA > 0) { 18015 item = mAvailProcessChanges.remove(NA-1); 18016 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18017 } else { 18018 item = new ProcessChangeItem(); 18019 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18020 } 18021 item.changes = 0; 18022 item.pid = app.pid; 18023 item.uid = app.info.uid; 18024 if (mPendingProcessChanges.size() == 0) { 18025 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18026 "*** Enqueueing dispatch processes changed!"); 18027 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18028 } 18029 mPendingProcessChanges.add(item); 18030 } 18031 item.changes |= changes; 18032 item.processState = app.repProcState; 18033 item.foregroundActivities = app.repForegroundActivities; 18034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18035 + Integer.toHexString(System.identityHashCode(item)) 18036 + " " + app.toShortString() + ": changes=" + item.changes 18037 + " procState=" + item.processState 18038 + " foreground=" + item.foregroundActivities 18039 + " type=" + app.adjType + " source=" + app.adjSource 18040 + " target=" + app.adjTarget); 18041 } 18042 18043 return success; 18044 } 18045 18046 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18047 if (proc.thread != null) { 18048 if (proc.baseProcessTracker != null) { 18049 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18050 } 18051 if (proc.repProcState >= 0) { 18052 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18053 proc.repProcState); 18054 } 18055 } 18056 } 18057 18058 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18059 ProcessRecord TOP_APP, boolean doingAll, long now) { 18060 if (app.thread == null) { 18061 return false; 18062 } 18063 18064 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18065 18066 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18067 } 18068 18069 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18070 boolean oomAdj) { 18071 if (isForeground != proc.foregroundServices) { 18072 proc.foregroundServices = isForeground; 18073 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18074 proc.info.uid); 18075 if (isForeground) { 18076 if (curProcs == null) { 18077 curProcs = new ArrayList<ProcessRecord>(); 18078 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18079 } 18080 if (!curProcs.contains(proc)) { 18081 curProcs.add(proc); 18082 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18083 proc.info.packageName, proc.info.uid); 18084 } 18085 } else { 18086 if (curProcs != null) { 18087 if (curProcs.remove(proc)) { 18088 mBatteryStatsService.noteEvent( 18089 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18090 proc.info.packageName, proc.info.uid); 18091 if (curProcs.size() <= 0) { 18092 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18093 } 18094 } 18095 } 18096 } 18097 if (oomAdj) { 18098 updateOomAdjLocked(); 18099 } 18100 } 18101 } 18102 18103 private final ActivityRecord resumedAppLocked() { 18104 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18105 String pkg; 18106 int uid; 18107 if (act != null) { 18108 pkg = act.packageName; 18109 uid = act.info.applicationInfo.uid; 18110 } else { 18111 pkg = null; 18112 uid = -1; 18113 } 18114 // Has the UID or resumed package name changed? 18115 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18116 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18117 if (mCurResumedPackage != null) { 18118 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18119 mCurResumedPackage, mCurResumedUid); 18120 } 18121 mCurResumedPackage = pkg; 18122 mCurResumedUid = uid; 18123 if (mCurResumedPackage != null) { 18124 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18125 mCurResumedPackage, mCurResumedUid); 18126 } 18127 } 18128 return act; 18129 } 18130 18131 final boolean updateOomAdjLocked(ProcessRecord app) { 18132 final ActivityRecord TOP_ACT = resumedAppLocked(); 18133 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18134 final boolean wasCached = app.cached; 18135 18136 mAdjSeq++; 18137 18138 // This is the desired cached adjusment we want to tell it to use. 18139 // If our app is currently cached, we know it, and that is it. Otherwise, 18140 // we don't know it yet, and it needs to now be cached we will then 18141 // need to do a complete oom adj. 18142 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18143 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18144 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18145 SystemClock.uptimeMillis()); 18146 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18147 // Changed to/from cached state, so apps after it in the LRU 18148 // list may also be changed. 18149 updateOomAdjLocked(); 18150 } 18151 return success; 18152 } 18153 18154 final void updateOomAdjLocked() { 18155 final ActivityRecord TOP_ACT = resumedAppLocked(); 18156 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18157 final long now = SystemClock.uptimeMillis(); 18158 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18159 final int N = mLruProcesses.size(); 18160 18161 if (false) { 18162 RuntimeException e = new RuntimeException(); 18163 e.fillInStackTrace(); 18164 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18165 } 18166 18167 mAdjSeq++; 18168 mNewNumServiceProcs = 0; 18169 mNewNumAServiceProcs = 0; 18170 18171 final int emptyProcessLimit; 18172 final int cachedProcessLimit; 18173 if (mProcessLimit <= 0) { 18174 emptyProcessLimit = cachedProcessLimit = 0; 18175 } else if (mProcessLimit == 1) { 18176 emptyProcessLimit = 1; 18177 cachedProcessLimit = 0; 18178 } else { 18179 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18180 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18181 } 18182 18183 // Let's determine how many processes we have running vs. 18184 // how many slots we have for background processes; we may want 18185 // to put multiple processes in a slot of there are enough of 18186 // them. 18187 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18188 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18189 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18190 if (numEmptyProcs > cachedProcessLimit) { 18191 // If there are more empty processes than our limit on cached 18192 // processes, then use the cached process limit for the factor. 18193 // This ensures that the really old empty processes get pushed 18194 // down to the bottom, so if we are running low on memory we will 18195 // have a better chance at keeping around more cached processes 18196 // instead of a gazillion empty processes. 18197 numEmptyProcs = cachedProcessLimit; 18198 } 18199 int emptyFactor = numEmptyProcs/numSlots; 18200 if (emptyFactor < 1) emptyFactor = 1; 18201 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18202 if (cachedFactor < 1) cachedFactor = 1; 18203 int stepCached = 0; 18204 int stepEmpty = 0; 18205 int numCached = 0; 18206 int numEmpty = 0; 18207 int numTrimming = 0; 18208 18209 mNumNonCachedProcs = 0; 18210 mNumCachedHiddenProcs = 0; 18211 18212 // First update the OOM adjustment for each of the 18213 // application processes based on their current state. 18214 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18215 int nextCachedAdj = curCachedAdj+1; 18216 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18217 int nextEmptyAdj = curEmptyAdj+2; 18218 for (int i=N-1; i>=0; i--) { 18219 ProcessRecord app = mLruProcesses.get(i); 18220 if (!app.killedByAm && app.thread != null) { 18221 app.procStateChanged = false; 18222 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18223 18224 // If we haven't yet assigned the final cached adj 18225 // to the process, do that now. 18226 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18227 switch (app.curProcState) { 18228 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18229 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18230 // This process is a cached process holding activities... 18231 // assign it the next cached value for that type, and then 18232 // step that cached level. 18233 app.curRawAdj = curCachedAdj; 18234 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18235 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18236 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18237 + ")"); 18238 if (curCachedAdj != nextCachedAdj) { 18239 stepCached++; 18240 if (stepCached >= cachedFactor) { 18241 stepCached = 0; 18242 curCachedAdj = nextCachedAdj; 18243 nextCachedAdj += 2; 18244 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18245 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18246 } 18247 } 18248 } 18249 break; 18250 default: 18251 // For everything else, assign next empty cached process 18252 // level and bump that up. Note that this means that 18253 // long-running services that have dropped down to the 18254 // cached level will be treated as empty (since their process 18255 // state is still as a service), which is what we want. 18256 app.curRawAdj = curEmptyAdj; 18257 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18258 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18259 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18260 + ")"); 18261 if (curEmptyAdj != nextEmptyAdj) { 18262 stepEmpty++; 18263 if (stepEmpty >= emptyFactor) { 18264 stepEmpty = 0; 18265 curEmptyAdj = nextEmptyAdj; 18266 nextEmptyAdj += 2; 18267 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18268 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18269 } 18270 } 18271 } 18272 break; 18273 } 18274 } 18275 18276 applyOomAdjLocked(app, TOP_APP, true, now); 18277 18278 // Count the number of process types. 18279 switch (app.curProcState) { 18280 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18281 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18282 mNumCachedHiddenProcs++; 18283 numCached++; 18284 if (numCached > cachedProcessLimit) { 18285 app.kill("cached #" + numCached, true); 18286 } 18287 break; 18288 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18289 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18290 && app.lastActivityTime < oldTime) { 18291 app.kill("empty for " 18292 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18293 / 1000) + "s", true); 18294 } else { 18295 numEmpty++; 18296 if (numEmpty > emptyProcessLimit) { 18297 app.kill("empty #" + numEmpty, true); 18298 } 18299 } 18300 break; 18301 default: 18302 mNumNonCachedProcs++; 18303 break; 18304 } 18305 18306 if (app.isolated && app.services.size() <= 0) { 18307 // If this is an isolated process, and there are no 18308 // services running in it, then the process is no longer 18309 // needed. We agressively kill these because we can by 18310 // definition not re-use the same process again, and it is 18311 // good to avoid having whatever code was running in them 18312 // left sitting around after no longer needed. 18313 app.kill("isolated not needed", true); 18314 } 18315 18316 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18317 && !app.killedByAm) { 18318 numTrimming++; 18319 } 18320 } 18321 } 18322 18323 mNumServiceProcs = mNewNumServiceProcs; 18324 18325 // Now determine the memory trimming level of background processes. 18326 // Unfortunately we need to start at the back of the list to do this 18327 // properly. We only do this if the number of background apps we 18328 // are managing to keep around is less than half the maximum we desire; 18329 // if we are keeping a good number around, we'll let them use whatever 18330 // memory they want. 18331 final int numCachedAndEmpty = numCached + numEmpty; 18332 int memFactor; 18333 if (numCached <= ProcessList.TRIM_CACHED_APPS 18334 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18335 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18336 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18337 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18338 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18339 } else { 18340 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18341 } 18342 } else { 18343 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18344 } 18345 // We always allow the memory level to go up (better). We only allow it to go 18346 // down if we are in a state where that is allowed, *and* the total number of processes 18347 // has gone down since last time. 18348 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18349 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18350 + " last=" + mLastNumProcesses); 18351 if (memFactor > mLastMemoryLevel) { 18352 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18353 memFactor = mLastMemoryLevel; 18354 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18355 } 18356 } 18357 mLastMemoryLevel = memFactor; 18358 mLastNumProcesses = mLruProcesses.size(); 18359 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18360 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18361 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18362 if (mLowRamStartTime == 0) { 18363 mLowRamStartTime = now; 18364 } 18365 int step = 0; 18366 int fgTrimLevel; 18367 switch (memFactor) { 18368 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18369 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18370 break; 18371 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18372 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18373 break; 18374 default: 18375 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18376 break; 18377 } 18378 int factor = numTrimming/3; 18379 int minFactor = 2; 18380 if (mHomeProcess != null) minFactor++; 18381 if (mPreviousProcess != null) minFactor++; 18382 if (factor < minFactor) factor = minFactor; 18383 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18384 for (int i=N-1; i>=0; i--) { 18385 ProcessRecord app = mLruProcesses.get(i); 18386 if (allChanged || app.procStateChanged) { 18387 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18388 app.procStateChanged = false; 18389 } 18390 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18391 && !app.killedByAm) { 18392 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18393 try { 18394 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18395 "Trimming memory of " + app.processName 18396 + " to " + curLevel); 18397 app.thread.scheduleTrimMemory(curLevel); 18398 } catch (RemoteException e) { 18399 } 18400 if (false) { 18401 // For now we won't do this; our memory trimming seems 18402 // to be good enough at this point that destroying 18403 // activities causes more harm than good. 18404 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18405 && app != mHomeProcess && app != mPreviousProcess) { 18406 // Need to do this on its own message because the stack may not 18407 // be in a consistent state at this point. 18408 // For these apps we will also finish their activities 18409 // to help them free memory. 18410 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18411 } 18412 } 18413 } 18414 app.trimMemoryLevel = curLevel; 18415 step++; 18416 if (step >= factor) { 18417 step = 0; 18418 switch (curLevel) { 18419 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18420 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18421 break; 18422 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18423 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18424 break; 18425 } 18426 } 18427 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18428 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18429 && app.thread != null) { 18430 try { 18431 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18432 "Trimming memory of heavy-weight " + app.processName 18433 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18434 app.thread.scheduleTrimMemory( 18435 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18436 } catch (RemoteException e) { 18437 } 18438 } 18439 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18440 } else { 18441 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18442 || app.systemNoUi) && app.pendingUiClean) { 18443 // If this application is now in the background and it 18444 // had done UI, then give it the special trim level to 18445 // have it free UI resources. 18446 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18447 if (app.trimMemoryLevel < level && app.thread != null) { 18448 try { 18449 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18450 "Trimming memory of bg-ui " + app.processName 18451 + " to " + level); 18452 app.thread.scheduleTrimMemory(level); 18453 } catch (RemoteException e) { 18454 } 18455 } 18456 app.pendingUiClean = false; 18457 } 18458 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18459 try { 18460 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18461 "Trimming memory of fg " + app.processName 18462 + " to " + fgTrimLevel); 18463 app.thread.scheduleTrimMemory(fgTrimLevel); 18464 } catch (RemoteException e) { 18465 } 18466 } 18467 app.trimMemoryLevel = fgTrimLevel; 18468 } 18469 } 18470 } else { 18471 if (mLowRamStartTime != 0) { 18472 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18473 mLowRamStartTime = 0; 18474 } 18475 for (int i=N-1; i>=0; i--) { 18476 ProcessRecord app = mLruProcesses.get(i); 18477 if (allChanged || app.procStateChanged) { 18478 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18479 app.procStateChanged = false; 18480 } 18481 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18482 || app.systemNoUi) && app.pendingUiClean) { 18483 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18484 && app.thread != null) { 18485 try { 18486 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18487 "Trimming memory of ui hidden " + app.processName 18488 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18489 app.thread.scheduleTrimMemory( 18490 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18491 } catch (RemoteException e) { 18492 } 18493 } 18494 app.pendingUiClean = false; 18495 } 18496 app.trimMemoryLevel = 0; 18497 } 18498 } 18499 18500 if (mAlwaysFinishActivities) { 18501 // Need to do this on its own message because the stack may not 18502 // be in a consistent state at this point. 18503 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18504 } 18505 18506 if (allChanged) { 18507 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18508 } 18509 18510 if (mProcessStats.shouldWriteNowLocked(now)) { 18511 mHandler.post(new Runnable() { 18512 @Override public void run() { 18513 synchronized (ActivityManagerService.this) { 18514 mProcessStats.writeStateAsyncLocked(); 18515 } 18516 } 18517 }); 18518 } 18519 18520 if (DEBUG_OOM_ADJ) { 18521 if (false) { 18522 RuntimeException here = new RuntimeException("here"); 18523 here.fillInStackTrace(); 18524 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18525 } else { 18526 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18527 } 18528 } 18529 } 18530 18531 final void trimApplications() { 18532 synchronized (this) { 18533 int i; 18534 18535 // First remove any unused application processes whose package 18536 // has been removed. 18537 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18538 final ProcessRecord app = mRemovedProcesses.get(i); 18539 if (app.activities.size() == 0 18540 && app.curReceiver == null && app.services.size() == 0) { 18541 Slog.i( 18542 TAG, "Exiting empty application process " 18543 + app.processName + " (" 18544 + (app.thread != null ? app.thread.asBinder() : null) 18545 + ")\n"); 18546 if (app.pid > 0 && app.pid != MY_PID) { 18547 app.kill("empty", false); 18548 } else { 18549 try { 18550 app.thread.scheduleExit(); 18551 } catch (Exception e) { 18552 // Ignore exceptions. 18553 } 18554 } 18555 cleanUpApplicationRecordLocked(app, false, true, -1); 18556 mRemovedProcesses.remove(i); 18557 18558 if (app.persistent) { 18559 addAppLocked(app.info, false, null /* ABI override */); 18560 } 18561 } 18562 } 18563 18564 // Now update the oom adj for all processes. 18565 updateOomAdjLocked(); 18566 } 18567 } 18568 18569 /** This method sends the specified signal to each of the persistent apps */ 18570 public void signalPersistentProcesses(int sig) throws RemoteException { 18571 if (sig != Process.SIGNAL_USR1) { 18572 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18573 } 18574 18575 synchronized (this) { 18576 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18577 != PackageManager.PERMISSION_GRANTED) { 18578 throw new SecurityException("Requires permission " 18579 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18580 } 18581 18582 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18583 ProcessRecord r = mLruProcesses.get(i); 18584 if (r.thread != null && r.persistent) { 18585 Process.sendSignal(r.pid, sig); 18586 } 18587 } 18588 } 18589 } 18590 18591 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18592 if (proc == null || proc == mProfileProc) { 18593 proc = mProfileProc; 18594 profileType = mProfileType; 18595 clearProfilerLocked(); 18596 } 18597 if (proc == null) { 18598 return; 18599 } 18600 try { 18601 proc.thread.profilerControl(false, null, profileType); 18602 } catch (RemoteException e) { 18603 throw new IllegalStateException("Process disappeared"); 18604 } 18605 } 18606 18607 private void clearProfilerLocked() { 18608 if (mProfileFd != null) { 18609 try { 18610 mProfileFd.close(); 18611 } catch (IOException e) { 18612 } 18613 } 18614 mProfileApp = null; 18615 mProfileProc = null; 18616 mProfileFile = null; 18617 mProfileType = 0; 18618 mAutoStopProfiler = false; 18619 mSamplingInterval = 0; 18620 } 18621 18622 public boolean profileControl(String process, int userId, boolean start, 18623 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18624 18625 try { 18626 synchronized (this) { 18627 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18628 // its own permission. 18629 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18630 != PackageManager.PERMISSION_GRANTED) { 18631 throw new SecurityException("Requires permission " 18632 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18633 } 18634 18635 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18636 throw new IllegalArgumentException("null profile info or fd"); 18637 } 18638 18639 ProcessRecord proc = null; 18640 if (process != null) { 18641 proc = findProcessLocked(process, userId, "profileControl"); 18642 } 18643 18644 if (start && (proc == null || proc.thread == null)) { 18645 throw new IllegalArgumentException("Unknown process: " + process); 18646 } 18647 18648 if (start) { 18649 stopProfilerLocked(null, 0); 18650 setProfileApp(proc.info, proc.processName, profilerInfo); 18651 mProfileProc = proc; 18652 mProfileType = profileType; 18653 ParcelFileDescriptor fd = profilerInfo.profileFd; 18654 try { 18655 fd = fd.dup(); 18656 } catch (IOException e) { 18657 fd = null; 18658 } 18659 profilerInfo.profileFd = fd; 18660 proc.thread.profilerControl(start, profilerInfo, profileType); 18661 fd = null; 18662 mProfileFd = null; 18663 } else { 18664 stopProfilerLocked(proc, profileType); 18665 if (profilerInfo != null && profilerInfo.profileFd != null) { 18666 try { 18667 profilerInfo.profileFd.close(); 18668 } catch (IOException e) { 18669 } 18670 } 18671 } 18672 18673 return true; 18674 } 18675 } catch (RemoteException e) { 18676 throw new IllegalStateException("Process disappeared"); 18677 } finally { 18678 if (profilerInfo != null && profilerInfo.profileFd != null) { 18679 try { 18680 profilerInfo.profileFd.close(); 18681 } catch (IOException e) { 18682 } 18683 } 18684 } 18685 } 18686 18687 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18688 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18689 userId, true, ALLOW_FULL_ONLY, callName, null); 18690 ProcessRecord proc = null; 18691 try { 18692 int pid = Integer.parseInt(process); 18693 synchronized (mPidsSelfLocked) { 18694 proc = mPidsSelfLocked.get(pid); 18695 } 18696 } catch (NumberFormatException e) { 18697 } 18698 18699 if (proc == null) { 18700 ArrayMap<String, SparseArray<ProcessRecord>> all 18701 = mProcessNames.getMap(); 18702 SparseArray<ProcessRecord> procs = all.get(process); 18703 if (procs != null && procs.size() > 0) { 18704 proc = procs.valueAt(0); 18705 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18706 for (int i=1; i<procs.size(); i++) { 18707 ProcessRecord thisProc = procs.valueAt(i); 18708 if (thisProc.userId == userId) { 18709 proc = thisProc; 18710 break; 18711 } 18712 } 18713 } 18714 } 18715 } 18716 18717 return proc; 18718 } 18719 18720 public boolean dumpHeap(String process, int userId, boolean managed, 18721 String path, ParcelFileDescriptor fd) throws RemoteException { 18722 18723 try { 18724 synchronized (this) { 18725 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18726 // its own permission (same as profileControl). 18727 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18728 != PackageManager.PERMISSION_GRANTED) { 18729 throw new SecurityException("Requires permission " 18730 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18731 } 18732 18733 if (fd == null) { 18734 throw new IllegalArgumentException("null fd"); 18735 } 18736 18737 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18738 if (proc == null || proc.thread == null) { 18739 throw new IllegalArgumentException("Unknown process: " + process); 18740 } 18741 18742 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18743 if (!isDebuggable) { 18744 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18745 throw new SecurityException("Process not debuggable: " + proc); 18746 } 18747 } 18748 18749 proc.thread.dumpHeap(managed, path, fd); 18750 fd = null; 18751 return true; 18752 } 18753 } catch (RemoteException e) { 18754 throw new IllegalStateException("Process disappeared"); 18755 } finally { 18756 if (fd != null) { 18757 try { 18758 fd.close(); 18759 } catch (IOException e) { 18760 } 18761 } 18762 } 18763 } 18764 18765 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18766 public void monitor() { 18767 synchronized (this) { } 18768 } 18769 18770 void onCoreSettingsChange(Bundle settings) { 18771 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18772 ProcessRecord processRecord = mLruProcesses.get(i); 18773 try { 18774 if (processRecord.thread != null) { 18775 processRecord.thread.setCoreSettings(settings); 18776 } 18777 } catch (RemoteException re) { 18778 /* ignore */ 18779 } 18780 } 18781 } 18782 18783 // Multi-user methods 18784 18785 /** 18786 * Start user, if its not already running, but don't bring it to foreground. 18787 */ 18788 @Override 18789 public boolean startUserInBackground(final int userId) { 18790 return startUser(userId, /* foreground */ false); 18791 } 18792 18793 /** 18794 * Start user, if its not already running, and bring it to foreground. 18795 */ 18796 boolean startUserInForeground(final int userId, Dialog dlg) { 18797 boolean result = startUser(userId, /* foreground */ true); 18798 dlg.dismiss(); 18799 return result; 18800 } 18801 18802 /** 18803 * Refreshes the list of users related to the current user when either a 18804 * user switch happens or when a new related user is started in the 18805 * background. 18806 */ 18807 private void updateCurrentProfileIdsLocked() { 18808 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18809 mCurrentUserId, false /* enabledOnly */); 18810 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18811 for (int i = 0; i < currentProfileIds.length; i++) { 18812 currentProfileIds[i] = profiles.get(i).id; 18813 } 18814 mCurrentProfileIds = currentProfileIds; 18815 18816 synchronized (mUserProfileGroupIdsSelfLocked) { 18817 mUserProfileGroupIdsSelfLocked.clear(); 18818 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18819 for (int i = 0; i < users.size(); i++) { 18820 UserInfo user = users.get(i); 18821 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18822 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18823 } 18824 } 18825 } 18826 } 18827 18828 private Set getProfileIdsLocked(int userId) { 18829 Set userIds = new HashSet<Integer>(); 18830 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18831 userId, false /* enabledOnly */); 18832 for (UserInfo user : profiles) { 18833 userIds.add(Integer.valueOf(user.id)); 18834 } 18835 return userIds; 18836 } 18837 18838 @Override 18839 public boolean switchUser(final int userId) { 18840 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18841 String userName; 18842 synchronized (this) { 18843 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18844 if (userInfo == null) { 18845 Slog.w(TAG, "No user info for user #" + userId); 18846 return false; 18847 } 18848 if (userInfo.isManagedProfile()) { 18849 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18850 return false; 18851 } 18852 userName = userInfo.name; 18853 mTargetUserId = userId; 18854 } 18855 mHandler.removeMessages(START_USER_SWITCH_MSG); 18856 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18857 return true; 18858 } 18859 18860 private void showUserSwitchDialog(int userId, String userName) { 18861 // The dialog will show and then initiate the user switch by calling startUserInForeground 18862 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18863 true /* above system */); 18864 d.show(); 18865 } 18866 18867 private boolean startUser(final int userId, final boolean foreground) { 18868 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18869 != PackageManager.PERMISSION_GRANTED) { 18870 String msg = "Permission Denial: switchUser() from pid=" 18871 + Binder.getCallingPid() 18872 + ", uid=" + Binder.getCallingUid() 18873 + " requires " + INTERACT_ACROSS_USERS_FULL; 18874 Slog.w(TAG, msg); 18875 throw new SecurityException(msg); 18876 } 18877 18878 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18879 18880 final long ident = Binder.clearCallingIdentity(); 18881 try { 18882 synchronized (this) { 18883 final int oldUserId = mCurrentUserId; 18884 if (oldUserId == userId) { 18885 return true; 18886 } 18887 18888 mStackSupervisor.setLockTaskModeLocked(null, false); 18889 18890 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18891 if (userInfo == null) { 18892 Slog.w(TAG, "No user info for user #" + userId); 18893 return false; 18894 } 18895 if (foreground && userInfo.isManagedProfile()) { 18896 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18897 return false; 18898 } 18899 18900 if (foreground) { 18901 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18902 R.anim.screen_user_enter); 18903 } 18904 18905 boolean needStart = false; 18906 18907 // If the user we are switching to is not currently started, then 18908 // we need to start it now. 18909 if (mStartedUsers.get(userId) == null) { 18910 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18911 updateStartedUserArrayLocked(); 18912 needStart = true; 18913 } 18914 18915 final Integer userIdInt = Integer.valueOf(userId); 18916 mUserLru.remove(userIdInt); 18917 mUserLru.add(userIdInt); 18918 18919 if (foreground) { 18920 mCurrentUserId = userId; 18921 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18922 updateCurrentProfileIdsLocked(); 18923 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18924 // Once the internal notion of the active user has switched, we lock the device 18925 // with the option to show the user switcher on the keyguard. 18926 mWindowManager.lockNow(null); 18927 } else { 18928 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18929 updateCurrentProfileIdsLocked(); 18930 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18931 mUserLru.remove(currentUserIdInt); 18932 mUserLru.add(currentUserIdInt); 18933 } 18934 18935 final UserStartedState uss = mStartedUsers.get(userId); 18936 18937 // Make sure user is in the started state. If it is currently 18938 // stopping, we need to knock that off. 18939 if (uss.mState == UserStartedState.STATE_STOPPING) { 18940 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18941 // so we can just fairly silently bring the user back from 18942 // the almost-dead. 18943 uss.mState = UserStartedState.STATE_RUNNING; 18944 updateStartedUserArrayLocked(); 18945 needStart = true; 18946 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18947 // This means ACTION_SHUTDOWN has been sent, so we will 18948 // need to treat this as a new boot of the user. 18949 uss.mState = UserStartedState.STATE_BOOTING; 18950 updateStartedUserArrayLocked(); 18951 needStart = true; 18952 } 18953 18954 if (uss.mState == UserStartedState.STATE_BOOTING) { 18955 // Booting up a new user, need to tell system services about it. 18956 // Note that this is on the same handler as scheduling of broadcasts, 18957 // which is important because it needs to go first. 18958 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18959 } 18960 18961 if (foreground) { 18962 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18963 oldUserId)); 18964 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18965 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18966 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18967 oldUserId, userId, uss)); 18968 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18969 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18970 } 18971 18972 if (needStart) { 18973 // Send USER_STARTED broadcast 18974 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18975 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18976 | Intent.FLAG_RECEIVER_FOREGROUND); 18977 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18978 broadcastIntentLocked(null, null, intent, 18979 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18980 false, false, MY_PID, Process.SYSTEM_UID, userId); 18981 } 18982 18983 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18984 if (userId != UserHandle.USER_OWNER) { 18985 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18986 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18987 broadcastIntentLocked(null, null, intent, null, 18988 new IIntentReceiver.Stub() { 18989 public void performReceive(Intent intent, int resultCode, 18990 String data, Bundle extras, boolean ordered, 18991 boolean sticky, int sendingUser) { 18992 onUserInitialized(uss, foreground, oldUserId, userId); 18993 } 18994 }, 0, null, null, null, AppOpsManager.OP_NONE, 18995 true, false, MY_PID, Process.SYSTEM_UID, 18996 userId); 18997 uss.initializing = true; 18998 } else { 18999 getUserManagerLocked().makeInitialized(userInfo.id); 19000 } 19001 } 19002 19003 if (foreground) { 19004 if (!uss.initializing) { 19005 moveUserToForeground(uss, oldUserId, userId); 19006 } 19007 } else { 19008 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19009 } 19010 19011 if (needStart) { 19012 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19013 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19014 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19015 broadcastIntentLocked(null, null, intent, 19016 null, new IIntentReceiver.Stub() { 19017 @Override 19018 public void performReceive(Intent intent, int resultCode, String data, 19019 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19020 throws RemoteException { 19021 } 19022 }, 0, null, null, 19023 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19024 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19025 } 19026 } 19027 } finally { 19028 Binder.restoreCallingIdentity(ident); 19029 } 19030 19031 return true; 19032 } 19033 19034 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19035 long ident = Binder.clearCallingIdentity(); 19036 try { 19037 Intent intent; 19038 if (oldUserId >= 0) { 19039 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19040 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19041 int count = profiles.size(); 19042 for (int i = 0; i < count; i++) { 19043 int profileUserId = profiles.get(i).id; 19044 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19045 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19046 | Intent.FLAG_RECEIVER_FOREGROUND); 19047 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19048 broadcastIntentLocked(null, null, intent, 19049 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19050 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19051 } 19052 } 19053 if (newUserId >= 0) { 19054 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19055 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19056 int count = profiles.size(); 19057 for (int i = 0; i < count; i++) { 19058 int profileUserId = profiles.get(i).id; 19059 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19060 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19061 | Intent.FLAG_RECEIVER_FOREGROUND); 19062 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19063 broadcastIntentLocked(null, null, intent, 19064 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19065 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19066 } 19067 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19068 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19069 | Intent.FLAG_RECEIVER_FOREGROUND); 19070 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19071 broadcastIntentLocked(null, null, intent, 19072 null, null, 0, null, null, 19073 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19074 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19075 } 19076 } finally { 19077 Binder.restoreCallingIdentity(ident); 19078 } 19079 } 19080 19081 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19082 final int newUserId) { 19083 final int N = mUserSwitchObservers.beginBroadcast(); 19084 if (N > 0) { 19085 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19086 int mCount = 0; 19087 @Override 19088 public void sendResult(Bundle data) throws RemoteException { 19089 synchronized (ActivityManagerService.this) { 19090 if (mCurUserSwitchCallback == this) { 19091 mCount++; 19092 if (mCount == N) { 19093 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19094 } 19095 } 19096 } 19097 } 19098 }; 19099 synchronized (this) { 19100 uss.switching = true; 19101 mCurUserSwitchCallback = callback; 19102 } 19103 for (int i=0; i<N; i++) { 19104 try { 19105 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19106 newUserId, callback); 19107 } catch (RemoteException e) { 19108 } 19109 } 19110 } else { 19111 synchronized (this) { 19112 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19113 } 19114 } 19115 mUserSwitchObservers.finishBroadcast(); 19116 } 19117 19118 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19119 synchronized (this) { 19120 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19121 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19122 } 19123 } 19124 19125 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19126 mCurUserSwitchCallback = null; 19127 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19128 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19129 oldUserId, newUserId, uss)); 19130 } 19131 19132 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19133 synchronized (this) { 19134 if (foreground) { 19135 moveUserToForeground(uss, oldUserId, newUserId); 19136 } 19137 } 19138 19139 completeSwitchAndInitalize(uss, newUserId, true, false); 19140 } 19141 19142 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19143 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19144 if (homeInFront) { 19145 startHomeActivityLocked(newUserId); 19146 } else { 19147 mStackSupervisor.resumeTopActivitiesLocked(); 19148 } 19149 EventLogTags.writeAmSwitchUser(newUserId); 19150 getUserManagerLocked().userForeground(newUserId); 19151 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19152 } 19153 19154 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19155 completeSwitchAndInitalize(uss, newUserId, false, true); 19156 } 19157 19158 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19159 boolean clearInitializing, boolean clearSwitching) { 19160 boolean unfrozen = false; 19161 synchronized (this) { 19162 if (clearInitializing) { 19163 uss.initializing = false; 19164 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19165 } 19166 if (clearSwitching) { 19167 uss.switching = false; 19168 } 19169 if (!uss.switching && !uss.initializing) { 19170 mWindowManager.stopFreezingScreen(); 19171 unfrozen = true; 19172 } 19173 } 19174 if (unfrozen) { 19175 final int N = mUserSwitchObservers.beginBroadcast(); 19176 for (int i=0; i<N; i++) { 19177 try { 19178 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19179 } catch (RemoteException e) { 19180 } 19181 } 19182 mUserSwitchObservers.finishBroadcast(); 19183 } 19184 stopGuestUserIfBackground(); 19185 } 19186 19187 /** 19188 * Stops the guest user if it has gone to the background. 19189 */ 19190 private void stopGuestUserIfBackground() { 19191 synchronized (this) { 19192 final int num = mUserLru.size(); 19193 for (int i = 0; i < num; i++) { 19194 Integer oldUserId = mUserLru.get(i); 19195 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19196 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19197 || oldUss.mState == UserStartedState.STATE_STOPPING 19198 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19199 continue; 19200 } 19201 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19202 if (userInfo.isGuest()) { 19203 // This is a user to be stopped. 19204 stopUserLocked(oldUserId, null); 19205 break; 19206 } 19207 } 19208 } 19209 } 19210 19211 void scheduleStartProfilesLocked() { 19212 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19213 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19214 DateUtils.SECOND_IN_MILLIS); 19215 } 19216 } 19217 19218 void startProfilesLocked() { 19219 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19220 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19221 mCurrentUserId, false /* enabledOnly */); 19222 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19223 for (UserInfo user : profiles) { 19224 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19225 && user.id != mCurrentUserId) { 19226 toStart.add(user); 19227 } 19228 } 19229 final int n = toStart.size(); 19230 int i = 0; 19231 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19232 startUserInBackground(toStart.get(i).id); 19233 } 19234 if (i < n) { 19235 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19236 } 19237 } 19238 19239 void finishUserBoot(UserStartedState uss) { 19240 synchronized (this) { 19241 if (uss.mState == UserStartedState.STATE_BOOTING 19242 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19243 uss.mState = UserStartedState.STATE_RUNNING; 19244 final int userId = uss.mHandle.getIdentifier(); 19245 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19246 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19247 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19248 broadcastIntentLocked(null, null, intent, 19249 null, null, 0, null, null, 19250 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19251 true, false, MY_PID, Process.SYSTEM_UID, userId); 19252 } 19253 } 19254 } 19255 19256 void finishUserSwitch(UserStartedState uss) { 19257 synchronized (this) { 19258 finishUserBoot(uss); 19259 19260 startProfilesLocked(); 19261 19262 int num = mUserLru.size(); 19263 int i = 0; 19264 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19265 Integer oldUserId = mUserLru.get(i); 19266 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19267 if (oldUss == null) { 19268 // Shouldn't happen, but be sane if it does. 19269 mUserLru.remove(i); 19270 num--; 19271 continue; 19272 } 19273 if (oldUss.mState == UserStartedState.STATE_STOPPING 19274 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19275 // This user is already stopping, doesn't count. 19276 num--; 19277 i++; 19278 continue; 19279 } 19280 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19281 // Owner and current can't be stopped, but count as running. 19282 i++; 19283 continue; 19284 } 19285 // This is a user to be stopped. 19286 stopUserLocked(oldUserId, null); 19287 num--; 19288 i++; 19289 } 19290 } 19291 } 19292 19293 @Override 19294 public int stopUser(final int userId, final IStopUserCallback callback) { 19295 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19296 != PackageManager.PERMISSION_GRANTED) { 19297 String msg = "Permission Denial: switchUser() from pid=" 19298 + Binder.getCallingPid() 19299 + ", uid=" + Binder.getCallingUid() 19300 + " requires " + INTERACT_ACROSS_USERS_FULL; 19301 Slog.w(TAG, msg); 19302 throw new SecurityException(msg); 19303 } 19304 if (userId <= 0) { 19305 throw new IllegalArgumentException("Can't stop primary user " + userId); 19306 } 19307 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19308 synchronized (this) { 19309 return stopUserLocked(userId, callback); 19310 } 19311 } 19312 19313 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19314 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19315 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19316 return ActivityManager.USER_OP_IS_CURRENT; 19317 } 19318 19319 final UserStartedState uss = mStartedUsers.get(userId); 19320 if (uss == null) { 19321 // User is not started, nothing to do... but we do need to 19322 // callback if requested. 19323 if (callback != null) { 19324 mHandler.post(new Runnable() { 19325 @Override 19326 public void run() { 19327 try { 19328 callback.userStopped(userId); 19329 } catch (RemoteException e) { 19330 } 19331 } 19332 }); 19333 } 19334 return ActivityManager.USER_OP_SUCCESS; 19335 } 19336 19337 if (callback != null) { 19338 uss.mStopCallbacks.add(callback); 19339 } 19340 19341 if (uss.mState != UserStartedState.STATE_STOPPING 19342 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19343 uss.mState = UserStartedState.STATE_STOPPING; 19344 updateStartedUserArrayLocked(); 19345 19346 long ident = Binder.clearCallingIdentity(); 19347 try { 19348 // We are going to broadcast ACTION_USER_STOPPING and then 19349 // once that is done send a final ACTION_SHUTDOWN and then 19350 // stop the user. 19351 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19352 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19353 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19354 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19355 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19356 // This is the result receiver for the final shutdown broadcast. 19357 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19358 @Override 19359 public void performReceive(Intent intent, int resultCode, String data, 19360 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19361 finishUserStop(uss); 19362 } 19363 }; 19364 // This is the result receiver for the initial stopping broadcast. 19365 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19366 @Override 19367 public void performReceive(Intent intent, int resultCode, String data, 19368 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19369 // On to the next. 19370 synchronized (ActivityManagerService.this) { 19371 if (uss.mState != UserStartedState.STATE_STOPPING) { 19372 // Whoops, we are being started back up. Abort, abort! 19373 return; 19374 } 19375 uss.mState = UserStartedState.STATE_SHUTDOWN; 19376 } 19377 mBatteryStatsService.noteEvent( 19378 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19379 Integer.toString(userId), userId); 19380 mSystemServiceManager.stopUser(userId); 19381 broadcastIntentLocked(null, null, shutdownIntent, 19382 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19383 true, false, MY_PID, Process.SYSTEM_UID, userId); 19384 } 19385 }; 19386 // Kick things off. 19387 broadcastIntentLocked(null, null, stoppingIntent, 19388 null, stoppingReceiver, 0, null, null, 19389 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19390 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19391 } finally { 19392 Binder.restoreCallingIdentity(ident); 19393 } 19394 } 19395 19396 return ActivityManager.USER_OP_SUCCESS; 19397 } 19398 19399 void finishUserStop(UserStartedState uss) { 19400 final int userId = uss.mHandle.getIdentifier(); 19401 boolean stopped; 19402 ArrayList<IStopUserCallback> callbacks; 19403 synchronized (this) { 19404 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19405 if (mStartedUsers.get(userId) != uss) { 19406 stopped = false; 19407 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19408 stopped = false; 19409 } else { 19410 stopped = true; 19411 // User can no longer run. 19412 mStartedUsers.remove(userId); 19413 mUserLru.remove(Integer.valueOf(userId)); 19414 updateStartedUserArrayLocked(); 19415 19416 // Clean up all state and processes associated with the user. 19417 // Kill all the processes for the user. 19418 forceStopUserLocked(userId, "finish user"); 19419 } 19420 19421 // Explicitly remove the old information in mRecentTasks. 19422 removeRecentTasksForUserLocked(userId); 19423 } 19424 19425 for (int i=0; i<callbacks.size(); i++) { 19426 try { 19427 if (stopped) callbacks.get(i).userStopped(userId); 19428 else callbacks.get(i).userStopAborted(userId); 19429 } catch (RemoteException e) { 19430 } 19431 } 19432 19433 if (stopped) { 19434 mSystemServiceManager.cleanupUser(userId); 19435 synchronized (this) { 19436 mStackSupervisor.removeUserLocked(userId); 19437 } 19438 } 19439 } 19440 19441 @Override 19442 public UserInfo getCurrentUser() { 19443 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19444 != PackageManager.PERMISSION_GRANTED) && ( 19445 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19446 != PackageManager.PERMISSION_GRANTED)) { 19447 String msg = "Permission Denial: getCurrentUser() from pid=" 19448 + Binder.getCallingPid() 19449 + ", uid=" + Binder.getCallingUid() 19450 + " requires " + INTERACT_ACROSS_USERS; 19451 Slog.w(TAG, msg); 19452 throw new SecurityException(msg); 19453 } 19454 synchronized (this) { 19455 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19456 return getUserManagerLocked().getUserInfo(userId); 19457 } 19458 } 19459 19460 int getCurrentUserIdLocked() { 19461 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19462 } 19463 19464 @Override 19465 public boolean isUserRunning(int userId, boolean orStopped) { 19466 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19467 != PackageManager.PERMISSION_GRANTED) { 19468 String msg = "Permission Denial: isUserRunning() from pid=" 19469 + Binder.getCallingPid() 19470 + ", uid=" + Binder.getCallingUid() 19471 + " requires " + INTERACT_ACROSS_USERS; 19472 Slog.w(TAG, msg); 19473 throw new SecurityException(msg); 19474 } 19475 synchronized (this) { 19476 return isUserRunningLocked(userId, orStopped); 19477 } 19478 } 19479 19480 boolean isUserRunningLocked(int userId, boolean orStopped) { 19481 UserStartedState state = mStartedUsers.get(userId); 19482 if (state == null) { 19483 return false; 19484 } 19485 if (orStopped) { 19486 return true; 19487 } 19488 return state.mState != UserStartedState.STATE_STOPPING 19489 && state.mState != UserStartedState.STATE_SHUTDOWN; 19490 } 19491 19492 @Override 19493 public int[] getRunningUserIds() { 19494 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19495 != PackageManager.PERMISSION_GRANTED) { 19496 String msg = "Permission Denial: isUserRunning() from pid=" 19497 + Binder.getCallingPid() 19498 + ", uid=" + Binder.getCallingUid() 19499 + " requires " + INTERACT_ACROSS_USERS; 19500 Slog.w(TAG, msg); 19501 throw new SecurityException(msg); 19502 } 19503 synchronized (this) { 19504 return mStartedUserArray; 19505 } 19506 } 19507 19508 private void updateStartedUserArrayLocked() { 19509 int num = 0; 19510 for (int i=0; i<mStartedUsers.size(); i++) { 19511 UserStartedState uss = mStartedUsers.valueAt(i); 19512 // This list does not include stopping users. 19513 if (uss.mState != UserStartedState.STATE_STOPPING 19514 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19515 num++; 19516 } 19517 } 19518 mStartedUserArray = new int[num]; 19519 num = 0; 19520 for (int i=0; i<mStartedUsers.size(); i++) { 19521 UserStartedState uss = mStartedUsers.valueAt(i); 19522 if (uss.mState != UserStartedState.STATE_STOPPING 19523 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19524 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19525 num++; 19526 } 19527 } 19528 } 19529 19530 @Override 19531 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19532 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19533 != PackageManager.PERMISSION_GRANTED) { 19534 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19535 + Binder.getCallingPid() 19536 + ", uid=" + Binder.getCallingUid() 19537 + " requires " + INTERACT_ACROSS_USERS_FULL; 19538 Slog.w(TAG, msg); 19539 throw new SecurityException(msg); 19540 } 19541 19542 mUserSwitchObservers.register(observer); 19543 } 19544 19545 @Override 19546 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19547 mUserSwitchObservers.unregister(observer); 19548 } 19549 19550 private boolean userExists(int userId) { 19551 if (userId == 0) { 19552 return true; 19553 } 19554 UserManagerService ums = getUserManagerLocked(); 19555 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19556 } 19557 19558 int[] getUsersLocked() { 19559 UserManagerService ums = getUserManagerLocked(); 19560 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19561 } 19562 19563 UserManagerService getUserManagerLocked() { 19564 if (mUserManager == null) { 19565 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19566 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19567 } 19568 return mUserManager; 19569 } 19570 19571 private int applyUserId(int uid, int userId) { 19572 return UserHandle.getUid(userId, uid); 19573 } 19574 19575 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19576 if (info == null) return null; 19577 ApplicationInfo newInfo = new ApplicationInfo(info); 19578 newInfo.uid = applyUserId(info.uid, userId); 19579 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19580 + info.packageName; 19581 return newInfo; 19582 } 19583 19584 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19585 if (aInfo == null 19586 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19587 return aInfo; 19588 } 19589 19590 ActivityInfo info = new ActivityInfo(aInfo); 19591 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19592 return info; 19593 } 19594 19595 private final class LocalService extends ActivityManagerInternal { 19596 @Override 19597 public void onWakefulnessChanged(int wakefulness) { 19598 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19599 } 19600 19601 @Override 19602 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19603 String processName, String abiOverride, int uid, Runnable crashHandler) { 19604 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19605 processName, abiOverride, uid, crashHandler); 19606 } 19607 } 19608 19609 /** 19610 * An implementation of IAppTask, that allows an app to manage its own tasks via 19611 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19612 * only the process that calls getAppTasks() can call the AppTask methods. 19613 */ 19614 class AppTaskImpl extends IAppTask.Stub { 19615 private int mTaskId; 19616 private int mCallingUid; 19617 19618 public AppTaskImpl(int taskId, int callingUid) { 19619 mTaskId = taskId; 19620 mCallingUid = callingUid; 19621 } 19622 19623 private void checkCaller() { 19624 if (mCallingUid != Binder.getCallingUid()) { 19625 throw new SecurityException("Caller " + mCallingUid 19626 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19627 } 19628 } 19629 19630 @Override 19631 public void finishAndRemoveTask() { 19632 checkCaller(); 19633 19634 synchronized (ActivityManagerService.this) { 19635 long origId = Binder.clearCallingIdentity(); 19636 try { 19637 if (!removeTaskByIdLocked(mTaskId, false)) { 19638 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19639 } 19640 } finally { 19641 Binder.restoreCallingIdentity(origId); 19642 } 19643 } 19644 } 19645 19646 @Override 19647 public ActivityManager.RecentTaskInfo getTaskInfo() { 19648 checkCaller(); 19649 19650 synchronized (ActivityManagerService.this) { 19651 long origId = Binder.clearCallingIdentity(); 19652 try { 19653 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19654 if (tr == null) { 19655 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19656 } 19657 return createRecentTaskInfoFromTaskRecord(tr); 19658 } finally { 19659 Binder.restoreCallingIdentity(origId); 19660 } 19661 } 19662 } 19663 19664 @Override 19665 public void moveToFront() { 19666 checkCaller(); 19667 // Will bring task to front if it already has a root activity. 19668 startActivityFromRecentsInner(mTaskId, null); 19669 } 19670 19671 @Override 19672 public int startActivity(IBinder whoThread, String callingPackage, 19673 Intent intent, String resolvedType, Bundle options) { 19674 checkCaller(); 19675 19676 int callingUser = UserHandle.getCallingUserId(); 19677 TaskRecord tr; 19678 IApplicationThread appThread; 19679 synchronized (ActivityManagerService.this) { 19680 tr = recentTaskForIdLocked(mTaskId); 19681 if (tr == null) { 19682 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19683 } 19684 appThread = ApplicationThreadNative.asInterface(whoThread); 19685 if (appThread == null) { 19686 throw new IllegalArgumentException("Bad app thread " + appThread); 19687 } 19688 } 19689 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19690 resolvedType, null, null, null, null, 0, 0, null, null, 19691 null, options, callingUser, null, tr); 19692 } 19693 19694 @Override 19695 public void setExcludeFromRecents(boolean exclude) { 19696 checkCaller(); 19697 19698 synchronized (ActivityManagerService.this) { 19699 long origId = Binder.clearCallingIdentity(); 19700 try { 19701 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19702 if (tr == null) { 19703 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19704 } 19705 Intent intent = tr.getBaseIntent(); 19706 if (exclude) { 19707 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19708 } else { 19709 intent.setFlags(intent.getFlags() 19710 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19711 } 19712 } finally { 19713 Binder.restoreCallingIdentity(origId); 19714 } 19715 } 19716 } 19717 } 19718} 19719