ActivityManagerService.java revision 1a4b5a4f02e7d8ff8ff645377d97e6062d36aeaa
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35import android.Manifest; 36import android.app.AppOpsManager; 37import android.app.ApplicationThreadNative; 38import android.app.IActivityContainer; 39import android.app.IActivityContainerCallback; 40import android.app.IAppTask; 41import android.app.ITaskStackListener; 42import android.app.ProfilerInfo; 43import android.app.admin.DevicePolicyManager; 44import android.app.usage.UsageEvents; 45import android.app.usage.UsageStatsManagerInternal; 46import android.appwidget.AppWidgetManager; 47import android.content.res.Resources; 48import android.graphics.Bitmap; 49import android.graphics.Point; 50import android.graphics.Rect; 51import android.os.BatteryStats; 52import android.os.PersistableBundle; 53import android.os.storage.IMountService; 54import android.os.storage.StorageManager; 55import android.service.voice.IVoiceInteractionSession; 56import android.util.ArrayMap; 57import android.util.ArraySet; 58import android.util.SparseIntArray; 59 60import com.android.internal.R; 61import com.android.internal.annotations.GuardedBy; 62import com.android.internal.app.IAppOpsService; 63import com.android.internal.app.IVoiceInteractor; 64import com.android.internal.app.ProcessMap; 65import com.android.internal.app.ProcessStats; 66import com.android.internal.os.BackgroundThread; 67import com.android.internal.os.BatteryStatsImpl; 68import com.android.internal.os.ProcessCpuTracker; 69import com.android.internal.os.TransferPipe; 70import com.android.internal.os.Zygote; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.MemInfoReader; 74import com.android.internal.util.Preconditions; 75import com.android.server.AppOpsService; 76import com.android.server.AttributeCache; 77import com.android.server.IntentResolver; 78import com.android.server.LocalServices; 79import com.android.server.ServiceThread; 80import com.android.server.SystemService; 81import com.android.server.SystemServiceManager; 82import com.android.server.Watchdog; 83import com.android.server.am.ActivityStack.ActivityState; 84import com.android.server.firewall.IntentFirewall; 85import com.android.server.pm.Installer; 86import com.android.server.pm.UserManagerService; 87import com.android.server.statusbar.StatusBarManagerInternal; 88import com.android.server.wm.AppTransition; 89import com.android.server.wm.WindowManagerService; 90import com.google.android.collect.Lists; 91import com.google.android.collect.Maps; 92 93import libcore.io.IoUtils; 94 95import org.xmlpull.v1.XmlPullParser; 96import org.xmlpull.v1.XmlPullParserException; 97import org.xmlpull.v1.XmlSerializer; 98 99import android.app.Activity; 100import android.app.ActivityManager; 101import android.app.ActivityManager.RunningTaskInfo; 102import android.app.ActivityManager.StackInfo; 103import android.app.ActivityManagerInternal; 104import android.app.ActivityManagerNative; 105import android.app.ActivityOptions; 106import android.app.ActivityThread; 107import android.app.AlertDialog; 108import android.app.AppGlobals; 109import android.app.ApplicationErrorReport; 110import android.app.Dialog; 111import android.app.IActivityController; 112import android.app.IApplicationThread; 113import android.app.IInstrumentationWatcher; 114import android.app.INotificationManager; 115import android.app.IProcessObserver; 116import android.app.IServiceConnection; 117import android.app.IStopUserCallback; 118import android.app.IUiAutomationConnection; 119import android.app.IUserSwitchObserver; 120import android.app.Instrumentation; 121import android.app.Notification; 122import android.app.NotificationManager; 123import android.app.PendingIntent; 124import android.app.backup.IBackupManager; 125import android.content.ActivityNotFoundException; 126import android.content.BroadcastReceiver; 127import android.content.ClipData; 128import android.content.ComponentCallbacks2; 129import android.content.ComponentName; 130import android.content.ContentProvider; 131import android.content.ContentResolver; 132import android.content.Context; 133import android.content.DialogInterface; 134import android.content.IContentProvider; 135import android.content.IIntentReceiver; 136import android.content.IIntentSender; 137import android.content.Intent; 138import android.content.IntentFilter; 139import android.content.IntentSender; 140import android.content.pm.ActivityInfo; 141import android.content.pm.ApplicationInfo; 142import android.content.pm.ConfigurationInfo; 143import android.content.pm.IPackageDataObserver; 144import android.content.pm.IPackageManager; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.PackageInfo; 147import android.content.pm.PackageManager; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.UserInfo; 150import android.content.pm.PackageManager.NameNotFoundException; 151import android.content.pm.PathPermission; 152import android.content.pm.ProviderInfo; 153import android.content.pm.ResolveInfo; 154import android.content.pm.ServiceInfo; 155import android.content.res.CompatibilityInfo; 156import android.content.res.Configuration; 157import android.net.Proxy; 158import android.net.ProxyInfo; 159import android.net.Uri; 160import android.os.Binder; 161import android.os.Build; 162import android.os.Bundle; 163import android.os.Debug; 164import android.os.DropBoxManager; 165import android.os.Environment; 166import android.os.FactoryTest; 167import android.os.FileObserver; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.IPermissionController; 172import android.os.IRemoteCallback; 173import android.os.IUserManager; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.PowerManagerInternal; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.SELinux; 183import android.os.ServiceManager; 184import android.os.StrictMode; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.UpdateLock; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.provider.Settings; 191import android.text.format.DateUtils; 192import android.text.format.Time; 193import android.util.AtomicFile; 194import android.util.EventLog; 195import android.util.Log; 196import android.util.Pair; 197import android.util.PrintWriterPrinter; 198import android.util.Slog; 199import android.util.SparseArray; 200import android.util.TimeUtils; 201import android.util.Xml; 202import android.view.Gravity; 203import android.view.LayoutInflater; 204import android.view.View; 205import android.view.WindowManager; 206 207import dalvik.system.VMRuntime; 208 209import java.io.BufferedInputStream; 210import java.io.BufferedOutputStream; 211import java.io.DataInputStream; 212import java.io.DataOutputStream; 213import java.io.File; 214import java.io.FileDescriptor; 215import java.io.FileInputStream; 216import java.io.FileNotFoundException; 217import java.io.FileOutputStream; 218import java.io.IOException; 219import java.io.InputStreamReader; 220import java.io.PrintWriter; 221import java.io.StringWriter; 222import java.lang.ref.WeakReference; 223import java.util.ArrayList; 224import java.util.Arrays; 225import java.util.Collections; 226import java.util.Comparator; 227import java.util.HashMap; 228import java.util.HashSet; 229import java.util.Iterator; 230import java.util.List; 231import java.util.Locale; 232import java.util.Map; 233import java.util.Set; 234import java.util.concurrent.atomic.AtomicBoolean; 235import java.util.concurrent.atomic.AtomicLong; 236 237public final class ActivityManagerService extends ActivityManagerNative 238 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 239 240 private static final String USER_DATA_DIR = "/data/user/"; 241 // File that stores last updated system version and called preboot receivers 242 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 243 244 static final String TAG = "ActivityManager"; 245 static final String TAG_MU = "ActivityManagerServiceMU"; 246 static final boolean DEBUG = false; 247 static final boolean localLOGV = DEBUG; 248 static final boolean DEBUG_BACKUP = localLOGV || false; 249 static final boolean DEBUG_BROADCAST = localLOGV || false; 250 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_CLEANUP = localLOGV || false; 253 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 254 static final boolean DEBUG_FOCUS = false; 255 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 256 static final boolean DEBUG_MU = localLOGV || false; 257 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 258 static final boolean DEBUG_LRU = localLOGV || false; 259 static final boolean DEBUG_PAUSE = localLOGV || false; 260 static final boolean DEBUG_POWER = localLOGV || false; 261 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 262 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 263 static final boolean DEBUG_PROCESSES = localLOGV || false; 264 static final boolean DEBUG_PROVIDER = localLOGV || false; 265 static final boolean DEBUG_RESULTS = localLOGV || false; 266 static final boolean DEBUG_SERVICE = localLOGV || false; 267 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 268 static final boolean DEBUG_STACK = localLOGV || false; 269 static final boolean DEBUG_SWITCH = localLOGV || false; 270 static final boolean DEBUG_TASKS = localLOGV || false; 271 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 272 static final boolean DEBUG_TRANSITION = localLOGV || false; 273 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 274 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 275 static final boolean DEBUG_VISBILITY = localLOGV || false; 276 static final boolean DEBUG_PSS = localLOGV || false; 277 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 278 static final boolean DEBUG_RECENTS = localLOGV || false; 279 static final boolean VALIDATE_TOKENS = false; 280 static final boolean SHOW_ACTIVITY_START_TIME = true; 281 282 // Control over CPU and battery monitoring. 283 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 284 static final boolean MONITOR_CPU_USAGE = true; 285 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 286 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 287 static final boolean MONITOR_THREAD_CPU_USAGE = false; 288 289 // The flags that are set for all calls we make to the package manager. 290 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 291 292 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 293 294 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 295 296 // Maximum number recent bitmaps to keep in memory. 297 static final int MAX_RECENT_BITMAPS = 3; 298 299 // Amount of time after a call to stopAppSwitches() during which we will 300 // prevent further untrusted switches from happening. 301 static final long APP_SWITCH_DELAY_TIME = 5*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real. 305 static final int PROC_START_TIMEOUT = 10*1000; 306 307 // How long we wait for a launched process to attach to the activity manager 308 // before we decide it's never going to come up for real, when the process was 309 // started with a wrapper for instrumentation (such as Valgrind) because it 310 // could take much longer than usual. 311 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 312 313 // How long to wait after going idle before forcing apps to GC. 314 static final int GC_TIMEOUT = 5*1000; 315 316 // The minimum amount of time between successive GC requests for a process. 317 static final int GC_MIN_INTERVAL = 60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process. 320 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 321 322 // The minimum amount of time between successive PSS requests for a process 323 // when the request is due to the memory state being lowered. 324 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 325 326 // The rate at which we check for apps using excessive power -- 15 mins. 327 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on wake locks to start killing things. 331 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // The minimum sample duration we will allow before deciding we have 334 // enough data on CPU usage to start killing things. 335 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 336 337 // How long we allow a receiver to run before giving up on it. 338 static final int BROADCAST_FG_TIMEOUT = 10*1000; 339 static final int BROADCAST_BG_TIMEOUT = 60*1000; 340 341 // How long we wait until we timeout on key dispatching. 342 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 343 344 // How long we wait until we timeout on key dispatching during instrumentation. 345 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 346 347 // Amount of time we wait for observers to handle a user switch before 348 // giving up on them and unfreezing the screen. 349 static final int USER_SWITCH_TIMEOUT = 2*1000; 350 351 // Maximum number of users we allow to be running at a time. 352 static final int MAX_RUNNING_USERS = 3; 353 354 // How long to wait in getAssistContextExtras for the activity and foreground services 355 // to respond with the result. 356 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 357 358 // Maximum number of persisted Uri grants a package is allowed 359 static final int MAX_PERSISTED_URI_GRANTS = 128; 360 361 static final int MY_PID = Process.myPid(); 362 363 static final String[] EMPTY_STRING_ARRAY = new String[0]; 364 365 // How many bytes to write into the dropbox log before truncating 366 static final int DROPBOX_MAX_SIZE = 256 * 1024; 367 368 // Access modes for handleIncomingUser. 369 static final int ALLOW_NON_FULL = 0; 370 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 371 static final int ALLOW_FULL_ONLY = 2; 372 373 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 374 375 // Delay in notifying task stack change listeners (in millis) 376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 377 378 /** All system services */ 379 SystemServiceManager mSystemServiceManager; 380 381 private Installer mInstaller; 382 383 /** Run all ActivityStacks through this */ 384 ActivityStackSupervisor mStackSupervisor; 385 386 /** Task stack change listeners. */ 387 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 388 new RemoteCallbackList<ITaskStackListener>(); 389 390 public IntentFirewall mIntentFirewall; 391 392 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 393 // default actuion automatically. Important for devices without direct input 394 // devices. 395 private boolean mShowDialogs = true; 396 397 BroadcastQueue mFgBroadcastQueue; 398 BroadcastQueue mBgBroadcastQueue; 399 // Convenient for easy iteration over the queues. Foreground is first 400 // so that dispatch of foreground broadcasts gets precedence. 401 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 402 403 BroadcastQueue broadcastQueueForIntent(Intent intent) { 404 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 405 if (DEBUG_BACKGROUND_BROADCAST) { 406 Slog.i(TAG, "Broadcast intent " + intent + " on " 407 + (isFg ? "foreground" : "background") 408 + " queue"); 409 } 410 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 411 } 412 413 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 414 for (BroadcastQueue queue : mBroadcastQueues) { 415 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 416 if (r != null) { 417 return r; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Activity we have told the window manager to have key focus. 425 */ 426 ActivityRecord mFocusedActivity = null; 427 428 /** 429 * List of intents that were used to start the most recent tasks. 430 */ 431 ArrayList<TaskRecord> mRecentTasks; 432 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 433 434 /** 435 * For addAppTask: cached of the last activity component that was added. 436 */ 437 ComponentName mLastAddedTaskComponent; 438 439 /** 440 * For addAppTask: cached of the last activity uid that was added. 441 */ 442 int mLastAddedTaskUid; 443 444 /** 445 * For addAppTask: cached of the last ActivityInfo that was added. 446 */ 447 ActivityInfo mLastAddedTaskActivity; 448 449 public class PendingAssistExtras extends Binder implements Runnable { 450 public final ActivityRecord activity; 451 public final Bundle extras; 452 public final Intent intent; 453 public final String hint; 454 public final int userHandle; 455 public boolean haveResult = false; 456 public Bundle result = null; 457 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 458 String _hint, int _userHandle) { 459 activity = _activity; 460 extras = _extras; 461 intent = _intent; 462 hint = _hint; 463 userHandle = _userHandle; 464 } 465 @Override 466 public void run() { 467 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 468 synchronized (this) { 469 haveResult = true; 470 notifyAll(); 471 } 472 } 473 } 474 475 final ArrayList<PendingAssistExtras> mPendingAssistExtras 476 = new ArrayList<PendingAssistExtras>(); 477 478 /** 479 * Process management. 480 */ 481 final ProcessList mProcessList = new ProcessList(); 482 483 /** 484 * All of the applications we currently have running organized by name. 485 * The keys are strings of the application package name (as 486 * returned by the package manager), and the keys are ApplicationRecord 487 * objects. 488 */ 489 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 490 491 /** 492 * Tracking long-term execution of processes to look for abuse and other 493 * bad app behavior. 494 */ 495 final ProcessStatsService mProcessStats; 496 497 /** 498 * The currently running isolated processes. 499 */ 500 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 501 502 /** 503 * Counter for assigning isolated process uids, to avoid frequently reusing the 504 * same ones. 505 */ 506 int mNextIsolatedProcessUid = 0; 507 508 /** 509 * The currently running heavy-weight process, if any. 510 */ 511 ProcessRecord mHeavyWeightProcess = null; 512 513 /** 514 * The last time that various processes have crashed. 515 */ 516 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 517 518 /** 519 * Information about a process that is currently marked as bad. 520 */ 521 static final class BadProcessInfo { 522 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 523 this.time = time; 524 this.shortMsg = shortMsg; 525 this.longMsg = longMsg; 526 this.stack = stack; 527 } 528 529 final long time; 530 final String shortMsg; 531 final String longMsg; 532 final String stack; 533 } 534 535 /** 536 * Set of applications that we consider to be bad, and will reject 537 * incoming broadcasts from (which the user has no control over). 538 * Processes are added to this set when they have crashed twice within 539 * a minimum amount of time; they are removed from it when they are 540 * later restarted (hopefully due to some user action). The value is the 541 * time it was added to the list. 542 */ 543 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 544 545 /** 546 * All of the processes we currently have running organized by pid. 547 * The keys are the pid running the application. 548 * 549 * <p>NOTE: This object is protected by its own lock, NOT the global 550 * activity manager lock! 551 */ 552 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 553 554 /** 555 * All of the processes that have been forced to be foreground. The key 556 * is the pid of the caller who requested it (we hold a death 557 * link on it). 558 */ 559 abstract class ForegroundToken implements IBinder.DeathRecipient { 560 int pid; 561 IBinder token; 562 } 563 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 564 565 /** 566 * List of records for processes that someone had tried to start before the 567 * system was ready. We don't start them at that point, but ensure they 568 * are started by the time booting is complete. 569 */ 570 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of persistent applications that are in the process 574 * of being started. 575 */ 576 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes that are being forcibly torn down. 580 */ 581 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * List of running applications, sorted by recent usage. 585 * The first entry in the list is the least recently used. 586 */ 587 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Where in mLruProcesses that the processes hosting activities start. 591 */ 592 int mLruProcessActivityStart = 0; 593 594 /** 595 * Where in mLruProcesses that the processes hosting services start. 596 * This is after (lower index) than mLruProcessesActivityStart. 597 */ 598 int mLruProcessServiceStart = 0; 599 600 /** 601 * List of processes that should gc as soon as things are idle. 602 */ 603 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 604 605 /** 606 * Processes we want to collect PSS data from. 607 */ 608 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 609 610 /** 611 * Last time we requested PSS data of all processes. 612 */ 613 long mLastFullPssTime = SystemClock.uptimeMillis(); 614 615 /** 616 * If set, the next time we collect PSS data we should do a full collection 617 * with data from native processes and the kernel. 618 */ 619 boolean mFullPssPending = false; 620 621 /** 622 * This is the process holding what we currently consider to be 623 * the "home" activity. 624 */ 625 ProcessRecord mHomeProcess; 626 627 /** 628 * This is the process holding the activity the user last visited that 629 * is in a different process from the one they are currently in. 630 */ 631 ProcessRecord mPreviousProcess; 632 633 /** 634 * The time at which the previous process was last visible. 635 */ 636 long mPreviousProcessVisibleTime; 637 638 /** 639 * Which uses have been started, so are allowed to run code. 640 */ 641 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 642 643 /** 644 * LRU list of history of current users. Most recently current is at the end. 645 */ 646 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 647 648 /** 649 * Constant array of the users that are currently started. 650 */ 651 int[] mStartedUserArray = new int[] { 0 }; 652 653 /** 654 * Registered observers of the user switching mechanics. 655 */ 656 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 657 = new RemoteCallbackList<IUserSwitchObserver>(); 658 659 /** 660 * Currently active user switch. 661 */ 662 Object mCurUserSwitchCallback; 663 664 /** 665 * Packages that the user has asked to have run in screen size 666 * compatibility mode instead of filling the screen. 667 */ 668 final CompatModePackages mCompatModePackages; 669 670 /** 671 * Set of IntentSenderRecord objects that are currently active. 672 */ 673 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 674 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 675 676 /** 677 * Fingerprints (hashCode()) of stack traces that we've 678 * already logged DropBox entries for. Guarded by itself. If 679 * something (rogue user app) forces this over 680 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 681 */ 682 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 683 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 684 685 /** 686 * Strict Mode background batched logging state. 687 * 688 * The string buffer is guarded by itself, and its lock is also 689 * used to determine if another batched write is already 690 * in-flight. 691 */ 692 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 693 694 /** 695 * Keeps track of all IIntentReceivers that have been registered for 696 * broadcasts. Hash keys are the receiver IBinder, hash value is 697 * a ReceiverList. 698 */ 699 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 700 new HashMap<IBinder, ReceiverList>(); 701 702 /** 703 * Resolver for broadcast intents to registered receivers. 704 * Holds BroadcastFilter (subclass of IntentFilter). 705 */ 706 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 707 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 708 @Override 709 protected boolean allowFilterResult( 710 BroadcastFilter filter, List<BroadcastFilter> dest) { 711 IBinder target = filter.receiverList.receiver.asBinder(); 712 for (int i=dest.size()-1; i>=0; i--) { 713 if (dest.get(i).receiverList.receiver.asBinder() == target) { 714 return false; 715 } 716 } 717 return true; 718 } 719 720 @Override 721 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 722 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 723 || userId == filter.owningUserId) { 724 return super.newResult(filter, match, userId); 725 } 726 return null; 727 } 728 729 @Override 730 protected BroadcastFilter[] newArray(int size) { 731 return new BroadcastFilter[size]; 732 } 733 734 @Override 735 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 736 return packageName.equals(filter.packageName); 737 } 738 }; 739 740 /** 741 * State of all active sticky broadcasts per user. Keys are the action of the 742 * sticky Intent, values are an ArrayList of all broadcasted intents with 743 * that action (which should usually be one). The SparseArray is keyed 744 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 745 * for stickies that are sent to all users. 746 */ 747 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 748 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 749 750 final ActiveServices mServices; 751 752 /** 753 * Backup/restore process management 754 */ 755 String mBackupAppName = null; 756 BackupRecord mBackupTarget = null; 757 758 final ProviderMap mProviderMap; 759 760 /** 761 * List of content providers who have clients waiting for them. The 762 * application is currently being launched and the provider will be 763 * removed from this list once it is published. 764 */ 765 final ArrayList<ContentProviderRecord> mLaunchingProviders 766 = new ArrayList<ContentProviderRecord>(); 767 768 /** 769 * File storing persisted {@link #mGrantedUriPermissions}. 770 */ 771 private final AtomicFile mGrantFile; 772 773 /** XML constants used in {@link #mGrantFile} */ 774 private static final String TAG_URI_GRANTS = "uri-grants"; 775 private static final String TAG_URI_GRANT = "uri-grant"; 776 private static final String ATTR_USER_HANDLE = "userHandle"; 777 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 778 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 779 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 780 private static final String ATTR_TARGET_PKG = "targetPkg"; 781 private static final String ATTR_URI = "uri"; 782 private static final String ATTR_MODE_FLAGS = "modeFlags"; 783 private static final String ATTR_CREATED_TIME = "createdTime"; 784 private static final String ATTR_PREFIX = "prefix"; 785 786 /** 787 * Global set of specific {@link Uri} permissions that have been granted. 788 * This optimized lookup structure maps from {@link UriPermission#targetUid} 789 * to {@link UriPermission#uri} to {@link UriPermission}. 790 */ 791 @GuardedBy("this") 792 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 793 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 794 795 public static class GrantUri { 796 public final int sourceUserId; 797 public final Uri uri; 798 public boolean prefix; 799 800 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 801 this.sourceUserId = sourceUserId; 802 this.uri = uri; 803 this.prefix = prefix; 804 } 805 806 @Override 807 public int hashCode() { 808 int hashCode = 1; 809 hashCode = 31 * hashCode + sourceUserId; 810 hashCode = 31 * hashCode + uri.hashCode(); 811 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 812 return hashCode; 813 } 814 815 @Override 816 public boolean equals(Object o) { 817 if (o instanceof GrantUri) { 818 GrantUri other = (GrantUri) o; 819 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 820 && prefix == other.prefix; 821 } 822 return false; 823 } 824 825 @Override 826 public String toString() { 827 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 828 if (prefix) result += " [prefix]"; 829 return result; 830 } 831 832 public String toSafeString() { 833 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 834 if (prefix) result += " [prefix]"; 835 return result; 836 } 837 838 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 839 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 840 ContentProvider.getUriWithoutUserId(uri), false); 841 } 842 } 843 844 CoreSettingsObserver mCoreSettingsObserver; 845 846 /** 847 * Thread-local storage used to carry caller permissions over through 848 * indirect content-provider access. 849 */ 850 private class Identity { 851 public final IBinder token; 852 public final int pid; 853 public final int uid; 854 855 Identity(IBinder _token, int _pid, int _uid) { 856 token = _token; 857 pid = _pid; 858 uid = _uid; 859 } 860 } 861 862 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 863 864 /** 865 * All information we have collected about the runtime performance of 866 * any user id that can impact battery performance. 867 */ 868 final BatteryStatsService mBatteryStatsService; 869 870 /** 871 * Information about component usage 872 */ 873 UsageStatsManagerInternal mUsageStatsService; 874 875 /** 876 * Information about and control over application operations 877 */ 878 final AppOpsService mAppOpsService; 879 880 /** 881 * Save recent tasks information across reboots. 882 */ 883 final TaskPersister mTaskPersister; 884 885 /** 886 * Current configuration information. HistoryRecord objects are given 887 * a reference to this object to indicate which configuration they are 888 * currently running in, so this object must be kept immutable. 889 */ 890 Configuration mConfiguration = new Configuration(); 891 892 /** 893 * Current sequencing integer of the configuration, for skipping old 894 * configurations. 895 */ 896 int mConfigurationSeq = 0; 897 898 /** 899 * Hardware-reported OpenGLES version. 900 */ 901 final int GL_ES_VERSION; 902 903 /** 904 * List of initialization arguments to pass to all processes when binding applications to them. 905 * For example, references to the commonly used services. 906 */ 907 HashMap<String, IBinder> mAppBindArgs; 908 909 /** 910 * Temporary to avoid allocations. Protected by main lock. 911 */ 912 final StringBuilder mStringBuilder = new StringBuilder(256); 913 914 /** 915 * Used to control how we initialize the service. 916 */ 917 ComponentName mTopComponent; 918 String mTopAction = Intent.ACTION_MAIN; 919 String mTopData; 920 boolean mProcessesReady = false; 921 boolean mSystemReady = false; 922 boolean mBooting = false; 923 boolean mCallFinishBooting = false; 924 boolean mBootAnimationComplete = false; 925 boolean mWaitingUpdate = false; 926 boolean mDidUpdate = false; 927 boolean mOnBattery = false; 928 boolean mLaunchWarningShown = false; 929 930 Context mContext; 931 932 int mFactoryTest; 933 934 boolean mCheckedForSetup; 935 936 /** 937 * The time at which we will allow normal application switches again, 938 * after a call to {@link #stopAppSwitches()}. 939 */ 940 long mAppSwitchesAllowedTime; 941 942 /** 943 * This is set to true after the first switch after mAppSwitchesAllowedTime 944 * is set; any switches after that will clear the time. 945 */ 946 boolean mDidAppSwitch; 947 948 /** 949 * Last time (in realtime) at which we checked for power usage. 950 */ 951 long mLastPowerCheckRealtime; 952 953 /** 954 * Last time (in uptime) at which we checked for power usage. 955 */ 956 long mLastPowerCheckUptime; 957 958 /** 959 * Set while we are wanting to sleep, to prevent any 960 * activities from being started/resumed. 961 */ 962 private boolean mSleeping = false; 963 964 /** 965 * Set while we are running a voice interaction. This overrides 966 * sleeping while it is active. 967 */ 968 private boolean mRunningVoice = false; 969 970 /** 971 * State of external calls telling us if the device is awake or asleep. 972 */ 973 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 974 975 static final int LOCK_SCREEN_HIDDEN = 0; 976 static final int LOCK_SCREEN_LEAVING = 1; 977 static final int LOCK_SCREEN_SHOWN = 2; 978 /** 979 * State of external call telling us if the lock screen is shown. 980 */ 981 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 982 983 /** 984 * Set if we are shutting down the system, similar to sleeping. 985 */ 986 boolean mShuttingDown = false; 987 988 /** 989 * Current sequence id for oom_adj computation traversal. 990 */ 991 int mAdjSeq = 0; 992 993 /** 994 * Current sequence id for process LRU updating. 995 */ 996 int mLruSeq = 0; 997 998 /** 999 * Keep track of the non-cached/empty process we last found, to help 1000 * determine how to distribute cached/empty processes next time. 1001 */ 1002 int mNumNonCachedProcs = 0; 1003 1004 /** 1005 * Keep track of the number of cached hidden procs, to balance oom adj 1006 * distribution between those and empty procs. 1007 */ 1008 int mNumCachedHiddenProcs = 0; 1009 1010 /** 1011 * Keep track of the number of service processes we last found, to 1012 * determine on the next iteration which should be B services. 1013 */ 1014 int mNumServiceProcs = 0; 1015 int mNewNumAServiceProcs = 0; 1016 int mNewNumServiceProcs = 0; 1017 1018 /** 1019 * Allow the current computed overall memory level of the system to go down? 1020 * This is set to false when we are killing processes for reasons other than 1021 * memory management, so that the now smaller process list will not be taken as 1022 * an indication that memory is tighter. 1023 */ 1024 boolean mAllowLowerMemLevel = false; 1025 1026 /** 1027 * The last computed memory level, for holding when we are in a state that 1028 * processes are going away for other reasons. 1029 */ 1030 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1031 1032 /** 1033 * The last total number of process we have, to determine if changes actually look 1034 * like a shrinking number of process due to lower RAM. 1035 */ 1036 int mLastNumProcesses; 1037 1038 /** 1039 * The uptime of the last time we performed idle maintenance. 1040 */ 1041 long mLastIdleTime = SystemClock.uptimeMillis(); 1042 1043 /** 1044 * Total time spent with RAM that has been added in the past since the last idle time. 1045 */ 1046 long mLowRamTimeSinceLastIdle = 0; 1047 1048 /** 1049 * If RAM is currently low, when that horrible situation started. 1050 */ 1051 long mLowRamStartTime = 0; 1052 1053 /** 1054 * For reporting to battery stats the current top application. 1055 */ 1056 private String mCurResumedPackage = null; 1057 private int mCurResumedUid = -1; 1058 1059 /** 1060 * For reporting to battery stats the apps currently running foreground 1061 * service. The ProcessMap is package/uid tuples; each of these contain 1062 * an array of the currently foreground processes. 1063 */ 1064 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1065 = new ProcessMap<ArrayList<ProcessRecord>>(); 1066 1067 /** 1068 * This is set if we had to do a delayed dexopt of an app before launching 1069 * it, to increase the ANR timeouts in that case. 1070 */ 1071 boolean mDidDexOpt; 1072 1073 /** 1074 * Set if the systemServer made a call to enterSafeMode. 1075 */ 1076 boolean mSafeMode; 1077 1078 /** 1079 * If true, we are running under a test environment so will sample PSS from processes 1080 * much more rapidly to try to collect better data when the tests are rapidly 1081 * running through apps. 1082 */ 1083 boolean mTestPssMode = false; 1084 1085 String mDebugApp = null; 1086 boolean mWaitForDebugger = false; 1087 boolean mDebugTransient = false; 1088 String mOrigDebugApp = null; 1089 boolean mOrigWaitForDebugger = false; 1090 boolean mAlwaysFinishActivities = false; 1091 IActivityController mController = null; 1092 String mProfileApp = null; 1093 ProcessRecord mProfileProc = null; 1094 String mProfileFile; 1095 ParcelFileDescriptor mProfileFd; 1096 int mSamplingInterval = 0; 1097 boolean mAutoStopProfiler = false; 1098 int mProfileType = 0; 1099 String mOpenGlTraceApp = null; 1100 1101 final long[] mTmpLong = new long[1]; 1102 1103 static class ProcessChangeItem { 1104 static final int CHANGE_ACTIVITIES = 1<<0; 1105 static final int CHANGE_PROCESS_STATE = 1<<1; 1106 int changes; 1107 int uid; 1108 int pid; 1109 int processState; 1110 boolean foregroundActivities; 1111 } 1112 1113 final RemoteCallbackList<IProcessObserver> mProcessObservers 1114 = new RemoteCallbackList<IProcessObserver>(); 1115 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1116 1117 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1118 = new ArrayList<ProcessChangeItem>(); 1119 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1120 = new ArrayList<ProcessChangeItem>(); 1121 1122 /** 1123 * Runtime CPU use collection thread. This object's lock is used to 1124 * perform synchronization with the thread (notifying it to run). 1125 */ 1126 final Thread mProcessCpuThread; 1127 1128 /** 1129 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1130 * Must acquire this object's lock when accessing it. 1131 * NOTE: this lock will be held while doing long operations (trawling 1132 * through all processes in /proc), so it should never be acquired by 1133 * any critical paths such as when holding the main activity manager lock. 1134 */ 1135 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1136 MONITOR_THREAD_CPU_USAGE); 1137 final AtomicLong mLastCpuTime = new AtomicLong(0); 1138 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1139 1140 long mLastWriteTime = 0; 1141 1142 /** 1143 * Used to retain an update lock when the foreground activity is in 1144 * immersive mode. 1145 */ 1146 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1147 1148 /** 1149 * Set to true after the system has finished booting. 1150 */ 1151 boolean mBooted = false; 1152 1153 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1154 int mProcessLimitOverride = -1; 1155 1156 WindowManagerService mWindowManager; 1157 1158 final ActivityThread mSystemThread; 1159 1160 // Holds the current foreground user's id 1161 int mCurrentUserId = 0; 1162 // Holds the target user's id during a user switch 1163 int mTargetUserId = UserHandle.USER_NULL; 1164 // If there are multiple profiles for the current user, their ids are here 1165 // Currently only the primary user can have managed profiles 1166 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1167 1168 /** 1169 * Mapping from each known user ID to the profile group ID it is associated with. 1170 */ 1171 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1172 1173 private UserManagerService mUserManager; 1174 1175 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1176 final ProcessRecord mApp; 1177 final int mPid; 1178 final IApplicationThread mAppThread; 1179 1180 AppDeathRecipient(ProcessRecord app, int pid, 1181 IApplicationThread thread) { 1182 if (localLOGV) Slog.v( 1183 TAG, "New death recipient " + this 1184 + " for thread " + thread.asBinder()); 1185 mApp = app; 1186 mPid = pid; 1187 mAppThread = thread; 1188 } 1189 1190 @Override 1191 public void binderDied() { 1192 if (localLOGV) Slog.v( 1193 TAG, "Death received in " + this 1194 + " for thread " + mAppThread.asBinder()); 1195 synchronized(ActivityManagerService.this) { 1196 appDiedLocked(mApp, mPid, mAppThread); 1197 } 1198 } 1199 } 1200 1201 static final int SHOW_ERROR_MSG = 1; 1202 static final int SHOW_NOT_RESPONDING_MSG = 2; 1203 static final int SHOW_FACTORY_ERROR_MSG = 3; 1204 static final int UPDATE_CONFIGURATION_MSG = 4; 1205 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1206 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1207 static final int SERVICE_TIMEOUT_MSG = 12; 1208 static final int UPDATE_TIME_ZONE = 13; 1209 static final int SHOW_UID_ERROR_MSG = 14; 1210 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1211 static final int PROC_START_TIMEOUT_MSG = 20; 1212 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1213 static final int KILL_APPLICATION_MSG = 22; 1214 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1215 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1216 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1217 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1218 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1219 static final int CLEAR_DNS_CACHE_MSG = 28; 1220 static final int UPDATE_HTTP_PROXY_MSG = 29; 1221 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1222 static final int DISPATCH_PROCESSES_CHANGED = 31; 1223 static final int DISPATCH_PROCESS_DIED = 32; 1224 static final int REPORT_MEM_USAGE_MSG = 33; 1225 static final int REPORT_USER_SWITCH_MSG = 34; 1226 static final int CONTINUE_USER_SWITCH_MSG = 35; 1227 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1228 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1229 static final int PERSIST_URI_GRANTS_MSG = 38; 1230 static final int REQUEST_ALL_PSS_MSG = 39; 1231 static final int START_PROFILES_MSG = 40; 1232 static final int UPDATE_TIME = 41; 1233 static final int SYSTEM_USER_START_MSG = 42; 1234 static final int SYSTEM_USER_CURRENT_MSG = 43; 1235 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1236 static final int FINISH_BOOTING_MSG = 45; 1237 static final int START_USER_SWITCH_MSG = 46; 1238 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1239 static final int DISMISS_DIALOG_MSG = 48; 1240 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1241 1242 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1243 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1244 static final int FIRST_COMPAT_MODE_MSG = 300; 1245 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1246 1247 CompatModeDialog mCompatModeDialog; 1248 long mLastMemUsageReportTime = 0; 1249 1250 /** 1251 * Flag whether the current user is a "monkey", i.e. whether 1252 * the UI is driven by a UI automation tool. 1253 */ 1254 private boolean mUserIsMonkey; 1255 1256 /** Flag whether the device has a Recents UI */ 1257 boolean mHasRecents; 1258 1259 /** The dimensions of the thumbnails in the Recents UI. */ 1260 int mThumbnailWidth; 1261 int mThumbnailHeight; 1262 1263 final ServiceThread mHandlerThread; 1264 final MainHandler mHandler; 1265 1266 final class MainHandler extends Handler { 1267 public MainHandler(Looper looper) { 1268 super(looper, null, true); 1269 } 1270 1271 @Override 1272 public void handleMessage(Message msg) { 1273 switch (msg.what) { 1274 case SHOW_ERROR_MSG: { 1275 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1276 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1277 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1278 synchronized (ActivityManagerService.this) { 1279 ProcessRecord proc = (ProcessRecord)data.get("app"); 1280 AppErrorResult res = (AppErrorResult) data.get("result"); 1281 if (proc != null && proc.crashDialog != null) { 1282 Slog.e(TAG, "App already has crash dialog: " + proc); 1283 if (res != null) { 1284 res.set(0); 1285 } 1286 return; 1287 } 1288 boolean isBackground = (UserHandle.getAppId(proc.uid) 1289 >= Process.FIRST_APPLICATION_UID 1290 && proc.pid != MY_PID); 1291 for (int userId : mCurrentProfileIds) { 1292 isBackground &= (proc.userId != userId); 1293 } 1294 if (isBackground && !showBackground) { 1295 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1296 if (res != null) { 1297 res.set(0); 1298 } 1299 return; 1300 } 1301 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1302 Dialog d = new AppErrorDialog(mContext, 1303 ActivityManagerService.this, res, proc); 1304 d.show(); 1305 proc.crashDialog = d; 1306 } else { 1307 // The device is asleep, so just pretend that the user 1308 // saw a crash dialog and hit "force quit". 1309 if (res != null) { 1310 res.set(0); 1311 } 1312 } 1313 } 1314 1315 ensureBootCompleted(); 1316 } break; 1317 case SHOW_NOT_RESPONDING_MSG: { 1318 synchronized (ActivityManagerService.this) { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 ProcessRecord proc = (ProcessRecord)data.get("app"); 1321 if (proc != null && proc.anrDialog != null) { 1322 Slog.e(TAG, "App already has anr dialog: " + proc); 1323 return; 1324 } 1325 1326 Intent intent = new Intent("android.intent.action.ANR"); 1327 if (!mProcessesReady) { 1328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1329 | Intent.FLAG_RECEIVER_FOREGROUND); 1330 } 1331 broadcastIntentLocked(null, null, intent, 1332 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1333 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1334 1335 if (mShowDialogs) { 1336 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1337 mContext, proc, (ActivityRecord)data.get("activity"), 1338 msg.arg1 != 0); 1339 d.show(); 1340 proc.anrDialog = d; 1341 } else { 1342 // Just kill the app if there is no dialog to be shown. 1343 killAppAtUsersRequest(proc, null); 1344 } 1345 } 1346 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1350 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1351 synchronized (ActivityManagerService.this) { 1352 ProcessRecord proc = (ProcessRecord) data.get("app"); 1353 if (proc == null) { 1354 Slog.e(TAG, "App not found when showing strict mode dialog."); 1355 break; 1356 } 1357 if (proc.crashDialog != null) { 1358 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1359 return; 1360 } 1361 AppErrorResult res = (AppErrorResult) data.get("result"); 1362 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1363 Dialog d = new StrictModeViolationDialog(mContext, 1364 ActivityManagerService.this, res, proc); 1365 d.show(); 1366 proc.crashDialog = d; 1367 } else { 1368 // The device is asleep, so just pretend that the user 1369 // saw a crash dialog and hit "force quit". 1370 res.set(0); 1371 } 1372 } 1373 ensureBootCompleted(); 1374 } break; 1375 case SHOW_FACTORY_ERROR_MSG: { 1376 Dialog d = new FactoryErrorDialog( 1377 mContext, msg.getData().getCharSequence("msg")); 1378 d.show(); 1379 ensureBootCompleted(); 1380 } break; 1381 case UPDATE_CONFIGURATION_MSG: { 1382 final ContentResolver resolver = mContext.getContentResolver(); 1383 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1384 } break; 1385 case GC_BACKGROUND_PROCESSES_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 performAppGcsIfAppropriateLocked(); 1388 } 1389 } break; 1390 case WAIT_FOR_DEBUGGER_MSG: { 1391 synchronized (ActivityManagerService.this) { 1392 ProcessRecord app = (ProcessRecord)msg.obj; 1393 if (msg.arg1 != 0) { 1394 if (!app.waitedForDebugger) { 1395 Dialog d = new AppWaitingForDebuggerDialog( 1396 ActivityManagerService.this, 1397 mContext, app); 1398 app.waitDialog = d; 1399 app.waitedForDebugger = true; 1400 d.show(); 1401 } 1402 } else { 1403 if (app.waitDialog != null) { 1404 app.waitDialog.dismiss(); 1405 app.waitDialog = null; 1406 } 1407 } 1408 } 1409 } break; 1410 case SERVICE_TIMEOUT_MSG: { 1411 if (mDidDexOpt) { 1412 mDidDexOpt = false; 1413 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1414 nmsg.obj = msg.obj; 1415 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1416 return; 1417 } 1418 mServices.serviceTimeout((ProcessRecord)msg.obj); 1419 } break; 1420 case UPDATE_TIME_ZONE: { 1421 synchronized (ActivityManagerService.this) { 1422 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1423 ProcessRecord r = mLruProcesses.get(i); 1424 if (r.thread != null) { 1425 try { 1426 r.thread.updateTimeZone(); 1427 } catch (RemoteException ex) { 1428 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1429 } 1430 } 1431 } 1432 } 1433 } break; 1434 case CLEAR_DNS_CACHE_MSG: { 1435 synchronized (ActivityManagerService.this) { 1436 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1437 ProcessRecord r = mLruProcesses.get(i); 1438 if (r.thread != null) { 1439 try { 1440 r.thread.clearDnsCache(); 1441 } catch (RemoteException ex) { 1442 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1443 } 1444 } 1445 } 1446 } 1447 } break; 1448 case UPDATE_HTTP_PROXY_MSG: { 1449 ProxyInfo proxy = (ProxyInfo)msg.obj; 1450 String host = ""; 1451 String port = ""; 1452 String exclList = ""; 1453 Uri pacFileUrl = Uri.EMPTY; 1454 if (proxy != null) { 1455 host = proxy.getHost(); 1456 port = Integer.toString(proxy.getPort()); 1457 exclList = proxy.getExclusionListAsString(); 1458 pacFileUrl = proxy.getPacFileUrl(); 1459 } 1460 synchronized (ActivityManagerService.this) { 1461 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1462 ProcessRecord r = mLruProcesses.get(i); 1463 if (r.thread != null) { 1464 try { 1465 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1466 } catch (RemoteException ex) { 1467 Slog.w(TAG, "Failed to update http proxy for: " + 1468 r.info.processName); 1469 } 1470 } 1471 } 1472 } 1473 } break; 1474 case SHOW_UID_ERROR_MSG: { 1475 if (mShowDialogs) { 1476 AlertDialog d = new BaseErrorDialog(mContext); 1477 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1478 d.setCancelable(false); 1479 d.setTitle(mContext.getText(R.string.android_system_label)); 1480 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1481 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1482 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1483 d.show(); 1484 } 1485 } break; 1486 case SHOW_FINGERPRINT_ERROR_MSG: { 1487 if (mShowDialogs) { 1488 AlertDialog d = new BaseErrorDialog(mContext); 1489 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1490 d.setCancelable(false); 1491 d.setTitle(mContext.getText(R.string.android_system_label)); 1492 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1493 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1494 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1495 d.show(); 1496 } 1497 } break; 1498 case PROC_START_TIMEOUT_MSG: { 1499 if (mDidDexOpt) { 1500 mDidDexOpt = false; 1501 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1502 nmsg.obj = msg.obj; 1503 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1504 return; 1505 } 1506 ProcessRecord app = (ProcessRecord)msg.obj; 1507 synchronized (ActivityManagerService.this) { 1508 processStartTimedOutLocked(app); 1509 } 1510 } break; 1511 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1512 synchronized (ActivityManagerService.this) { 1513 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1514 } 1515 } break; 1516 case KILL_APPLICATION_MSG: { 1517 synchronized (ActivityManagerService.this) { 1518 int appid = msg.arg1; 1519 boolean restart = (msg.arg2 == 1); 1520 Bundle bundle = (Bundle)msg.obj; 1521 String pkg = bundle.getString("pkg"); 1522 String reason = bundle.getString("reason"); 1523 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1524 false, UserHandle.USER_ALL, reason); 1525 } 1526 } break; 1527 case FINALIZE_PENDING_INTENT_MSG: { 1528 ((PendingIntentRecord)msg.obj).completeFinalize(); 1529 } break; 1530 case POST_HEAVY_NOTIFICATION_MSG: { 1531 INotificationManager inm = NotificationManager.getService(); 1532 if (inm == null) { 1533 return; 1534 } 1535 1536 ActivityRecord root = (ActivityRecord)msg.obj; 1537 ProcessRecord process = root.app; 1538 if (process == null) { 1539 return; 1540 } 1541 1542 try { 1543 Context context = mContext.createPackageContext(process.info.packageName, 0); 1544 String text = mContext.getString(R.string.heavy_weight_notification, 1545 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1546 Notification notification = new Notification(); 1547 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1548 notification.when = 0; 1549 notification.flags = Notification.FLAG_ONGOING_EVENT; 1550 notification.tickerText = text; 1551 notification.defaults = 0; // please be quiet 1552 notification.sound = null; 1553 notification.vibrate = null; 1554 notification.color = mContext.getResources().getColor( 1555 com.android.internal.R.color.system_notification_accent_color); 1556 notification.setLatestEventInfo(context, text, 1557 mContext.getText(R.string.heavy_weight_notification_detail), 1558 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1559 PendingIntent.FLAG_CANCEL_CURRENT, null, 1560 new UserHandle(root.userId))); 1561 1562 try { 1563 int[] outId = new int[1]; 1564 inm.enqueueNotificationWithTag("android", "android", null, 1565 R.string.heavy_weight_notification, 1566 notification, outId, root.userId); 1567 } catch (RuntimeException e) { 1568 Slog.w(ActivityManagerService.TAG, 1569 "Error showing notification for heavy-weight app", e); 1570 } catch (RemoteException e) { 1571 } 1572 } catch (NameNotFoundException e) { 1573 Slog.w(TAG, "Unable to create context for heavy notification", e); 1574 } 1575 } break; 1576 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1577 INotificationManager inm = NotificationManager.getService(); 1578 if (inm == null) { 1579 return; 1580 } 1581 try { 1582 inm.cancelNotificationWithTag("android", null, 1583 R.string.heavy_weight_notification, msg.arg1); 1584 } catch (RuntimeException e) { 1585 Slog.w(ActivityManagerService.TAG, 1586 "Error canceling notification for service", e); 1587 } catch (RemoteException e) { 1588 } 1589 } break; 1590 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1591 synchronized (ActivityManagerService.this) { 1592 checkExcessivePowerUsageLocked(true); 1593 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1594 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1595 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1596 } 1597 } break; 1598 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1599 synchronized (ActivityManagerService.this) { 1600 ActivityRecord ar = (ActivityRecord)msg.obj; 1601 if (mCompatModeDialog != null) { 1602 if (mCompatModeDialog.mAppInfo.packageName.equals( 1603 ar.info.applicationInfo.packageName)) { 1604 return; 1605 } 1606 mCompatModeDialog.dismiss(); 1607 mCompatModeDialog = null; 1608 } 1609 if (ar != null && false) { 1610 if (mCompatModePackages.getPackageAskCompatModeLocked( 1611 ar.packageName)) { 1612 int mode = mCompatModePackages.computeCompatModeLocked( 1613 ar.info.applicationInfo); 1614 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1615 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1616 mCompatModeDialog = new CompatModeDialog( 1617 ActivityManagerService.this, mContext, 1618 ar.info.applicationInfo); 1619 mCompatModeDialog.show(); 1620 } 1621 } 1622 } 1623 } 1624 break; 1625 } 1626 case DISPATCH_PROCESSES_CHANGED: { 1627 dispatchProcessesChanged(); 1628 break; 1629 } 1630 case DISPATCH_PROCESS_DIED: { 1631 final int pid = msg.arg1; 1632 final int uid = msg.arg2; 1633 dispatchProcessDied(pid, uid); 1634 break; 1635 } 1636 case REPORT_MEM_USAGE_MSG: { 1637 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1638 Thread thread = new Thread() { 1639 @Override public void run() { 1640 reportMemUsage(memInfos); 1641 } 1642 }; 1643 thread.start(); 1644 break; 1645 } 1646 case START_USER_SWITCH_MSG: { 1647 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1648 break; 1649 } 1650 case REPORT_USER_SWITCH_MSG: { 1651 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1652 break; 1653 } 1654 case CONTINUE_USER_SWITCH_MSG: { 1655 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1656 break; 1657 } 1658 case USER_SWITCH_TIMEOUT_MSG: { 1659 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1660 break; 1661 } 1662 case IMMERSIVE_MODE_LOCK_MSG: { 1663 final boolean nextState = (msg.arg1 != 0); 1664 if (mUpdateLock.isHeld() != nextState) { 1665 if (DEBUG_IMMERSIVE) { 1666 final ActivityRecord r = (ActivityRecord) msg.obj; 1667 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1668 } 1669 if (nextState) { 1670 mUpdateLock.acquire(); 1671 } else { 1672 mUpdateLock.release(); 1673 } 1674 } 1675 break; 1676 } 1677 case PERSIST_URI_GRANTS_MSG: { 1678 writeGrantedUriPermissions(); 1679 break; 1680 } 1681 case REQUEST_ALL_PSS_MSG: { 1682 synchronized (ActivityManagerService.this) { 1683 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1684 } 1685 break; 1686 } 1687 case START_PROFILES_MSG: { 1688 synchronized (ActivityManagerService.this) { 1689 startProfilesLocked(); 1690 } 1691 break; 1692 } 1693 case UPDATE_TIME: { 1694 synchronized (ActivityManagerService.this) { 1695 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1696 ProcessRecord r = mLruProcesses.get(i); 1697 if (r.thread != null) { 1698 try { 1699 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1700 } catch (RemoteException ex) { 1701 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1702 } 1703 } 1704 } 1705 } 1706 break; 1707 } 1708 case SYSTEM_USER_START_MSG: { 1709 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1710 Integer.toString(msg.arg1), msg.arg1); 1711 mSystemServiceManager.startUser(msg.arg1); 1712 break; 1713 } 1714 case SYSTEM_USER_CURRENT_MSG: { 1715 mBatteryStatsService.noteEvent( 1716 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1717 Integer.toString(msg.arg2), msg.arg2); 1718 mBatteryStatsService.noteEvent( 1719 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1720 Integer.toString(msg.arg1), msg.arg1); 1721 mSystemServiceManager.switchUser(msg.arg1); 1722 break; 1723 } 1724 case ENTER_ANIMATION_COMPLETE_MSG: { 1725 synchronized (ActivityManagerService.this) { 1726 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1727 if (r != null && r.app != null && r.app.thread != null) { 1728 try { 1729 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1730 } catch (RemoteException e) { 1731 } 1732 } 1733 } 1734 break; 1735 } 1736 case FINISH_BOOTING_MSG: { 1737 if (msg.arg1 != 0) { 1738 finishBooting(); 1739 } 1740 if (msg.arg2 != 0) { 1741 enableScreenAfterBoot(); 1742 } 1743 break; 1744 } 1745 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1746 try { 1747 Locale l = (Locale) msg.obj; 1748 IBinder service = ServiceManager.getService("mount"); 1749 IMountService mountService = IMountService.Stub.asInterface(service); 1750 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1751 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1752 } catch (RemoteException e) { 1753 Log.e(TAG, "Error storing locale for decryption UI", e); 1754 } 1755 break; 1756 } 1757 case DISMISS_DIALOG_MSG: { 1758 final Dialog d = (Dialog) msg.obj; 1759 d.dismiss(); 1760 break; 1761 } 1762 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1763 synchronized (ActivityManagerService.this) { 1764 int i = mTaskStackListeners.beginBroadcast(); 1765 while (i > 0) { 1766 i--; 1767 try { 1768 // Make a one-way callback to the listener 1769 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1770 } catch (RemoteException e){ 1771 // Handled by the RemoteCallbackList 1772 } 1773 } 1774 mTaskStackListeners.finishBroadcast(); 1775 } 1776 break; 1777 } 1778 } 1779 } 1780 }; 1781 1782 static final int COLLECT_PSS_BG_MSG = 1; 1783 1784 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1785 @Override 1786 public void handleMessage(Message msg) { 1787 switch (msg.what) { 1788 case COLLECT_PSS_BG_MSG: { 1789 long start = SystemClock.uptimeMillis(); 1790 MemInfoReader memInfo = null; 1791 synchronized (ActivityManagerService.this) { 1792 if (mFullPssPending) { 1793 mFullPssPending = false; 1794 memInfo = new MemInfoReader(); 1795 } 1796 } 1797 if (memInfo != null) { 1798 updateCpuStatsNow(); 1799 long nativeTotalPss = 0; 1800 synchronized (mProcessCpuTracker) { 1801 final int N = mProcessCpuTracker.countStats(); 1802 for (int j=0; j<N; j++) { 1803 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1804 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1805 // This is definitely an application process; skip it. 1806 continue; 1807 } 1808 synchronized (mPidsSelfLocked) { 1809 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1810 // This is one of our own processes; skip it. 1811 continue; 1812 } 1813 } 1814 nativeTotalPss += Debug.getPss(st.pid, null, null); 1815 } 1816 } 1817 memInfo.readMemInfo(); 1818 synchronized (ActivityManagerService.this) { 1819 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1820 + (SystemClock.uptimeMillis()-start) + "ms"); 1821 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1822 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1823 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1824 } 1825 } 1826 1827 int num = 0; 1828 long[] tmp = new long[1]; 1829 do { 1830 ProcessRecord proc; 1831 int procState; 1832 int pid; 1833 long lastPssTime; 1834 synchronized (ActivityManagerService.this) { 1835 if (mPendingPssProcesses.size() <= 0) { 1836 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1837 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1838 mPendingPssProcesses.clear(); 1839 return; 1840 } 1841 proc = mPendingPssProcesses.remove(0); 1842 procState = proc.pssProcState; 1843 lastPssTime = proc.lastPssTime; 1844 if (proc.thread != null && procState == proc.setProcState) { 1845 pid = proc.pid; 1846 } else { 1847 proc = null; 1848 pid = 0; 1849 } 1850 } 1851 if (proc != null) { 1852 long pss = Debug.getPss(pid, tmp, null); 1853 synchronized (ActivityManagerService.this) { 1854 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1855 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1856 num++; 1857 recordPssSample(proc, procState, pss, tmp[0], 1858 SystemClock.uptimeMillis()); 1859 } 1860 } 1861 } 1862 } while (true); 1863 } 1864 } 1865 } 1866 }; 1867 1868 public void setSystemProcess() { 1869 try { 1870 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1871 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1872 ServiceManager.addService("meminfo", new MemBinder(this)); 1873 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1874 ServiceManager.addService("dbinfo", new DbBinder(this)); 1875 if (MONITOR_CPU_USAGE) { 1876 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1877 } 1878 ServiceManager.addService("permission", new PermissionController(this)); 1879 1880 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1881 "android", STOCK_PM_FLAGS); 1882 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1883 1884 synchronized (this) { 1885 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1886 app.persistent = true; 1887 app.pid = MY_PID; 1888 app.maxAdj = ProcessList.SYSTEM_ADJ; 1889 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1890 mProcessNames.put(app.processName, app.uid, app); 1891 synchronized (mPidsSelfLocked) { 1892 mPidsSelfLocked.put(app.pid, app); 1893 } 1894 updateLruProcessLocked(app, false, null); 1895 updateOomAdjLocked(); 1896 } 1897 } catch (PackageManager.NameNotFoundException e) { 1898 throw new RuntimeException( 1899 "Unable to find android system package", e); 1900 } 1901 } 1902 1903 public void setWindowManager(WindowManagerService wm) { 1904 mWindowManager = wm; 1905 mStackSupervisor.setWindowManager(wm); 1906 } 1907 1908 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1909 mUsageStatsService = usageStatsManager; 1910 } 1911 1912 public void startObservingNativeCrashes() { 1913 final NativeCrashListener ncl = new NativeCrashListener(this); 1914 ncl.start(); 1915 } 1916 1917 public IAppOpsService getAppOpsService() { 1918 return mAppOpsService; 1919 } 1920 1921 static class MemBinder extends Binder { 1922 ActivityManagerService mActivityManagerService; 1923 MemBinder(ActivityManagerService activityManagerService) { 1924 mActivityManagerService = activityManagerService; 1925 } 1926 1927 @Override 1928 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1929 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1930 != PackageManager.PERMISSION_GRANTED) { 1931 pw.println("Permission Denial: can't dump meminfo from from pid=" 1932 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1933 + " without permission " + android.Manifest.permission.DUMP); 1934 return; 1935 } 1936 1937 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1938 } 1939 } 1940 1941 static class GraphicsBinder extends Binder { 1942 ActivityManagerService mActivityManagerService; 1943 GraphicsBinder(ActivityManagerService activityManagerService) { 1944 mActivityManagerService = activityManagerService; 1945 } 1946 1947 @Override 1948 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1949 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1950 != PackageManager.PERMISSION_GRANTED) { 1951 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1952 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1953 + " without permission " + android.Manifest.permission.DUMP); 1954 return; 1955 } 1956 1957 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1958 } 1959 } 1960 1961 static class DbBinder extends Binder { 1962 ActivityManagerService mActivityManagerService; 1963 DbBinder(ActivityManagerService activityManagerService) { 1964 mActivityManagerService = activityManagerService; 1965 } 1966 1967 @Override 1968 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1969 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1970 != PackageManager.PERMISSION_GRANTED) { 1971 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1972 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1973 + " without permission " + android.Manifest.permission.DUMP); 1974 return; 1975 } 1976 1977 mActivityManagerService.dumpDbInfo(fd, pw, args); 1978 } 1979 } 1980 1981 static class CpuBinder extends Binder { 1982 ActivityManagerService mActivityManagerService; 1983 CpuBinder(ActivityManagerService activityManagerService) { 1984 mActivityManagerService = activityManagerService; 1985 } 1986 1987 @Override 1988 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1989 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1990 != PackageManager.PERMISSION_GRANTED) { 1991 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1992 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1993 + " without permission " + android.Manifest.permission.DUMP); 1994 return; 1995 } 1996 1997 synchronized (mActivityManagerService.mProcessCpuTracker) { 1998 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1999 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2000 SystemClock.uptimeMillis())); 2001 } 2002 } 2003 } 2004 2005 public static final class Lifecycle extends SystemService { 2006 private final ActivityManagerService mService; 2007 2008 public Lifecycle(Context context) { 2009 super(context); 2010 mService = new ActivityManagerService(context); 2011 } 2012 2013 @Override 2014 public void onStart() { 2015 mService.start(); 2016 } 2017 2018 public ActivityManagerService getService() { 2019 return mService; 2020 } 2021 } 2022 2023 // Note: This method is invoked on the main thread but may need to attach various 2024 // handlers to other threads. So take care to be explicit about the looper. 2025 public ActivityManagerService(Context systemContext) { 2026 mContext = systemContext; 2027 mFactoryTest = FactoryTest.getMode(); 2028 mSystemThread = ActivityThread.currentActivityThread(); 2029 2030 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2031 2032 mHandlerThread = new ServiceThread(TAG, 2033 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2034 mHandlerThread.start(); 2035 mHandler = new MainHandler(mHandlerThread.getLooper()); 2036 2037 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2038 "foreground", BROADCAST_FG_TIMEOUT, false); 2039 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2040 "background", BROADCAST_BG_TIMEOUT, true); 2041 mBroadcastQueues[0] = mFgBroadcastQueue; 2042 mBroadcastQueues[1] = mBgBroadcastQueue; 2043 2044 mServices = new ActiveServices(this); 2045 mProviderMap = new ProviderMap(this); 2046 2047 // TODO: Move creation of battery stats service outside of activity manager service. 2048 File dataDir = Environment.getDataDirectory(); 2049 File systemDir = new File(dataDir, "system"); 2050 systemDir.mkdirs(); 2051 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2052 mBatteryStatsService.getActiveStatistics().readLocked(); 2053 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2054 mOnBattery = DEBUG_POWER ? true 2055 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2056 mBatteryStatsService.getActiveStatistics().setCallback(this); 2057 2058 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2059 2060 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2061 2062 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2063 2064 // User 0 is the first and only user that runs at boot. 2065 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2066 mUserLru.add(Integer.valueOf(0)); 2067 updateStartedUserArrayLocked(); 2068 2069 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2070 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2071 2072 mConfiguration.setToDefaults(); 2073 mConfiguration.setLocale(Locale.getDefault()); 2074 2075 mConfigurationSeq = mConfiguration.seq = 1; 2076 mProcessCpuTracker.init(); 2077 2078 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2079 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2080 mStackSupervisor = new ActivityStackSupervisor(this); 2081 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2082 2083 mProcessCpuThread = new Thread("CpuTracker") { 2084 @Override 2085 public void run() { 2086 while (true) { 2087 try { 2088 try { 2089 synchronized(this) { 2090 final long now = SystemClock.uptimeMillis(); 2091 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2092 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2093 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2094 // + ", write delay=" + nextWriteDelay); 2095 if (nextWriteDelay < nextCpuDelay) { 2096 nextCpuDelay = nextWriteDelay; 2097 } 2098 if (nextCpuDelay > 0) { 2099 mProcessCpuMutexFree.set(true); 2100 this.wait(nextCpuDelay); 2101 } 2102 } 2103 } catch (InterruptedException e) { 2104 } 2105 updateCpuStatsNow(); 2106 } catch (Exception e) { 2107 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2108 } 2109 } 2110 } 2111 }; 2112 2113 Watchdog.getInstance().addMonitor(this); 2114 Watchdog.getInstance().addThread(mHandler); 2115 } 2116 2117 public void setSystemServiceManager(SystemServiceManager mgr) { 2118 mSystemServiceManager = mgr; 2119 } 2120 2121 public void setInstaller(Installer installer) { 2122 mInstaller = installer; 2123 } 2124 2125 private void start() { 2126 Process.removeAllProcessGroups(); 2127 mProcessCpuThread.start(); 2128 2129 mBatteryStatsService.publish(mContext); 2130 mAppOpsService.publish(mContext); 2131 Slog.d("AppOps", "AppOpsService published"); 2132 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2133 } 2134 2135 public void initPowerManagement() { 2136 mStackSupervisor.initPowerManagement(); 2137 mBatteryStatsService.initPowerManagement(); 2138 } 2139 2140 @Override 2141 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2142 throws RemoteException { 2143 if (code == SYSPROPS_TRANSACTION) { 2144 // We need to tell all apps about the system property change. 2145 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2146 synchronized(this) { 2147 final int NP = mProcessNames.getMap().size(); 2148 for (int ip=0; ip<NP; ip++) { 2149 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2150 final int NA = apps.size(); 2151 for (int ia=0; ia<NA; ia++) { 2152 ProcessRecord app = apps.valueAt(ia); 2153 if (app.thread != null) { 2154 procs.add(app.thread.asBinder()); 2155 } 2156 } 2157 } 2158 } 2159 2160 int N = procs.size(); 2161 for (int i=0; i<N; i++) { 2162 Parcel data2 = Parcel.obtain(); 2163 try { 2164 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2165 } catch (RemoteException e) { 2166 } 2167 data2.recycle(); 2168 } 2169 } 2170 try { 2171 return super.onTransact(code, data, reply, flags); 2172 } catch (RuntimeException e) { 2173 // The activity manager only throws security exceptions, so let's 2174 // log all others. 2175 if (!(e instanceof SecurityException)) { 2176 Slog.wtf(TAG, "Activity Manager Crash", e); 2177 } 2178 throw e; 2179 } 2180 } 2181 2182 void updateCpuStats() { 2183 final long now = SystemClock.uptimeMillis(); 2184 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2185 return; 2186 } 2187 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2188 synchronized (mProcessCpuThread) { 2189 mProcessCpuThread.notify(); 2190 } 2191 } 2192 } 2193 2194 void updateCpuStatsNow() { 2195 synchronized (mProcessCpuTracker) { 2196 mProcessCpuMutexFree.set(false); 2197 final long now = SystemClock.uptimeMillis(); 2198 boolean haveNewCpuStats = false; 2199 2200 if (MONITOR_CPU_USAGE && 2201 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2202 mLastCpuTime.set(now); 2203 haveNewCpuStats = true; 2204 mProcessCpuTracker.update(); 2205 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2206 //Slog.i(TAG, "Total CPU usage: " 2207 // + mProcessCpu.getTotalCpuPercent() + "%"); 2208 2209 // Slog the cpu usage if the property is set. 2210 if ("true".equals(SystemProperties.get("events.cpu"))) { 2211 int user = mProcessCpuTracker.getLastUserTime(); 2212 int system = mProcessCpuTracker.getLastSystemTime(); 2213 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2214 int irq = mProcessCpuTracker.getLastIrqTime(); 2215 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2216 int idle = mProcessCpuTracker.getLastIdleTime(); 2217 2218 int total = user + system + iowait + irq + softIrq + idle; 2219 if (total == 0) total = 1; 2220 2221 EventLog.writeEvent(EventLogTags.CPU, 2222 ((user+system+iowait+irq+softIrq) * 100) / total, 2223 (user * 100) / total, 2224 (system * 100) / total, 2225 (iowait * 100) / total, 2226 (irq * 100) / total, 2227 (softIrq * 100) / total); 2228 } 2229 } 2230 2231 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2232 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2233 synchronized(bstats) { 2234 synchronized(mPidsSelfLocked) { 2235 if (haveNewCpuStats) { 2236 if (mOnBattery) { 2237 int perc = bstats.startAddingCpuLocked(); 2238 int totalUTime = 0; 2239 int totalSTime = 0; 2240 final int N = mProcessCpuTracker.countStats(); 2241 for (int i=0; i<N; i++) { 2242 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2243 if (!st.working) { 2244 continue; 2245 } 2246 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2247 int otherUTime = (st.rel_utime*perc)/100; 2248 int otherSTime = (st.rel_stime*perc)/100; 2249 totalUTime += otherUTime; 2250 totalSTime += otherSTime; 2251 if (pr != null) { 2252 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2253 if (ps == null || !ps.isActive()) { 2254 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2255 pr.info.uid, pr.processName); 2256 } 2257 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2258 st.rel_stime-otherSTime); 2259 ps.addSpeedStepTimes(cpuSpeedTimes); 2260 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2261 } else { 2262 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2263 if (ps == null || !ps.isActive()) { 2264 st.batteryStats = ps = bstats.getProcessStatsLocked( 2265 bstats.mapUid(st.uid), st.name); 2266 } 2267 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2268 st.rel_stime-otherSTime); 2269 ps.addSpeedStepTimes(cpuSpeedTimes); 2270 } 2271 } 2272 bstats.finishAddingCpuLocked(perc, totalUTime, 2273 totalSTime, cpuSpeedTimes); 2274 } 2275 } 2276 } 2277 2278 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2279 mLastWriteTime = now; 2280 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2281 } 2282 } 2283 } 2284 } 2285 2286 @Override 2287 public void batteryNeedsCpuUpdate() { 2288 updateCpuStatsNow(); 2289 } 2290 2291 @Override 2292 public void batteryPowerChanged(boolean onBattery) { 2293 // When plugging in, update the CPU stats first before changing 2294 // the plug state. 2295 updateCpuStatsNow(); 2296 synchronized (this) { 2297 synchronized(mPidsSelfLocked) { 2298 mOnBattery = DEBUG_POWER ? true : onBattery; 2299 } 2300 } 2301 } 2302 2303 /** 2304 * Initialize the application bind args. These are passed to each 2305 * process when the bindApplication() IPC is sent to the process. They're 2306 * lazily setup to make sure the services are running when they're asked for. 2307 */ 2308 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2309 if (mAppBindArgs == null) { 2310 mAppBindArgs = new HashMap<>(); 2311 2312 // Isolated processes won't get this optimization, so that we don't 2313 // violate the rules about which services they have access to. 2314 if (!isolated) { 2315 // Setup the application init args 2316 mAppBindArgs.put("package", ServiceManager.getService("package")); 2317 mAppBindArgs.put("window", ServiceManager.getService("window")); 2318 mAppBindArgs.put(Context.ALARM_SERVICE, 2319 ServiceManager.getService(Context.ALARM_SERVICE)); 2320 } 2321 } 2322 return mAppBindArgs; 2323 } 2324 2325 final void setFocusedActivityLocked(ActivityRecord r) { 2326 if (mFocusedActivity != r) { 2327 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2328 mFocusedActivity = r; 2329 if (r.task != null && r.task.voiceInteractor != null) { 2330 startRunningVoiceLocked(); 2331 } else { 2332 finishRunningVoiceLocked(); 2333 } 2334 mStackSupervisor.setFocusedStack(r); 2335 if (r != null) { 2336 mWindowManager.setFocusedApp(r.appToken, true); 2337 } 2338 applyUpdateLockStateLocked(r); 2339 } 2340 } 2341 2342 final void clearFocusedActivity(ActivityRecord r) { 2343 if (mFocusedActivity == r) { 2344 mFocusedActivity = null; 2345 } 2346 } 2347 2348 @Override 2349 public void setFocusedStack(int stackId) { 2350 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2351 synchronized (ActivityManagerService.this) { 2352 ActivityStack stack = mStackSupervisor.getStack(stackId); 2353 if (stack != null) { 2354 ActivityRecord r = stack.topRunningActivityLocked(null); 2355 if (r != null) { 2356 setFocusedActivityLocked(r); 2357 } 2358 } 2359 } 2360 } 2361 2362 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2363 @Override 2364 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2365 synchronized (ActivityManagerService.this) { 2366 if (listener != null) { 2367 mTaskStackListeners.register(listener); 2368 } 2369 } 2370 } 2371 2372 @Override 2373 public void notifyActivityDrawn(IBinder token) { 2374 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2375 synchronized (this) { 2376 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2377 if (r != null) { 2378 r.task.stack.notifyActivityDrawnLocked(r); 2379 } 2380 } 2381 } 2382 2383 final void applyUpdateLockStateLocked(ActivityRecord r) { 2384 // Modifications to the UpdateLock state are done on our handler, outside 2385 // the activity manager's locks. The new state is determined based on the 2386 // state *now* of the relevant activity record. The object is passed to 2387 // the handler solely for logging detail, not to be consulted/modified. 2388 final boolean nextState = r != null && r.immersive; 2389 mHandler.sendMessage( 2390 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2391 } 2392 2393 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2394 Message msg = Message.obtain(); 2395 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2396 msg.obj = r.task.askedCompatMode ? null : r; 2397 mHandler.sendMessage(msg); 2398 } 2399 2400 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2401 String what, Object obj, ProcessRecord srcApp) { 2402 app.lastActivityTime = now; 2403 2404 if (app.activities.size() > 0) { 2405 // Don't want to touch dependent processes that are hosting activities. 2406 return index; 2407 } 2408 2409 int lrui = mLruProcesses.lastIndexOf(app); 2410 if (lrui < 0) { 2411 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2412 + what + " " + obj + " from " + srcApp); 2413 return index; 2414 } 2415 2416 if (lrui >= index) { 2417 // Don't want to cause this to move dependent processes *back* in the 2418 // list as if they were less frequently used. 2419 return index; 2420 } 2421 2422 if (lrui >= mLruProcessActivityStart) { 2423 // Don't want to touch dependent processes that are hosting activities. 2424 return index; 2425 } 2426 2427 mLruProcesses.remove(lrui); 2428 if (index > 0) { 2429 index--; 2430 } 2431 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2432 + " in LRU list: " + app); 2433 mLruProcesses.add(index, app); 2434 return index; 2435 } 2436 2437 final void removeLruProcessLocked(ProcessRecord app) { 2438 int lrui = mLruProcesses.lastIndexOf(app); 2439 if (lrui >= 0) { 2440 if (!app.killed) { 2441 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2442 Process.killProcessQuiet(app.pid); 2443 Process.killProcessGroup(app.info.uid, app.pid); 2444 } 2445 if (lrui <= mLruProcessActivityStart) { 2446 mLruProcessActivityStart--; 2447 } 2448 if (lrui <= mLruProcessServiceStart) { 2449 mLruProcessServiceStart--; 2450 } 2451 mLruProcesses.remove(lrui); 2452 } 2453 } 2454 2455 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2456 ProcessRecord client) { 2457 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2458 || app.treatLikeActivity; 2459 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2460 if (!activityChange && hasActivity) { 2461 // The process has activities, so we are only allowing activity-based adjustments 2462 // to move it. It should be kept in the front of the list with other 2463 // processes that have activities, and we don't want those to change their 2464 // order except due to activity operations. 2465 return; 2466 } 2467 2468 mLruSeq++; 2469 final long now = SystemClock.uptimeMillis(); 2470 app.lastActivityTime = now; 2471 2472 // First a quick reject: if the app is already at the position we will 2473 // put it, then there is nothing to do. 2474 if (hasActivity) { 2475 final int N = mLruProcesses.size(); 2476 if (N > 0 && mLruProcesses.get(N-1) == app) { 2477 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2478 return; 2479 } 2480 } else { 2481 if (mLruProcessServiceStart > 0 2482 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2483 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2484 return; 2485 } 2486 } 2487 2488 int lrui = mLruProcesses.lastIndexOf(app); 2489 2490 if (app.persistent && lrui >= 0) { 2491 // We don't care about the position of persistent processes, as long as 2492 // they are in the list. 2493 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2494 return; 2495 } 2496 2497 /* In progress: compute new position first, so we can avoid doing work 2498 if the process is not actually going to move. Not yet working. 2499 int addIndex; 2500 int nextIndex; 2501 boolean inActivity = false, inService = false; 2502 if (hasActivity) { 2503 // Process has activities, put it at the very tipsy-top. 2504 addIndex = mLruProcesses.size(); 2505 nextIndex = mLruProcessServiceStart; 2506 inActivity = true; 2507 } else if (hasService) { 2508 // Process has services, put it at the top of the service list. 2509 addIndex = mLruProcessActivityStart; 2510 nextIndex = mLruProcessServiceStart; 2511 inActivity = true; 2512 inService = true; 2513 } else { 2514 // Process not otherwise of interest, it goes to the top of the non-service area. 2515 addIndex = mLruProcessServiceStart; 2516 if (client != null) { 2517 int clientIndex = mLruProcesses.lastIndexOf(client); 2518 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2519 + app); 2520 if (clientIndex >= 0 && addIndex > clientIndex) { 2521 addIndex = clientIndex; 2522 } 2523 } 2524 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2525 } 2526 2527 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2528 + mLruProcessActivityStart + "): " + app); 2529 */ 2530 2531 if (lrui >= 0) { 2532 if (lrui < mLruProcessActivityStart) { 2533 mLruProcessActivityStart--; 2534 } 2535 if (lrui < mLruProcessServiceStart) { 2536 mLruProcessServiceStart--; 2537 } 2538 /* 2539 if (addIndex > lrui) { 2540 addIndex--; 2541 } 2542 if (nextIndex > lrui) { 2543 nextIndex--; 2544 } 2545 */ 2546 mLruProcesses.remove(lrui); 2547 } 2548 2549 /* 2550 mLruProcesses.add(addIndex, app); 2551 if (inActivity) { 2552 mLruProcessActivityStart++; 2553 } 2554 if (inService) { 2555 mLruProcessActivityStart++; 2556 } 2557 */ 2558 2559 int nextIndex; 2560 if (hasActivity) { 2561 final int N = mLruProcesses.size(); 2562 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2563 // Process doesn't have activities, but has clients with 2564 // activities... move it up, but one below the top (the top 2565 // should always have a real activity). 2566 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2567 mLruProcesses.add(N-1, app); 2568 // To keep it from spamming the LRU list (by making a bunch of clients), 2569 // we will push down any other entries owned by the app. 2570 final int uid = app.info.uid; 2571 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2572 ProcessRecord subProc = mLruProcesses.get(i); 2573 if (subProc.info.uid == uid) { 2574 // We want to push this one down the list. If the process after 2575 // it is for the same uid, however, don't do so, because we don't 2576 // want them internally to be re-ordered. 2577 if (mLruProcesses.get(i-1).info.uid != uid) { 2578 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2579 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2580 ProcessRecord tmp = mLruProcesses.get(i); 2581 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2582 mLruProcesses.set(i-1, tmp); 2583 i--; 2584 } 2585 } else { 2586 // A gap, we can stop here. 2587 break; 2588 } 2589 } 2590 } else { 2591 // Process has activities, put it at the very tipsy-top. 2592 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2593 mLruProcesses.add(app); 2594 } 2595 nextIndex = mLruProcessServiceStart; 2596 } else if (hasService) { 2597 // Process has services, put it at the top of the service list. 2598 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2599 mLruProcesses.add(mLruProcessActivityStart, app); 2600 nextIndex = mLruProcessServiceStart; 2601 mLruProcessActivityStart++; 2602 } else { 2603 // Process not otherwise of interest, it goes to the top of the non-service area. 2604 int index = mLruProcessServiceStart; 2605 if (client != null) { 2606 // If there is a client, don't allow the process to be moved up higher 2607 // in the list than that client. 2608 int clientIndex = mLruProcesses.lastIndexOf(client); 2609 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2610 + " when updating " + app); 2611 if (clientIndex <= lrui) { 2612 // Don't allow the client index restriction to push it down farther in the 2613 // list than it already is. 2614 clientIndex = lrui; 2615 } 2616 if (clientIndex >= 0 && index > clientIndex) { 2617 index = clientIndex; 2618 } 2619 } 2620 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2621 mLruProcesses.add(index, app); 2622 nextIndex = index-1; 2623 mLruProcessActivityStart++; 2624 mLruProcessServiceStart++; 2625 } 2626 2627 // If the app is currently using a content provider or service, 2628 // bump those processes as well. 2629 for (int j=app.connections.size()-1; j>=0; j--) { 2630 ConnectionRecord cr = app.connections.valueAt(j); 2631 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2632 && cr.binding.service.app != null 2633 && cr.binding.service.app.lruSeq != mLruSeq 2634 && !cr.binding.service.app.persistent) { 2635 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2636 "service connection", cr, app); 2637 } 2638 } 2639 for (int j=app.conProviders.size()-1; j>=0; j--) { 2640 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2641 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2642 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2643 "provider reference", cpr, app); 2644 } 2645 } 2646 } 2647 2648 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2649 if (uid == Process.SYSTEM_UID) { 2650 // The system gets to run in any process. If there are multiple 2651 // processes with the same uid, just pick the first (this 2652 // should never happen). 2653 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2654 if (procs == null) return null; 2655 final int N = procs.size(); 2656 for (int i = 0; i < N; i++) { 2657 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2658 } 2659 } 2660 ProcessRecord proc = mProcessNames.get(processName, uid); 2661 if (false && proc != null && !keepIfLarge 2662 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2663 && proc.lastCachedPss >= 4000) { 2664 // Turn this condition on to cause killing to happen regularly, for testing. 2665 if (proc.baseProcessTracker != null) { 2666 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2667 } 2668 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2669 } else if (proc != null && !keepIfLarge 2670 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2671 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2672 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2673 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2674 if (proc.baseProcessTracker != null) { 2675 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2676 } 2677 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2678 } 2679 } 2680 return proc; 2681 } 2682 2683 void ensurePackageDexOpt(String packageName) { 2684 IPackageManager pm = AppGlobals.getPackageManager(); 2685 try { 2686 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2687 mDidDexOpt = true; 2688 } 2689 } catch (RemoteException e) { 2690 } 2691 } 2692 2693 boolean isNextTransitionForward() { 2694 int transit = mWindowManager.getPendingAppTransition(); 2695 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2696 || transit == AppTransition.TRANSIT_TASK_OPEN 2697 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2698 } 2699 2700 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2701 String processName, String abiOverride, int uid, Runnable crashHandler) { 2702 synchronized(this) { 2703 ApplicationInfo info = new ApplicationInfo(); 2704 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2705 // For isolated processes, the former contains the parent's uid and the latter the 2706 // actual uid of the isolated process. 2707 // In the special case introduced by this method (which is, starting an isolated 2708 // process directly from the SystemServer without an actual parent app process) the 2709 // closest thing to a parent's uid is SYSTEM_UID. 2710 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2711 // the |isolated| logic in the ProcessRecord constructor. 2712 info.uid = Process.SYSTEM_UID; 2713 info.processName = processName; 2714 info.className = entryPoint; 2715 info.packageName = "android"; 2716 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2717 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2718 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2719 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2720 crashHandler); 2721 return proc != null ? proc.pid : 0; 2722 } 2723 } 2724 2725 final ProcessRecord startProcessLocked(String processName, 2726 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2727 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2728 boolean isolated, boolean keepIfLarge) { 2729 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2730 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2731 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2732 null /* crashHandler */); 2733 } 2734 2735 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2736 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2737 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2738 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2739 long startTime = SystemClock.elapsedRealtime(); 2740 ProcessRecord app; 2741 if (!isolated) { 2742 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2743 checkTime(startTime, "startProcess: after getProcessRecord"); 2744 } else { 2745 // If this is an isolated process, it can't re-use an existing process. 2746 app = null; 2747 } 2748 // We don't have to do anything more if: 2749 // (1) There is an existing application record; and 2750 // (2) The caller doesn't think it is dead, OR there is no thread 2751 // object attached to it so we know it couldn't have crashed; and 2752 // (3) There is a pid assigned to it, so it is either starting or 2753 // already running. 2754 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2755 + " app=" + app + " knownToBeDead=" + knownToBeDead 2756 + " thread=" + (app != null ? app.thread : null) 2757 + " pid=" + (app != null ? app.pid : -1)); 2758 if (app != null && app.pid > 0) { 2759 if (!knownToBeDead || app.thread == null) { 2760 // We already have the app running, or are waiting for it to 2761 // come up (we have a pid but not yet its thread), so keep it. 2762 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2763 // If this is a new package in the process, add the package to the list 2764 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2765 checkTime(startTime, "startProcess: done, added package to proc"); 2766 return app; 2767 } 2768 2769 // An application record is attached to a previous process, 2770 // clean it up now. 2771 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2772 checkTime(startTime, "startProcess: bad proc running, killing"); 2773 Process.killProcessGroup(app.info.uid, app.pid); 2774 handleAppDiedLocked(app, true, true); 2775 checkTime(startTime, "startProcess: done killing old proc"); 2776 } 2777 2778 String hostingNameStr = hostingName != null 2779 ? hostingName.flattenToShortString() : null; 2780 2781 if (!isolated) { 2782 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2783 // If we are in the background, then check to see if this process 2784 // is bad. If so, we will just silently fail. 2785 if (mBadProcesses.get(info.processName, info.uid) != null) { 2786 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2787 + "/" + info.processName); 2788 return null; 2789 } 2790 } else { 2791 // When the user is explicitly starting a process, then clear its 2792 // crash count so that we won't make it bad until they see at 2793 // least one crash dialog again, and make the process good again 2794 // if it had been bad. 2795 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2796 + "/" + info.processName); 2797 mProcessCrashTimes.remove(info.processName, info.uid); 2798 if (mBadProcesses.get(info.processName, info.uid) != null) { 2799 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2800 UserHandle.getUserId(info.uid), info.uid, 2801 info.processName); 2802 mBadProcesses.remove(info.processName, info.uid); 2803 if (app != null) { 2804 app.bad = false; 2805 } 2806 } 2807 } 2808 } 2809 2810 if (app == null) { 2811 checkTime(startTime, "startProcess: creating new process record"); 2812 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2813 if (app == null) { 2814 Slog.w(TAG, "Failed making new process record for " 2815 + processName + "/" + info.uid + " isolated=" + isolated); 2816 return null; 2817 } 2818 app.crashHandler = crashHandler; 2819 mProcessNames.put(processName, app.uid, app); 2820 if (isolated) { 2821 mIsolatedProcesses.put(app.uid, app); 2822 } 2823 checkTime(startTime, "startProcess: done creating new process record"); 2824 } else { 2825 // If this is a new package in the process, add the package to the list 2826 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2827 checkTime(startTime, "startProcess: added package to existing proc"); 2828 } 2829 2830 // If the system is not ready yet, then hold off on starting this 2831 // process until it is. 2832 if (!mProcessesReady 2833 && !isAllowedWhileBooting(info) 2834 && !allowWhileBooting) { 2835 if (!mProcessesOnHold.contains(app)) { 2836 mProcessesOnHold.add(app); 2837 } 2838 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2839 checkTime(startTime, "startProcess: returning with proc on hold"); 2840 return app; 2841 } 2842 2843 checkTime(startTime, "startProcess: stepping in to startProcess"); 2844 startProcessLocked( 2845 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2846 checkTime(startTime, "startProcess: done starting proc!"); 2847 return (app.pid != 0) ? app : null; 2848 } 2849 2850 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2851 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2852 } 2853 2854 private final void startProcessLocked(ProcessRecord app, 2855 String hostingType, String hostingNameStr) { 2856 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2857 null /* entryPoint */, null /* entryPointArgs */); 2858 } 2859 2860 private final void startProcessLocked(ProcessRecord app, String hostingType, 2861 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2862 long startTime = SystemClock.elapsedRealtime(); 2863 if (app.pid > 0 && app.pid != MY_PID) { 2864 checkTime(startTime, "startProcess: removing from pids map"); 2865 synchronized (mPidsSelfLocked) { 2866 mPidsSelfLocked.remove(app.pid); 2867 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2868 } 2869 checkTime(startTime, "startProcess: done removing from pids map"); 2870 app.setPid(0); 2871 } 2872 2873 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2874 "startProcessLocked removing on hold: " + app); 2875 mProcessesOnHold.remove(app); 2876 2877 checkTime(startTime, "startProcess: starting to update cpu stats"); 2878 updateCpuStats(); 2879 checkTime(startTime, "startProcess: done updating cpu stats"); 2880 2881 try { 2882 int uid = app.uid; 2883 2884 int[] gids = null; 2885 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2886 if (!app.isolated) { 2887 int[] permGids = null; 2888 try { 2889 checkTime(startTime, "startProcess: getting gids from package manager"); 2890 final PackageManager pm = mContext.getPackageManager(); 2891 permGids = pm.getPackageGids(app.info.packageName); 2892 2893 if (Environment.isExternalStorageEmulated()) { 2894 checkTime(startTime, "startProcess: checking external storage perm"); 2895 if (pm.checkPermission( 2896 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2897 app.info.packageName) == PERMISSION_GRANTED) { 2898 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2899 } else { 2900 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2901 } 2902 } 2903 } catch (PackageManager.NameNotFoundException e) { 2904 Slog.w(TAG, "Unable to retrieve gids", e); 2905 } 2906 2907 /* 2908 * Add shared application and profile GIDs so applications can share some 2909 * resources like shared libraries and access user-wide resources 2910 */ 2911 if (permGids == null) { 2912 gids = new int[2]; 2913 } else { 2914 gids = new int[permGids.length + 2]; 2915 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2916 } 2917 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2918 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2919 } 2920 checkTime(startTime, "startProcess: building args"); 2921 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2922 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2923 && mTopComponent != null 2924 && app.processName.equals(mTopComponent.getPackageName())) { 2925 uid = 0; 2926 } 2927 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2928 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2929 uid = 0; 2930 } 2931 } 2932 int debugFlags = 0; 2933 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2934 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2935 // Also turn on CheckJNI for debuggable apps. It's quite 2936 // awkward to turn on otherwise. 2937 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2938 } 2939 // Run the app in safe mode if its manifest requests so or the 2940 // system is booted in safe mode. 2941 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2942 mSafeMode == true) { 2943 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2944 } 2945 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2946 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2947 } 2948 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2949 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2950 } 2951 if ("1".equals(SystemProperties.get("debug.assert"))) { 2952 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2953 } 2954 2955 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2956 if (requiredAbi == null) { 2957 requiredAbi = Build.SUPPORTED_ABIS[0]; 2958 } 2959 2960 String instructionSet = null; 2961 if (app.info.primaryCpuAbi != null) { 2962 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2963 } 2964 2965 // Start the process. It will either succeed and return a result containing 2966 // the PID of the new process, or else throw a RuntimeException. 2967 boolean isActivityProcess = (entryPoint == null); 2968 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2969 checkTime(startTime, "startProcess: asking zygote to start proc"); 2970 Process.ProcessStartResult startResult = Process.start(entryPoint, 2971 app.processName, uid, uid, gids, debugFlags, mountExternal, 2972 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2973 app.info.dataDir, entryPointArgs); 2974 checkTime(startTime, "startProcess: returned from zygote!"); 2975 2976 if (app.isolated) { 2977 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2978 } 2979 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2980 checkTime(startTime, "startProcess: done updating battery stats"); 2981 2982 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2983 UserHandle.getUserId(uid), startResult.pid, uid, 2984 app.processName, hostingType, 2985 hostingNameStr != null ? hostingNameStr : ""); 2986 2987 if (app.persistent) { 2988 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2989 } 2990 2991 checkTime(startTime, "startProcess: building log message"); 2992 StringBuilder buf = mStringBuilder; 2993 buf.setLength(0); 2994 buf.append("Start proc "); 2995 buf.append(app.processName); 2996 if (!isActivityProcess) { 2997 buf.append(" ["); 2998 buf.append(entryPoint); 2999 buf.append("]"); 3000 } 3001 buf.append(" for "); 3002 buf.append(hostingType); 3003 if (hostingNameStr != null) { 3004 buf.append(" "); 3005 buf.append(hostingNameStr); 3006 } 3007 buf.append(": pid="); 3008 buf.append(startResult.pid); 3009 buf.append(" uid="); 3010 buf.append(uid); 3011 buf.append(" gids={"); 3012 if (gids != null) { 3013 for (int gi=0; gi<gids.length; gi++) { 3014 if (gi != 0) buf.append(", "); 3015 buf.append(gids[gi]); 3016 3017 } 3018 } 3019 buf.append("}"); 3020 if (requiredAbi != null) { 3021 buf.append(" abi="); 3022 buf.append(requiredAbi); 3023 } 3024 Slog.i(TAG, buf.toString()); 3025 app.setPid(startResult.pid); 3026 app.usingWrapper = startResult.usingWrapper; 3027 app.removed = false; 3028 app.killed = false; 3029 app.killedByAm = false; 3030 checkTime(startTime, "startProcess: starting to update pids map"); 3031 synchronized (mPidsSelfLocked) { 3032 this.mPidsSelfLocked.put(startResult.pid, app); 3033 if (isActivityProcess) { 3034 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3035 msg.obj = app; 3036 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3037 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3038 } 3039 } 3040 checkTime(startTime, "startProcess: done updating pids map"); 3041 } catch (RuntimeException e) { 3042 // XXX do better error recovery. 3043 app.setPid(0); 3044 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3045 if (app.isolated) { 3046 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3047 } 3048 Slog.e(TAG, "Failure starting process " + app.processName, e); 3049 } 3050 } 3051 3052 void updateUsageStats(ActivityRecord component, boolean resumed) { 3053 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3054 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3055 if (resumed) { 3056 if (mUsageStatsService != null) { 3057 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3058 UsageEvents.Event.MOVE_TO_FOREGROUND); 3059 } 3060 synchronized (stats) { 3061 stats.noteActivityResumedLocked(component.app.uid); 3062 } 3063 } else { 3064 if (mUsageStatsService != null) { 3065 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3066 UsageEvents.Event.MOVE_TO_BACKGROUND); 3067 } 3068 synchronized (stats) { 3069 stats.noteActivityPausedLocked(component.app.uid); 3070 } 3071 } 3072 } 3073 3074 Intent getHomeIntent() { 3075 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3076 intent.setComponent(mTopComponent); 3077 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3078 intent.addCategory(Intent.CATEGORY_HOME); 3079 } 3080 return intent; 3081 } 3082 3083 boolean startHomeActivityLocked(int userId) { 3084 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3085 && mTopAction == null) { 3086 // We are running in factory test mode, but unable to find 3087 // the factory test app, so just sit around displaying the 3088 // error message and don't try to start anything. 3089 return false; 3090 } 3091 Intent intent = getHomeIntent(); 3092 ActivityInfo aInfo = 3093 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3094 if (aInfo != null) { 3095 intent.setComponent(new ComponentName( 3096 aInfo.applicationInfo.packageName, aInfo.name)); 3097 // Don't do this if the home app is currently being 3098 // instrumented. 3099 aInfo = new ActivityInfo(aInfo); 3100 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3101 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3102 aInfo.applicationInfo.uid, true); 3103 if (app == null || app.instrumentationClass == null) { 3104 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3105 mStackSupervisor.startHomeActivity(intent, aInfo); 3106 } 3107 } 3108 3109 return true; 3110 } 3111 3112 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3113 ActivityInfo ai = null; 3114 ComponentName comp = intent.getComponent(); 3115 try { 3116 if (comp != null) { 3117 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3118 } else { 3119 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3120 intent, 3121 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3122 flags, userId); 3123 3124 if (info != null) { 3125 ai = info.activityInfo; 3126 } 3127 } 3128 } catch (RemoteException e) { 3129 // ignore 3130 } 3131 3132 return ai; 3133 } 3134 3135 /** 3136 * Starts the "new version setup screen" if appropriate. 3137 */ 3138 void startSetupActivityLocked() { 3139 // Only do this once per boot. 3140 if (mCheckedForSetup) { 3141 return; 3142 } 3143 3144 // We will show this screen if the current one is a different 3145 // version than the last one shown, and we are not running in 3146 // low-level factory test mode. 3147 final ContentResolver resolver = mContext.getContentResolver(); 3148 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3149 Settings.Global.getInt(resolver, 3150 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3151 mCheckedForSetup = true; 3152 3153 // See if we should be showing the platform update setup UI. 3154 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3155 List<ResolveInfo> ris = mContext.getPackageManager() 3156 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3157 3158 // We don't allow third party apps to replace this. 3159 ResolveInfo ri = null; 3160 for (int i=0; ris != null && i<ris.size(); i++) { 3161 if ((ris.get(i).activityInfo.applicationInfo.flags 3162 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3163 ri = ris.get(i); 3164 break; 3165 } 3166 } 3167 3168 if (ri != null) { 3169 String vers = ri.activityInfo.metaData != null 3170 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3171 : null; 3172 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3173 vers = ri.activityInfo.applicationInfo.metaData.getString( 3174 Intent.METADATA_SETUP_VERSION); 3175 } 3176 String lastVers = Settings.Secure.getString( 3177 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3178 if (vers != null && !vers.equals(lastVers)) { 3179 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3180 intent.setComponent(new ComponentName( 3181 ri.activityInfo.packageName, ri.activityInfo.name)); 3182 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3183 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3184 null); 3185 } 3186 } 3187 } 3188 } 3189 3190 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3191 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3192 } 3193 3194 void enforceNotIsolatedCaller(String caller) { 3195 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3196 throw new SecurityException("Isolated process not allowed to call " + caller); 3197 } 3198 } 3199 3200 void enforceShellRestriction(String restriction, int userHandle) { 3201 if (Binder.getCallingUid() == Process.SHELL_UID) { 3202 if (userHandle < 0 3203 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3204 throw new SecurityException("Shell does not have permission to access user " 3205 + userHandle); 3206 } 3207 } 3208 } 3209 3210 @Override 3211 public int getFrontActivityScreenCompatMode() { 3212 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3213 synchronized (this) { 3214 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3215 } 3216 } 3217 3218 @Override 3219 public void setFrontActivityScreenCompatMode(int mode) { 3220 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3221 "setFrontActivityScreenCompatMode"); 3222 synchronized (this) { 3223 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3224 } 3225 } 3226 3227 @Override 3228 public int getPackageScreenCompatMode(String packageName) { 3229 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3230 synchronized (this) { 3231 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3232 } 3233 } 3234 3235 @Override 3236 public void setPackageScreenCompatMode(String packageName, int mode) { 3237 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3238 "setPackageScreenCompatMode"); 3239 synchronized (this) { 3240 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3241 } 3242 } 3243 3244 @Override 3245 public boolean getPackageAskScreenCompat(String packageName) { 3246 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3247 synchronized (this) { 3248 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3249 } 3250 } 3251 3252 @Override 3253 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3254 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3255 "setPackageAskScreenCompat"); 3256 synchronized (this) { 3257 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3258 } 3259 } 3260 3261 private void dispatchProcessesChanged() { 3262 int N; 3263 synchronized (this) { 3264 N = mPendingProcessChanges.size(); 3265 if (mActiveProcessChanges.length < N) { 3266 mActiveProcessChanges = new ProcessChangeItem[N]; 3267 } 3268 mPendingProcessChanges.toArray(mActiveProcessChanges); 3269 mAvailProcessChanges.addAll(mPendingProcessChanges); 3270 mPendingProcessChanges.clear(); 3271 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3272 } 3273 3274 int i = mProcessObservers.beginBroadcast(); 3275 while (i > 0) { 3276 i--; 3277 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3278 if (observer != null) { 3279 try { 3280 for (int j=0; j<N; j++) { 3281 ProcessChangeItem item = mActiveProcessChanges[j]; 3282 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3283 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3284 + item.pid + " uid=" + item.uid + ": " 3285 + item.foregroundActivities); 3286 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3287 item.foregroundActivities); 3288 } 3289 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3290 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3291 + item.pid + " uid=" + item.uid + ": " + item.processState); 3292 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3293 } 3294 } 3295 } catch (RemoteException e) { 3296 } 3297 } 3298 } 3299 mProcessObservers.finishBroadcast(); 3300 } 3301 3302 private void dispatchProcessDied(int pid, int uid) { 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 observer.onProcessDied(pid, uid); 3310 } catch (RemoteException e) { 3311 } 3312 } 3313 } 3314 mProcessObservers.finishBroadcast(); 3315 } 3316 3317 @Override 3318 public final int startActivity(IApplicationThread caller, String callingPackage, 3319 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3320 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3321 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3322 resultWho, requestCode, startFlags, profilerInfo, options, 3323 UserHandle.getCallingUserId()); 3324 } 3325 3326 @Override 3327 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3328 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3329 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3330 enforceNotIsolatedCaller("startActivity"); 3331 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3332 false, ALLOW_FULL_ONLY, "startActivity", null); 3333 // TODO: Switch to user app stacks here. 3334 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3335 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3336 profilerInfo, null, null, options, userId, null, null); 3337 } 3338 3339 @Override 3340 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3341 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3342 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3343 3344 // This is very dangerous -- it allows you to perform a start activity (including 3345 // permission grants) as any app that may launch one of your own activities. So 3346 // we will only allow this to be done from activities that are part of the core framework, 3347 // and then only when they are running as the system. 3348 final ActivityRecord sourceRecord; 3349 final int targetUid; 3350 final String targetPackage; 3351 synchronized (this) { 3352 if (resultTo == null) { 3353 throw new SecurityException("Must be called from an activity"); 3354 } 3355 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3356 if (sourceRecord == null) { 3357 throw new SecurityException("Called with bad activity token: " + resultTo); 3358 } 3359 if (!sourceRecord.info.packageName.equals("android")) { 3360 throw new SecurityException( 3361 "Must be called from an activity that is declared in the android package"); 3362 } 3363 if (sourceRecord.app == null) { 3364 throw new SecurityException("Called without a process attached to activity"); 3365 } 3366 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3367 // This is still okay, as long as this activity is running under the 3368 // uid of the original calling activity. 3369 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3370 throw new SecurityException( 3371 "Calling activity in uid " + sourceRecord.app.uid 3372 + " must be system uid or original calling uid " 3373 + sourceRecord.launchedFromUid); 3374 } 3375 } 3376 targetUid = sourceRecord.launchedFromUid; 3377 targetPackage = sourceRecord.launchedFromPackage; 3378 } 3379 3380 if (userId == UserHandle.USER_NULL) { 3381 userId = UserHandle.getUserId(sourceRecord.app.uid); 3382 } 3383 3384 // TODO: Switch to user app stacks here. 3385 try { 3386 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3387 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3388 null, null, options, userId, null, null); 3389 return ret; 3390 } catch (SecurityException e) { 3391 // XXX need to figure out how to propagate to original app. 3392 // A SecurityException here is generally actually a fault of the original 3393 // calling activity (such as a fairly granting permissions), so propagate it 3394 // back to them. 3395 /* 3396 StringBuilder msg = new StringBuilder(); 3397 msg.append("While launching"); 3398 msg.append(intent.toString()); 3399 msg.append(": "); 3400 msg.append(e.getMessage()); 3401 */ 3402 throw e; 3403 } 3404 } 3405 3406 @Override 3407 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3408 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3409 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3410 enforceNotIsolatedCaller("startActivityAndWait"); 3411 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3412 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3413 WaitResult res = new WaitResult(); 3414 // TODO: Switch to user app stacks here. 3415 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3416 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3417 options, userId, null, null); 3418 return res; 3419 } 3420 3421 @Override 3422 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3423 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3424 int startFlags, Configuration config, Bundle options, int userId) { 3425 enforceNotIsolatedCaller("startActivityWithConfig"); 3426 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3427 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3428 // TODO: Switch to user app stacks here. 3429 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3430 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3431 null, null, config, options, userId, null, null); 3432 return ret; 3433 } 3434 3435 @Override 3436 public int startActivityIntentSender(IApplicationThread caller, 3437 IntentSender intent, Intent fillInIntent, String resolvedType, 3438 IBinder resultTo, String resultWho, int requestCode, 3439 int flagsMask, int flagsValues, Bundle options) { 3440 enforceNotIsolatedCaller("startActivityIntentSender"); 3441 // Refuse possible leaked file descriptors 3442 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3443 throw new IllegalArgumentException("File descriptors passed in Intent"); 3444 } 3445 3446 IIntentSender sender = intent.getTarget(); 3447 if (!(sender instanceof PendingIntentRecord)) { 3448 throw new IllegalArgumentException("Bad PendingIntent object"); 3449 } 3450 3451 PendingIntentRecord pir = (PendingIntentRecord)sender; 3452 3453 synchronized (this) { 3454 // If this is coming from the currently resumed activity, it is 3455 // effectively saying that app switches are allowed at this point. 3456 final ActivityStack stack = getFocusedStack(); 3457 if (stack.mResumedActivity != null && 3458 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3459 mAppSwitchesAllowedTime = 0; 3460 } 3461 } 3462 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3463 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3464 return ret; 3465 } 3466 3467 @Override 3468 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3469 Intent intent, String resolvedType, IVoiceInteractionSession session, 3470 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3471 Bundle options, int userId) { 3472 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3473 != PackageManager.PERMISSION_GRANTED) { 3474 String msg = "Permission Denial: startVoiceActivity() from pid=" 3475 + Binder.getCallingPid() 3476 + ", uid=" + Binder.getCallingUid() 3477 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3478 Slog.w(TAG, msg); 3479 throw new SecurityException(msg); 3480 } 3481 if (session == null || interactor == null) { 3482 throw new NullPointerException("null session or interactor"); 3483 } 3484 userId = handleIncomingUser(callingPid, callingUid, userId, 3485 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3486 // TODO: Switch to user app stacks here. 3487 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3488 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3489 null, options, userId, null, null); 3490 } 3491 3492 @Override 3493 public boolean startNextMatchingActivity(IBinder callingActivity, 3494 Intent intent, Bundle options) { 3495 // Refuse possible leaked file descriptors 3496 if (intent != null && intent.hasFileDescriptors() == true) { 3497 throw new IllegalArgumentException("File descriptors passed in Intent"); 3498 } 3499 3500 synchronized (this) { 3501 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3502 if (r == null) { 3503 ActivityOptions.abort(options); 3504 return false; 3505 } 3506 if (r.app == null || r.app.thread == null) { 3507 // The caller is not running... d'oh! 3508 ActivityOptions.abort(options); 3509 return false; 3510 } 3511 intent = new Intent(intent); 3512 // The caller is not allowed to change the data. 3513 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3514 // And we are resetting to find the next component... 3515 intent.setComponent(null); 3516 3517 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3518 3519 ActivityInfo aInfo = null; 3520 try { 3521 List<ResolveInfo> resolves = 3522 AppGlobals.getPackageManager().queryIntentActivities( 3523 intent, r.resolvedType, 3524 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3525 UserHandle.getCallingUserId()); 3526 3527 // Look for the original activity in the list... 3528 final int N = resolves != null ? resolves.size() : 0; 3529 for (int i=0; i<N; i++) { 3530 ResolveInfo rInfo = resolves.get(i); 3531 if (rInfo.activityInfo.packageName.equals(r.packageName) 3532 && rInfo.activityInfo.name.equals(r.info.name)) { 3533 // We found the current one... the next matching is 3534 // after it. 3535 i++; 3536 if (i<N) { 3537 aInfo = resolves.get(i).activityInfo; 3538 } 3539 if (debug) { 3540 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3541 + "/" + r.info.name); 3542 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3543 + "/" + aInfo.name); 3544 } 3545 break; 3546 } 3547 } 3548 } catch (RemoteException e) { 3549 } 3550 3551 if (aInfo == null) { 3552 // Nobody who is next! 3553 ActivityOptions.abort(options); 3554 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3555 return false; 3556 } 3557 3558 intent.setComponent(new ComponentName( 3559 aInfo.applicationInfo.packageName, aInfo.name)); 3560 intent.setFlags(intent.getFlags()&~( 3561 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3562 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3563 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3564 Intent.FLAG_ACTIVITY_NEW_TASK)); 3565 3566 // Okay now we need to start the new activity, replacing the 3567 // currently running activity. This is a little tricky because 3568 // we want to start the new one as if the current one is finished, 3569 // but not finish the current one first so that there is no flicker. 3570 // And thus... 3571 final boolean wasFinishing = r.finishing; 3572 r.finishing = true; 3573 3574 // Propagate reply information over to the new activity. 3575 final ActivityRecord resultTo = r.resultTo; 3576 final String resultWho = r.resultWho; 3577 final int requestCode = r.requestCode; 3578 r.resultTo = null; 3579 if (resultTo != null) { 3580 resultTo.removeResultsLocked(r, resultWho, requestCode); 3581 } 3582 3583 final long origId = Binder.clearCallingIdentity(); 3584 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3585 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3586 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3587 -1, r.launchedFromUid, 0, options, false, null, null, null); 3588 Binder.restoreCallingIdentity(origId); 3589 3590 r.finishing = wasFinishing; 3591 if (res != ActivityManager.START_SUCCESS) { 3592 return false; 3593 } 3594 return true; 3595 } 3596 } 3597 3598 @Override 3599 public final int startActivityFromRecents(int taskId, Bundle options) { 3600 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3601 String msg = "Permission Denial: startActivityFromRecents called without " + 3602 START_TASKS_FROM_RECENTS; 3603 Slog.w(TAG, msg); 3604 throw new SecurityException(msg); 3605 } 3606 return startActivityFromRecentsInner(taskId, options); 3607 } 3608 3609 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3610 final TaskRecord task; 3611 final int callingUid; 3612 final String callingPackage; 3613 final Intent intent; 3614 final int userId; 3615 synchronized (this) { 3616 task = recentTaskForIdLocked(taskId); 3617 if (task == null) { 3618 throw new IllegalArgumentException("Task " + taskId + " not found."); 3619 } 3620 callingUid = task.mCallingUid; 3621 callingPackage = task.mCallingPackage; 3622 intent = task.intent; 3623 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3624 userId = task.userId; 3625 } 3626 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3627 options, userId, null, task); 3628 } 3629 3630 final int startActivityInPackage(int uid, String callingPackage, 3631 Intent intent, String resolvedType, IBinder resultTo, 3632 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3633 IActivityContainer container, TaskRecord inTask) { 3634 3635 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3636 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3637 3638 // TODO: Switch to user app stacks here. 3639 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3640 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3641 null, null, null, options, userId, container, inTask); 3642 return ret; 3643 } 3644 3645 @Override 3646 public final int startActivities(IApplicationThread caller, String callingPackage, 3647 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3648 int userId) { 3649 enforceNotIsolatedCaller("startActivities"); 3650 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3651 false, ALLOW_FULL_ONLY, "startActivity", null); 3652 // TODO: Switch to user app stacks here. 3653 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3654 resolvedTypes, resultTo, options, userId); 3655 return ret; 3656 } 3657 3658 final int startActivitiesInPackage(int uid, String callingPackage, 3659 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3660 Bundle options, int userId) { 3661 3662 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3663 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3664 // TODO: Switch to user app stacks here. 3665 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3666 resultTo, options, userId); 3667 return ret; 3668 } 3669 3670 //explicitly remove thd old information in mRecentTasks when removing existing user. 3671 private void removeRecentTasksForUserLocked(int userId) { 3672 if(userId <= 0) { 3673 Slog.i(TAG, "Can't remove recent task on user " + userId); 3674 return; 3675 } 3676 3677 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3678 TaskRecord tr = mRecentTasks.get(i); 3679 if (tr.userId == userId) { 3680 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3681 + " when finishing user" + userId); 3682 mRecentTasks.remove(i); 3683 tr.removedFromRecents(); 3684 } 3685 } 3686 3687 // Remove tasks from persistent storage. 3688 notifyTaskPersisterLocked(null, true); 3689 } 3690 3691 // Sort by taskId 3692 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3693 @Override 3694 public int compare(TaskRecord lhs, TaskRecord rhs) { 3695 return rhs.taskId - lhs.taskId; 3696 } 3697 }; 3698 3699 // Extract the affiliates of the chain containing mRecentTasks[start]. 3700 private int processNextAffiliateChainLocked(int start) { 3701 final TaskRecord startTask = mRecentTasks.get(start); 3702 final int affiliateId = startTask.mAffiliatedTaskId; 3703 3704 // Quick identification of isolated tasks. I.e. those not launched behind. 3705 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3706 startTask.mNextAffiliate == null) { 3707 // There is still a slim chance that there are other tasks that point to this task 3708 // and that the chain is so messed up that this task no longer points to them but 3709 // the gain of this optimization outweighs the risk. 3710 startTask.inRecents = true; 3711 return start + 1; 3712 } 3713 3714 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3715 mTmpRecents.clear(); 3716 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3717 final TaskRecord task = mRecentTasks.get(i); 3718 if (task.mAffiliatedTaskId == affiliateId) { 3719 mRecentTasks.remove(i); 3720 mTmpRecents.add(task); 3721 } 3722 } 3723 3724 // Sort them all by taskId. That is the order they were create in and that order will 3725 // always be correct. 3726 Collections.sort(mTmpRecents, mTaskRecordComparator); 3727 3728 // Go through and fix up the linked list. 3729 // The first one is the end of the chain and has no next. 3730 final TaskRecord first = mTmpRecents.get(0); 3731 first.inRecents = true; 3732 if (first.mNextAffiliate != null) { 3733 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3734 first.setNextAffiliate(null); 3735 notifyTaskPersisterLocked(first, false); 3736 } 3737 // Everything in the middle is doubly linked from next to prev. 3738 final int tmpSize = mTmpRecents.size(); 3739 for (int i = 0; i < tmpSize - 1; ++i) { 3740 final TaskRecord next = mTmpRecents.get(i); 3741 final TaskRecord prev = mTmpRecents.get(i + 1); 3742 if (next.mPrevAffiliate != prev) { 3743 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3744 " setting prev=" + prev); 3745 next.setPrevAffiliate(prev); 3746 notifyTaskPersisterLocked(next, false); 3747 } 3748 if (prev.mNextAffiliate != next) { 3749 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3750 " setting next=" + next); 3751 prev.setNextAffiliate(next); 3752 notifyTaskPersisterLocked(prev, false); 3753 } 3754 prev.inRecents = true; 3755 } 3756 // The last one is the beginning of the list and has no prev. 3757 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3758 if (last.mPrevAffiliate != null) { 3759 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3760 last.setPrevAffiliate(null); 3761 notifyTaskPersisterLocked(last, false); 3762 } 3763 3764 // Insert the group back into mRecentTasks at start. 3765 mRecentTasks.addAll(start, mTmpRecents); 3766 3767 // Let the caller know where we left off. 3768 return start + tmpSize; 3769 } 3770 3771 /** 3772 * Update the recent tasks lists: make sure tasks should still be here (their 3773 * applications / activities still exist), update their availability, fixup ordering 3774 * of affiliations. 3775 */ 3776 void cleanupRecentTasksLocked(int userId) { 3777 if (mRecentTasks == null) { 3778 // Happens when called from the packagemanager broadcast before boot. 3779 return; 3780 } 3781 3782 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3783 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3784 final IPackageManager pm = AppGlobals.getPackageManager(); 3785 final ActivityInfo dummyAct = new ActivityInfo(); 3786 final ApplicationInfo dummyApp = new ApplicationInfo(); 3787 3788 int N = mRecentTasks.size(); 3789 3790 int[] users = userId == UserHandle.USER_ALL 3791 ? getUsersLocked() : new int[] { userId }; 3792 for (int user : users) { 3793 for (int i = 0; i < N; i++) { 3794 TaskRecord task = mRecentTasks.get(i); 3795 if (task.userId != user) { 3796 // Only look at tasks for the user ID of interest. 3797 continue; 3798 } 3799 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3800 // This situation is broken, and we should just get rid of it now. 3801 mRecentTasks.remove(i); 3802 task.removedFromRecents(); 3803 i--; 3804 N--; 3805 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3806 continue; 3807 } 3808 // Check whether this activity is currently available. 3809 if (task.realActivity != null) { 3810 ActivityInfo ai = availActCache.get(task.realActivity); 3811 if (ai == null) { 3812 try { 3813 ai = pm.getActivityInfo(task.realActivity, 3814 PackageManager.GET_UNINSTALLED_PACKAGES 3815 | PackageManager.GET_DISABLED_COMPONENTS, user); 3816 } catch (RemoteException e) { 3817 // Will never happen. 3818 continue; 3819 } 3820 if (ai == null) { 3821 ai = dummyAct; 3822 } 3823 availActCache.put(task.realActivity, ai); 3824 } 3825 if (ai == dummyAct) { 3826 // This could be either because the activity no longer exists, or the 3827 // app is temporarily gone. For the former we want to remove the recents 3828 // entry; for the latter we want to mark it as unavailable. 3829 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3830 if (app == null) { 3831 try { 3832 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3833 PackageManager.GET_UNINSTALLED_PACKAGES 3834 | PackageManager.GET_DISABLED_COMPONENTS, user); 3835 } catch (RemoteException e) { 3836 // Will never happen. 3837 continue; 3838 } 3839 if (app == null) { 3840 app = dummyApp; 3841 } 3842 availAppCache.put(task.realActivity.getPackageName(), app); 3843 } 3844 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3845 // Doesn't exist any more! Good-bye. 3846 mRecentTasks.remove(i); 3847 task.removedFromRecents(); 3848 i--; 3849 N--; 3850 Slog.w(TAG, "Removing no longer valid recent: " + task); 3851 continue; 3852 } else { 3853 // Otherwise just not available for now. 3854 if (task.isAvailable) { 3855 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3856 + task); 3857 } 3858 task.isAvailable = false; 3859 } 3860 } else { 3861 if (!ai.enabled || !ai.applicationInfo.enabled 3862 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3863 if (task.isAvailable) { 3864 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3865 + task + " (enabled=" + ai.enabled + "/" 3866 + ai.applicationInfo.enabled + " flags=" 3867 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3868 } 3869 task.isAvailable = false; 3870 } else { 3871 if (!task.isAvailable) { 3872 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3873 + task); 3874 } 3875 task.isAvailable = true; 3876 } 3877 } 3878 } 3879 } 3880 } 3881 3882 // Verify the affiliate chain for each task. 3883 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3884 } 3885 3886 mTmpRecents.clear(); 3887 // mRecentTasks is now in sorted, affiliated order. 3888 } 3889 3890 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3891 int N = mRecentTasks.size(); 3892 TaskRecord top = task; 3893 int topIndex = taskIndex; 3894 while (top.mNextAffiliate != null && topIndex > 0) { 3895 top = top.mNextAffiliate; 3896 topIndex--; 3897 } 3898 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3899 + topIndex + " from intial " + taskIndex); 3900 // Find the end of the chain, doing a sanity check along the way. 3901 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3902 int endIndex = topIndex; 3903 TaskRecord prev = top; 3904 while (endIndex < N) { 3905 TaskRecord cur = mRecentTasks.get(endIndex); 3906 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3907 + endIndex + " " + cur); 3908 if (cur == top) { 3909 // Verify start of the chain. 3910 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3911 Slog.wtf(TAG, "Bad chain @" + endIndex 3912 + ": first task has next affiliate: " + prev); 3913 sane = false; 3914 break; 3915 } 3916 } else { 3917 // Verify middle of the chain's next points back to the one before. 3918 if (cur.mNextAffiliate != prev 3919 || cur.mNextAffiliateTaskId != prev.taskId) { 3920 Slog.wtf(TAG, "Bad chain @" + endIndex 3921 + ": middle task " + cur + " @" + endIndex 3922 + " has bad next affiliate " 3923 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3924 + ", expected " + prev); 3925 sane = false; 3926 break; 3927 } 3928 } 3929 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3930 // Chain ends here. 3931 if (cur.mPrevAffiliate != null) { 3932 Slog.wtf(TAG, "Bad chain @" + endIndex 3933 + ": last task " + cur + " has previous affiliate " 3934 + cur.mPrevAffiliate); 3935 sane = false; 3936 } 3937 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3938 break; 3939 } else { 3940 // Verify middle of the chain's prev points to a valid item. 3941 if (cur.mPrevAffiliate == null) { 3942 Slog.wtf(TAG, "Bad chain @" + endIndex 3943 + ": task " + cur + " has previous affiliate " 3944 + cur.mPrevAffiliate + " but should be id " 3945 + cur.mPrevAffiliate); 3946 sane = false; 3947 break; 3948 } 3949 } 3950 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3951 Slog.wtf(TAG, "Bad chain @" + endIndex 3952 + ": task " + cur + " has affiliated id " 3953 + cur.mAffiliatedTaskId + " but should be " 3954 + task.mAffiliatedTaskId); 3955 sane = false; 3956 break; 3957 } 3958 prev = cur; 3959 endIndex++; 3960 if (endIndex >= N) { 3961 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3962 + ": last task " + prev); 3963 sane = false; 3964 break; 3965 } 3966 } 3967 if (sane) { 3968 if (endIndex < taskIndex) { 3969 Slog.wtf(TAG, "Bad chain @" + endIndex 3970 + ": did not extend to task " + task + " @" + taskIndex); 3971 sane = false; 3972 } 3973 } 3974 if (sane) { 3975 // All looks good, we can just move all of the affiliated tasks 3976 // to the top. 3977 for (int i=topIndex; i<=endIndex; i++) { 3978 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3979 + " from " + i + " to " + (i-topIndex)); 3980 TaskRecord cur = mRecentTasks.remove(i); 3981 mRecentTasks.add(i-topIndex, cur); 3982 } 3983 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3984 + " to " + endIndex); 3985 return true; 3986 } 3987 3988 // Whoops, couldn't do it. 3989 return false; 3990 } 3991 3992 final void addRecentTaskLocked(TaskRecord task) { 3993 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3994 || task.mNextAffiliateTaskId != INVALID_TASK_ID 3995 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 3996 3997 int N = mRecentTasks.size(); 3998 // Quick case: check if the top-most recent task is the same. 3999 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4000 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4001 return; 4002 } 4003 // Another quick case: check if this is part of a set of affiliated 4004 // tasks that are at the top. 4005 if (isAffiliated && N > 0 && task.inRecents 4006 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4007 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4008 + " at top when adding " + task); 4009 return; 4010 } 4011 // Another quick case: never add voice sessions. 4012 if (task.voiceSession != null) { 4013 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4014 return; 4015 } 4016 4017 boolean needAffiliationFix = false; 4018 4019 // Slightly less quick case: the task is already in recents, so all we need 4020 // to do is move it. 4021 if (task.inRecents) { 4022 int taskIndex = mRecentTasks.indexOf(task); 4023 if (taskIndex >= 0) { 4024 if (!isAffiliated) { 4025 // Simple case: this is not an affiliated task, so we just move it to the front. 4026 mRecentTasks.remove(taskIndex); 4027 mRecentTasks.add(0, task); 4028 notifyTaskPersisterLocked(task, false); 4029 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4030 + " from " + taskIndex); 4031 return; 4032 } else { 4033 // More complicated: need to keep all affiliated tasks together. 4034 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4035 // All went well. 4036 return; 4037 } 4038 4039 // Uh oh... something bad in the affiliation chain, try to rebuild 4040 // everything and then go through our general path of adding a new task. 4041 needAffiliationFix = true; 4042 } 4043 } else { 4044 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4045 needAffiliationFix = true; 4046 } 4047 } 4048 4049 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4050 trimRecentsForTaskLocked(task, true); 4051 4052 N = mRecentTasks.size(); 4053 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4054 final TaskRecord tr = mRecentTasks.remove(N - 1); 4055 tr.removedFromRecents(); 4056 N--; 4057 } 4058 task.inRecents = true; 4059 if (!isAffiliated || needAffiliationFix) { 4060 // If this is a simple non-affiliated task, or we had some failure trying to 4061 // handle it as part of an affilated task, then just place it at the top. 4062 mRecentTasks.add(0, task); 4063 } else if (isAffiliated) { 4064 // If this is a new affiliated task, then move all of the affiliated tasks 4065 // to the front and insert this new one. 4066 TaskRecord other = task.mNextAffiliate; 4067 if (other == null) { 4068 other = task.mPrevAffiliate; 4069 } 4070 if (other != null) { 4071 int otherIndex = mRecentTasks.indexOf(other); 4072 if (otherIndex >= 0) { 4073 // Insert new task at appropriate location. 4074 int taskIndex; 4075 if (other == task.mNextAffiliate) { 4076 // We found the index of our next affiliation, which is who is 4077 // before us in the list, so add after that point. 4078 taskIndex = otherIndex+1; 4079 } else { 4080 // We found the index of our previous affiliation, which is who is 4081 // after us in the list, so add at their position. 4082 taskIndex = otherIndex; 4083 } 4084 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4085 + taskIndex + ": " + task); 4086 mRecentTasks.add(taskIndex, task); 4087 4088 // Now move everything to the front. 4089 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4090 // All went well. 4091 return; 4092 } 4093 4094 // Uh oh... something bad in the affiliation chain, try to rebuild 4095 // everything and then go through our general path of adding a new task. 4096 needAffiliationFix = true; 4097 } else { 4098 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4099 + other); 4100 needAffiliationFix = true; 4101 } 4102 } else { 4103 if (DEBUG_RECENTS) Slog.d(TAG, 4104 "addRecent: adding affiliated task without next/prev:" + task); 4105 needAffiliationFix = true; 4106 } 4107 } 4108 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4109 4110 if (needAffiliationFix) { 4111 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4112 cleanupRecentTasksLocked(task.userId); 4113 } 4114 } 4115 4116 /** 4117 * If needed, remove oldest existing entries in recents that are for the same kind 4118 * of task as the given one. 4119 */ 4120 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4121 int N = mRecentTasks.size(); 4122 final Intent intent = task.intent; 4123 final boolean document = intent != null && intent.isDocument(); 4124 4125 int maxRecents = task.maxRecents - 1; 4126 for (int i=0; i<N; i++) { 4127 final TaskRecord tr = mRecentTasks.get(i); 4128 if (task != tr) { 4129 if (task.userId != tr.userId) { 4130 continue; 4131 } 4132 if (i > MAX_RECENT_BITMAPS) { 4133 tr.freeLastThumbnail(); 4134 } 4135 final Intent trIntent = tr.intent; 4136 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4137 (intent == null || !intent.filterEquals(trIntent))) { 4138 continue; 4139 } 4140 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4141 if (document && trIsDocument) { 4142 // These are the same document activity (not necessarily the same doc). 4143 if (maxRecents > 0) { 4144 --maxRecents; 4145 continue; 4146 } 4147 // Hit the maximum number of documents for this task. Fall through 4148 // and remove this document from recents. 4149 } else if (document || trIsDocument) { 4150 // Only one of these is a document. Not the droid we're looking for. 4151 continue; 4152 } 4153 } 4154 4155 if (!doTrim) { 4156 // If the caller is not actually asking for a trim, just tell them we reached 4157 // a point where the trim would happen. 4158 return i; 4159 } 4160 4161 // Either task and tr are the same or, their affinities match or their intents match 4162 // and neither of them is a document, or they are documents using the same activity 4163 // and their maxRecents has been reached. 4164 tr.disposeThumbnail(); 4165 mRecentTasks.remove(i); 4166 if (task != tr) { 4167 tr.removedFromRecents(); 4168 } 4169 i--; 4170 N--; 4171 if (task.intent == null) { 4172 // If the new recent task we are adding is not fully 4173 // specified, then replace it with the existing recent task. 4174 task = tr; 4175 } 4176 notifyTaskPersisterLocked(tr, false); 4177 } 4178 4179 return -1; 4180 } 4181 4182 @Override 4183 public void reportActivityFullyDrawn(IBinder token) { 4184 synchronized (this) { 4185 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4186 if (r == null) { 4187 return; 4188 } 4189 r.reportFullyDrawnLocked(); 4190 } 4191 } 4192 4193 @Override 4194 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4195 synchronized (this) { 4196 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4197 if (r == null) { 4198 return; 4199 } 4200 final long origId = Binder.clearCallingIdentity(); 4201 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4202 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4203 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4204 if (config != null) { 4205 r.frozenBeforeDestroy = true; 4206 if (!updateConfigurationLocked(config, r, false, false)) { 4207 mStackSupervisor.resumeTopActivitiesLocked(); 4208 } 4209 } 4210 Binder.restoreCallingIdentity(origId); 4211 } 4212 } 4213 4214 @Override 4215 public int getRequestedOrientation(IBinder token) { 4216 synchronized (this) { 4217 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4218 if (r == null) { 4219 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4220 } 4221 return mWindowManager.getAppOrientation(r.appToken); 4222 } 4223 } 4224 4225 /** 4226 * This is the internal entry point for handling Activity.finish(). 4227 * 4228 * @param token The Binder token referencing the Activity we want to finish. 4229 * @param resultCode Result code, if any, from this Activity. 4230 * @param resultData Result data (Intent), if any, from this Activity. 4231 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4232 * the root Activity in the task. 4233 * 4234 * @return Returns true if the activity successfully finished, or false if it is still running. 4235 */ 4236 @Override 4237 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4238 boolean finishTask) { 4239 // Refuse possible leaked file descriptors 4240 if (resultData != null && resultData.hasFileDescriptors() == true) { 4241 throw new IllegalArgumentException("File descriptors passed in Intent"); 4242 } 4243 4244 synchronized(this) { 4245 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4246 if (r == null) { 4247 return true; 4248 } 4249 // Keep track of the root activity of the task before we finish it 4250 TaskRecord tr = r.task; 4251 ActivityRecord rootR = tr.getRootActivity(); 4252 if (rootR == null) { 4253 Slog.w(TAG, "Finishing task with all activities already finished"); 4254 } 4255 // Do not allow task to finish in Lock Task mode. 4256 if (tr == mStackSupervisor.mLockTaskModeTask) { 4257 if (rootR == r) { 4258 Slog.i(TAG, "Not finishing task in lock task mode"); 4259 mStackSupervisor.showLockTaskToast(); 4260 return false; 4261 } 4262 } 4263 if (mController != null) { 4264 // Find the first activity that is not finishing. 4265 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4266 if (next != null) { 4267 // ask watcher if this is allowed 4268 boolean resumeOK = true; 4269 try { 4270 resumeOK = mController.activityResuming(next.packageName); 4271 } catch (RemoteException e) { 4272 mController = null; 4273 Watchdog.getInstance().setActivityController(null); 4274 } 4275 4276 if (!resumeOK) { 4277 Slog.i(TAG, "Not finishing activity because controller resumed"); 4278 return false; 4279 } 4280 } 4281 } 4282 final long origId = Binder.clearCallingIdentity(); 4283 try { 4284 boolean res; 4285 if (finishTask && r == rootR) { 4286 // If requested, remove the task that is associated to this activity only if it 4287 // was the root activity in the task. The result code and data is ignored 4288 // because we don't support returning them across task boundaries. 4289 res = removeTaskByIdLocked(tr.taskId, false); 4290 if (!res) { 4291 Slog.i(TAG, "Removing task failed to finish activity"); 4292 } 4293 } else { 4294 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4295 resultData, "app-request", true); 4296 if (!res) { 4297 Slog.i(TAG, "Failed to finish by app-request"); 4298 } 4299 } 4300 return res; 4301 } finally { 4302 Binder.restoreCallingIdentity(origId); 4303 } 4304 } 4305 } 4306 4307 @Override 4308 public final void finishHeavyWeightApp() { 4309 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4310 != PackageManager.PERMISSION_GRANTED) { 4311 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4312 + Binder.getCallingPid() 4313 + ", uid=" + Binder.getCallingUid() 4314 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4315 Slog.w(TAG, msg); 4316 throw new SecurityException(msg); 4317 } 4318 4319 synchronized(this) { 4320 if (mHeavyWeightProcess == null) { 4321 return; 4322 } 4323 4324 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4325 mHeavyWeightProcess.activities); 4326 for (int i=0; i<activities.size(); i++) { 4327 ActivityRecord r = activities.get(i); 4328 if (!r.finishing) { 4329 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4330 null, "finish-heavy", true); 4331 } 4332 } 4333 4334 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4335 mHeavyWeightProcess.userId, 0)); 4336 mHeavyWeightProcess = null; 4337 } 4338 } 4339 4340 @Override 4341 public void crashApplication(int uid, int initialPid, String packageName, 4342 String message) { 4343 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4344 != PackageManager.PERMISSION_GRANTED) { 4345 String msg = "Permission Denial: crashApplication() from pid=" 4346 + Binder.getCallingPid() 4347 + ", uid=" + Binder.getCallingUid() 4348 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4349 Slog.w(TAG, msg); 4350 throw new SecurityException(msg); 4351 } 4352 4353 synchronized(this) { 4354 ProcessRecord proc = null; 4355 4356 // Figure out which process to kill. We don't trust that initialPid 4357 // still has any relation to current pids, so must scan through the 4358 // list. 4359 synchronized (mPidsSelfLocked) { 4360 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4361 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4362 if (p.uid != uid) { 4363 continue; 4364 } 4365 if (p.pid == initialPid) { 4366 proc = p; 4367 break; 4368 } 4369 if (p.pkgList.containsKey(packageName)) { 4370 proc = p; 4371 } 4372 } 4373 } 4374 4375 if (proc == null) { 4376 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4377 + " initialPid=" + initialPid 4378 + " packageName=" + packageName); 4379 return; 4380 } 4381 4382 if (proc.thread != null) { 4383 if (proc.pid == Process.myPid()) { 4384 Log.w(TAG, "crashApplication: trying to crash self!"); 4385 return; 4386 } 4387 long ident = Binder.clearCallingIdentity(); 4388 try { 4389 proc.thread.scheduleCrash(message); 4390 } catch (RemoteException e) { 4391 } 4392 Binder.restoreCallingIdentity(ident); 4393 } 4394 } 4395 } 4396 4397 @Override 4398 public final void finishSubActivity(IBinder token, String resultWho, 4399 int requestCode) { 4400 synchronized(this) { 4401 final long origId = Binder.clearCallingIdentity(); 4402 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4403 if (r != null) { 4404 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4405 } 4406 Binder.restoreCallingIdentity(origId); 4407 } 4408 } 4409 4410 @Override 4411 public boolean finishActivityAffinity(IBinder token) { 4412 synchronized(this) { 4413 final long origId = Binder.clearCallingIdentity(); 4414 try { 4415 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4416 4417 ActivityRecord rootR = r.task.getRootActivity(); 4418 // Do not allow task to finish in Lock Task mode. 4419 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4420 if (rootR == r) { 4421 mStackSupervisor.showLockTaskToast(); 4422 return false; 4423 } 4424 } 4425 boolean res = false; 4426 if (r != null) { 4427 res = r.task.stack.finishActivityAffinityLocked(r); 4428 } 4429 return res; 4430 } finally { 4431 Binder.restoreCallingIdentity(origId); 4432 } 4433 } 4434 } 4435 4436 @Override 4437 public void finishVoiceTask(IVoiceInteractionSession session) { 4438 synchronized(this) { 4439 final long origId = Binder.clearCallingIdentity(); 4440 try { 4441 mStackSupervisor.finishVoiceTask(session); 4442 } finally { 4443 Binder.restoreCallingIdentity(origId); 4444 } 4445 } 4446 4447 } 4448 4449 @Override 4450 public boolean releaseActivityInstance(IBinder token) { 4451 synchronized(this) { 4452 final long origId = Binder.clearCallingIdentity(); 4453 try { 4454 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4455 if (r.task == null || r.task.stack == null) { 4456 return false; 4457 } 4458 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4459 } finally { 4460 Binder.restoreCallingIdentity(origId); 4461 } 4462 } 4463 } 4464 4465 @Override 4466 public void releaseSomeActivities(IApplicationThread appInt) { 4467 synchronized(this) { 4468 final long origId = Binder.clearCallingIdentity(); 4469 try { 4470 ProcessRecord app = getRecordForAppLocked(appInt); 4471 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4472 } finally { 4473 Binder.restoreCallingIdentity(origId); 4474 } 4475 } 4476 } 4477 4478 @Override 4479 public boolean willActivityBeVisible(IBinder token) { 4480 synchronized(this) { 4481 ActivityStack stack = ActivityRecord.getStackLocked(token); 4482 if (stack != null) { 4483 return stack.willActivityBeVisibleLocked(token); 4484 } 4485 return false; 4486 } 4487 } 4488 4489 @Override 4490 public void overridePendingTransition(IBinder token, String packageName, 4491 int enterAnim, int exitAnim) { 4492 synchronized(this) { 4493 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4494 if (self == null) { 4495 return; 4496 } 4497 4498 final long origId = Binder.clearCallingIdentity(); 4499 4500 if (self.state == ActivityState.RESUMED 4501 || self.state == ActivityState.PAUSING) { 4502 mWindowManager.overridePendingAppTransition(packageName, 4503 enterAnim, exitAnim, null); 4504 } 4505 4506 Binder.restoreCallingIdentity(origId); 4507 } 4508 } 4509 4510 /** 4511 * Main function for removing an existing process from the activity manager 4512 * as a result of that process going away. Clears out all connections 4513 * to the process. 4514 */ 4515 private final void handleAppDiedLocked(ProcessRecord app, 4516 boolean restarting, boolean allowRestart) { 4517 int pid = app.pid; 4518 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4519 if (!kept && !restarting) { 4520 removeLruProcessLocked(app); 4521 if (pid > 0) { 4522 ProcessList.remove(pid); 4523 } 4524 } 4525 4526 if (mProfileProc == app) { 4527 clearProfilerLocked(); 4528 } 4529 4530 // Remove this application's activities from active lists. 4531 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4532 4533 app.activities.clear(); 4534 4535 if (app.instrumentationClass != null) { 4536 Slog.w(TAG, "Crash of app " + app.processName 4537 + " running instrumentation " + app.instrumentationClass); 4538 Bundle info = new Bundle(); 4539 info.putString("shortMsg", "Process crashed."); 4540 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4541 } 4542 4543 if (!restarting) { 4544 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4545 // If there was nothing to resume, and we are not already 4546 // restarting this process, but there is a visible activity that 4547 // is hosted by the process... then make sure all visible 4548 // activities are running, taking care of restarting this 4549 // process. 4550 if (hasVisibleActivities) { 4551 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4552 } 4553 } 4554 } 4555 } 4556 4557 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4558 IBinder threadBinder = thread.asBinder(); 4559 // Find the application record. 4560 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4561 ProcessRecord rec = mLruProcesses.get(i); 4562 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4563 return i; 4564 } 4565 } 4566 return -1; 4567 } 4568 4569 final ProcessRecord getRecordForAppLocked( 4570 IApplicationThread thread) { 4571 if (thread == null) { 4572 return null; 4573 } 4574 4575 int appIndex = getLRURecordIndexForAppLocked(thread); 4576 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4577 } 4578 4579 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4580 // If there are no longer any background processes running, 4581 // and the app that died was not running instrumentation, 4582 // then tell everyone we are now low on memory. 4583 boolean haveBg = false; 4584 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4585 ProcessRecord rec = mLruProcesses.get(i); 4586 if (rec.thread != null 4587 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4588 haveBg = true; 4589 break; 4590 } 4591 } 4592 4593 if (!haveBg) { 4594 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4595 if (doReport) { 4596 long now = SystemClock.uptimeMillis(); 4597 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4598 doReport = false; 4599 } else { 4600 mLastMemUsageReportTime = now; 4601 } 4602 } 4603 final ArrayList<ProcessMemInfo> memInfos 4604 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4605 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4606 long now = SystemClock.uptimeMillis(); 4607 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4608 ProcessRecord rec = mLruProcesses.get(i); 4609 if (rec == dyingProc || rec.thread == null) { 4610 continue; 4611 } 4612 if (doReport) { 4613 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4614 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4615 } 4616 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4617 // The low memory report is overriding any current 4618 // state for a GC request. Make sure to do 4619 // heavy/important/visible/foreground processes first. 4620 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4621 rec.lastRequestedGc = 0; 4622 } else { 4623 rec.lastRequestedGc = rec.lastLowMemory; 4624 } 4625 rec.reportLowMemory = true; 4626 rec.lastLowMemory = now; 4627 mProcessesToGc.remove(rec); 4628 addProcessToGcListLocked(rec); 4629 } 4630 } 4631 if (doReport) { 4632 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4633 mHandler.sendMessage(msg); 4634 } 4635 scheduleAppGcsLocked(); 4636 } 4637 } 4638 4639 final void appDiedLocked(ProcessRecord app) { 4640 appDiedLocked(app, app.pid, app.thread); 4641 } 4642 4643 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4644 // First check if this ProcessRecord is actually active for the pid. 4645 synchronized (mPidsSelfLocked) { 4646 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4647 if (curProc != app) { 4648 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4649 return; 4650 } 4651 } 4652 4653 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4654 synchronized (stats) { 4655 stats.noteProcessDiedLocked(app.info.uid, pid); 4656 } 4657 4658 Process.killProcessQuiet(pid); 4659 Process.killProcessGroup(app.info.uid, pid); 4660 app.killed = true; 4661 4662 // Clean up already done if the process has been re-started. 4663 if (app.pid == pid && app.thread != null && 4664 app.thread.asBinder() == thread.asBinder()) { 4665 boolean doLowMem = app.instrumentationClass == null; 4666 boolean doOomAdj = doLowMem; 4667 if (!app.killedByAm) { 4668 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4669 + ") has died"); 4670 mAllowLowerMemLevel = true; 4671 } else { 4672 // Note that we always want to do oom adj to update our state with the 4673 // new number of procs. 4674 mAllowLowerMemLevel = false; 4675 doLowMem = false; 4676 } 4677 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4678 if (DEBUG_CLEANUP) Slog.v( 4679 TAG, "Dying app: " + app + ", pid: " + pid 4680 + ", thread: " + thread.asBinder()); 4681 handleAppDiedLocked(app, false, true); 4682 4683 if (doOomAdj) { 4684 updateOomAdjLocked(); 4685 } 4686 if (doLowMem) { 4687 doLowMemReportIfNeededLocked(app); 4688 } 4689 } else if (app.pid != pid) { 4690 // A new process has already been started. 4691 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4692 + ") has died and restarted (pid " + app.pid + ")."); 4693 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4694 } else if (DEBUG_PROCESSES) { 4695 Slog.d(TAG, "Received spurious death notification for thread " 4696 + thread.asBinder()); 4697 } 4698 } 4699 4700 /** 4701 * If a stack trace dump file is configured, dump process stack traces. 4702 * @param clearTraces causes the dump file to be erased prior to the new 4703 * traces being written, if true; when false, the new traces will be 4704 * appended to any existing file content. 4705 * @param firstPids of dalvik VM processes to dump stack traces for first 4706 * @param lastPids of dalvik VM processes to dump stack traces for last 4707 * @param nativeProcs optional list of native process names to dump stack crawls 4708 * @return file containing stack traces, or null if no dump file is configured 4709 */ 4710 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4711 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4712 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4713 if (tracesPath == null || tracesPath.length() == 0) { 4714 return null; 4715 } 4716 4717 File tracesFile = new File(tracesPath); 4718 try { 4719 File tracesDir = tracesFile.getParentFile(); 4720 if (!tracesDir.exists()) { 4721 tracesDir.mkdirs(); 4722 if (!SELinux.restorecon(tracesDir)) { 4723 return null; 4724 } 4725 } 4726 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4727 4728 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4729 tracesFile.createNewFile(); 4730 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4731 } catch (IOException e) { 4732 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4733 return null; 4734 } 4735 4736 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4737 return tracesFile; 4738 } 4739 4740 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4741 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4742 // Use a FileObserver to detect when traces finish writing. 4743 // The order of traces is considered important to maintain for legibility. 4744 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4745 @Override 4746 public synchronized void onEvent(int event, String path) { notify(); } 4747 }; 4748 4749 try { 4750 observer.startWatching(); 4751 4752 // First collect all of the stacks of the most important pids. 4753 if (firstPids != null) { 4754 try { 4755 int num = firstPids.size(); 4756 for (int i = 0; i < num; i++) { 4757 synchronized (observer) { 4758 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4759 observer.wait(200); // Wait for write-close, give up after 200msec 4760 } 4761 } 4762 } catch (InterruptedException e) { 4763 Slog.wtf(TAG, e); 4764 } 4765 } 4766 4767 // Next collect the stacks of the native pids 4768 if (nativeProcs != null) { 4769 int[] pids = Process.getPidsForCommands(nativeProcs); 4770 if (pids != null) { 4771 for (int pid : pids) { 4772 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4773 } 4774 } 4775 } 4776 4777 // Lastly, measure CPU usage. 4778 if (processCpuTracker != null) { 4779 processCpuTracker.init(); 4780 System.gc(); 4781 processCpuTracker.update(); 4782 try { 4783 synchronized (processCpuTracker) { 4784 processCpuTracker.wait(500); // measure over 1/2 second. 4785 } 4786 } catch (InterruptedException e) { 4787 } 4788 processCpuTracker.update(); 4789 4790 // We'll take the stack crawls of just the top apps using CPU. 4791 final int N = processCpuTracker.countWorkingStats(); 4792 int numProcs = 0; 4793 for (int i=0; i<N && numProcs<5; i++) { 4794 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4795 if (lastPids.indexOfKey(stats.pid) >= 0) { 4796 numProcs++; 4797 try { 4798 synchronized (observer) { 4799 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4800 observer.wait(200); // Wait for write-close, give up after 200msec 4801 } 4802 } catch (InterruptedException e) { 4803 Slog.wtf(TAG, e); 4804 } 4805 4806 } 4807 } 4808 } 4809 } finally { 4810 observer.stopWatching(); 4811 } 4812 } 4813 4814 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4815 if (true || IS_USER_BUILD) { 4816 return; 4817 } 4818 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4819 if (tracesPath == null || tracesPath.length() == 0) { 4820 return; 4821 } 4822 4823 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4824 StrictMode.allowThreadDiskWrites(); 4825 try { 4826 final File tracesFile = new File(tracesPath); 4827 final File tracesDir = tracesFile.getParentFile(); 4828 final File tracesTmp = new File(tracesDir, "__tmp__"); 4829 try { 4830 if (!tracesDir.exists()) { 4831 tracesDir.mkdirs(); 4832 if (!SELinux.restorecon(tracesDir.getPath())) { 4833 return; 4834 } 4835 } 4836 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4837 4838 if (tracesFile.exists()) { 4839 tracesTmp.delete(); 4840 tracesFile.renameTo(tracesTmp); 4841 } 4842 StringBuilder sb = new StringBuilder(); 4843 Time tobj = new Time(); 4844 tobj.set(System.currentTimeMillis()); 4845 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4846 sb.append(": "); 4847 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4848 sb.append(" since "); 4849 sb.append(msg); 4850 FileOutputStream fos = new FileOutputStream(tracesFile); 4851 fos.write(sb.toString().getBytes()); 4852 if (app == null) { 4853 fos.write("\n*** No application process!".getBytes()); 4854 } 4855 fos.close(); 4856 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4857 } catch (IOException e) { 4858 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4859 return; 4860 } 4861 4862 if (app != null) { 4863 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4864 firstPids.add(app.pid); 4865 dumpStackTraces(tracesPath, firstPids, null, null, null); 4866 } 4867 4868 File lastTracesFile = null; 4869 File curTracesFile = null; 4870 for (int i=9; i>=0; i--) { 4871 String name = String.format(Locale.US, "slow%02d.txt", i); 4872 curTracesFile = new File(tracesDir, name); 4873 if (curTracesFile.exists()) { 4874 if (lastTracesFile != null) { 4875 curTracesFile.renameTo(lastTracesFile); 4876 } else { 4877 curTracesFile.delete(); 4878 } 4879 } 4880 lastTracesFile = curTracesFile; 4881 } 4882 tracesFile.renameTo(curTracesFile); 4883 if (tracesTmp.exists()) { 4884 tracesTmp.renameTo(tracesFile); 4885 } 4886 } finally { 4887 StrictMode.setThreadPolicy(oldPolicy); 4888 } 4889 } 4890 4891 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4892 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4893 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4894 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4895 4896 if (mController != null) { 4897 try { 4898 // 0 == continue, -1 = kill process immediately 4899 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4900 if (res < 0 && app.pid != MY_PID) { 4901 app.kill("anr", true); 4902 } 4903 } catch (RemoteException e) { 4904 mController = null; 4905 Watchdog.getInstance().setActivityController(null); 4906 } 4907 } 4908 4909 long anrTime = SystemClock.uptimeMillis(); 4910 if (MONITOR_CPU_USAGE) { 4911 updateCpuStatsNow(); 4912 } 4913 4914 synchronized (this) { 4915 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4916 if (mShuttingDown) { 4917 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4918 return; 4919 } else if (app.notResponding) { 4920 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4921 return; 4922 } else if (app.crashing) { 4923 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4924 return; 4925 } 4926 4927 // In case we come through here for the same app before completing 4928 // this one, mark as anring now so we will bail out. 4929 app.notResponding = true; 4930 4931 // Log the ANR to the event log. 4932 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4933 app.processName, app.info.flags, annotation); 4934 4935 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4936 firstPids.add(app.pid); 4937 4938 int parentPid = app.pid; 4939 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4940 if (parentPid != app.pid) firstPids.add(parentPid); 4941 4942 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4943 4944 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4945 ProcessRecord r = mLruProcesses.get(i); 4946 if (r != null && r.thread != null) { 4947 int pid = r.pid; 4948 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4949 if (r.persistent) { 4950 firstPids.add(pid); 4951 } else { 4952 lastPids.put(pid, Boolean.TRUE); 4953 } 4954 } 4955 } 4956 } 4957 } 4958 4959 // Log the ANR to the main log. 4960 StringBuilder info = new StringBuilder(); 4961 info.setLength(0); 4962 info.append("ANR in ").append(app.processName); 4963 if (activity != null && activity.shortComponentName != null) { 4964 info.append(" (").append(activity.shortComponentName).append(")"); 4965 } 4966 info.append("\n"); 4967 info.append("PID: ").append(app.pid).append("\n"); 4968 if (annotation != null) { 4969 info.append("Reason: ").append(annotation).append("\n"); 4970 } 4971 if (parent != null && parent != activity) { 4972 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4973 } 4974 4975 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4976 4977 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4978 NATIVE_STACKS_OF_INTEREST); 4979 4980 String cpuInfo = null; 4981 if (MONITOR_CPU_USAGE) { 4982 updateCpuStatsNow(); 4983 synchronized (mProcessCpuTracker) { 4984 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4985 } 4986 info.append(processCpuTracker.printCurrentLoad()); 4987 info.append(cpuInfo); 4988 } 4989 4990 info.append(processCpuTracker.printCurrentState(anrTime)); 4991 4992 Slog.e(TAG, info.toString()); 4993 if (tracesFile == null) { 4994 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4995 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4996 } 4997 4998 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4999 cpuInfo, tracesFile, null); 5000 5001 if (mController != null) { 5002 try { 5003 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5004 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5005 if (res != 0) { 5006 if (res < 0 && app.pid != MY_PID) { 5007 app.kill("anr", true); 5008 } else { 5009 synchronized (this) { 5010 mServices.scheduleServiceTimeoutLocked(app); 5011 } 5012 } 5013 return; 5014 } 5015 } catch (RemoteException e) { 5016 mController = null; 5017 Watchdog.getInstance().setActivityController(null); 5018 } 5019 } 5020 5021 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5022 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5023 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5024 5025 synchronized (this) { 5026 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5027 5028 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5029 app.kill("bg anr", true); 5030 return; 5031 } 5032 5033 // Set the app's notResponding state, and look up the errorReportReceiver 5034 makeAppNotRespondingLocked(app, 5035 activity != null ? activity.shortComponentName : null, 5036 annotation != null ? "ANR " + annotation : "ANR", 5037 info.toString()); 5038 5039 // Bring up the infamous App Not Responding dialog 5040 Message msg = Message.obtain(); 5041 HashMap<String, Object> map = new HashMap<String, Object>(); 5042 msg.what = SHOW_NOT_RESPONDING_MSG; 5043 msg.obj = map; 5044 msg.arg1 = aboveSystem ? 1 : 0; 5045 map.put("app", app); 5046 if (activity != null) { 5047 map.put("activity", activity); 5048 } 5049 5050 mHandler.sendMessage(msg); 5051 } 5052 } 5053 5054 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5055 if (!mLaunchWarningShown) { 5056 mLaunchWarningShown = true; 5057 mHandler.post(new Runnable() { 5058 @Override 5059 public void run() { 5060 synchronized (ActivityManagerService.this) { 5061 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5062 d.show(); 5063 mHandler.postDelayed(new Runnable() { 5064 @Override 5065 public void run() { 5066 synchronized (ActivityManagerService.this) { 5067 d.dismiss(); 5068 mLaunchWarningShown = false; 5069 } 5070 } 5071 }, 4000); 5072 } 5073 } 5074 }); 5075 } 5076 } 5077 5078 @Override 5079 public boolean clearApplicationUserData(final String packageName, 5080 final IPackageDataObserver observer, int userId) { 5081 enforceNotIsolatedCaller("clearApplicationUserData"); 5082 int uid = Binder.getCallingUid(); 5083 int pid = Binder.getCallingPid(); 5084 userId = handleIncomingUser(pid, uid, 5085 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5086 long callingId = Binder.clearCallingIdentity(); 5087 try { 5088 IPackageManager pm = AppGlobals.getPackageManager(); 5089 int pkgUid = -1; 5090 synchronized(this) { 5091 try { 5092 pkgUid = pm.getPackageUid(packageName, userId); 5093 } catch (RemoteException e) { 5094 } 5095 if (pkgUid == -1) { 5096 Slog.w(TAG, "Invalid packageName: " + packageName); 5097 if (observer != null) { 5098 try { 5099 observer.onRemoveCompleted(packageName, false); 5100 } catch (RemoteException e) { 5101 Slog.i(TAG, "Observer no longer exists."); 5102 } 5103 } 5104 return false; 5105 } 5106 if (uid == pkgUid || checkComponentPermission( 5107 android.Manifest.permission.CLEAR_APP_USER_DATA, 5108 pid, uid, -1, true) 5109 == PackageManager.PERMISSION_GRANTED) { 5110 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5111 } else { 5112 throw new SecurityException("PID " + pid + " does not have permission " 5113 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5114 + " of package " + packageName); 5115 } 5116 5117 // Remove all tasks match the cleared application package and user 5118 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5119 final TaskRecord tr = mRecentTasks.get(i); 5120 final String taskPackageName = 5121 tr.getBaseIntent().getComponent().getPackageName(); 5122 if (tr.userId != userId) continue; 5123 if (!taskPackageName.equals(packageName)) continue; 5124 removeTaskByIdLocked(tr.taskId, false); 5125 } 5126 } 5127 5128 try { 5129 // Clear application user data 5130 pm.clearApplicationUserData(packageName, observer, userId); 5131 5132 synchronized(this) { 5133 // Remove all permissions granted from/to this package 5134 removeUriPermissionsForPackageLocked(packageName, userId, true); 5135 } 5136 5137 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5138 Uri.fromParts("package", packageName, null)); 5139 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5140 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5141 null, null, 0, null, null, null, false, false, userId); 5142 } catch (RemoteException e) { 5143 } 5144 } finally { 5145 Binder.restoreCallingIdentity(callingId); 5146 } 5147 return true; 5148 } 5149 5150 @Override 5151 public void killBackgroundProcesses(final String packageName, int userId) { 5152 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5153 != PackageManager.PERMISSION_GRANTED && 5154 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5155 != PackageManager.PERMISSION_GRANTED) { 5156 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5157 + Binder.getCallingPid() 5158 + ", uid=" + Binder.getCallingUid() 5159 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5160 Slog.w(TAG, msg); 5161 throw new SecurityException(msg); 5162 } 5163 5164 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5165 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5166 long callingId = Binder.clearCallingIdentity(); 5167 try { 5168 IPackageManager pm = AppGlobals.getPackageManager(); 5169 synchronized(this) { 5170 int appId = -1; 5171 try { 5172 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5173 } catch (RemoteException e) { 5174 } 5175 if (appId == -1) { 5176 Slog.w(TAG, "Invalid packageName: " + packageName); 5177 return; 5178 } 5179 killPackageProcessesLocked(packageName, appId, userId, 5180 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5181 } 5182 } finally { 5183 Binder.restoreCallingIdentity(callingId); 5184 } 5185 } 5186 5187 @Override 5188 public void killAllBackgroundProcesses() { 5189 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5190 != PackageManager.PERMISSION_GRANTED) { 5191 String msg = "Permission Denial: killAllBackgroundProcesses() 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 long callingId = Binder.clearCallingIdentity(); 5200 try { 5201 synchronized(this) { 5202 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5203 final int NP = mProcessNames.getMap().size(); 5204 for (int ip=0; ip<NP; ip++) { 5205 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5206 final int NA = apps.size(); 5207 for (int ia=0; ia<NA; ia++) { 5208 ProcessRecord app = apps.valueAt(ia); 5209 if (app.persistent) { 5210 // we don't kill persistent processes 5211 continue; 5212 } 5213 if (app.removed) { 5214 procs.add(app); 5215 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5216 app.removed = true; 5217 procs.add(app); 5218 } 5219 } 5220 } 5221 5222 int N = procs.size(); 5223 for (int i=0; i<N; i++) { 5224 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5225 } 5226 mAllowLowerMemLevel = true; 5227 updateOomAdjLocked(); 5228 doLowMemReportIfNeededLocked(null); 5229 } 5230 } finally { 5231 Binder.restoreCallingIdentity(callingId); 5232 } 5233 } 5234 5235 @Override 5236 public void forceStopPackage(final String packageName, int userId) { 5237 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5238 != PackageManager.PERMISSION_GRANTED) { 5239 String msg = "Permission Denial: forceStopPackage() from pid=" 5240 + Binder.getCallingPid() 5241 + ", uid=" + Binder.getCallingUid() 5242 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5243 Slog.w(TAG, msg); 5244 throw new SecurityException(msg); 5245 } 5246 final int callingPid = Binder.getCallingPid(); 5247 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5248 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5249 long callingId = Binder.clearCallingIdentity(); 5250 try { 5251 IPackageManager pm = AppGlobals.getPackageManager(); 5252 synchronized(this) { 5253 int[] users = userId == UserHandle.USER_ALL 5254 ? getUsersLocked() : new int[] { userId }; 5255 for (int user : users) { 5256 int pkgUid = -1; 5257 try { 5258 pkgUid = pm.getPackageUid(packageName, user); 5259 } catch (RemoteException e) { 5260 } 5261 if (pkgUid == -1) { 5262 Slog.w(TAG, "Invalid packageName: " + packageName); 5263 continue; 5264 } 5265 try { 5266 pm.setPackageStoppedState(packageName, true, user); 5267 } catch (RemoteException e) { 5268 } catch (IllegalArgumentException e) { 5269 Slog.w(TAG, "Failed trying to unstop package " 5270 + packageName + ": " + e); 5271 } 5272 if (isUserRunningLocked(user, false)) { 5273 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5274 } 5275 } 5276 } 5277 } finally { 5278 Binder.restoreCallingIdentity(callingId); 5279 } 5280 } 5281 5282 @Override 5283 public void addPackageDependency(String packageName) { 5284 synchronized (this) { 5285 int callingPid = Binder.getCallingPid(); 5286 if (callingPid == Process.myPid()) { 5287 // Yeah, um, no. 5288 Slog.w(TAG, "Can't addPackageDependency on system process"); 5289 return; 5290 } 5291 ProcessRecord proc; 5292 synchronized (mPidsSelfLocked) { 5293 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5294 } 5295 if (proc != null) { 5296 if (proc.pkgDeps == null) { 5297 proc.pkgDeps = new ArraySet<String>(1); 5298 } 5299 proc.pkgDeps.add(packageName); 5300 } 5301 } 5302 } 5303 5304 /* 5305 * The pkg name and app id have to be specified. 5306 */ 5307 @Override 5308 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5309 if (pkg == null) { 5310 return; 5311 } 5312 // Make sure the uid is valid. 5313 if (appid < 0) { 5314 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5315 return; 5316 } 5317 int callerUid = Binder.getCallingUid(); 5318 // Only the system server can kill an application 5319 if (callerUid == Process.SYSTEM_UID) { 5320 // Post an aysnc message to kill the application 5321 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5322 msg.arg1 = appid; 5323 msg.arg2 = 0; 5324 Bundle bundle = new Bundle(); 5325 bundle.putString("pkg", pkg); 5326 bundle.putString("reason", reason); 5327 msg.obj = bundle; 5328 mHandler.sendMessage(msg); 5329 } else { 5330 throw new SecurityException(callerUid + " cannot kill pkg: " + 5331 pkg); 5332 } 5333 } 5334 5335 @Override 5336 public void closeSystemDialogs(String reason) { 5337 enforceNotIsolatedCaller("closeSystemDialogs"); 5338 5339 final int pid = Binder.getCallingPid(); 5340 final int uid = Binder.getCallingUid(); 5341 final long origId = Binder.clearCallingIdentity(); 5342 try { 5343 synchronized (this) { 5344 // Only allow this from foreground processes, so that background 5345 // applications can't abuse it to prevent system UI from being shown. 5346 if (uid >= Process.FIRST_APPLICATION_UID) { 5347 ProcessRecord proc; 5348 synchronized (mPidsSelfLocked) { 5349 proc = mPidsSelfLocked.get(pid); 5350 } 5351 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5352 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5353 + " from background process " + proc); 5354 return; 5355 } 5356 } 5357 closeSystemDialogsLocked(reason); 5358 } 5359 } finally { 5360 Binder.restoreCallingIdentity(origId); 5361 } 5362 } 5363 5364 void closeSystemDialogsLocked(String reason) { 5365 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5366 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5367 | Intent.FLAG_RECEIVER_FOREGROUND); 5368 if (reason != null) { 5369 intent.putExtra("reason", reason); 5370 } 5371 mWindowManager.closeSystemDialogs(reason); 5372 5373 mStackSupervisor.closeSystemDialogsLocked(); 5374 5375 broadcastIntentLocked(null, null, intent, null, 5376 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5377 Process.SYSTEM_UID, UserHandle.USER_ALL); 5378 } 5379 5380 @Override 5381 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5382 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5383 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5384 for (int i=pids.length-1; i>=0; i--) { 5385 ProcessRecord proc; 5386 int oomAdj; 5387 synchronized (this) { 5388 synchronized (mPidsSelfLocked) { 5389 proc = mPidsSelfLocked.get(pids[i]); 5390 oomAdj = proc != null ? proc.setAdj : 0; 5391 } 5392 } 5393 infos[i] = new Debug.MemoryInfo(); 5394 Debug.getMemoryInfo(pids[i], infos[i]); 5395 if (proc != null) { 5396 synchronized (this) { 5397 if (proc.thread != null && proc.setAdj == oomAdj) { 5398 // Record this for posterity if the process has been stable. 5399 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5400 infos[i].getTotalUss(), false, proc.pkgList); 5401 } 5402 } 5403 } 5404 } 5405 return infos; 5406 } 5407 5408 @Override 5409 public long[] getProcessPss(int[] pids) { 5410 enforceNotIsolatedCaller("getProcessPss"); 5411 long[] pss = new long[pids.length]; 5412 for (int i=pids.length-1; i>=0; i--) { 5413 ProcessRecord proc; 5414 int oomAdj; 5415 synchronized (this) { 5416 synchronized (mPidsSelfLocked) { 5417 proc = mPidsSelfLocked.get(pids[i]); 5418 oomAdj = proc != null ? proc.setAdj : 0; 5419 } 5420 } 5421 long[] tmpUss = new long[1]; 5422 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5423 if (proc != null) { 5424 synchronized (this) { 5425 if (proc.thread != null && proc.setAdj == oomAdj) { 5426 // Record this for posterity if the process has been stable. 5427 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5428 } 5429 } 5430 } 5431 } 5432 return pss; 5433 } 5434 5435 @Override 5436 public void killApplicationProcess(String processName, int uid) { 5437 if (processName == null) { 5438 return; 5439 } 5440 5441 int callerUid = Binder.getCallingUid(); 5442 // Only the system server can kill an application 5443 if (callerUid == Process.SYSTEM_UID) { 5444 synchronized (this) { 5445 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5446 if (app != null && app.thread != null) { 5447 try { 5448 app.thread.scheduleSuicide(); 5449 } catch (RemoteException e) { 5450 // If the other end already died, then our work here is done. 5451 } 5452 } else { 5453 Slog.w(TAG, "Process/uid not found attempting kill of " 5454 + processName + " / " + uid); 5455 } 5456 } 5457 } else { 5458 throw new SecurityException(callerUid + " cannot kill app process: " + 5459 processName); 5460 } 5461 } 5462 5463 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5464 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5465 false, true, false, false, UserHandle.getUserId(uid), reason); 5466 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5467 Uri.fromParts("package", packageName, null)); 5468 if (!mProcessesReady) { 5469 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5470 | Intent.FLAG_RECEIVER_FOREGROUND); 5471 } 5472 intent.putExtra(Intent.EXTRA_UID, uid); 5473 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5474 broadcastIntentLocked(null, null, intent, 5475 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5476 false, false, 5477 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5478 } 5479 5480 private void forceStopUserLocked(int userId, String reason) { 5481 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5482 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5483 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5484 | Intent.FLAG_RECEIVER_FOREGROUND); 5485 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5486 broadcastIntentLocked(null, null, intent, 5487 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5488 false, false, 5489 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5490 } 5491 5492 private final boolean killPackageProcessesLocked(String packageName, int appId, 5493 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5494 boolean doit, boolean evenPersistent, String reason) { 5495 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5496 5497 // Remove all processes this package may have touched: all with the 5498 // same UID (except for the system or root user), and all whose name 5499 // matches the package name. 5500 final int NP = mProcessNames.getMap().size(); 5501 for (int ip=0; ip<NP; ip++) { 5502 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5503 final int NA = apps.size(); 5504 for (int ia=0; ia<NA; ia++) { 5505 ProcessRecord app = apps.valueAt(ia); 5506 if (app.persistent && !evenPersistent) { 5507 // we don't kill persistent processes 5508 continue; 5509 } 5510 if (app.removed) { 5511 if (doit) { 5512 procs.add(app); 5513 } 5514 continue; 5515 } 5516 5517 // Skip process if it doesn't meet our oom adj requirement. 5518 if (app.setAdj < minOomAdj) { 5519 continue; 5520 } 5521 5522 // If no package is specified, we call all processes under the 5523 // give user id. 5524 if (packageName == null) { 5525 if (app.userId != userId) { 5526 continue; 5527 } 5528 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5529 continue; 5530 } 5531 // Package has been specified, we want to hit all processes 5532 // that match it. We need to qualify this by the processes 5533 // that are running under the specified app and user ID. 5534 } else { 5535 final boolean isDep = app.pkgDeps != null 5536 && app.pkgDeps.contains(packageName); 5537 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5538 continue; 5539 } 5540 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5541 continue; 5542 } 5543 if (!app.pkgList.containsKey(packageName) && !isDep) { 5544 continue; 5545 } 5546 } 5547 5548 // Process has passed all conditions, kill it! 5549 if (!doit) { 5550 return true; 5551 } 5552 app.removed = true; 5553 procs.add(app); 5554 } 5555 } 5556 5557 int N = procs.size(); 5558 for (int i=0; i<N; i++) { 5559 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5560 } 5561 updateOomAdjLocked(); 5562 return N > 0; 5563 } 5564 5565 private final boolean forceStopPackageLocked(String name, int appId, 5566 boolean callerWillRestart, boolean purgeCache, boolean doit, 5567 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5568 int i; 5569 int N; 5570 5571 if (userId == UserHandle.USER_ALL && name == null) { 5572 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5573 } 5574 5575 if (appId < 0 && name != null) { 5576 try { 5577 appId = UserHandle.getAppId( 5578 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5579 } catch (RemoteException e) { 5580 } 5581 } 5582 5583 if (doit) { 5584 if (name != null) { 5585 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5586 + " user=" + userId + ": " + reason); 5587 } else { 5588 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5589 } 5590 5591 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5592 for (int ip=pmap.size()-1; ip>=0; ip--) { 5593 SparseArray<Long> ba = pmap.valueAt(ip); 5594 for (i=ba.size()-1; i>=0; i--) { 5595 boolean remove = false; 5596 final int entUid = ba.keyAt(i); 5597 if (name != null) { 5598 if (userId == UserHandle.USER_ALL) { 5599 if (UserHandle.getAppId(entUid) == appId) { 5600 remove = true; 5601 } 5602 } else { 5603 if (entUid == UserHandle.getUid(userId, appId)) { 5604 remove = true; 5605 } 5606 } 5607 } else if (UserHandle.getUserId(entUid) == userId) { 5608 remove = true; 5609 } 5610 if (remove) { 5611 ba.removeAt(i); 5612 } 5613 } 5614 if (ba.size() == 0) { 5615 pmap.removeAt(ip); 5616 } 5617 } 5618 } 5619 5620 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5621 -100, callerWillRestart, true, doit, evenPersistent, 5622 name == null ? ("stop user " + userId) : ("stop " + name)); 5623 5624 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5625 if (!doit) { 5626 return true; 5627 } 5628 didSomething = true; 5629 } 5630 5631 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5632 if (!doit) { 5633 return true; 5634 } 5635 didSomething = true; 5636 } 5637 5638 if (name == null) { 5639 // Remove all sticky broadcasts from this user. 5640 mStickyBroadcasts.remove(userId); 5641 } 5642 5643 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5644 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5645 userId, providers)) { 5646 if (!doit) { 5647 return true; 5648 } 5649 didSomething = true; 5650 } 5651 N = providers.size(); 5652 for (i=0; i<N; i++) { 5653 removeDyingProviderLocked(null, providers.get(i), true); 5654 } 5655 5656 // Remove transient permissions granted from/to this package/user 5657 removeUriPermissionsForPackageLocked(name, userId, false); 5658 5659 if (name == null || uninstalling) { 5660 // Remove pending intents. For now we only do this when force 5661 // stopping users, because we have some problems when doing this 5662 // for packages -- app widgets are not currently cleaned up for 5663 // such packages, so they can be left with bad pending intents. 5664 if (mIntentSenderRecords.size() > 0) { 5665 Iterator<WeakReference<PendingIntentRecord>> it 5666 = mIntentSenderRecords.values().iterator(); 5667 while (it.hasNext()) { 5668 WeakReference<PendingIntentRecord> wpir = it.next(); 5669 if (wpir == null) { 5670 it.remove(); 5671 continue; 5672 } 5673 PendingIntentRecord pir = wpir.get(); 5674 if (pir == null) { 5675 it.remove(); 5676 continue; 5677 } 5678 if (name == null) { 5679 // Stopping user, remove all objects for the user. 5680 if (pir.key.userId != userId) { 5681 // Not the same user, skip it. 5682 continue; 5683 } 5684 } else { 5685 if (UserHandle.getAppId(pir.uid) != appId) { 5686 // Different app id, skip it. 5687 continue; 5688 } 5689 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5690 // Different user, skip it. 5691 continue; 5692 } 5693 if (!pir.key.packageName.equals(name)) { 5694 // Different package, skip it. 5695 continue; 5696 } 5697 } 5698 if (!doit) { 5699 return true; 5700 } 5701 didSomething = true; 5702 it.remove(); 5703 pir.canceled = true; 5704 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5705 pir.key.activity.pendingResults.remove(pir.ref); 5706 } 5707 } 5708 } 5709 } 5710 5711 if (doit) { 5712 if (purgeCache && name != null) { 5713 AttributeCache ac = AttributeCache.instance(); 5714 if (ac != null) { 5715 ac.removePackage(name); 5716 } 5717 } 5718 if (mBooted) { 5719 mStackSupervisor.resumeTopActivitiesLocked(); 5720 mStackSupervisor.scheduleIdleLocked(); 5721 } 5722 } 5723 5724 return didSomething; 5725 } 5726 5727 private final boolean removeProcessLocked(ProcessRecord app, 5728 boolean callerWillRestart, boolean allowRestart, String reason) { 5729 final String name = app.processName; 5730 final int uid = app.uid; 5731 if (DEBUG_PROCESSES) Slog.d( 5732 TAG, "Force removing proc " + app.toShortString() + " (" + name 5733 + "/" + uid + ")"); 5734 5735 mProcessNames.remove(name, uid); 5736 mIsolatedProcesses.remove(app.uid); 5737 if (mHeavyWeightProcess == app) { 5738 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5739 mHeavyWeightProcess.userId, 0)); 5740 mHeavyWeightProcess = null; 5741 } 5742 boolean needRestart = false; 5743 if (app.pid > 0 && app.pid != MY_PID) { 5744 int pid = app.pid; 5745 synchronized (mPidsSelfLocked) { 5746 mPidsSelfLocked.remove(pid); 5747 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5748 } 5749 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5750 if (app.isolated) { 5751 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5752 } 5753 app.kill(reason, true); 5754 handleAppDiedLocked(app, true, allowRestart); 5755 removeLruProcessLocked(app); 5756 5757 if (app.persistent && !app.isolated) { 5758 if (!callerWillRestart) { 5759 addAppLocked(app.info, false, null /* ABI override */); 5760 } else { 5761 needRestart = true; 5762 } 5763 } 5764 } else { 5765 mRemovedProcesses.add(app); 5766 } 5767 5768 return needRestart; 5769 } 5770 5771 private final void processStartTimedOutLocked(ProcessRecord app) { 5772 final int pid = app.pid; 5773 boolean gone = false; 5774 synchronized (mPidsSelfLocked) { 5775 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5776 if (knownApp != null && knownApp.thread == null) { 5777 mPidsSelfLocked.remove(pid); 5778 gone = true; 5779 } 5780 } 5781 5782 if (gone) { 5783 Slog.w(TAG, "Process " + app + " failed to attach"); 5784 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5785 pid, app.uid, app.processName); 5786 mProcessNames.remove(app.processName, app.uid); 5787 mIsolatedProcesses.remove(app.uid); 5788 if (mHeavyWeightProcess == app) { 5789 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5790 mHeavyWeightProcess.userId, 0)); 5791 mHeavyWeightProcess = null; 5792 } 5793 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5794 if (app.isolated) { 5795 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5796 } 5797 // Take care of any launching providers waiting for this process. 5798 checkAppInLaunchingProvidersLocked(app, true); 5799 // Take care of any services that are waiting for the process. 5800 mServices.processStartTimedOutLocked(app); 5801 app.kill("start timeout", true); 5802 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5803 Slog.w(TAG, "Unattached app died before backup, skipping"); 5804 try { 5805 IBackupManager bm = IBackupManager.Stub.asInterface( 5806 ServiceManager.getService(Context.BACKUP_SERVICE)); 5807 bm.agentDisconnected(app.info.packageName); 5808 } catch (RemoteException e) { 5809 // Can't happen; the backup manager is local 5810 } 5811 } 5812 if (isPendingBroadcastProcessLocked(pid)) { 5813 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5814 skipPendingBroadcastLocked(pid); 5815 } 5816 } else { 5817 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5818 } 5819 } 5820 5821 private final boolean attachApplicationLocked(IApplicationThread thread, 5822 int pid) { 5823 5824 // Find the application record that is being attached... either via 5825 // the pid if we are running in multiple processes, or just pull the 5826 // next app record if we are emulating process with anonymous threads. 5827 ProcessRecord app; 5828 if (pid != MY_PID && pid >= 0) { 5829 synchronized (mPidsSelfLocked) { 5830 app = mPidsSelfLocked.get(pid); 5831 } 5832 } else { 5833 app = null; 5834 } 5835 5836 if (app == null) { 5837 Slog.w(TAG, "No pending application record for pid " + pid 5838 + " (IApplicationThread " + thread + "); dropping process"); 5839 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5840 if (pid > 0 && pid != MY_PID) { 5841 Process.killProcessQuiet(pid); 5842 //TODO: Process.killProcessGroup(app.info.uid, pid); 5843 } else { 5844 try { 5845 thread.scheduleExit(); 5846 } catch (Exception e) { 5847 // Ignore exceptions. 5848 } 5849 } 5850 return false; 5851 } 5852 5853 // If this application record is still attached to a previous 5854 // process, clean it up now. 5855 if (app.thread != null) { 5856 handleAppDiedLocked(app, true, true); 5857 } 5858 5859 // Tell the process all about itself. 5860 5861 if (localLOGV) Slog.v( 5862 TAG, "Binding process pid " + pid + " to record " + app); 5863 5864 final String processName = app.processName; 5865 try { 5866 AppDeathRecipient adr = new AppDeathRecipient( 5867 app, pid, thread); 5868 thread.asBinder().linkToDeath(adr, 0); 5869 app.deathRecipient = adr; 5870 } catch (RemoteException e) { 5871 app.resetPackageList(mProcessStats); 5872 startProcessLocked(app, "link fail", processName); 5873 return false; 5874 } 5875 5876 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5877 5878 app.makeActive(thread, mProcessStats); 5879 app.curAdj = app.setAdj = -100; 5880 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5881 app.forcingToForeground = null; 5882 updateProcessForegroundLocked(app, false, false); 5883 app.hasShownUi = false; 5884 app.debugging = false; 5885 app.cached = false; 5886 app.killedByAm = false; 5887 5888 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5889 5890 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5891 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5892 5893 if (!normalMode) { 5894 Slog.i(TAG, "Launching preboot mode app: " + app); 5895 } 5896 5897 if (localLOGV) Slog.v( 5898 TAG, "New app record " + app 5899 + " thread=" + thread.asBinder() + " pid=" + pid); 5900 try { 5901 int testMode = IApplicationThread.DEBUG_OFF; 5902 if (mDebugApp != null && mDebugApp.equals(processName)) { 5903 testMode = mWaitForDebugger 5904 ? IApplicationThread.DEBUG_WAIT 5905 : IApplicationThread.DEBUG_ON; 5906 app.debugging = true; 5907 if (mDebugTransient) { 5908 mDebugApp = mOrigDebugApp; 5909 mWaitForDebugger = mOrigWaitForDebugger; 5910 } 5911 } 5912 String profileFile = app.instrumentationProfileFile; 5913 ParcelFileDescriptor profileFd = null; 5914 int samplingInterval = 0; 5915 boolean profileAutoStop = false; 5916 if (mProfileApp != null && mProfileApp.equals(processName)) { 5917 mProfileProc = app; 5918 profileFile = mProfileFile; 5919 profileFd = mProfileFd; 5920 samplingInterval = mSamplingInterval; 5921 profileAutoStop = mAutoStopProfiler; 5922 } 5923 boolean enableOpenGlTrace = false; 5924 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5925 enableOpenGlTrace = true; 5926 mOpenGlTraceApp = null; 5927 } 5928 5929 // If the app is being launched for restore or full backup, set it up specially 5930 boolean isRestrictedBackupMode = false; 5931 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5932 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5933 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5934 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5935 } 5936 5937 ensurePackageDexOpt(app.instrumentationInfo != null 5938 ? app.instrumentationInfo.packageName 5939 : app.info.packageName); 5940 if (app.instrumentationClass != null) { 5941 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5942 } 5943 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5944 + processName + " with config " + mConfiguration); 5945 ApplicationInfo appInfo = app.instrumentationInfo != null 5946 ? app.instrumentationInfo : app.info; 5947 app.compat = compatibilityInfoForPackageLocked(appInfo); 5948 if (profileFd != null) { 5949 profileFd = profileFd.dup(); 5950 } 5951 ProfilerInfo profilerInfo = profileFile == null ? null 5952 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5953 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5954 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5955 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5956 isRestrictedBackupMode || !normalMode, app.persistent, 5957 new Configuration(mConfiguration), app.compat, 5958 getCommonServicesLocked(app.isolated), 5959 mCoreSettingsObserver.getCoreSettingsLocked()); 5960 updateLruProcessLocked(app, false, null); 5961 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5962 } catch (Exception e) { 5963 // todo: Yikes! What should we do? For now we will try to 5964 // start another process, but that could easily get us in 5965 // an infinite loop of restarting processes... 5966 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5967 5968 app.resetPackageList(mProcessStats); 5969 app.unlinkDeathRecipient(); 5970 startProcessLocked(app, "bind fail", processName); 5971 return false; 5972 } 5973 5974 // Remove this record from the list of starting applications. 5975 mPersistentStartingProcesses.remove(app); 5976 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5977 "Attach application locked removing on hold: " + app); 5978 mProcessesOnHold.remove(app); 5979 5980 boolean badApp = false; 5981 boolean didSomething = false; 5982 5983 // See if the top visible activity is waiting to run in this process... 5984 if (normalMode) { 5985 try { 5986 if (mStackSupervisor.attachApplicationLocked(app)) { 5987 didSomething = true; 5988 } 5989 } catch (Exception e) { 5990 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5991 badApp = true; 5992 } 5993 } 5994 5995 // Find any services that should be running in this process... 5996 if (!badApp) { 5997 try { 5998 didSomething |= mServices.attachApplicationLocked(app, processName); 5999 } catch (Exception e) { 6000 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6001 badApp = true; 6002 } 6003 } 6004 6005 // Check if a next-broadcast receiver is in this process... 6006 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6007 try { 6008 didSomething |= sendPendingBroadcastsLocked(app); 6009 } catch (Exception e) { 6010 // If the app died trying to launch the receiver we declare it 'bad' 6011 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6012 badApp = true; 6013 } 6014 } 6015 6016 // Check whether the next backup agent is in this process... 6017 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6018 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6019 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6020 try { 6021 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6022 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6023 mBackupTarget.backupMode); 6024 } catch (Exception e) { 6025 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6026 badApp = true; 6027 } 6028 } 6029 6030 if (badApp) { 6031 app.kill("error during init", true); 6032 handleAppDiedLocked(app, false, true); 6033 return false; 6034 } 6035 6036 if (!didSomething) { 6037 updateOomAdjLocked(); 6038 } 6039 6040 return true; 6041 } 6042 6043 @Override 6044 public final void attachApplication(IApplicationThread thread) { 6045 synchronized (this) { 6046 int callingPid = Binder.getCallingPid(); 6047 final long origId = Binder.clearCallingIdentity(); 6048 attachApplicationLocked(thread, callingPid); 6049 Binder.restoreCallingIdentity(origId); 6050 } 6051 } 6052 6053 @Override 6054 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6055 final long origId = Binder.clearCallingIdentity(); 6056 synchronized (this) { 6057 ActivityStack stack = ActivityRecord.getStackLocked(token); 6058 if (stack != null) { 6059 ActivityRecord r = 6060 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6061 if (stopProfiling) { 6062 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6063 try { 6064 mProfileFd.close(); 6065 } catch (IOException e) { 6066 } 6067 clearProfilerLocked(); 6068 } 6069 } 6070 } 6071 } 6072 Binder.restoreCallingIdentity(origId); 6073 } 6074 6075 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6076 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6077 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6078 } 6079 6080 void enableScreenAfterBoot() { 6081 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6082 SystemClock.uptimeMillis()); 6083 mWindowManager.enableScreenAfterBoot(); 6084 6085 synchronized (this) { 6086 updateEventDispatchingLocked(); 6087 } 6088 } 6089 6090 @Override 6091 public void showBootMessage(final CharSequence msg, final boolean always) { 6092 enforceNotIsolatedCaller("showBootMessage"); 6093 mWindowManager.showBootMessage(msg, always); 6094 } 6095 6096 @Override 6097 public void keyguardWaitingForActivityDrawn() { 6098 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6099 final long token = Binder.clearCallingIdentity(); 6100 try { 6101 synchronized (this) { 6102 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6103 mWindowManager.keyguardWaitingForActivityDrawn(); 6104 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6105 mLockScreenShown = LOCK_SCREEN_LEAVING; 6106 updateSleepIfNeededLocked(); 6107 } 6108 } 6109 } finally { 6110 Binder.restoreCallingIdentity(token); 6111 } 6112 } 6113 6114 final void finishBooting() { 6115 synchronized (this) { 6116 if (!mBootAnimationComplete) { 6117 mCallFinishBooting = true; 6118 return; 6119 } 6120 mCallFinishBooting = false; 6121 } 6122 6123 ArraySet<String> completedIsas = new ArraySet<String>(); 6124 for (String abi : Build.SUPPORTED_ABIS) { 6125 Process.establishZygoteConnectionForAbi(abi); 6126 final String instructionSet = VMRuntime.getInstructionSet(abi); 6127 if (!completedIsas.contains(instructionSet)) { 6128 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6129 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6130 } 6131 completedIsas.add(instructionSet); 6132 } 6133 } 6134 6135 IntentFilter pkgFilter = new IntentFilter(); 6136 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6137 pkgFilter.addDataScheme("package"); 6138 mContext.registerReceiver(new BroadcastReceiver() { 6139 @Override 6140 public void onReceive(Context context, Intent intent) { 6141 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6142 if (pkgs != null) { 6143 for (String pkg : pkgs) { 6144 synchronized (ActivityManagerService.this) { 6145 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6146 0, "finished booting")) { 6147 setResultCode(Activity.RESULT_OK); 6148 return; 6149 } 6150 } 6151 } 6152 } 6153 } 6154 }, pkgFilter); 6155 6156 // Let system services know. 6157 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6158 6159 synchronized (this) { 6160 // Ensure that any processes we had put on hold are now started 6161 // up. 6162 final int NP = mProcessesOnHold.size(); 6163 if (NP > 0) { 6164 ArrayList<ProcessRecord> procs = 6165 new ArrayList<ProcessRecord>(mProcessesOnHold); 6166 for (int ip=0; ip<NP; ip++) { 6167 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6168 + procs.get(ip)); 6169 startProcessLocked(procs.get(ip), "on-hold", null); 6170 } 6171 } 6172 6173 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6174 // Start looking for apps that are abusing wake locks. 6175 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6176 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6177 // Tell anyone interested that we are done booting! 6178 SystemProperties.set("sys.boot_completed", "1"); 6179 6180 // And trigger dev.bootcomplete if we are not showing encryption progress 6181 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6182 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6183 SystemProperties.set("dev.bootcomplete", "1"); 6184 } 6185 for (int i=0; i<mStartedUsers.size(); i++) { 6186 UserStartedState uss = mStartedUsers.valueAt(i); 6187 if (uss.mState == UserStartedState.STATE_BOOTING) { 6188 uss.mState = UserStartedState.STATE_RUNNING; 6189 final int userId = mStartedUsers.keyAt(i); 6190 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6191 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6192 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6193 broadcastIntentLocked(null, null, intent, null, 6194 new IIntentReceiver.Stub() { 6195 @Override 6196 public void performReceive(Intent intent, int resultCode, 6197 String data, Bundle extras, boolean ordered, 6198 boolean sticky, int sendingUser) { 6199 synchronized (ActivityManagerService.this) { 6200 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6201 true, false); 6202 } 6203 } 6204 }, 6205 0, null, null, 6206 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6207 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6208 userId); 6209 } 6210 } 6211 scheduleStartProfilesLocked(); 6212 } 6213 } 6214 } 6215 6216 @Override 6217 public void bootAnimationComplete() { 6218 final boolean callFinishBooting; 6219 synchronized (this) { 6220 callFinishBooting = mCallFinishBooting; 6221 mBootAnimationComplete = true; 6222 } 6223 if (callFinishBooting) { 6224 finishBooting(); 6225 } 6226 } 6227 6228 @Override 6229 public void systemBackupRestored() { 6230 synchronized (this) { 6231 if (mSystemReady) { 6232 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6233 } else { 6234 Slog.w(TAG, "System backup restored before system is ready"); 6235 } 6236 } 6237 } 6238 6239 final void ensureBootCompleted() { 6240 boolean booting; 6241 boolean enableScreen; 6242 synchronized (this) { 6243 booting = mBooting; 6244 mBooting = false; 6245 enableScreen = !mBooted; 6246 mBooted = true; 6247 } 6248 6249 if (booting) { 6250 finishBooting(); 6251 } 6252 6253 if (enableScreen) { 6254 enableScreenAfterBoot(); 6255 } 6256 } 6257 6258 @Override 6259 public final void activityResumed(IBinder token) { 6260 final long origId = Binder.clearCallingIdentity(); 6261 synchronized(this) { 6262 ActivityStack stack = ActivityRecord.getStackLocked(token); 6263 if (stack != null) { 6264 ActivityRecord.activityResumedLocked(token); 6265 } 6266 } 6267 Binder.restoreCallingIdentity(origId); 6268 } 6269 6270 @Override 6271 public final void activityPaused(IBinder token) { 6272 final long origId = Binder.clearCallingIdentity(); 6273 synchronized(this) { 6274 ActivityStack stack = ActivityRecord.getStackLocked(token); 6275 if (stack != null) { 6276 stack.activityPausedLocked(token, false); 6277 } 6278 } 6279 Binder.restoreCallingIdentity(origId); 6280 } 6281 6282 @Override 6283 public final void activityStopped(IBinder token, Bundle icicle, 6284 PersistableBundle persistentState, CharSequence description) { 6285 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6286 6287 // Refuse possible leaked file descriptors 6288 if (icicle != null && icicle.hasFileDescriptors()) { 6289 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6290 } 6291 6292 final long origId = Binder.clearCallingIdentity(); 6293 6294 synchronized (this) { 6295 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6296 if (r != null) { 6297 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6298 } 6299 } 6300 6301 trimApplications(); 6302 6303 Binder.restoreCallingIdentity(origId); 6304 } 6305 6306 @Override 6307 public final void activityDestroyed(IBinder token) { 6308 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6309 synchronized (this) { 6310 ActivityStack stack = ActivityRecord.getStackLocked(token); 6311 if (stack != null) { 6312 stack.activityDestroyedLocked(token); 6313 } 6314 } 6315 } 6316 6317 @Override 6318 public final void backgroundResourcesReleased(IBinder token) { 6319 final long origId = Binder.clearCallingIdentity(); 6320 try { 6321 synchronized (this) { 6322 ActivityStack stack = ActivityRecord.getStackLocked(token); 6323 if (stack != null) { 6324 stack.backgroundResourcesReleased(); 6325 } 6326 } 6327 } finally { 6328 Binder.restoreCallingIdentity(origId); 6329 } 6330 } 6331 6332 @Override 6333 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6334 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6335 } 6336 6337 @Override 6338 public final void notifyEnterAnimationComplete(IBinder token) { 6339 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6340 } 6341 6342 @Override 6343 public String getCallingPackage(IBinder token) { 6344 synchronized (this) { 6345 ActivityRecord r = getCallingRecordLocked(token); 6346 return r != null ? r.info.packageName : null; 6347 } 6348 } 6349 6350 @Override 6351 public ComponentName getCallingActivity(IBinder token) { 6352 synchronized (this) { 6353 ActivityRecord r = getCallingRecordLocked(token); 6354 return r != null ? r.intent.getComponent() : null; 6355 } 6356 } 6357 6358 private ActivityRecord getCallingRecordLocked(IBinder token) { 6359 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6360 if (r == null) { 6361 return null; 6362 } 6363 return r.resultTo; 6364 } 6365 6366 @Override 6367 public ComponentName getActivityClassForToken(IBinder token) { 6368 synchronized(this) { 6369 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6370 if (r == null) { 6371 return null; 6372 } 6373 return r.intent.getComponent(); 6374 } 6375 } 6376 6377 @Override 6378 public String getPackageForToken(IBinder token) { 6379 synchronized(this) { 6380 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6381 if (r == null) { 6382 return null; 6383 } 6384 return r.packageName; 6385 } 6386 } 6387 6388 @Override 6389 public IIntentSender getIntentSender(int type, 6390 String packageName, IBinder token, String resultWho, 6391 int requestCode, Intent[] intents, String[] resolvedTypes, 6392 int flags, Bundle options, int userId) { 6393 enforceNotIsolatedCaller("getIntentSender"); 6394 // Refuse possible leaked file descriptors 6395 if (intents != null) { 6396 if (intents.length < 1) { 6397 throw new IllegalArgumentException("Intents array length must be >= 1"); 6398 } 6399 for (int i=0; i<intents.length; i++) { 6400 Intent intent = intents[i]; 6401 if (intent != null) { 6402 if (intent.hasFileDescriptors()) { 6403 throw new IllegalArgumentException("File descriptors passed in Intent"); 6404 } 6405 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6406 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6407 throw new IllegalArgumentException( 6408 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6409 } 6410 intents[i] = new Intent(intent); 6411 } 6412 } 6413 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6414 throw new IllegalArgumentException( 6415 "Intent array length does not match resolvedTypes length"); 6416 } 6417 } 6418 if (options != null) { 6419 if (options.hasFileDescriptors()) { 6420 throw new IllegalArgumentException("File descriptors passed in options"); 6421 } 6422 } 6423 6424 synchronized(this) { 6425 int callingUid = Binder.getCallingUid(); 6426 int origUserId = userId; 6427 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6428 type == ActivityManager.INTENT_SENDER_BROADCAST, 6429 ALLOW_NON_FULL, "getIntentSender", null); 6430 if (origUserId == UserHandle.USER_CURRENT) { 6431 // We don't want to evaluate this until the pending intent is 6432 // actually executed. However, we do want to always do the 6433 // security checking for it above. 6434 userId = UserHandle.USER_CURRENT; 6435 } 6436 try { 6437 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6438 int uid = AppGlobals.getPackageManager() 6439 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6440 if (!UserHandle.isSameApp(callingUid, uid)) { 6441 String msg = "Permission Denial: getIntentSender() from pid=" 6442 + Binder.getCallingPid() 6443 + ", uid=" + Binder.getCallingUid() 6444 + ", (need uid=" + uid + ")" 6445 + " is not allowed to send as package " + packageName; 6446 Slog.w(TAG, msg); 6447 throw new SecurityException(msg); 6448 } 6449 } 6450 6451 return getIntentSenderLocked(type, packageName, callingUid, userId, 6452 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6453 6454 } catch (RemoteException e) { 6455 throw new SecurityException(e); 6456 } 6457 } 6458 } 6459 6460 IIntentSender getIntentSenderLocked(int type, String packageName, 6461 int callingUid, int userId, IBinder token, String resultWho, 6462 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6463 Bundle options) { 6464 if (DEBUG_MU) 6465 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6466 ActivityRecord activity = null; 6467 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6468 activity = ActivityRecord.isInStackLocked(token); 6469 if (activity == null) { 6470 return null; 6471 } 6472 if (activity.finishing) { 6473 return null; 6474 } 6475 } 6476 6477 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6478 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6479 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6480 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6481 |PendingIntent.FLAG_UPDATE_CURRENT); 6482 6483 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6484 type, packageName, activity, resultWho, 6485 requestCode, intents, resolvedTypes, flags, options, userId); 6486 WeakReference<PendingIntentRecord> ref; 6487 ref = mIntentSenderRecords.get(key); 6488 PendingIntentRecord rec = ref != null ? ref.get() : null; 6489 if (rec != null) { 6490 if (!cancelCurrent) { 6491 if (updateCurrent) { 6492 if (rec.key.requestIntent != null) { 6493 rec.key.requestIntent.replaceExtras(intents != null ? 6494 intents[intents.length - 1] : null); 6495 } 6496 if (intents != null) { 6497 intents[intents.length-1] = rec.key.requestIntent; 6498 rec.key.allIntents = intents; 6499 rec.key.allResolvedTypes = resolvedTypes; 6500 } else { 6501 rec.key.allIntents = null; 6502 rec.key.allResolvedTypes = null; 6503 } 6504 } 6505 return rec; 6506 } 6507 rec.canceled = true; 6508 mIntentSenderRecords.remove(key); 6509 } 6510 if (noCreate) { 6511 return rec; 6512 } 6513 rec = new PendingIntentRecord(this, key, callingUid); 6514 mIntentSenderRecords.put(key, rec.ref); 6515 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6516 if (activity.pendingResults == null) { 6517 activity.pendingResults 6518 = new HashSet<WeakReference<PendingIntentRecord>>(); 6519 } 6520 activity.pendingResults.add(rec.ref); 6521 } 6522 return rec; 6523 } 6524 6525 @Override 6526 public void cancelIntentSender(IIntentSender sender) { 6527 if (!(sender instanceof PendingIntentRecord)) { 6528 return; 6529 } 6530 synchronized(this) { 6531 PendingIntentRecord rec = (PendingIntentRecord)sender; 6532 try { 6533 int uid = AppGlobals.getPackageManager() 6534 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6535 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6536 String msg = "Permission Denial: cancelIntentSender() from pid=" 6537 + Binder.getCallingPid() 6538 + ", uid=" + Binder.getCallingUid() 6539 + " is not allowed to cancel packges " 6540 + rec.key.packageName; 6541 Slog.w(TAG, msg); 6542 throw new SecurityException(msg); 6543 } 6544 } catch (RemoteException e) { 6545 throw new SecurityException(e); 6546 } 6547 cancelIntentSenderLocked(rec, true); 6548 } 6549 } 6550 6551 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6552 rec.canceled = true; 6553 mIntentSenderRecords.remove(rec.key); 6554 if (cleanActivity && rec.key.activity != null) { 6555 rec.key.activity.pendingResults.remove(rec.ref); 6556 } 6557 } 6558 6559 @Override 6560 public String getPackageForIntentSender(IIntentSender pendingResult) { 6561 if (!(pendingResult instanceof PendingIntentRecord)) { 6562 return null; 6563 } 6564 try { 6565 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6566 return res.key.packageName; 6567 } catch (ClassCastException e) { 6568 } 6569 return null; 6570 } 6571 6572 @Override 6573 public int getUidForIntentSender(IIntentSender sender) { 6574 if (sender instanceof PendingIntentRecord) { 6575 try { 6576 PendingIntentRecord res = (PendingIntentRecord)sender; 6577 return res.uid; 6578 } catch (ClassCastException e) { 6579 } 6580 } 6581 return -1; 6582 } 6583 6584 @Override 6585 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6586 if (!(pendingResult instanceof PendingIntentRecord)) { 6587 return false; 6588 } 6589 try { 6590 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6591 if (res.key.allIntents == null) { 6592 return false; 6593 } 6594 for (int i=0; i<res.key.allIntents.length; i++) { 6595 Intent intent = res.key.allIntents[i]; 6596 if (intent.getPackage() != null && intent.getComponent() != null) { 6597 return false; 6598 } 6599 } 6600 return true; 6601 } catch (ClassCastException e) { 6602 } 6603 return false; 6604 } 6605 6606 @Override 6607 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6608 if (!(pendingResult instanceof PendingIntentRecord)) { 6609 return false; 6610 } 6611 try { 6612 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6613 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6614 return true; 6615 } 6616 return false; 6617 } catch (ClassCastException e) { 6618 } 6619 return false; 6620 } 6621 6622 @Override 6623 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6624 if (!(pendingResult instanceof PendingIntentRecord)) { 6625 return null; 6626 } 6627 try { 6628 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6629 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6630 } catch (ClassCastException e) { 6631 } 6632 return null; 6633 } 6634 6635 @Override 6636 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6637 if (!(pendingResult instanceof PendingIntentRecord)) { 6638 return null; 6639 } 6640 try { 6641 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6642 Intent intent = res.key.requestIntent; 6643 if (intent != null) { 6644 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6645 || res.lastTagPrefix.equals(prefix))) { 6646 return res.lastTag; 6647 } 6648 res.lastTagPrefix = prefix; 6649 StringBuilder sb = new StringBuilder(128); 6650 if (prefix != null) { 6651 sb.append(prefix); 6652 } 6653 if (intent.getAction() != null) { 6654 sb.append(intent.getAction()); 6655 } else if (intent.getComponent() != null) { 6656 intent.getComponent().appendShortString(sb); 6657 } else { 6658 sb.append("?"); 6659 } 6660 return res.lastTag = sb.toString(); 6661 } 6662 } catch (ClassCastException e) { 6663 } 6664 return null; 6665 } 6666 6667 @Override 6668 public void setProcessLimit(int max) { 6669 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6670 "setProcessLimit()"); 6671 synchronized (this) { 6672 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6673 mProcessLimitOverride = max; 6674 } 6675 trimApplications(); 6676 } 6677 6678 @Override 6679 public int getProcessLimit() { 6680 synchronized (this) { 6681 return mProcessLimitOverride; 6682 } 6683 } 6684 6685 void foregroundTokenDied(ForegroundToken token) { 6686 synchronized (ActivityManagerService.this) { 6687 synchronized (mPidsSelfLocked) { 6688 ForegroundToken cur 6689 = mForegroundProcesses.get(token.pid); 6690 if (cur != token) { 6691 return; 6692 } 6693 mForegroundProcesses.remove(token.pid); 6694 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6695 if (pr == null) { 6696 return; 6697 } 6698 pr.forcingToForeground = null; 6699 updateProcessForegroundLocked(pr, false, false); 6700 } 6701 updateOomAdjLocked(); 6702 } 6703 } 6704 6705 @Override 6706 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6707 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6708 "setProcessForeground()"); 6709 synchronized(this) { 6710 boolean changed = false; 6711 6712 synchronized (mPidsSelfLocked) { 6713 ProcessRecord pr = mPidsSelfLocked.get(pid); 6714 if (pr == null && isForeground) { 6715 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6716 return; 6717 } 6718 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6719 if (oldToken != null) { 6720 oldToken.token.unlinkToDeath(oldToken, 0); 6721 mForegroundProcesses.remove(pid); 6722 if (pr != null) { 6723 pr.forcingToForeground = null; 6724 } 6725 changed = true; 6726 } 6727 if (isForeground && token != null) { 6728 ForegroundToken newToken = new ForegroundToken() { 6729 @Override 6730 public void binderDied() { 6731 foregroundTokenDied(this); 6732 } 6733 }; 6734 newToken.pid = pid; 6735 newToken.token = token; 6736 try { 6737 token.linkToDeath(newToken, 0); 6738 mForegroundProcesses.put(pid, newToken); 6739 pr.forcingToForeground = token; 6740 changed = true; 6741 } catch (RemoteException e) { 6742 // If the process died while doing this, we will later 6743 // do the cleanup with the process death link. 6744 } 6745 } 6746 } 6747 6748 if (changed) { 6749 updateOomAdjLocked(); 6750 } 6751 } 6752 } 6753 6754 // ========================================================= 6755 // PERMISSIONS 6756 // ========================================================= 6757 6758 static class PermissionController extends IPermissionController.Stub { 6759 ActivityManagerService mActivityManagerService; 6760 PermissionController(ActivityManagerService activityManagerService) { 6761 mActivityManagerService = activityManagerService; 6762 } 6763 6764 @Override 6765 public boolean checkPermission(String permission, int pid, int uid) { 6766 return mActivityManagerService.checkPermission(permission, pid, 6767 uid) == PackageManager.PERMISSION_GRANTED; 6768 } 6769 } 6770 6771 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6772 @Override 6773 public int checkComponentPermission(String permission, int pid, int uid, 6774 int owningUid, boolean exported) { 6775 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6776 owningUid, exported); 6777 } 6778 6779 @Override 6780 public Object getAMSLock() { 6781 return ActivityManagerService.this; 6782 } 6783 } 6784 6785 /** 6786 * This can be called with or without the global lock held. 6787 */ 6788 int checkComponentPermission(String permission, int pid, int uid, 6789 int owningUid, boolean exported) { 6790 if (pid == MY_PID) { 6791 return PackageManager.PERMISSION_GRANTED; 6792 } 6793 return ActivityManager.checkComponentPermission(permission, uid, 6794 owningUid, exported); 6795 } 6796 6797 /** 6798 * As the only public entry point for permissions checking, this method 6799 * can enforce the semantic that requesting a check on a null global 6800 * permission is automatically denied. (Internally a null permission 6801 * string is used when calling {@link #checkComponentPermission} in cases 6802 * when only uid-based security is needed.) 6803 * 6804 * This can be called with or without the global lock held. 6805 */ 6806 @Override 6807 public int checkPermission(String permission, int pid, int uid) { 6808 if (permission == null) { 6809 return PackageManager.PERMISSION_DENIED; 6810 } 6811 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6812 } 6813 6814 @Override 6815 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6816 if (permission == null) { 6817 return PackageManager.PERMISSION_DENIED; 6818 } 6819 6820 // We might be performing an operation on behalf of an indirect binder 6821 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6822 // client identity accordingly before proceeding. 6823 Identity tlsIdentity = sCallerIdentity.get(); 6824 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6825 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6826 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6827 uid = tlsIdentity.uid; 6828 pid = tlsIdentity.pid; 6829 } 6830 6831 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6832 } 6833 6834 /** 6835 * Binder IPC calls go through the public entry point. 6836 * This can be called with or without the global lock held. 6837 */ 6838 int checkCallingPermission(String permission) { 6839 return checkPermission(permission, 6840 Binder.getCallingPid(), 6841 UserHandle.getAppId(Binder.getCallingUid())); 6842 } 6843 6844 /** 6845 * This can be called with or without the global lock held. 6846 */ 6847 void enforceCallingPermission(String permission, String func) { 6848 if (checkCallingPermission(permission) 6849 == PackageManager.PERMISSION_GRANTED) { 6850 return; 6851 } 6852 6853 String msg = "Permission Denial: " + func + " from pid=" 6854 + Binder.getCallingPid() 6855 + ", uid=" + Binder.getCallingUid() 6856 + " requires " + permission; 6857 Slog.w(TAG, msg); 6858 throw new SecurityException(msg); 6859 } 6860 6861 /** 6862 * Determine if UID is holding permissions required to access {@link Uri} in 6863 * the given {@link ProviderInfo}. Final permission checking is always done 6864 * in {@link ContentProvider}. 6865 */ 6866 private final boolean checkHoldingPermissionsLocked( 6867 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6868 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6869 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6870 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6871 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6872 != PERMISSION_GRANTED) { 6873 return false; 6874 } 6875 } 6876 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6877 } 6878 6879 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6880 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6881 if (pi.applicationInfo.uid == uid) { 6882 return true; 6883 } else if (!pi.exported) { 6884 return false; 6885 } 6886 6887 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6888 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6889 try { 6890 // check if target holds top-level <provider> permissions 6891 if (!readMet && pi.readPermission != null && considerUidPermissions 6892 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6893 readMet = true; 6894 } 6895 if (!writeMet && pi.writePermission != null && considerUidPermissions 6896 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6897 writeMet = true; 6898 } 6899 6900 // track if unprotected read/write is allowed; any denied 6901 // <path-permission> below removes this ability 6902 boolean allowDefaultRead = pi.readPermission == null; 6903 boolean allowDefaultWrite = pi.writePermission == null; 6904 6905 // check if target holds any <path-permission> that match uri 6906 final PathPermission[] pps = pi.pathPermissions; 6907 if (pps != null) { 6908 final String path = grantUri.uri.getPath(); 6909 int i = pps.length; 6910 while (i > 0 && (!readMet || !writeMet)) { 6911 i--; 6912 PathPermission pp = pps[i]; 6913 if (pp.match(path)) { 6914 if (!readMet) { 6915 final String pprperm = pp.getReadPermission(); 6916 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6917 + pprperm + " for " + pp.getPath() 6918 + ": match=" + pp.match(path) 6919 + " check=" + pm.checkUidPermission(pprperm, uid)); 6920 if (pprperm != null) { 6921 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6922 == PERMISSION_GRANTED) { 6923 readMet = true; 6924 } else { 6925 allowDefaultRead = false; 6926 } 6927 } 6928 } 6929 if (!writeMet) { 6930 final String ppwperm = pp.getWritePermission(); 6931 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6932 + ppwperm + " for " + pp.getPath() 6933 + ": match=" + pp.match(path) 6934 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6935 if (ppwperm != null) { 6936 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6937 == PERMISSION_GRANTED) { 6938 writeMet = true; 6939 } else { 6940 allowDefaultWrite = false; 6941 } 6942 } 6943 } 6944 } 6945 } 6946 } 6947 6948 // grant unprotected <provider> read/write, if not blocked by 6949 // <path-permission> above 6950 if (allowDefaultRead) readMet = true; 6951 if (allowDefaultWrite) writeMet = true; 6952 6953 } catch (RemoteException e) { 6954 return false; 6955 } 6956 6957 return readMet && writeMet; 6958 } 6959 6960 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6961 ProviderInfo pi = null; 6962 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6963 if (cpr != null) { 6964 pi = cpr.info; 6965 } else { 6966 try { 6967 pi = AppGlobals.getPackageManager().resolveContentProvider( 6968 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6969 } catch (RemoteException ex) { 6970 } 6971 } 6972 return pi; 6973 } 6974 6975 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6976 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6977 if (targetUris != null) { 6978 return targetUris.get(grantUri); 6979 } 6980 return null; 6981 } 6982 6983 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6984 String targetPkg, int targetUid, GrantUri grantUri) { 6985 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6986 if (targetUris == null) { 6987 targetUris = Maps.newArrayMap(); 6988 mGrantedUriPermissions.put(targetUid, targetUris); 6989 } 6990 6991 UriPermission perm = targetUris.get(grantUri); 6992 if (perm == null) { 6993 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6994 targetUris.put(grantUri, perm); 6995 } 6996 6997 return perm; 6998 } 6999 7000 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7001 final int modeFlags) { 7002 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7003 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7004 : UriPermission.STRENGTH_OWNED; 7005 7006 // Root gets to do everything. 7007 if (uid == 0) { 7008 return true; 7009 } 7010 7011 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7012 if (perms == null) return false; 7013 7014 // First look for exact match 7015 final UriPermission exactPerm = perms.get(grantUri); 7016 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7017 return true; 7018 } 7019 7020 // No exact match, look for prefixes 7021 final int N = perms.size(); 7022 for (int i = 0; i < N; i++) { 7023 final UriPermission perm = perms.valueAt(i); 7024 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7025 && perm.getStrength(modeFlags) >= minStrength) { 7026 return true; 7027 } 7028 } 7029 7030 return false; 7031 } 7032 7033 /** 7034 * @param uri This uri must NOT contain an embedded userId. 7035 * @param userId The userId in which the uri is to be resolved. 7036 */ 7037 @Override 7038 public int checkUriPermission(Uri uri, int pid, int uid, 7039 final int modeFlags, int userId, IBinder callerToken) { 7040 enforceNotIsolatedCaller("checkUriPermission"); 7041 7042 // Another redirected-binder-call permissions check as in 7043 // {@link checkPermissionWithToken}. 7044 Identity tlsIdentity = sCallerIdentity.get(); 7045 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7046 uid = tlsIdentity.uid; 7047 pid = tlsIdentity.pid; 7048 } 7049 7050 // Our own process gets to do everything. 7051 if (pid == MY_PID) { 7052 return PackageManager.PERMISSION_GRANTED; 7053 } 7054 synchronized (this) { 7055 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7056 ? PackageManager.PERMISSION_GRANTED 7057 : PackageManager.PERMISSION_DENIED; 7058 } 7059 } 7060 7061 /** 7062 * Check if the targetPkg can be granted permission to access uri by 7063 * the callingUid using the given modeFlags. Throws a security exception 7064 * if callingUid is not allowed to do this. Returns the uid of the target 7065 * if the URI permission grant should be performed; returns -1 if it is not 7066 * needed (for example targetPkg already has permission to access the URI). 7067 * If you already know the uid of the target, you can supply it in 7068 * lastTargetUid else set that to -1. 7069 */ 7070 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7071 final int modeFlags, int lastTargetUid) { 7072 if (!Intent.isAccessUriMode(modeFlags)) { 7073 return -1; 7074 } 7075 7076 if (targetPkg != null) { 7077 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7078 "Checking grant " + targetPkg + " permission to " + grantUri); 7079 } 7080 7081 final IPackageManager pm = AppGlobals.getPackageManager(); 7082 7083 // If this is not a content: uri, we can't do anything with it. 7084 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7085 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7086 "Can't grant URI permission for non-content URI: " + grantUri); 7087 return -1; 7088 } 7089 7090 final String authority = grantUri.uri.getAuthority(); 7091 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7092 if (pi == null) { 7093 Slog.w(TAG, "No content provider found for permission check: " + 7094 grantUri.uri.toSafeString()); 7095 return -1; 7096 } 7097 7098 int targetUid = lastTargetUid; 7099 if (targetUid < 0 && targetPkg != null) { 7100 try { 7101 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7102 if (targetUid < 0) { 7103 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7104 "Can't grant URI permission no uid for: " + targetPkg); 7105 return -1; 7106 } 7107 } catch (RemoteException ex) { 7108 return -1; 7109 } 7110 } 7111 7112 if (targetUid >= 0) { 7113 // First... does the target actually need this permission? 7114 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7115 // No need to grant the target this permission. 7116 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7117 "Target " + targetPkg + " already has full permission to " + grantUri); 7118 return -1; 7119 } 7120 } else { 7121 // First... there is no target package, so can anyone access it? 7122 boolean allowed = pi.exported; 7123 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7124 if (pi.readPermission != null) { 7125 allowed = false; 7126 } 7127 } 7128 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7129 if (pi.writePermission != null) { 7130 allowed = false; 7131 } 7132 } 7133 if (allowed) { 7134 return -1; 7135 } 7136 } 7137 7138 /* There is a special cross user grant if: 7139 * - The target is on another user. 7140 * - Apps on the current user can access the uri without any uid permissions. 7141 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7142 * grant uri permissions. 7143 */ 7144 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7145 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7146 modeFlags, false /*without considering the uid permissions*/); 7147 7148 // Second... is the provider allowing granting of URI permissions? 7149 if (!specialCrossUserGrant) { 7150 if (!pi.grantUriPermissions) { 7151 throw new SecurityException("Provider " + pi.packageName 7152 + "/" + pi.name 7153 + " does not allow granting of Uri permissions (uri " 7154 + grantUri + ")"); 7155 } 7156 if (pi.uriPermissionPatterns != null) { 7157 final int N = pi.uriPermissionPatterns.length; 7158 boolean allowed = false; 7159 for (int i=0; i<N; i++) { 7160 if (pi.uriPermissionPatterns[i] != null 7161 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7162 allowed = true; 7163 break; 7164 } 7165 } 7166 if (!allowed) { 7167 throw new SecurityException("Provider " + pi.packageName 7168 + "/" + pi.name 7169 + " does not allow granting of permission to path of Uri " 7170 + grantUri); 7171 } 7172 } 7173 } 7174 7175 // Third... does the caller itself have permission to access 7176 // this uri? 7177 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7178 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7179 // Require they hold a strong enough Uri permission 7180 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7181 throw new SecurityException("Uid " + callingUid 7182 + " does not have permission to uri " + grantUri); 7183 } 7184 } 7185 } 7186 return targetUid; 7187 } 7188 7189 /** 7190 * @param uri This uri must NOT contain an embedded userId. 7191 * @param userId The userId in which the uri is to be resolved. 7192 */ 7193 @Override 7194 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7195 final int modeFlags, int userId) { 7196 enforceNotIsolatedCaller("checkGrantUriPermission"); 7197 synchronized(this) { 7198 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7199 new GrantUri(userId, uri, false), modeFlags, -1); 7200 } 7201 } 7202 7203 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7204 final int modeFlags, UriPermissionOwner owner) { 7205 if (!Intent.isAccessUriMode(modeFlags)) { 7206 return; 7207 } 7208 7209 // So here we are: the caller has the assumed permission 7210 // to the uri, and the target doesn't. Let's now give this to 7211 // the target. 7212 7213 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7214 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7215 7216 final String authority = grantUri.uri.getAuthority(); 7217 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7218 if (pi == null) { 7219 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7220 return; 7221 } 7222 7223 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7224 grantUri.prefix = true; 7225 } 7226 final UriPermission perm = findOrCreateUriPermissionLocked( 7227 pi.packageName, targetPkg, targetUid, grantUri); 7228 perm.grantModes(modeFlags, owner); 7229 } 7230 7231 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7232 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7233 if (targetPkg == null) { 7234 throw new NullPointerException("targetPkg"); 7235 } 7236 int targetUid; 7237 final IPackageManager pm = AppGlobals.getPackageManager(); 7238 try { 7239 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7240 } catch (RemoteException ex) { 7241 return; 7242 } 7243 7244 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7245 targetUid); 7246 if (targetUid < 0) { 7247 return; 7248 } 7249 7250 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7251 owner); 7252 } 7253 7254 static class NeededUriGrants extends ArrayList<GrantUri> { 7255 final String targetPkg; 7256 final int targetUid; 7257 final int flags; 7258 7259 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7260 this.targetPkg = targetPkg; 7261 this.targetUid = targetUid; 7262 this.flags = flags; 7263 } 7264 } 7265 7266 /** 7267 * Like checkGrantUriPermissionLocked, but takes an Intent. 7268 */ 7269 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7270 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7271 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7272 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7273 + " clip=" + (intent != null ? intent.getClipData() : null) 7274 + " from " + intent + "; flags=0x" 7275 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7276 7277 if (targetPkg == null) { 7278 throw new NullPointerException("targetPkg"); 7279 } 7280 7281 if (intent == null) { 7282 return null; 7283 } 7284 Uri data = intent.getData(); 7285 ClipData clip = intent.getClipData(); 7286 if (data == null && clip == null) { 7287 return null; 7288 } 7289 // Default userId for uris in the intent (if they don't specify it themselves) 7290 int contentUserHint = intent.getContentUserHint(); 7291 if (contentUserHint == UserHandle.USER_CURRENT) { 7292 contentUserHint = UserHandle.getUserId(callingUid); 7293 } 7294 final IPackageManager pm = AppGlobals.getPackageManager(); 7295 int targetUid; 7296 if (needed != null) { 7297 targetUid = needed.targetUid; 7298 } else { 7299 try { 7300 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7301 } catch (RemoteException ex) { 7302 return null; 7303 } 7304 if (targetUid < 0) { 7305 if (DEBUG_URI_PERMISSION) { 7306 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7307 + " on user " + targetUserId); 7308 } 7309 return null; 7310 } 7311 } 7312 if (data != null) { 7313 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7314 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7315 targetUid); 7316 if (targetUid > 0) { 7317 if (needed == null) { 7318 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7319 } 7320 needed.add(grantUri); 7321 } 7322 } 7323 if (clip != null) { 7324 for (int i=0; i<clip.getItemCount(); i++) { 7325 Uri uri = clip.getItemAt(i).getUri(); 7326 if (uri != null) { 7327 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7328 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7329 targetUid); 7330 if (targetUid > 0) { 7331 if (needed == null) { 7332 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7333 } 7334 needed.add(grantUri); 7335 } 7336 } else { 7337 Intent clipIntent = clip.getItemAt(i).getIntent(); 7338 if (clipIntent != null) { 7339 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7340 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7341 if (newNeeded != null) { 7342 needed = newNeeded; 7343 } 7344 } 7345 } 7346 } 7347 } 7348 7349 return needed; 7350 } 7351 7352 /** 7353 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7354 */ 7355 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7356 UriPermissionOwner owner) { 7357 if (needed != null) { 7358 for (int i=0; i<needed.size(); i++) { 7359 GrantUri grantUri = needed.get(i); 7360 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7361 grantUri, needed.flags, owner); 7362 } 7363 } 7364 } 7365 7366 void grantUriPermissionFromIntentLocked(int callingUid, 7367 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7368 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7369 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7370 if (needed == null) { 7371 return; 7372 } 7373 7374 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7375 } 7376 7377 /** 7378 * @param uri This uri must NOT contain an embedded userId. 7379 * @param userId The userId in which the uri is to be resolved. 7380 */ 7381 @Override 7382 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7383 final int modeFlags, int userId) { 7384 enforceNotIsolatedCaller("grantUriPermission"); 7385 GrantUri grantUri = new GrantUri(userId, uri, false); 7386 synchronized(this) { 7387 final ProcessRecord r = getRecordForAppLocked(caller); 7388 if (r == null) { 7389 throw new SecurityException("Unable to find app for caller " 7390 + caller 7391 + " when granting permission to uri " + grantUri); 7392 } 7393 if (targetPkg == null) { 7394 throw new IllegalArgumentException("null target"); 7395 } 7396 if (grantUri == null) { 7397 throw new IllegalArgumentException("null uri"); 7398 } 7399 7400 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7401 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7402 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7403 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7404 7405 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7406 UserHandle.getUserId(r.uid)); 7407 } 7408 } 7409 7410 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7411 if (perm.modeFlags == 0) { 7412 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7413 perm.targetUid); 7414 if (perms != null) { 7415 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7416 "Removing " + perm.targetUid + " permission to " + perm.uri); 7417 7418 perms.remove(perm.uri); 7419 if (perms.isEmpty()) { 7420 mGrantedUriPermissions.remove(perm.targetUid); 7421 } 7422 } 7423 } 7424 } 7425 7426 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7427 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7428 7429 final IPackageManager pm = AppGlobals.getPackageManager(); 7430 final String authority = grantUri.uri.getAuthority(); 7431 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7432 if (pi == null) { 7433 Slog.w(TAG, "No content provider found for permission revoke: " 7434 + grantUri.toSafeString()); 7435 return; 7436 } 7437 7438 // Does the caller have this permission on the URI? 7439 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7440 // If they don't have direct access to the URI, then revoke any 7441 // ownerless URI permissions that have been granted to them. 7442 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7443 if (perms != null) { 7444 boolean persistChanged = false; 7445 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7446 final UriPermission perm = it.next(); 7447 if (perm.uri.sourceUserId == grantUri.sourceUserId 7448 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7449 if (DEBUG_URI_PERMISSION) 7450 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7451 " permission to " + perm.uri); 7452 persistChanged |= perm.revokeModes( 7453 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7454 if (perm.modeFlags == 0) { 7455 it.remove(); 7456 } 7457 } 7458 } 7459 if (perms.isEmpty()) { 7460 mGrantedUriPermissions.remove(callingUid); 7461 } 7462 if (persistChanged) { 7463 schedulePersistUriGrants(); 7464 } 7465 } 7466 return; 7467 } 7468 7469 boolean persistChanged = false; 7470 7471 // Go through all of the permissions and remove any that match. 7472 int N = mGrantedUriPermissions.size(); 7473 for (int i = 0; i < N; i++) { 7474 final int targetUid = mGrantedUriPermissions.keyAt(i); 7475 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7476 7477 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7478 final UriPermission perm = it.next(); 7479 if (perm.uri.sourceUserId == grantUri.sourceUserId 7480 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7481 if (DEBUG_URI_PERMISSION) 7482 Slog.v(TAG, 7483 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7484 persistChanged |= perm.revokeModes( 7485 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7486 if (perm.modeFlags == 0) { 7487 it.remove(); 7488 } 7489 } 7490 } 7491 7492 if (perms.isEmpty()) { 7493 mGrantedUriPermissions.remove(targetUid); 7494 N--; 7495 i--; 7496 } 7497 } 7498 7499 if (persistChanged) { 7500 schedulePersistUriGrants(); 7501 } 7502 } 7503 7504 /** 7505 * @param uri This uri must NOT contain an embedded userId. 7506 * @param userId The userId in which the uri is to be resolved. 7507 */ 7508 @Override 7509 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7510 int userId) { 7511 enforceNotIsolatedCaller("revokeUriPermission"); 7512 synchronized(this) { 7513 final ProcessRecord r = getRecordForAppLocked(caller); 7514 if (r == null) { 7515 throw new SecurityException("Unable to find app for caller " 7516 + caller 7517 + " when revoking permission to uri " + uri); 7518 } 7519 if (uri == null) { 7520 Slog.w(TAG, "revokeUriPermission: null uri"); 7521 return; 7522 } 7523 7524 if (!Intent.isAccessUriMode(modeFlags)) { 7525 return; 7526 } 7527 7528 final IPackageManager pm = AppGlobals.getPackageManager(); 7529 final String authority = uri.getAuthority(); 7530 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7531 if (pi == null) { 7532 Slog.w(TAG, "No content provider found for permission revoke: " 7533 + uri.toSafeString()); 7534 return; 7535 } 7536 7537 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7538 } 7539 } 7540 7541 /** 7542 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7543 * given package. 7544 * 7545 * @param packageName Package name to match, or {@code null} to apply to all 7546 * packages. 7547 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7548 * to all users. 7549 * @param persistable If persistable grants should be removed. 7550 */ 7551 private void removeUriPermissionsForPackageLocked( 7552 String packageName, int userHandle, boolean persistable) { 7553 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7554 throw new IllegalArgumentException("Must narrow by either package or user"); 7555 } 7556 7557 boolean persistChanged = false; 7558 7559 int N = mGrantedUriPermissions.size(); 7560 for (int i = 0; i < N; i++) { 7561 final int targetUid = mGrantedUriPermissions.keyAt(i); 7562 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7563 7564 // Only inspect grants matching user 7565 if (userHandle == UserHandle.USER_ALL 7566 || userHandle == UserHandle.getUserId(targetUid)) { 7567 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7568 final UriPermission perm = it.next(); 7569 7570 // Only inspect grants matching package 7571 if (packageName == null || perm.sourcePkg.equals(packageName) 7572 || perm.targetPkg.equals(packageName)) { 7573 persistChanged |= perm.revokeModes(persistable 7574 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7575 7576 // Only remove when no modes remain; any persisted grants 7577 // will keep this alive. 7578 if (perm.modeFlags == 0) { 7579 it.remove(); 7580 } 7581 } 7582 } 7583 7584 if (perms.isEmpty()) { 7585 mGrantedUriPermissions.remove(targetUid); 7586 N--; 7587 i--; 7588 } 7589 } 7590 } 7591 7592 if (persistChanged) { 7593 schedulePersistUriGrants(); 7594 } 7595 } 7596 7597 @Override 7598 public IBinder newUriPermissionOwner(String name) { 7599 enforceNotIsolatedCaller("newUriPermissionOwner"); 7600 synchronized(this) { 7601 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7602 return owner.getExternalTokenLocked(); 7603 } 7604 } 7605 7606 /** 7607 * @param uri This uri must NOT contain an embedded userId. 7608 * @param sourceUserId The userId in which the uri is to be resolved. 7609 * @param targetUserId The userId of the app that receives the grant. 7610 */ 7611 @Override 7612 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7613 final int modeFlags, int sourceUserId, int targetUserId) { 7614 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7615 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7616 synchronized(this) { 7617 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7618 if (owner == null) { 7619 throw new IllegalArgumentException("Unknown owner: " + token); 7620 } 7621 if (fromUid != Binder.getCallingUid()) { 7622 if (Binder.getCallingUid() != Process.myUid()) { 7623 // Only system code can grant URI permissions on behalf 7624 // of other users. 7625 throw new SecurityException("nice try"); 7626 } 7627 } 7628 if (targetPkg == null) { 7629 throw new IllegalArgumentException("null target"); 7630 } 7631 if (uri == null) { 7632 throw new IllegalArgumentException("null uri"); 7633 } 7634 7635 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7636 modeFlags, owner, targetUserId); 7637 } 7638 } 7639 7640 /** 7641 * @param uri This uri must NOT contain an embedded userId. 7642 * @param userId The userId in which the uri is to be resolved. 7643 */ 7644 @Override 7645 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7646 synchronized(this) { 7647 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7648 if (owner == null) { 7649 throw new IllegalArgumentException("Unknown owner: " + token); 7650 } 7651 7652 if (uri == null) { 7653 owner.removeUriPermissionsLocked(mode); 7654 } else { 7655 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7656 } 7657 } 7658 } 7659 7660 private void schedulePersistUriGrants() { 7661 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7662 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7663 10 * DateUtils.SECOND_IN_MILLIS); 7664 } 7665 } 7666 7667 private void writeGrantedUriPermissions() { 7668 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7669 7670 // Snapshot permissions so we can persist without lock 7671 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7672 synchronized (this) { 7673 final int size = mGrantedUriPermissions.size(); 7674 for (int i = 0; i < size; i++) { 7675 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7676 for (UriPermission perm : perms.values()) { 7677 if (perm.persistedModeFlags != 0) { 7678 persist.add(perm.snapshot()); 7679 } 7680 } 7681 } 7682 } 7683 7684 FileOutputStream fos = null; 7685 try { 7686 fos = mGrantFile.startWrite(); 7687 7688 XmlSerializer out = new FastXmlSerializer(); 7689 out.setOutput(fos, "utf-8"); 7690 out.startDocument(null, true); 7691 out.startTag(null, TAG_URI_GRANTS); 7692 for (UriPermission.Snapshot perm : persist) { 7693 out.startTag(null, TAG_URI_GRANT); 7694 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7695 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7696 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7697 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7698 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7699 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7700 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7701 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7702 out.endTag(null, TAG_URI_GRANT); 7703 } 7704 out.endTag(null, TAG_URI_GRANTS); 7705 out.endDocument(); 7706 7707 mGrantFile.finishWrite(fos); 7708 } catch (IOException e) { 7709 if (fos != null) { 7710 mGrantFile.failWrite(fos); 7711 } 7712 } 7713 } 7714 7715 private void readGrantedUriPermissionsLocked() { 7716 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7717 7718 final long now = System.currentTimeMillis(); 7719 7720 FileInputStream fis = null; 7721 try { 7722 fis = mGrantFile.openRead(); 7723 final XmlPullParser in = Xml.newPullParser(); 7724 in.setInput(fis, null); 7725 7726 int type; 7727 while ((type = in.next()) != END_DOCUMENT) { 7728 final String tag = in.getName(); 7729 if (type == START_TAG) { 7730 if (TAG_URI_GRANT.equals(tag)) { 7731 final int sourceUserId; 7732 final int targetUserId; 7733 final int userHandle = readIntAttribute(in, 7734 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7735 if (userHandle != UserHandle.USER_NULL) { 7736 // For backwards compatibility. 7737 sourceUserId = userHandle; 7738 targetUserId = userHandle; 7739 } else { 7740 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7741 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7742 } 7743 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7744 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7745 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7746 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7747 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7748 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7749 7750 // Sanity check that provider still belongs to source package 7751 final ProviderInfo pi = getProviderInfoLocked( 7752 uri.getAuthority(), sourceUserId); 7753 if (pi != null && sourcePkg.equals(pi.packageName)) { 7754 int targetUid = -1; 7755 try { 7756 targetUid = AppGlobals.getPackageManager() 7757 .getPackageUid(targetPkg, targetUserId); 7758 } catch (RemoteException e) { 7759 } 7760 if (targetUid != -1) { 7761 final UriPermission perm = findOrCreateUriPermissionLocked( 7762 sourcePkg, targetPkg, targetUid, 7763 new GrantUri(sourceUserId, uri, prefix)); 7764 perm.initPersistedModes(modeFlags, createdTime); 7765 } 7766 } else { 7767 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7768 + " but instead found " + pi); 7769 } 7770 } 7771 } 7772 } 7773 } catch (FileNotFoundException e) { 7774 // Missing grants is okay 7775 } catch (IOException e) { 7776 Slog.wtf(TAG, "Failed reading Uri grants", e); 7777 } catch (XmlPullParserException e) { 7778 Slog.wtf(TAG, "Failed reading Uri grants", e); 7779 } finally { 7780 IoUtils.closeQuietly(fis); 7781 } 7782 } 7783 7784 /** 7785 * @param uri This uri must NOT contain an embedded userId. 7786 * @param userId The userId in which the uri is to be resolved. 7787 */ 7788 @Override 7789 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7790 enforceNotIsolatedCaller("takePersistableUriPermission"); 7791 7792 Preconditions.checkFlagsArgument(modeFlags, 7793 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7794 7795 synchronized (this) { 7796 final int callingUid = Binder.getCallingUid(); 7797 boolean persistChanged = false; 7798 GrantUri grantUri = new GrantUri(userId, uri, false); 7799 7800 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7801 new GrantUri(userId, uri, false)); 7802 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7803 new GrantUri(userId, uri, true)); 7804 7805 final boolean exactValid = (exactPerm != null) 7806 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7807 final boolean prefixValid = (prefixPerm != null) 7808 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7809 7810 if (!(exactValid || prefixValid)) { 7811 throw new SecurityException("No persistable permission grants found for UID " 7812 + callingUid + " and Uri " + grantUri.toSafeString()); 7813 } 7814 7815 if (exactValid) { 7816 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7817 } 7818 if (prefixValid) { 7819 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7820 } 7821 7822 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7823 7824 if (persistChanged) { 7825 schedulePersistUriGrants(); 7826 } 7827 } 7828 } 7829 7830 /** 7831 * @param uri This uri must NOT contain an embedded userId. 7832 * @param userId The userId in which the uri is to be resolved. 7833 */ 7834 @Override 7835 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7836 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7837 7838 Preconditions.checkFlagsArgument(modeFlags, 7839 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7840 7841 synchronized (this) { 7842 final int callingUid = Binder.getCallingUid(); 7843 boolean persistChanged = false; 7844 7845 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7846 new GrantUri(userId, uri, false)); 7847 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7848 new GrantUri(userId, uri, true)); 7849 if (exactPerm == null && prefixPerm == null) { 7850 throw new SecurityException("No permission grants found for UID " + callingUid 7851 + " and Uri " + uri.toSafeString()); 7852 } 7853 7854 if (exactPerm != null) { 7855 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7856 removeUriPermissionIfNeededLocked(exactPerm); 7857 } 7858 if (prefixPerm != null) { 7859 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7860 removeUriPermissionIfNeededLocked(prefixPerm); 7861 } 7862 7863 if (persistChanged) { 7864 schedulePersistUriGrants(); 7865 } 7866 } 7867 } 7868 7869 /** 7870 * Prune any older {@link UriPermission} for the given UID until outstanding 7871 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7872 * 7873 * @return if any mutations occured that require persisting. 7874 */ 7875 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7876 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7877 if (perms == null) return false; 7878 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7879 7880 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7881 for (UriPermission perm : perms.values()) { 7882 if (perm.persistedModeFlags != 0) { 7883 persisted.add(perm); 7884 } 7885 } 7886 7887 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7888 if (trimCount <= 0) return false; 7889 7890 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7891 for (int i = 0; i < trimCount; i++) { 7892 final UriPermission perm = persisted.get(i); 7893 7894 if (DEBUG_URI_PERMISSION) { 7895 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7896 } 7897 7898 perm.releasePersistableModes(~0); 7899 removeUriPermissionIfNeededLocked(perm); 7900 } 7901 7902 return true; 7903 } 7904 7905 @Override 7906 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7907 String packageName, boolean incoming) { 7908 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7909 Preconditions.checkNotNull(packageName, "packageName"); 7910 7911 final int callingUid = Binder.getCallingUid(); 7912 final IPackageManager pm = AppGlobals.getPackageManager(); 7913 try { 7914 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7915 if (packageUid != callingUid) { 7916 throw new SecurityException( 7917 "Package " + packageName + " does not belong to calling UID " + callingUid); 7918 } 7919 } catch (RemoteException e) { 7920 throw new SecurityException("Failed to verify package name ownership"); 7921 } 7922 7923 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7924 synchronized (this) { 7925 if (incoming) { 7926 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7927 callingUid); 7928 if (perms == null) { 7929 Slog.w(TAG, "No permission grants found for " + packageName); 7930 } else { 7931 for (UriPermission perm : perms.values()) { 7932 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7933 result.add(perm.buildPersistedPublicApiObject()); 7934 } 7935 } 7936 } 7937 } else { 7938 final int size = mGrantedUriPermissions.size(); 7939 for (int i = 0; i < size; i++) { 7940 final ArrayMap<GrantUri, UriPermission> perms = 7941 mGrantedUriPermissions.valueAt(i); 7942 for (UriPermission perm : perms.values()) { 7943 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7944 result.add(perm.buildPersistedPublicApiObject()); 7945 } 7946 } 7947 } 7948 } 7949 } 7950 return new ParceledListSlice<android.content.UriPermission>(result); 7951 } 7952 7953 @Override 7954 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7955 synchronized (this) { 7956 ProcessRecord app = 7957 who != null ? getRecordForAppLocked(who) : null; 7958 if (app == null) return; 7959 7960 Message msg = Message.obtain(); 7961 msg.what = WAIT_FOR_DEBUGGER_MSG; 7962 msg.obj = app; 7963 msg.arg1 = waiting ? 1 : 0; 7964 mHandler.sendMessage(msg); 7965 } 7966 } 7967 7968 @Override 7969 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7970 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7971 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7972 outInfo.availMem = Process.getFreeMemory(); 7973 outInfo.totalMem = Process.getTotalMemory(); 7974 outInfo.threshold = homeAppMem; 7975 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7976 outInfo.hiddenAppThreshold = cachedAppMem; 7977 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7978 ProcessList.SERVICE_ADJ); 7979 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7980 ProcessList.VISIBLE_APP_ADJ); 7981 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7982 ProcessList.FOREGROUND_APP_ADJ); 7983 } 7984 7985 // ========================================================= 7986 // TASK MANAGEMENT 7987 // ========================================================= 7988 7989 @Override 7990 public List<IAppTask> getAppTasks(String callingPackage) { 7991 int callingUid = Binder.getCallingUid(); 7992 long ident = Binder.clearCallingIdentity(); 7993 7994 synchronized(this) { 7995 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7996 try { 7997 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7998 7999 final int N = mRecentTasks.size(); 8000 for (int i = 0; i < N; i++) { 8001 TaskRecord tr = mRecentTasks.get(i); 8002 // Skip tasks that do not match the caller. We don't need to verify 8003 // callingPackage, because we are also limiting to callingUid and know 8004 // that will limit to the correct security sandbox. 8005 if (tr.effectiveUid != callingUid) { 8006 continue; 8007 } 8008 Intent intent = tr.getBaseIntent(); 8009 if (intent == null || 8010 !callingPackage.equals(intent.getComponent().getPackageName())) { 8011 continue; 8012 } 8013 ActivityManager.RecentTaskInfo taskInfo = 8014 createRecentTaskInfoFromTaskRecord(tr); 8015 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8016 list.add(taskImpl); 8017 } 8018 } finally { 8019 Binder.restoreCallingIdentity(ident); 8020 } 8021 return list; 8022 } 8023 } 8024 8025 @Override 8026 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8027 final int callingUid = Binder.getCallingUid(); 8028 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8029 8030 synchronized(this) { 8031 if (localLOGV) Slog.v( 8032 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8033 8034 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8035 callingUid); 8036 8037 // TODO: Improve with MRU list from all ActivityStacks. 8038 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8039 } 8040 8041 return list; 8042 } 8043 8044 /** 8045 * Creates a new RecentTaskInfo from a TaskRecord. 8046 */ 8047 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8048 // Update the task description to reflect any changes in the task stack 8049 tr.updateTaskDescription(); 8050 8051 // Compose the recent task info 8052 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8053 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8054 rti.persistentId = tr.taskId; 8055 rti.baseIntent = new Intent(tr.getBaseIntent()); 8056 rti.origActivity = tr.origActivity; 8057 rti.description = tr.lastDescription; 8058 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8059 rti.userId = tr.userId; 8060 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8061 rti.firstActiveTime = tr.firstActiveTime; 8062 rti.lastActiveTime = tr.lastActiveTime; 8063 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8064 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8065 return rti; 8066 } 8067 8068 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8069 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8070 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8071 if (!allowed) { 8072 if (checkPermission(android.Manifest.permission.GET_TASKS, 8073 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8074 // Temporary compatibility: some existing apps on the system image may 8075 // still be requesting the old permission and not switched to the new 8076 // one; if so, we'll still allow them full access. This means we need 8077 // to see if they are holding the old permission and are a system app. 8078 try { 8079 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8080 allowed = true; 8081 Slog.w(TAG, caller + ": caller " + callingUid 8082 + " is using old GET_TASKS but privileged; allowing"); 8083 } 8084 } catch (RemoteException e) { 8085 } 8086 } 8087 } 8088 if (!allowed) { 8089 Slog.w(TAG, caller + ": caller " + callingUid 8090 + " does not hold GET_TASKS; limiting output"); 8091 } 8092 return allowed; 8093 } 8094 8095 @Override 8096 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8097 final int callingUid = Binder.getCallingUid(); 8098 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8099 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8100 8101 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8102 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8103 synchronized (this) { 8104 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8105 callingUid); 8106 final boolean detailed = checkCallingPermission( 8107 android.Manifest.permission.GET_DETAILED_TASKS) 8108 == PackageManager.PERMISSION_GRANTED; 8109 8110 final int N = mRecentTasks.size(); 8111 ArrayList<ActivityManager.RecentTaskInfo> res 8112 = new ArrayList<ActivityManager.RecentTaskInfo>( 8113 maxNum < N ? maxNum : N); 8114 8115 final Set<Integer> includedUsers; 8116 if (includeProfiles) { 8117 includedUsers = getProfileIdsLocked(userId); 8118 } else { 8119 includedUsers = new HashSet<Integer>(); 8120 } 8121 includedUsers.add(Integer.valueOf(userId)); 8122 8123 for (int i=0; i<N && maxNum > 0; i++) { 8124 TaskRecord tr = mRecentTasks.get(i); 8125 // Only add calling user or related users recent tasks 8126 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8127 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8128 continue; 8129 } 8130 8131 // Return the entry if desired by the caller. We always return 8132 // the first entry, because callers always expect this to be the 8133 // foreground app. We may filter others if the caller has 8134 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8135 // we should exclude the entry. 8136 8137 if (i == 0 8138 || withExcluded 8139 || (tr.intent == null) 8140 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8141 == 0)) { 8142 if (!allowed) { 8143 // If the caller doesn't have the GET_TASKS permission, then only 8144 // allow them to see a small subset of tasks -- their own and home. 8145 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8146 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8147 continue; 8148 } 8149 } 8150 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8151 if (tr.stack != null && tr.stack.isHomeStack()) { 8152 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8153 continue; 8154 } 8155 } 8156 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8157 // Don't include auto remove tasks that are finished or finishing. 8158 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8159 + tr); 8160 continue; 8161 } 8162 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8163 && !tr.isAvailable) { 8164 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8165 continue; 8166 } 8167 8168 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8169 if (!detailed) { 8170 rti.baseIntent.replaceExtras((Bundle)null); 8171 } 8172 8173 res.add(rti); 8174 maxNum--; 8175 } 8176 } 8177 return res; 8178 } 8179 } 8180 8181 private TaskRecord taskForIdLocked(int id) { 8182 final TaskRecord task = recentTaskForIdLocked(id); 8183 if (task != null) { 8184 return task; 8185 } 8186 8187 // Don't give up. Sometimes it just hasn't made it to recents yet. 8188 return mStackSupervisor.anyTaskForIdLocked(id); 8189 } 8190 8191 private TaskRecord recentTaskForIdLocked(int id) { 8192 final int N = mRecentTasks.size(); 8193 for (int i=0; i<N; i++) { 8194 TaskRecord tr = mRecentTasks.get(i); 8195 if (tr.taskId == id) { 8196 return tr; 8197 } 8198 } 8199 return null; 8200 } 8201 8202 @Override 8203 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8204 synchronized (this) { 8205 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8206 "getTaskThumbnail()"); 8207 TaskRecord tr = recentTaskForIdLocked(id); 8208 if (tr != null) { 8209 return tr.getTaskThumbnailLocked(); 8210 } 8211 } 8212 return null; 8213 } 8214 8215 @Override 8216 public int addAppTask(IBinder activityToken, Intent intent, 8217 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8218 final int callingUid = Binder.getCallingUid(); 8219 final long callingIdent = Binder.clearCallingIdentity(); 8220 8221 try { 8222 synchronized (this) { 8223 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8224 if (r == null) { 8225 throw new IllegalArgumentException("Activity does not exist; token=" 8226 + activityToken); 8227 } 8228 ComponentName comp = intent.getComponent(); 8229 if (comp == null) { 8230 throw new IllegalArgumentException("Intent " + intent 8231 + " must specify explicit component"); 8232 } 8233 if (thumbnail.getWidth() != mThumbnailWidth 8234 || thumbnail.getHeight() != mThumbnailHeight) { 8235 throw new IllegalArgumentException("Bad thumbnail size: got " 8236 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8237 + mThumbnailWidth + "x" + mThumbnailHeight); 8238 } 8239 if (intent.getSelector() != null) { 8240 intent.setSelector(null); 8241 } 8242 if (intent.getSourceBounds() != null) { 8243 intent.setSourceBounds(null); 8244 } 8245 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8246 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8247 // The caller has added this as an auto-remove task... that makes no 8248 // sense, so turn off auto-remove. 8249 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8250 } 8251 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8252 // Must be a new task. 8253 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8254 } 8255 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8256 mLastAddedTaskActivity = null; 8257 } 8258 ActivityInfo ainfo = mLastAddedTaskActivity; 8259 if (ainfo == null) { 8260 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8261 comp, 0, UserHandle.getUserId(callingUid)); 8262 if (ainfo.applicationInfo.uid != callingUid) { 8263 throw new SecurityException( 8264 "Can't add task for another application: target uid=" 8265 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8266 } 8267 } 8268 8269 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8270 intent, description); 8271 8272 int trimIdx = trimRecentsForTaskLocked(task, false); 8273 if (trimIdx >= 0) { 8274 // If this would have caused a trim, then we'll abort because that 8275 // means it would be added at the end of the list but then just removed. 8276 return INVALID_TASK_ID; 8277 } 8278 8279 final int N = mRecentTasks.size(); 8280 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8281 final TaskRecord tr = mRecentTasks.remove(N - 1); 8282 tr.removedFromRecents(); 8283 } 8284 8285 task.inRecents = true; 8286 mRecentTasks.add(task); 8287 r.task.stack.addTask(task, false, false); 8288 8289 task.setLastThumbnail(thumbnail); 8290 task.freeLastThumbnail(); 8291 8292 return task.taskId; 8293 } 8294 } finally { 8295 Binder.restoreCallingIdentity(callingIdent); 8296 } 8297 } 8298 8299 @Override 8300 public Point getAppTaskThumbnailSize() { 8301 synchronized (this) { 8302 return new Point(mThumbnailWidth, mThumbnailHeight); 8303 } 8304 } 8305 8306 @Override 8307 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8308 synchronized (this) { 8309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8310 if (r != null) { 8311 r.setTaskDescription(td); 8312 r.task.updateTaskDescription(); 8313 } 8314 } 8315 } 8316 8317 @Override 8318 public Bitmap getTaskDescriptionIcon(String filename) { 8319 if (!FileUtils.isValidExtFilename(filename) 8320 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8321 throw new IllegalArgumentException("Bad filename: " + filename); 8322 } 8323 return mTaskPersister.getTaskDescriptionIcon(filename); 8324 } 8325 8326 @Override 8327 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8328 throws RemoteException { 8329 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8330 opts.getCustomInPlaceResId() == 0) { 8331 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8332 "with valid animation"); 8333 } 8334 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8335 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8336 opts.getCustomInPlaceResId()); 8337 mWindowManager.executeAppTransition(); 8338 } 8339 8340 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8341 mRecentTasks.remove(tr); 8342 tr.removedFromRecents(); 8343 ComponentName component = tr.getBaseIntent().getComponent(); 8344 if (component == null) { 8345 Slog.w(TAG, "No component for base intent of task: " + tr); 8346 return; 8347 } 8348 8349 if (!killProcess) { 8350 return; 8351 } 8352 8353 // Determine if the process(es) for this task should be killed. 8354 final String pkg = component.getPackageName(); 8355 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8356 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8357 for (int i = 0; i < pmap.size(); i++) { 8358 8359 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8360 for (int j = 0; j < uids.size(); j++) { 8361 ProcessRecord proc = uids.valueAt(j); 8362 if (proc.userId != tr.userId) { 8363 // Don't kill process for a different user. 8364 continue; 8365 } 8366 if (proc == mHomeProcess) { 8367 // Don't kill the home process along with tasks from the same package. 8368 continue; 8369 } 8370 if (!proc.pkgList.containsKey(pkg)) { 8371 // Don't kill process that is not associated with this task. 8372 continue; 8373 } 8374 8375 for (int k = 0; k < proc.activities.size(); k++) { 8376 TaskRecord otherTask = proc.activities.get(k).task; 8377 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8378 // Don't kill process(es) that has an activity in a different task that is 8379 // also in recents. 8380 return; 8381 } 8382 } 8383 8384 // Add process to kill list. 8385 procsToKill.add(proc); 8386 } 8387 } 8388 8389 // Find any running services associated with this app and stop if needed. 8390 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8391 8392 // Kill the running processes. 8393 for (int i = 0; i < procsToKill.size(); i++) { 8394 ProcessRecord pr = procsToKill.get(i); 8395 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8396 pr.kill("remove task", true); 8397 } else { 8398 pr.waitingToKill = "remove task"; 8399 } 8400 } 8401 } 8402 8403 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8404 // Remove all tasks with activities in the specified package from the list of recent tasks 8405 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8406 TaskRecord tr = mRecentTasks.get(i); 8407 if (tr.userId != userId) continue; 8408 8409 ComponentName cn = tr.intent.getComponent(); 8410 if (cn != null && cn.getPackageName().equals(packageName)) { 8411 // If the package name matches, remove the task. 8412 removeTaskByIdLocked(tr.taskId, true); 8413 } 8414 } 8415 } 8416 8417 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8418 final IPackageManager pm = AppGlobals.getPackageManager(); 8419 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8420 8421 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8422 TaskRecord tr = mRecentTasks.get(i); 8423 if (tr.userId != userId) continue; 8424 8425 ComponentName cn = tr.intent.getComponent(); 8426 if (cn != null && cn.getPackageName().equals(packageName)) { 8427 // Skip if component still exists in the package. 8428 if (componentsKnownToExist.contains(cn)) continue; 8429 8430 try { 8431 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8432 if (info != null) { 8433 componentsKnownToExist.add(cn); 8434 } else { 8435 removeTaskByIdLocked(tr.taskId, false); 8436 } 8437 } catch (RemoteException e) { 8438 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8439 } 8440 } 8441 } 8442 } 8443 8444 /** 8445 * Removes the task with the specified task id. 8446 * 8447 * @param taskId Identifier of the task to be removed. 8448 * @param killProcess Kill any process associated with the task if possible. 8449 * @return Returns true if the given task was found and removed. 8450 */ 8451 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8452 TaskRecord tr = taskForIdLocked(taskId); 8453 if (tr != null) { 8454 tr.removeTaskActivitiesLocked(); 8455 cleanUpRemovedTaskLocked(tr, killProcess); 8456 if (tr.isPersistable) { 8457 notifyTaskPersisterLocked(null, true); 8458 } 8459 return true; 8460 } 8461 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8462 return false; 8463 } 8464 8465 @Override 8466 public boolean removeTask(int taskId) { 8467 synchronized (this) { 8468 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8469 "removeTask()"); 8470 long ident = Binder.clearCallingIdentity(); 8471 try { 8472 return removeTaskByIdLocked(taskId, true); 8473 } finally { 8474 Binder.restoreCallingIdentity(ident); 8475 } 8476 } 8477 } 8478 8479 /** 8480 * TODO: Add mController hook 8481 */ 8482 @Override 8483 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8484 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8485 "moveTaskToFront()"); 8486 8487 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8488 synchronized(this) { 8489 moveTaskToFrontLocked(taskId, flags, options); 8490 } 8491 } 8492 8493 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8494 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8495 Binder.getCallingUid(), -1, -1, "Task to front")) { 8496 ActivityOptions.abort(options); 8497 return; 8498 } 8499 final long origId = Binder.clearCallingIdentity(); 8500 try { 8501 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8502 if (task == null) { 8503 Slog.d(TAG, "Could not find task for id: "+ taskId); 8504 return; 8505 } 8506 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8507 mStackSupervisor.showLockTaskToast(); 8508 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8509 return; 8510 } 8511 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8512 if (prev != null && prev.isRecentsActivity()) { 8513 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8514 } 8515 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8516 } finally { 8517 Binder.restoreCallingIdentity(origId); 8518 } 8519 ActivityOptions.abort(options); 8520 } 8521 8522 @Override 8523 public void moveTaskToBack(int taskId) { 8524 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8525 "moveTaskToBack()"); 8526 8527 synchronized(this) { 8528 TaskRecord tr = taskForIdLocked(taskId); 8529 if (tr != null) { 8530 if (tr == mStackSupervisor.mLockTaskModeTask) { 8531 mStackSupervisor.showLockTaskToast(); 8532 return; 8533 } 8534 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8535 ActivityStack stack = tr.stack; 8536 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8537 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8538 Binder.getCallingUid(), -1, -1, "Task to back")) { 8539 return; 8540 } 8541 } 8542 final long origId = Binder.clearCallingIdentity(); 8543 try { 8544 stack.moveTaskToBackLocked(taskId, null); 8545 } finally { 8546 Binder.restoreCallingIdentity(origId); 8547 } 8548 } 8549 } 8550 } 8551 8552 /** 8553 * Moves an activity, and all of the other activities within the same task, to the bottom 8554 * of the history stack. The activity's order within the task is unchanged. 8555 * 8556 * @param token A reference to the activity we wish to move 8557 * @param nonRoot If false then this only works if the activity is the root 8558 * of a task; if true it will work for any activity in a task. 8559 * @return Returns true if the move completed, false if not. 8560 */ 8561 @Override 8562 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8563 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8564 synchronized(this) { 8565 final long origId = Binder.clearCallingIdentity(); 8566 try { 8567 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8568 if (taskId >= 0) { 8569 if ((mStackSupervisor.mLockTaskModeTask != null) 8570 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8571 mStackSupervisor.showLockTaskToast(); 8572 return false; 8573 } 8574 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8575 } 8576 } finally { 8577 Binder.restoreCallingIdentity(origId); 8578 } 8579 } 8580 return false; 8581 } 8582 8583 @Override 8584 public void moveTaskBackwards(int task) { 8585 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8586 "moveTaskBackwards()"); 8587 8588 synchronized(this) { 8589 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8590 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8591 return; 8592 } 8593 final long origId = Binder.clearCallingIdentity(); 8594 moveTaskBackwardsLocked(task); 8595 Binder.restoreCallingIdentity(origId); 8596 } 8597 } 8598 8599 private final void moveTaskBackwardsLocked(int task) { 8600 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8601 } 8602 8603 @Override 8604 public IBinder getHomeActivityToken() throws RemoteException { 8605 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8606 "getHomeActivityToken()"); 8607 synchronized (this) { 8608 return mStackSupervisor.getHomeActivityToken(); 8609 } 8610 } 8611 8612 @Override 8613 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8614 IActivityContainerCallback callback) throws RemoteException { 8615 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8616 "createActivityContainer()"); 8617 synchronized (this) { 8618 if (parentActivityToken == null) { 8619 throw new IllegalArgumentException("parent token must not be null"); 8620 } 8621 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8622 if (r == null) { 8623 return null; 8624 } 8625 if (callback == null) { 8626 throw new IllegalArgumentException("callback must not be null"); 8627 } 8628 return mStackSupervisor.createActivityContainer(r, callback); 8629 } 8630 } 8631 8632 @Override 8633 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8634 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8635 "deleteActivityContainer()"); 8636 synchronized (this) { 8637 mStackSupervisor.deleteActivityContainer(container); 8638 } 8639 } 8640 8641 @Override 8642 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8643 throws RemoteException { 8644 synchronized (this) { 8645 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8646 if (stack != null) { 8647 return stack.mActivityContainer; 8648 } 8649 return null; 8650 } 8651 } 8652 8653 @Override 8654 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8655 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8656 "moveTaskToStack()"); 8657 if (stackId == HOME_STACK_ID) { 8658 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8659 new RuntimeException("here").fillInStackTrace()); 8660 } 8661 synchronized (this) { 8662 long ident = Binder.clearCallingIdentity(); 8663 try { 8664 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8665 + stackId + " toTop=" + toTop); 8666 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8667 } finally { 8668 Binder.restoreCallingIdentity(ident); 8669 } 8670 } 8671 } 8672 8673 @Override 8674 public void resizeStack(int stackBoxId, Rect bounds) { 8675 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8676 "resizeStackBox()"); 8677 long ident = Binder.clearCallingIdentity(); 8678 try { 8679 mWindowManager.resizeStack(stackBoxId, bounds); 8680 } finally { 8681 Binder.restoreCallingIdentity(ident); 8682 } 8683 } 8684 8685 @Override 8686 public List<StackInfo> getAllStackInfos() { 8687 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8688 "getAllStackInfos()"); 8689 long ident = Binder.clearCallingIdentity(); 8690 try { 8691 synchronized (this) { 8692 return mStackSupervisor.getAllStackInfosLocked(); 8693 } 8694 } finally { 8695 Binder.restoreCallingIdentity(ident); 8696 } 8697 } 8698 8699 @Override 8700 public StackInfo getStackInfo(int stackId) { 8701 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8702 "getStackInfo()"); 8703 long ident = Binder.clearCallingIdentity(); 8704 try { 8705 synchronized (this) { 8706 return mStackSupervisor.getStackInfoLocked(stackId); 8707 } 8708 } finally { 8709 Binder.restoreCallingIdentity(ident); 8710 } 8711 } 8712 8713 @Override 8714 public boolean isInHomeStack(int taskId) { 8715 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8716 "getStackInfo()"); 8717 long ident = Binder.clearCallingIdentity(); 8718 try { 8719 synchronized (this) { 8720 TaskRecord tr = taskForIdLocked(taskId); 8721 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8722 } 8723 } finally { 8724 Binder.restoreCallingIdentity(ident); 8725 } 8726 } 8727 8728 @Override 8729 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8730 synchronized(this) { 8731 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8732 } 8733 } 8734 8735 private boolean isLockTaskAuthorized(String pkg) { 8736 final DevicePolicyManager dpm = (DevicePolicyManager) 8737 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8738 try { 8739 int uid = mContext.getPackageManager().getPackageUid(pkg, 8740 Binder.getCallingUserHandle().getIdentifier()); 8741 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8742 } catch (NameNotFoundException e) { 8743 return false; 8744 } 8745 } 8746 8747 void startLockTaskMode(TaskRecord task) { 8748 final String pkg; 8749 synchronized (this) { 8750 pkg = task.intent.getComponent().getPackageName(); 8751 } 8752 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8753 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8754 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8755 StatusBarManagerInternal.class); 8756 if (statusBarManager != null) { 8757 statusBarManager.showScreenPinningRequest(); 8758 } 8759 return; 8760 } 8761 long ident = Binder.clearCallingIdentity(); 8762 try { 8763 synchronized (this) { 8764 // Since we lost lock on task, make sure it is still there. 8765 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8766 if (task != null) { 8767 if (!isSystemInitiated 8768 && ((mStackSupervisor.getFocusedStack() == null) 8769 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8770 throw new IllegalArgumentException("Invalid task, not in foreground"); 8771 } 8772 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8773 } 8774 } 8775 } finally { 8776 Binder.restoreCallingIdentity(ident); 8777 } 8778 } 8779 8780 @Override 8781 public void startLockTaskMode(int taskId) { 8782 final TaskRecord task; 8783 long ident = Binder.clearCallingIdentity(); 8784 try { 8785 synchronized (this) { 8786 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8787 } 8788 } finally { 8789 Binder.restoreCallingIdentity(ident); 8790 } 8791 if (task != null) { 8792 startLockTaskMode(task); 8793 } 8794 } 8795 8796 @Override 8797 public void startLockTaskMode(IBinder token) { 8798 final TaskRecord task; 8799 long ident = Binder.clearCallingIdentity(); 8800 try { 8801 synchronized (this) { 8802 final ActivityRecord r = ActivityRecord.forToken(token); 8803 if (r == null) { 8804 return; 8805 } 8806 task = r.task; 8807 } 8808 } finally { 8809 Binder.restoreCallingIdentity(ident); 8810 } 8811 if (task != null) { 8812 startLockTaskMode(task); 8813 } 8814 } 8815 8816 @Override 8817 public void startLockTaskModeOnCurrent() throws RemoteException { 8818 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8819 "startLockTaskModeOnCurrent"); 8820 long ident = Binder.clearCallingIdentity(); 8821 try { 8822 ActivityRecord r = null; 8823 synchronized (this) { 8824 r = mStackSupervisor.topRunningActivityLocked(); 8825 } 8826 startLockTaskMode(r.task); 8827 } finally { 8828 Binder.restoreCallingIdentity(ident); 8829 } 8830 } 8831 8832 @Override 8833 public void stopLockTaskMode() { 8834 // Verify that the user matches the package of the intent for the TaskRecord 8835 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8836 // and stopLockTaskMode. 8837 final int callingUid = Binder.getCallingUid(); 8838 if (callingUid != Process.SYSTEM_UID) { 8839 try { 8840 String pkg = 8841 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8842 int uid = mContext.getPackageManager().getPackageUid(pkg, 8843 Binder.getCallingUserHandle().getIdentifier()); 8844 if (uid != callingUid) { 8845 throw new SecurityException("Invalid uid, expected " + uid); 8846 } 8847 } catch (NameNotFoundException e) { 8848 Log.d(TAG, "stopLockTaskMode " + e); 8849 return; 8850 } 8851 } 8852 long ident = Binder.clearCallingIdentity(); 8853 try { 8854 Log.d(TAG, "stopLockTaskMode"); 8855 // Stop lock task 8856 synchronized (this) { 8857 mStackSupervisor.setLockTaskModeLocked(null, false); 8858 } 8859 } finally { 8860 Binder.restoreCallingIdentity(ident); 8861 } 8862 } 8863 8864 @Override 8865 public void stopLockTaskModeOnCurrent() throws RemoteException { 8866 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8867 "stopLockTaskModeOnCurrent"); 8868 long ident = Binder.clearCallingIdentity(); 8869 try { 8870 stopLockTaskMode(); 8871 } finally { 8872 Binder.restoreCallingIdentity(ident); 8873 } 8874 } 8875 8876 @Override 8877 public boolean isInLockTaskMode() { 8878 synchronized (this) { 8879 return mStackSupervisor.isInLockTaskMode(); 8880 } 8881 } 8882 8883 // ========================================================= 8884 // CONTENT PROVIDERS 8885 // ========================================================= 8886 8887 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8888 List<ProviderInfo> providers = null; 8889 try { 8890 providers = AppGlobals.getPackageManager(). 8891 queryContentProviders(app.processName, app.uid, 8892 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8893 } catch (RemoteException ex) { 8894 } 8895 if (DEBUG_MU) 8896 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8897 int userId = app.userId; 8898 if (providers != null) { 8899 int N = providers.size(); 8900 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8901 for (int i=0; i<N; i++) { 8902 ProviderInfo cpi = 8903 (ProviderInfo)providers.get(i); 8904 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8905 cpi.name, cpi.flags); 8906 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8907 // This is a singleton provider, but a user besides the 8908 // default user is asking to initialize a process it runs 8909 // in... well, no, it doesn't actually run in this process, 8910 // it runs in the process of the default user. Get rid of it. 8911 providers.remove(i); 8912 N--; 8913 i--; 8914 continue; 8915 } 8916 8917 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8918 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8919 if (cpr == null) { 8920 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8921 mProviderMap.putProviderByClass(comp, cpr); 8922 } 8923 if (DEBUG_MU) 8924 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8925 app.pubProviders.put(cpi.name, cpr); 8926 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8927 // Don't add this if it is a platform component that is marked 8928 // to run in multiple processes, because this is actually 8929 // part of the framework so doesn't make sense to track as a 8930 // separate apk in the process. 8931 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8932 mProcessStats); 8933 } 8934 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8935 } 8936 } 8937 return providers; 8938 } 8939 8940 /** 8941 * Check if {@link ProcessRecord} has a possible chance at accessing the 8942 * given {@link ProviderInfo}. Final permission checking is always done 8943 * in {@link ContentProvider}. 8944 */ 8945 private final String checkContentProviderPermissionLocked( 8946 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8947 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8948 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8949 boolean checkedGrants = false; 8950 if (checkUser) { 8951 // Looking for cross-user grants before enforcing the typical cross-users permissions 8952 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8953 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8954 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8955 return null; 8956 } 8957 checkedGrants = true; 8958 } 8959 userId = handleIncomingUser(callingPid, callingUid, userId, 8960 false, ALLOW_NON_FULL, 8961 "checkContentProviderPermissionLocked " + cpi.authority, null); 8962 if (userId != tmpTargetUserId) { 8963 // When we actually went to determine the final targer user ID, this ended 8964 // up different than our initial check for the authority. This is because 8965 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8966 // SELF. So we need to re-check the grants again. 8967 checkedGrants = false; 8968 } 8969 } 8970 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8971 cpi.applicationInfo.uid, cpi.exported) 8972 == PackageManager.PERMISSION_GRANTED) { 8973 return null; 8974 } 8975 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8976 cpi.applicationInfo.uid, cpi.exported) 8977 == PackageManager.PERMISSION_GRANTED) { 8978 return null; 8979 } 8980 8981 PathPermission[] pps = cpi.pathPermissions; 8982 if (pps != null) { 8983 int i = pps.length; 8984 while (i > 0) { 8985 i--; 8986 PathPermission pp = pps[i]; 8987 String pprperm = pp.getReadPermission(); 8988 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8989 cpi.applicationInfo.uid, cpi.exported) 8990 == PackageManager.PERMISSION_GRANTED) { 8991 return null; 8992 } 8993 String ppwperm = pp.getWritePermission(); 8994 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8995 cpi.applicationInfo.uid, cpi.exported) 8996 == PackageManager.PERMISSION_GRANTED) { 8997 return null; 8998 } 8999 } 9000 } 9001 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9002 return null; 9003 } 9004 9005 String msg; 9006 if (!cpi.exported) { 9007 msg = "Permission Denial: opening provider " + cpi.name 9008 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9009 + ", uid=" + callingUid + ") that is not exported from uid " 9010 + cpi.applicationInfo.uid; 9011 } else { 9012 msg = "Permission Denial: opening provider " + cpi.name 9013 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9014 + ", uid=" + callingUid + ") requires " 9015 + cpi.readPermission + " or " + cpi.writePermission; 9016 } 9017 Slog.w(TAG, msg); 9018 return msg; 9019 } 9020 9021 /** 9022 * Returns if the ContentProvider has granted a uri to callingUid 9023 */ 9024 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9025 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9026 if (perms != null) { 9027 for (int i=perms.size()-1; i>=0; i--) { 9028 GrantUri grantUri = perms.keyAt(i); 9029 if (grantUri.sourceUserId == userId || !checkUser) { 9030 if (matchesProvider(grantUri.uri, cpi)) { 9031 return true; 9032 } 9033 } 9034 } 9035 } 9036 return false; 9037 } 9038 9039 /** 9040 * Returns true if the uri authority is one of the authorities specified in the provider. 9041 */ 9042 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9043 String uriAuth = uri.getAuthority(); 9044 String cpiAuth = cpi.authority; 9045 if (cpiAuth.indexOf(';') == -1) { 9046 return cpiAuth.equals(uriAuth); 9047 } 9048 String[] cpiAuths = cpiAuth.split(";"); 9049 int length = cpiAuths.length; 9050 for (int i = 0; i < length; i++) { 9051 if (cpiAuths[i].equals(uriAuth)) return true; 9052 } 9053 return false; 9054 } 9055 9056 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9057 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9058 if (r != null) { 9059 for (int i=0; i<r.conProviders.size(); i++) { 9060 ContentProviderConnection conn = r.conProviders.get(i); 9061 if (conn.provider == cpr) { 9062 if (DEBUG_PROVIDER) Slog.v(TAG, 9063 "Adding provider requested by " 9064 + r.processName + " from process " 9065 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9066 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9067 if (stable) { 9068 conn.stableCount++; 9069 conn.numStableIncs++; 9070 } else { 9071 conn.unstableCount++; 9072 conn.numUnstableIncs++; 9073 } 9074 return conn; 9075 } 9076 } 9077 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9078 if (stable) { 9079 conn.stableCount = 1; 9080 conn.numStableIncs = 1; 9081 } else { 9082 conn.unstableCount = 1; 9083 conn.numUnstableIncs = 1; 9084 } 9085 cpr.connections.add(conn); 9086 r.conProviders.add(conn); 9087 return conn; 9088 } 9089 cpr.addExternalProcessHandleLocked(externalProcessToken); 9090 return null; 9091 } 9092 9093 boolean decProviderCountLocked(ContentProviderConnection conn, 9094 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9095 if (conn != null) { 9096 cpr = conn.provider; 9097 if (DEBUG_PROVIDER) Slog.v(TAG, 9098 "Removing provider requested by " 9099 + conn.client.processName + " from process " 9100 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9101 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9102 if (stable) { 9103 conn.stableCount--; 9104 } else { 9105 conn.unstableCount--; 9106 } 9107 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9108 cpr.connections.remove(conn); 9109 conn.client.conProviders.remove(conn); 9110 return true; 9111 } 9112 return false; 9113 } 9114 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9115 return false; 9116 } 9117 9118 private void checkTime(long startTime, String where) { 9119 long now = SystemClock.elapsedRealtime(); 9120 if ((now-startTime) > 1000) { 9121 // If we are taking more than a second, log about it. 9122 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9123 } 9124 } 9125 9126 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9127 String name, IBinder token, boolean stable, int userId) { 9128 ContentProviderRecord cpr; 9129 ContentProviderConnection conn = null; 9130 ProviderInfo cpi = null; 9131 9132 synchronized(this) { 9133 long startTime = SystemClock.elapsedRealtime(); 9134 9135 ProcessRecord r = null; 9136 if (caller != null) { 9137 r = getRecordForAppLocked(caller); 9138 if (r == null) { 9139 throw new SecurityException( 9140 "Unable to find app for caller " + caller 9141 + " (pid=" + Binder.getCallingPid() 9142 + ") when getting content provider " + name); 9143 } 9144 } 9145 9146 boolean checkCrossUser = true; 9147 9148 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9149 9150 // First check if this content provider has been published... 9151 cpr = mProviderMap.getProviderByName(name, userId); 9152 // If that didn't work, check if it exists for user 0 and then 9153 // verify that it's a singleton provider before using it. 9154 if (cpr == null && userId != UserHandle.USER_OWNER) { 9155 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9156 if (cpr != null) { 9157 cpi = cpr.info; 9158 if (isSingleton(cpi.processName, cpi.applicationInfo, 9159 cpi.name, cpi.flags) 9160 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9161 userId = UserHandle.USER_OWNER; 9162 checkCrossUser = false; 9163 } else { 9164 cpr = null; 9165 cpi = null; 9166 } 9167 } 9168 } 9169 9170 boolean providerRunning = cpr != null; 9171 if (providerRunning) { 9172 cpi = cpr.info; 9173 String msg; 9174 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9175 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9176 != null) { 9177 throw new SecurityException(msg); 9178 } 9179 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9180 9181 if (r != null && cpr.canRunHere(r)) { 9182 // This provider has been published or is in the process 9183 // of being published... but it is also allowed to run 9184 // in the caller's process, so don't make a connection 9185 // and just let the caller instantiate its own instance. 9186 ContentProviderHolder holder = cpr.newHolder(null); 9187 // don't give caller the provider object, it needs 9188 // to make its own. 9189 holder.provider = null; 9190 return holder; 9191 } 9192 9193 final long origId = Binder.clearCallingIdentity(); 9194 9195 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9196 9197 // In this case the provider instance already exists, so we can 9198 // return it right away. 9199 conn = incProviderCountLocked(r, cpr, token, stable); 9200 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9201 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9202 // If this is a perceptible app accessing the provider, 9203 // make sure to count it as being accessed and thus 9204 // back up on the LRU list. This is good because 9205 // content providers are often expensive to start. 9206 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9207 updateLruProcessLocked(cpr.proc, false, null); 9208 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9209 } 9210 } 9211 9212 if (cpr.proc != null) { 9213 if (false) { 9214 if (cpr.name.flattenToShortString().equals( 9215 "com.android.providers.calendar/.CalendarProvider2")) { 9216 Slog.v(TAG, "****************** KILLING " 9217 + cpr.name.flattenToShortString()); 9218 Process.killProcess(cpr.proc.pid); 9219 } 9220 } 9221 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9222 boolean success = updateOomAdjLocked(cpr.proc); 9223 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9224 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9225 // NOTE: there is still a race here where a signal could be 9226 // pending on the process even though we managed to update its 9227 // adj level. Not sure what to do about this, but at least 9228 // the race is now smaller. 9229 if (!success) { 9230 // Uh oh... it looks like the provider's process 9231 // has been killed on us. We need to wait for a new 9232 // process to be started, and make sure its death 9233 // doesn't kill our process. 9234 Slog.i(TAG, 9235 "Existing provider " + cpr.name.flattenToShortString() 9236 + " is crashing; detaching " + r); 9237 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9238 checkTime(startTime, "getContentProviderImpl: before appDied"); 9239 appDiedLocked(cpr.proc); 9240 checkTime(startTime, "getContentProviderImpl: after appDied"); 9241 if (!lastRef) { 9242 // This wasn't the last ref our process had on 9243 // the provider... we have now been killed, bail. 9244 return null; 9245 } 9246 providerRunning = false; 9247 conn = null; 9248 } 9249 } 9250 9251 Binder.restoreCallingIdentity(origId); 9252 } 9253 9254 boolean singleton; 9255 if (!providerRunning) { 9256 try { 9257 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9258 cpi = AppGlobals.getPackageManager(). 9259 resolveContentProvider(name, 9260 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9261 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9262 } catch (RemoteException ex) { 9263 } 9264 if (cpi == null) { 9265 return null; 9266 } 9267 // If the provider is a singleton AND 9268 // (it's a call within the same user || the provider is a 9269 // privileged app) 9270 // Then allow connecting to the singleton provider 9271 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9272 cpi.name, cpi.flags) 9273 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9274 if (singleton) { 9275 userId = UserHandle.USER_OWNER; 9276 } 9277 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9278 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9279 9280 String msg; 9281 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9282 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9283 != null) { 9284 throw new SecurityException(msg); 9285 } 9286 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9287 9288 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9289 && !cpi.processName.equals("system")) { 9290 // If this content provider does not run in the system 9291 // process, and the system is not yet ready to run other 9292 // processes, then fail fast instead of hanging. 9293 throw new IllegalArgumentException( 9294 "Attempt to launch content provider before system ready"); 9295 } 9296 9297 // Make sure that the user who owns this provider is running. If not, 9298 // we don't want to allow it to run. 9299 if (!isUserRunningLocked(userId, false)) { 9300 Slog.w(TAG, "Unable to launch app " 9301 + cpi.applicationInfo.packageName + "/" 9302 + cpi.applicationInfo.uid + " for provider " 9303 + name + ": user " + userId + " is stopped"); 9304 return null; 9305 } 9306 9307 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9308 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9309 cpr = mProviderMap.getProviderByClass(comp, userId); 9310 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9311 final boolean firstClass = cpr == null; 9312 if (firstClass) { 9313 final long ident = Binder.clearCallingIdentity(); 9314 try { 9315 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9316 ApplicationInfo ai = 9317 AppGlobals.getPackageManager(). 9318 getApplicationInfo( 9319 cpi.applicationInfo.packageName, 9320 STOCK_PM_FLAGS, userId); 9321 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9322 if (ai == null) { 9323 Slog.w(TAG, "No package info for content provider " 9324 + cpi.name); 9325 return null; 9326 } 9327 ai = getAppInfoForUser(ai, userId); 9328 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9329 } catch (RemoteException ex) { 9330 // pm is in same process, this will never happen. 9331 } finally { 9332 Binder.restoreCallingIdentity(ident); 9333 } 9334 } 9335 9336 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9337 9338 if (r != null && cpr.canRunHere(r)) { 9339 // If this is a multiprocess provider, then just return its 9340 // info and allow the caller to instantiate it. Only do 9341 // this if the provider is the same user as the caller's 9342 // process, or can run as root (so can be in any process). 9343 return cpr.newHolder(null); 9344 } 9345 9346 if (DEBUG_PROVIDER) { 9347 RuntimeException e = new RuntimeException("here"); 9348 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9349 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9350 } 9351 9352 // This is single process, and our app is now connecting to it. 9353 // See if we are already in the process of launching this 9354 // provider. 9355 final int N = mLaunchingProviders.size(); 9356 int i; 9357 for (i=0; i<N; i++) { 9358 if (mLaunchingProviders.get(i) == cpr) { 9359 break; 9360 } 9361 } 9362 9363 // If the provider is not already being launched, then get it 9364 // started. 9365 if (i >= N) { 9366 final long origId = Binder.clearCallingIdentity(); 9367 9368 try { 9369 // Content provider is now in use, its package can't be stopped. 9370 try { 9371 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9372 AppGlobals.getPackageManager().setPackageStoppedState( 9373 cpr.appInfo.packageName, false, userId); 9374 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9375 } catch (RemoteException e) { 9376 } catch (IllegalArgumentException e) { 9377 Slog.w(TAG, "Failed trying to unstop package " 9378 + cpr.appInfo.packageName + ": " + e); 9379 } 9380 9381 // Use existing process if already started 9382 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9383 ProcessRecord proc = getProcessRecordLocked( 9384 cpi.processName, cpr.appInfo.uid, false); 9385 if (proc != null && proc.thread != null) { 9386 if (DEBUG_PROVIDER) { 9387 Slog.d(TAG, "Installing in existing process " + proc); 9388 } 9389 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9390 proc.pubProviders.put(cpi.name, cpr); 9391 try { 9392 proc.thread.scheduleInstallProvider(cpi); 9393 } catch (RemoteException e) { 9394 } 9395 } else { 9396 checkTime(startTime, "getContentProviderImpl: before start process"); 9397 proc = startProcessLocked(cpi.processName, 9398 cpr.appInfo, false, 0, "content provider", 9399 new ComponentName(cpi.applicationInfo.packageName, 9400 cpi.name), false, false, false); 9401 checkTime(startTime, "getContentProviderImpl: after start process"); 9402 if (proc == null) { 9403 Slog.w(TAG, "Unable to launch app " 9404 + cpi.applicationInfo.packageName + "/" 9405 + cpi.applicationInfo.uid + " for provider " 9406 + name + ": process is bad"); 9407 return null; 9408 } 9409 } 9410 cpr.launchingApp = proc; 9411 mLaunchingProviders.add(cpr); 9412 } finally { 9413 Binder.restoreCallingIdentity(origId); 9414 } 9415 } 9416 9417 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9418 9419 // Make sure the provider is published (the same provider class 9420 // may be published under multiple names). 9421 if (firstClass) { 9422 mProviderMap.putProviderByClass(comp, cpr); 9423 } 9424 9425 mProviderMap.putProviderByName(name, cpr); 9426 conn = incProviderCountLocked(r, cpr, token, stable); 9427 if (conn != null) { 9428 conn.waiting = true; 9429 } 9430 } 9431 checkTime(startTime, "getContentProviderImpl: done!"); 9432 } 9433 9434 // Wait for the provider to be published... 9435 synchronized (cpr) { 9436 while (cpr.provider == null) { 9437 if (cpr.launchingApp == null) { 9438 Slog.w(TAG, "Unable to launch app " 9439 + cpi.applicationInfo.packageName + "/" 9440 + cpi.applicationInfo.uid + " for provider " 9441 + name + ": launching app became null"); 9442 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9443 UserHandle.getUserId(cpi.applicationInfo.uid), 9444 cpi.applicationInfo.packageName, 9445 cpi.applicationInfo.uid, name); 9446 return null; 9447 } 9448 try { 9449 if (DEBUG_MU) { 9450 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9451 + cpr.launchingApp); 9452 } 9453 if (conn != null) { 9454 conn.waiting = true; 9455 } 9456 cpr.wait(); 9457 } catch (InterruptedException ex) { 9458 } finally { 9459 if (conn != null) { 9460 conn.waiting = false; 9461 } 9462 } 9463 } 9464 } 9465 return cpr != null ? cpr.newHolder(conn) : null; 9466 } 9467 9468 @Override 9469 public final ContentProviderHolder getContentProvider( 9470 IApplicationThread caller, String name, int userId, boolean stable) { 9471 enforceNotIsolatedCaller("getContentProvider"); 9472 if (caller == null) { 9473 String msg = "null IApplicationThread when getting content provider " 9474 + name; 9475 Slog.w(TAG, msg); 9476 throw new SecurityException(msg); 9477 } 9478 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9479 // with cross-user grant. 9480 return getContentProviderImpl(caller, name, null, stable, userId); 9481 } 9482 9483 public ContentProviderHolder getContentProviderExternal( 9484 String name, int userId, IBinder token) { 9485 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9486 "Do not have permission in call getContentProviderExternal()"); 9487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9488 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9489 return getContentProviderExternalUnchecked(name, token, userId); 9490 } 9491 9492 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9493 IBinder token, int userId) { 9494 return getContentProviderImpl(null, name, token, true, userId); 9495 } 9496 9497 /** 9498 * Drop a content provider from a ProcessRecord's bookkeeping 9499 */ 9500 public void removeContentProvider(IBinder connection, boolean stable) { 9501 enforceNotIsolatedCaller("removeContentProvider"); 9502 long ident = Binder.clearCallingIdentity(); 9503 try { 9504 synchronized (this) { 9505 ContentProviderConnection conn; 9506 try { 9507 conn = (ContentProviderConnection)connection; 9508 } catch (ClassCastException e) { 9509 String msg ="removeContentProvider: " + connection 9510 + " not a ContentProviderConnection"; 9511 Slog.w(TAG, msg); 9512 throw new IllegalArgumentException(msg); 9513 } 9514 if (conn == null) { 9515 throw new NullPointerException("connection is null"); 9516 } 9517 if (decProviderCountLocked(conn, null, null, stable)) { 9518 updateOomAdjLocked(); 9519 } 9520 } 9521 } finally { 9522 Binder.restoreCallingIdentity(ident); 9523 } 9524 } 9525 9526 public void removeContentProviderExternal(String name, IBinder token) { 9527 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9528 "Do not have permission in call removeContentProviderExternal()"); 9529 int userId = UserHandle.getCallingUserId(); 9530 long ident = Binder.clearCallingIdentity(); 9531 try { 9532 removeContentProviderExternalUnchecked(name, token, userId); 9533 } finally { 9534 Binder.restoreCallingIdentity(ident); 9535 } 9536 } 9537 9538 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9539 synchronized (this) { 9540 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9541 if(cpr == null) { 9542 //remove from mProvidersByClass 9543 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9544 return; 9545 } 9546 9547 //update content provider record entry info 9548 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9549 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9550 if (localCpr.hasExternalProcessHandles()) { 9551 if (localCpr.removeExternalProcessHandleLocked(token)) { 9552 updateOomAdjLocked(); 9553 } else { 9554 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9555 + " with no external reference for token: " 9556 + token + "."); 9557 } 9558 } else { 9559 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9560 + " with no external references."); 9561 } 9562 } 9563 } 9564 9565 public final void publishContentProviders(IApplicationThread caller, 9566 List<ContentProviderHolder> providers) { 9567 if (providers == null) { 9568 return; 9569 } 9570 9571 enforceNotIsolatedCaller("publishContentProviders"); 9572 synchronized (this) { 9573 final ProcessRecord r = getRecordForAppLocked(caller); 9574 if (DEBUG_MU) 9575 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9576 if (r == null) { 9577 throw new SecurityException( 9578 "Unable to find app for caller " + caller 9579 + " (pid=" + Binder.getCallingPid() 9580 + ") when publishing content providers"); 9581 } 9582 9583 final long origId = Binder.clearCallingIdentity(); 9584 9585 final int N = providers.size(); 9586 for (int i=0; i<N; i++) { 9587 ContentProviderHolder src = providers.get(i); 9588 if (src == null || src.info == null || src.provider == null) { 9589 continue; 9590 } 9591 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9592 if (DEBUG_MU) 9593 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9594 if (dst != null) { 9595 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9596 mProviderMap.putProviderByClass(comp, dst); 9597 String names[] = dst.info.authority.split(";"); 9598 for (int j = 0; j < names.length; j++) { 9599 mProviderMap.putProviderByName(names[j], dst); 9600 } 9601 9602 int NL = mLaunchingProviders.size(); 9603 int j; 9604 for (j=0; j<NL; j++) { 9605 if (mLaunchingProviders.get(j) == dst) { 9606 mLaunchingProviders.remove(j); 9607 j--; 9608 NL--; 9609 } 9610 } 9611 synchronized (dst) { 9612 dst.provider = src.provider; 9613 dst.proc = r; 9614 dst.notifyAll(); 9615 } 9616 updateOomAdjLocked(r); 9617 } 9618 } 9619 9620 Binder.restoreCallingIdentity(origId); 9621 } 9622 } 9623 9624 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9625 ContentProviderConnection conn; 9626 try { 9627 conn = (ContentProviderConnection)connection; 9628 } catch (ClassCastException e) { 9629 String msg ="refContentProvider: " + connection 9630 + " not a ContentProviderConnection"; 9631 Slog.w(TAG, msg); 9632 throw new IllegalArgumentException(msg); 9633 } 9634 if (conn == null) { 9635 throw new NullPointerException("connection is null"); 9636 } 9637 9638 synchronized (this) { 9639 if (stable > 0) { 9640 conn.numStableIncs += stable; 9641 } 9642 stable = conn.stableCount + stable; 9643 if (stable < 0) { 9644 throw new IllegalStateException("stableCount < 0: " + stable); 9645 } 9646 9647 if (unstable > 0) { 9648 conn.numUnstableIncs += unstable; 9649 } 9650 unstable = conn.unstableCount + unstable; 9651 if (unstable < 0) { 9652 throw new IllegalStateException("unstableCount < 0: " + unstable); 9653 } 9654 9655 if ((stable+unstable) <= 0) { 9656 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9657 + stable + " unstable=" + unstable); 9658 } 9659 conn.stableCount = stable; 9660 conn.unstableCount = unstable; 9661 return !conn.dead; 9662 } 9663 } 9664 9665 public void unstableProviderDied(IBinder connection) { 9666 ContentProviderConnection conn; 9667 try { 9668 conn = (ContentProviderConnection)connection; 9669 } catch (ClassCastException e) { 9670 String msg ="refContentProvider: " + connection 9671 + " not a ContentProviderConnection"; 9672 Slog.w(TAG, msg); 9673 throw new IllegalArgumentException(msg); 9674 } 9675 if (conn == null) { 9676 throw new NullPointerException("connection is null"); 9677 } 9678 9679 // Safely retrieve the content provider associated with the connection. 9680 IContentProvider provider; 9681 synchronized (this) { 9682 provider = conn.provider.provider; 9683 } 9684 9685 if (provider == null) { 9686 // Um, yeah, we're way ahead of you. 9687 return; 9688 } 9689 9690 // Make sure the caller is being honest with us. 9691 if (provider.asBinder().pingBinder()) { 9692 // Er, no, still looks good to us. 9693 synchronized (this) { 9694 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9695 + " says " + conn + " died, but we don't agree"); 9696 return; 9697 } 9698 } 9699 9700 // Well look at that! It's dead! 9701 synchronized (this) { 9702 if (conn.provider.provider != provider) { 9703 // But something changed... good enough. 9704 return; 9705 } 9706 9707 ProcessRecord proc = conn.provider.proc; 9708 if (proc == null || proc.thread == null) { 9709 // Seems like the process is already cleaned up. 9710 return; 9711 } 9712 9713 // As far as we're concerned, this is just like receiving a 9714 // death notification... just a bit prematurely. 9715 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9716 + ") early provider death"); 9717 final long ident = Binder.clearCallingIdentity(); 9718 try { 9719 appDiedLocked(proc); 9720 } finally { 9721 Binder.restoreCallingIdentity(ident); 9722 } 9723 } 9724 } 9725 9726 @Override 9727 public void appNotRespondingViaProvider(IBinder connection) { 9728 enforceCallingPermission( 9729 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9730 9731 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9732 if (conn == null) { 9733 Slog.w(TAG, "ContentProviderConnection is null"); 9734 return; 9735 } 9736 9737 final ProcessRecord host = conn.provider.proc; 9738 if (host == null) { 9739 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9740 return; 9741 } 9742 9743 final long token = Binder.clearCallingIdentity(); 9744 try { 9745 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9746 } finally { 9747 Binder.restoreCallingIdentity(token); 9748 } 9749 } 9750 9751 public final void installSystemProviders() { 9752 List<ProviderInfo> providers; 9753 synchronized (this) { 9754 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9755 providers = generateApplicationProvidersLocked(app); 9756 if (providers != null) { 9757 for (int i=providers.size()-1; i>=0; i--) { 9758 ProviderInfo pi = (ProviderInfo)providers.get(i); 9759 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9760 Slog.w(TAG, "Not installing system proc provider " + pi.name 9761 + ": not system .apk"); 9762 providers.remove(i); 9763 } 9764 } 9765 } 9766 } 9767 if (providers != null) { 9768 mSystemThread.installSystemProviders(providers); 9769 } 9770 9771 mCoreSettingsObserver = new CoreSettingsObserver(this); 9772 9773 //mUsageStatsService.monitorPackages(); 9774 } 9775 9776 /** 9777 * Allows apps to retrieve the MIME type of a URI. 9778 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9779 * users, then it does not need permission to access the ContentProvider. 9780 * Either, it needs cross-user uri grants. 9781 * 9782 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9783 * 9784 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9785 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9786 */ 9787 public String getProviderMimeType(Uri uri, int userId) { 9788 enforceNotIsolatedCaller("getProviderMimeType"); 9789 final String name = uri.getAuthority(); 9790 int callingUid = Binder.getCallingUid(); 9791 int callingPid = Binder.getCallingPid(); 9792 long ident = 0; 9793 boolean clearedIdentity = false; 9794 userId = unsafeConvertIncomingUser(userId); 9795 if (canClearIdentity(callingPid, callingUid, userId)) { 9796 clearedIdentity = true; 9797 ident = Binder.clearCallingIdentity(); 9798 } 9799 ContentProviderHolder holder = null; 9800 try { 9801 holder = getContentProviderExternalUnchecked(name, null, userId); 9802 if (holder != null) { 9803 return holder.provider.getType(uri); 9804 } 9805 } catch (RemoteException e) { 9806 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9807 return null; 9808 } finally { 9809 // We need to clear the identity to call removeContentProviderExternalUnchecked 9810 if (!clearedIdentity) { 9811 ident = Binder.clearCallingIdentity(); 9812 } 9813 try { 9814 if (holder != null) { 9815 removeContentProviderExternalUnchecked(name, null, userId); 9816 } 9817 } finally { 9818 Binder.restoreCallingIdentity(ident); 9819 } 9820 } 9821 9822 return null; 9823 } 9824 9825 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9826 if (UserHandle.getUserId(callingUid) == userId) { 9827 return true; 9828 } 9829 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9830 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9831 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9832 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9833 return true; 9834 } 9835 return false; 9836 } 9837 9838 // ========================================================= 9839 // GLOBAL MANAGEMENT 9840 // ========================================================= 9841 9842 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9843 boolean isolated, int isolatedUid) { 9844 String proc = customProcess != null ? customProcess : info.processName; 9845 BatteryStatsImpl.Uid.Proc ps = null; 9846 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9847 int uid = info.uid; 9848 if (isolated) { 9849 if (isolatedUid == 0) { 9850 int userId = UserHandle.getUserId(uid); 9851 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9852 while (true) { 9853 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9854 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9855 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9856 } 9857 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9858 mNextIsolatedProcessUid++; 9859 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9860 // No process for this uid, use it. 9861 break; 9862 } 9863 stepsLeft--; 9864 if (stepsLeft <= 0) { 9865 return null; 9866 } 9867 } 9868 } else { 9869 // Special case for startIsolatedProcess (internal only), where 9870 // the uid of the isolated process is specified by the caller. 9871 uid = isolatedUid; 9872 } 9873 } 9874 return new ProcessRecord(stats, info, proc, uid); 9875 } 9876 9877 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9878 String abiOverride) { 9879 ProcessRecord app; 9880 if (!isolated) { 9881 app = getProcessRecordLocked(info.processName, info.uid, true); 9882 } else { 9883 app = null; 9884 } 9885 9886 if (app == null) { 9887 app = newProcessRecordLocked(info, null, isolated, 0); 9888 mProcessNames.put(info.processName, app.uid, app); 9889 if (isolated) { 9890 mIsolatedProcesses.put(app.uid, app); 9891 } 9892 updateLruProcessLocked(app, false, null); 9893 updateOomAdjLocked(); 9894 } 9895 9896 // This package really, really can not be stopped. 9897 try { 9898 AppGlobals.getPackageManager().setPackageStoppedState( 9899 info.packageName, false, UserHandle.getUserId(app.uid)); 9900 } catch (RemoteException e) { 9901 } catch (IllegalArgumentException e) { 9902 Slog.w(TAG, "Failed trying to unstop package " 9903 + info.packageName + ": " + e); 9904 } 9905 9906 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9907 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9908 app.persistent = true; 9909 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9910 } 9911 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9912 mPersistentStartingProcesses.add(app); 9913 startProcessLocked(app, "added application", app.processName, abiOverride, 9914 null /* entryPoint */, null /* entryPointArgs */); 9915 } 9916 9917 return app; 9918 } 9919 9920 public void unhandledBack() { 9921 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9922 "unhandledBack()"); 9923 9924 synchronized(this) { 9925 final long origId = Binder.clearCallingIdentity(); 9926 try { 9927 getFocusedStack().unhandledBackLocked(); 9928 } finally { 9929 Binder.restoreCallingIdentity(origId); 9930 } 9931 } 9932 } 9933 9934 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9935 enforceNotIsolatedCaller("openContentUri"); 9936 final int userId = UserHandle.getCallingUserId(); 9937 String name = uri.getAuthority(); 9938 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9939 ParcelFileDescriptor pfd = null; 9940 if (cph != null) { 9941 // We record the binder invoker's uid in thread-local storage before 9942 // going to the content provider to open the file. Later, in the code 9943 // that handles all permissions checks, we look for this uid and use 9944 // that rather than the Activity Manager's own uid. The effect is that 9945 // we do the check against the caller's permissions even though it looks 9946 // to the content provider like the Activity Manager itself is making 9947 // the request. 9948 Binder token = new Binder(); 9949 sCallerIdentity.set(new Identity( 9950 token, Binder.getCallingPid(), Binder.getCallingUid())); 9951 try { 9952 pfd = cph.provider.openFile(null, uri, "r", null, token); 9953 } catch (FileNotFoundException e) { 9954 // do nothing; pfd will be returned null 9955 } finally { 9956 // Ensure that whatever happens, we clean up the identity state 9957 sCallerIdentity.remove(); 9958 } 9959 9960 // We've got the fd now, so we're done with the provider. 9961 removeContentProviderExternalUnchecked(name, null, userId); 9962 } else { 9963 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9964 } 9965 return pfd; 9966 } 9967 9968 // Actually is sleeping or shutting down or whatever else in the future 9969 // is an inactive state. 9970 public boolean isSleepingOrShuttingDown() { 9971 return isSleeping() || mShuttingDown; 9972 } 9973 9974 public boolean isSleeping() { 9975 return mSleeping; 9976 } 9977 9978 void onWakefulnessChanged(int wakefulness) { 9979 synchronized(this) { 9980 mWakefulness = wakefulness; 9981 updateSleepIfNeededLocked(); 9982 } 9983 } 9984 9985 void finishRunningVoiceLocked() { 9986 if (mRunningVoice) { 9987 mRunningVoice = false; 9988 updateSleepIfNeededLocked(); 9989 } 9990 } 9991 9992 void updateSleepIfNeededLocked() { 9993 if (mSleeping && !shouldSleepLocked()) { 9994 mSleeping = false; 9995 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9996 } else if (!mSleeping && shouldSleepLocked()) { 9997 mSleeping = true; 9998 mStackSupervisor.goingToSleepLocked(); 9999 10000 // Initialize the wake times of all processes. 10001 checkExcessivePowerUsageLocked(false); 10002 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10003 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10004 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10005 } 10006 } 10007 10008 private boolean shouldSleepLocked() { 10009 // Resume applications while running a voice interactor. 10010 if (mRunningVoice) { 10011 return false; 10012 } 10013 10014 switch (mWakefulness) { 10015 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10016 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10017 // If we're interactive but applications are already paused then defer 10018 // resuming them until the lock screen is hidden. 10019 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10020 case PowerManagerInternal.WAKEFULNESS_DOZING: 10021 // If we're dozing then pause applications whenever the lock screen is shown. 10022 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10023 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10024 default: 10025 // If we're asleep then pause applications unconditionally. 10026 return true; 10027 } 10028 } 10029 10030 /** Pokes the task persister. */ 10031 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10032 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10033 // Never persist the home stack. 10034 return; 10035 } 10036 mTaskPersister.wakeup(task, flush); 10037 } 10038 10039 /** Notifies all listeners when the task stack has changed. */ 10040 void notifyTaskStackChangedLocked() { 10041 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10042 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10043 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10044 } 10045 10046 @Override 10047 public boolean shutdown(int timeout) { 10048 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10049 != PackageManager.PERMISSION_GRANTED) { 10050 throw new SecurityException("Requires permission " 10051 + android.Manifest.permission.SHUTDOWN); 10052 } 10053 10054 boolean timedout = false; 10055 10056 synchronized(this) { 10057 mShuttingDown = true; 10058 updateEventDispatchingLocked(); 10059 timedout = mStackSupervisor.shutdownLocked(timeout); 10060 } 10061 10062 mAppOpsService.shutdown(); 10063 if (mUsageStatsService != null) { 10064 mUsageStatsService.prepareShutdown(); 10065 } 10066 mBatteryStatsService.shutdown(); 10067 synchronized (this) { 10068 mProcessStats.shutdownLocked(); 10069 notifyTaskPersisterLocked(null, true); 10070 } 10071 10072 return timedout; 10073 } 10074 10075 public final void activitySlept(IBinder token) { 10076 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10077 10078 final long origId = Binder.clearCallingIdentity(); 10079 10080 synchronized (this) { 10081 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10082 if (r != null) { 10083 mStackSupervisor.activitySleptLocked(r); 10084 } 10085 } 10086 10087 Binder.restoreCallingIdentity(origId); 10088 } 10089 10090 private String lockScreenShownToString() { 10091 switch (mLockScreenShown) { 10092 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10093 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10094 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10095 default: return "Unknown=" + mLockScreenShown; 10096 } 10097 } 10098 10099 void logLockScreen(String msg) { 10100 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10101 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10102 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10103 + " mSleeping=" + mSleeping); 10104 } 10105 10106 void startRunningVoiceLocked() { 10107 if (!mRunningVoice) { 10108 mRunningVoice = true; 10109 updateSleepIfNeededLocked(); 10110 } 10111 } 10112 10113 private void updateEventDispatchingLocked() { 10114 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10115 } 10116 10117 public void setLockScreenShown(boolean shown) { 10118 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10119 != PackageManager.PERMISSION_GRANTED) { 10120 throw new SecurityException("Requires permission " 10121 + android.Manifest.permission.DEVICE_POWER); 10122 } 10123 10124 synchronized(this) { 10125 long ident = Binder.clearCallingIdentity(); 10126 try { 10127 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10128 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10129 updateSleepIfNeededLocked(); 10130 } finally { 10131 Binder.restoreCallingIdentity(ident); 10132 } 10133 } 10134 } 10135 10136 @Override 10137 public void stopAppSwitches() { 10138 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10139 != PackageManager.PERMISSION_GRANTED) { 10140 throw new SecurityException("Requires permission " 10141 + android.Manifest.permission.STOP_APP_SWITCHES); 10142 } 10143 10144 synchronized(this) { 10145 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10146 + APP_SWITCH_DELAY_TIME; 10147 mDidAppSwitch = false; 10148 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10149 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10150 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10151 } 10152 } 10153 10154 public void resumeAppSwitches() { 10155 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10156 != PackageManager.PERMISSION_GRANTED) { 10157 throw new SecurityException("Requires permission " 10158 + android.Manifest.permission.STOP_APP_SWITCHES); 10159 } 10160 10161 synchronized(this) { 10162 // Note that we don't execute any pending app switches... we will 10163 // let those wait until either the timeout, or the next start 10164 // activity request. 10165 mAppSwitchesAllowedTime = 0; 10166 } 10167 } 10168 10169 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10170 int callingPid, int callingUid, String name) { 10171 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10172 return true; 10173 } 10174 10175 int perm = checkComponentPermission( 10176 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10177 sourceUid, -1, true); 10178 if (perm == PackageManager.PERMISSION_GRANTED) { 10179 return true; 10180 } 10181 10182 // If the actual IPC caller is different from the logical source, then 10183 // also see if they are allowed to control app switches. 10184 if (callingUid != -1 && callingUid != sourceUid) { 10185 perm = checkComponentPermission( 10186 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10187 callingUid, -1, true); 10188 if (perm == PackageManager.PERMISSION_GRANTED) { 10189 return true; 10190 } 10191 } 10192 10193 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10194 return false; 10195 } 10196 10197 public void setDebugApp(String packageName, boolean waitForDebugger, 10198 boolean persistent) { 10199 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10200 "setDebugApp()"); 10201 10202 long ident = Binder.clearCallingIdentity(); 10203 try { 10204 // Note that this is not really thread safe if there are multiple 10205 // callers into it at the same time, but that's not a situation we 10206 // care about. 10207 if (persistent) { 10208 final ContentResolver resolver = mContext.getContentResolver(); 10209 Settings.Global.putString( 10210 resolver, Settings.Global.DEBUG_APP, 10211 packageName); 10212 Settings.Global.putInt( 10213 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10214 waitForDebugger ? 1 : 0); 10215 } 10216 10217 synchronized (this) { 10218 if (!persistent) { 10219 mOrigDebugApp = mDebugApp; 10220 mOrigWaitForDebugger = mWaitForDebugger; 10221 } 10222 mDebugApp = packageName; 10223 mWaitForDebugger = waitForDebugger; 10224 mDebugTransient = !persistent; 10225 if (packageName != null) { 10226 forceStopPackageLocked(packageName, -1, false, false, true, true, 10227 false, UserHandle.USER_ALL, "set debug app"); 10228 } 10229 } 10230 } finally { 10231 Binder.restoreCallingIdentity(ident); 10232 } 10233 } 10234 10235 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10236 synchronized (this) { 10237 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10238 if (!isDebuggable) { 10239 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10240 throw new SecurityException("Process not debuggable: " + app.packageName); 10241 } 10242 } 10243 10244 mOpenGlTraceApp = processName; 10245 } 10246 } 10247 10248 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10249 synchronized (this) { 10250 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10251 if (!isDebuggable) { 10252 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10253 throw new SecurityException("Process not debuggable: " + app.packageName); 10254 } 10255 } 10256 mProfileApp = processName; 10257 mProfileFile = profilerInfo.profileFile; 10258 if (mProfileFd != null) { 10259 try { 10260 mProfileFd.close(); 10261 } catch (IOException e) { 10262 } 10263 mProfileFd = null; 10264 } 10265 mProfileFd = profilerInfo.profileFd; 10266 mSamplingInterval = profilerInfo.samplingInterval; 10267 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10268 mProfileType = 0; 10269 } 10270 } 10271 10272 @Override 10273 public void setAlwaysFinish(boolean enabled) { 10274 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10275 "setAlwaysFinish()"); 10276 10277 Settings.Global.putInt( 10278 mContext.getContentResolver(), 10279 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10280 10281 synchronized (this) { 10282 mAlwaysFinishActivities = enabled; 10283 } 10284 } 10285 10286 @Override 10287 public void setActivityController(IActivityController controller) { 10288 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10289 "setActivityController()"); 10290 synchronized (this) { 10291 mController = controller; 10292 Watchdog.getInstance().setActivityController(controller); 10293 } 10294 } 10295 10296 @Override 10297 public void setUserIsMonkey(boolean userIsMonkey) { 10298 synchronized (this) { 10299 synchronized (mPidsSelfLocked) { 10300 final int callingPid = Binder.getCallingPid(); 10301 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10302 if (precessRecord == null) { 10303 throw new SecurityException("Unknown process: " + callingPid); 10304 } 10305 if (precessRecord.instrumentationUiAutomationConnection == null) { 10306 throw new SecurityException("Only an instrumentation process " 10307 + "with a UiAutomation can call setUserIsMonkey"); 10308 } 10309 } 10310 mUserIsMonkey = userIsMonkey; 10311 } 10312 } 10313 10314 @Override 10315 public boolean isUserAMonkey() { 10316 synchronized (this) { 10317 // If there is a controller also implies the user is a monkey. 10318 return (mUserIsMonkey || mController != null); 10319 } 10320 } 10321 10322 public void requestBugReport() { 10323 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10324 SystemProperties.set("ctl.start", "bugreport"); 10325 } 10326 10327 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10328 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10329 } 10330 10331 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10332 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10333 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10334 } 10335 return KEY_DISPATCHING_TIMEOUT; 10336 } 10337 10338 @Override 10339 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10340 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10341 != PackageManager.PERMISSION_GRANTED) { 10342 throw new SecurityException("Requires permission " 10343 + android.Manifest.permission.FILTER_EVENTS); 10344 } 10345 ProcessRecord proc; 10346 long timeout; 10347 synchronized (this) { 10348 synchronized (mPidsSelfLocked) { 10349 proc = mPidsSelfLocked.get(pid); 10350 } 10351 timeout = getInputDispatchingTimeoutLocked(proc); 10352 } 10353 10354 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10355 return -1; 10356 } 10357 10358 return timeout; 10359 } 10360 10361 /** 10362 * Handle input dispatching timeouts. 10363 * Returns whether input dispatching should be aborted or not. 10364 */ 10365 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10366 final ActivityRecord activity, final ActivityRecord parent, 10367 final boolean aboveSystem, String reason) { 10368 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10369 != PackageManager.PERMISSION_GRANTED) { 10370 throw new SecurityException("Requires permission " 10371 + android.Manifest.permission.FILTER_EVENTS); 10372 } 10373 10374 final String annotation; 10375 if (reason == null) { 10376 annotation = "Input dispatching timed out"; 10377 } else { 10378 annotation = "Input dispatching timed out (" + reason + ")"; 10379 } 10380 10381 if (proc != null) { 10382 synchronized (this) { 10383 if (proc.debugging) { 10384 return false; 10385 } 10386 10387 if (mDidDexOpt) { 10388 // Give more time since we were dexopting. 10389 mDidDexOpt = false; 10390 return false; 10391 } 10392 10393 if (proc.instrumentationClass != null) { 10394 Bundle info = new Bundle(); 10395 info.putString("shortMsg", "keyDispatchingTimedOut"); 10396 info.putString("longMsg", annotation); 10397 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10398 return true; 10399 } 10400 } 10401 mHandler.post(new Runnable() { 10402 @Override 10403 public void run() { 10404 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10405 } 10406 }); 10407 } 10408 10409 return true; 10410 } 10411 10412 public Bundle getAssistContextExtras(int requestType) { 10413 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10414 UserHandle.getCallingUserId()); 10415 if (pae == null) { 10416 return null; 10417 } 10418 synchronized (pae) { 10419 while (!pae.haveResult) { 10420 try { 10421 pae.wait(); 10422 } catch (InterruptedException e) { 10423 } 10424 } 10425 if (pae.result != null) { 10426 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10427 } 10428 } 10429 synchronized (this) { 10430 mPendingAssistExtras.remove(pae); 10431 mHandler.removeCallbacks(pae); 10432 } 10433 return pae.extras; 10434 } 10435 10436 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10437 int userHandle) { 10438 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10439 "getAssistContextExtras()"); 10440 PendingAssistExtras pae; 10441 Bundle extras = new Bundle(); 10442 synchronized (this) { 10443 ActivityRecord activity = getFocusedStack().mResumedActivity; 10444 if (activity == null) { 10445 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10446 return null; 10447 } 10448 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10449 if (activity.app == null || activity.app.thread == null) { 10450 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10451 return null; 10452 } 10453 if (activity.app.pid == Binder.getCallingPid()) { 10454 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10455 return null; 10456 } 10457 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10458 try { 10459 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10460 requestType); 10461 mPendingAssistExtras.add(pae); 10462 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10463 } catch (RemoteException e) { 10464 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10465 return null; 10466 } 10467 return pae; 10468 } 10469 } 10470 10471 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10472 PendingAssistExtras pae = (PendingAssistExtras)token; 10473 synchronized (pae) { 10474 pae.result = extras; 10475 pae.haveResult = true; 10476 pae.notifyAll(); 10477 if (pae.intent == null) { 10478 // Caller is just waiting for the result. 10479 return; 10480 } 10481 } 10482 10483 // We are now ready to launch the assist activity. 10484 synchronized (this) { 10485 boolean exists = mPendingAssistExtras.remove(pae); 10486 mHandler.removeCallbacks(pae); 10487 if (!exists) { 10488 // Timed out. 10489 return; 10490 } 10491 } 10492 pae.intent.replaceExtras(extras); 10493 if (pae.hint != null) { 10494 pae.intent.putExtra(pae.hint, true); 10495 } 10496 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10497 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10498 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10499 closeSystemDialogs("assist"); 10500 try { 10501 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10502 } catch (ActivityNotFoundException e) { 10503 Slog.w(TAG, "No activity to handle assist action.", e); 10504 } 10505 } 10506 10507 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10508 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10509 } 10510 10511 public void registerProcessObserver(IProcessObserver observer) { 10512 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10513 "registerProcessObserver()"); 10514 synchronized (this) { 10515 mProcessObservers.register(observer); 10516 } 10517 } 10518 10519 @Override 10520 public void unregisterProcessObserver(IProcessObserver observer) { 10521 synchronized (this) { 10522 mProcessObservers.unregister(observer); 10523 } 10524 } 10525 10526 @Override 10527 public boolean convertFromTranslucent(IBinder token) { 10528 final long origId = Binder.clearCallingIdentity(); 10529 try { 10530 synchronized (this) { 10531 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10532 if (r == null) { 10533 return false; 10534 } 10535 final boolean translucentChanged = r.changeWindowTranslucency(true); 10536 if (translucentChanged) { 10537 r.task.stack.releaseBackgroundResources(); 10538 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10539 } 10540 mWindowManager.setAppFullscreen(token, true); 10541 return translucentChanged; 10542 } 10543 } finally { 10544 Binder.restoreCallingIdentity(origId); 10545 } 10546 } 10547 10548 @Override 10549 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10550 final long origId = Binder.clearCallingIdentity(); 10551 try { 10552 synchronized (this) { 10553 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10554 if (r == null) { 10555 return false; 10556 } 10557 int index = r.task.mActivities.lastIndexOf(r); 10558 if (index > 0) { 10559 ActivityRecord under = r.task.mActivities.get(index - 1); 10560 under.returningOptions = options; 10561 } 10562 final boolean translucentChanged = r.changeWindowTranslucency(false); 10563 if (translucentChanged) { 10564 r.task.stack.convertToTranslucent(r); 10565 } 10566 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10567 mWindowManager.setAppFullscreen(token, false); 10568 return translucentChanged; 10569 } 10570 } finally { 10571 Binder.restoreCallingIdentity(origId); 10572 } 10573 } 10574 10575 @Override 10576 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10577 final long origId = Binder.clearCallingIdentity(); 10578 try { 10579 synchronized (this) { 10580 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10581 if (r != null) { 10582 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10583 } 10584 } 10585 return false; 10586 } finally { 10587 Binder.restoreCallingIdentity(origId); 10588 } 10589 } 10590 10591 @Override 10592 public boolean isBackgroundVisibleBehind(IBinder token) { 10593 final long origId = Binder.clearCallingIdentity(); 10594 try { 10595 synchronized (this) { 10596 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10597 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10598 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10599 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10600 return visible; 10601 } 10602 } finally { 10603 Binder.restoreCallingIdentity(origId); 10604 } 10605 } 10606 10607 @Override 10608 public ActivityOptions getActivityOptions(IBinder token) { 10609 final long origId = Binder.clearCallingIdentity(); 10610 try { 10611 synchronized (this) { 10612 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10613 if (r != null) { 10614 final ActivityOptions activityOptions = r.pendingOptions; 10615 r.pendingOptions = null; 10616 return activityOptions; 10617 } 10618 return null; 10619 } 10620 } finally { 10621 Binder.restoreCallingIdentity(origId); 10622 } 10623 } 10624 10625 @Override 10626 public void setImmersive(IBinder token, boolean immersive) { 10627 synchronized(this) { 10628 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10629 if (r == null) { 10630 throw new IllegalArgumentException(); 10631 } 10632 r.immersive = immersive; 10633 10634 // update associated state if we're frontmost 10635 if (r == mFocusedActivity) { 10636 if (DEBUG_IMMERSIVE) { 10637 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10638 } 10639 applyUpdateLockStateLocked(r); 10640 } 10641 } 10642 } 10643 10644 @Override 10645 public boolean isImmersive(IBinder token) { 10646 synchronized (this) { 10647 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10648 if (r == null) { 10649 throw new IllegalArgumentException(); 10650 } 10651 return r.immersive; 10652 } 10653 } 10654 10655 public boolean isTopActivityImmersive() { 10656 enforceNotIsolatedCaller("startActivity"); 10657 synchronized (this) { 10658 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10659 return (r != null) ? r.immersive : false; 10660 } 10661 } 10662 10663 @Override 10664 public boolean isTopOfTask(IBinder token) { 10665 synchronized (this) { 10666 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10667 if (r == null) { 10668 throw new IllegalArgumentException(); 10669 } 10670 return r.task.getTopActivity() == r; 10671 } 10672 } 10673 10674 public final void enterSafeMode() { 10675 synchronized(this) { 10676 // It only makes sense to do this before the system is ready 10677 // and started launching other packages. 10678 if (!mSystemReady) { 10679 try { 10680 AppGlobals.getPackageManager().enterSafeMode(); 10681 } catch (RemoteException e) { 10682 } 10683 } 10684 10685 mSafeMode = true; 10686 } 10687 } 10688 10689 public final void showSafeModeOverlay() { 10690 View v = LayoutInflater.from(mContext).inflate( 10691 com.android.internal.R.layout.safe_mode, null); 10692 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10693 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10694 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10695 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10696 lp.gravity = Gravity.BOTTOM | Gravity.START; 10697 lp.format = v.getBackground().getOpacity(); 10698 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10699 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10700 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10701 ((WindowManager)mContext.getSystemService( 10702 Context.WINDOW_SERVICE)).addView(v, lp); 10703 } 10704 10705 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10706 if (!(sender instanceof PendingIntentRecord)) { 10707 return; 10708 } 10709 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10710 synchronized (stats) { 10711 if (mBatteryStatsService.isOnBattery()) { 10712 mBatteryStatsService.enforceCallingPermission(); 10713 PendingIntentRecord rec = (PendingIntentRecord)sender; 10714 int MY_UID = Binder.getCallingUid(); 10715 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10716 BatteryStatsImpl.Uid.Pkg pkg = 10717 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10718 sourcePkg != null ? sourcePkg : rec.key.packageName); 10719 pkg.incWakeupsLocked(); 10720 } 10721 } 10722 } 10723 10724 public boolean killPids(int[] pids, String pReason, boolean secure) { 10725 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10726 throw new SecurityException("killPids only available to the system"); 10727 } 10728 String reason = (pReason == null) ? "Unknown" : pReason; 10729 // XXX Note: don't acquire main activity lock here, because the window 10730 // manager calls in with its locks held. 10731 10732 boolean killed = false; 10733 synchronized (mPidsSelfLocked) { 10734 int[] types = new int[pids.length]; 10735 int worstType = 0; 10736 for (int i=0; i<pids.length; i++) { 10737 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10738 if (proc != null) { 10739 int type = proc.setAdj; 10740 types[i] = type; 10741 if (type > worstType) { 10742 worstType = type; 10743 } 10744 } 10745 } 10746 10747 // If the worst oom_adj is somewhere in the cached proc LRU range, 10748 // then constrain it so we will kill all cached procs. 10749 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10750 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10751 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10752 } 10753 10754 // If this is not a secure call, don't let it kill processes that 10755 // are important. 10756 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10757 worstType = ProcessList.SERVICE_ADJ; 10758 } 10759 10760 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10761 for (int i=0; i<pids.length; i++) { 10762 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10763 if (proc == null) { 10764 continue; 10765 } 10766 int adj = proc.setAdj; 10767 if (adj >= worstType && !proc.killedByAm) { 10768 proc.kill(reason, true); 10769 killed = true; 10770 } 10771 } 10772 } 10773 return killed; 10774 } 10775 10776 @Override 10777 public void killUid(int uid, String reason) { 10778 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10779 throw new SecurityException("killUid only available to the system"); 10780 } 10781 synchronized (this) { 10782 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10783 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10784 reason != null ? reason : "kill uid"); 10785 } 10786 } 10787 10788 @Override 10789 public boolean killProcessesBelowForeground(String reason) { 10790 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10791 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10792 } 10793 10794 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10795 } 10796 10797 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10798 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10799 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10800 } 10801 10802 boolean killed = false; 10803 synchronized (mPidsSelfLocked) { 10804 final int size = mPidsSelfLocked.size(); 10805 for (int i = 0; i < size; i++) { 10806 final int pid = mPidsSelfLocked.keyAt(i); 10807 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10808 if (proc == null) continue; 10809 10810 final int adj = proc.setAdj; 10811 if (adj > belowAdj && !proc.killedByAm) { 10812 proc.kill(reason, true); 10813 killed = true; 10814 } 10815 } 10816 } 10817 return killed; 10818 } 10819 10820 @Override 10821 public void hang(final IBinder who, boolean allowRestart) { 10822 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10823 != PackageManager.PERMISSION_GRANTED) { 10824 throw new SecurityException("Requires permission " 10825 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10826 } 10827 10828 final IBinder.DeathRecipient death = new DeathRecipient() { 10829 @Override 10830 public void binderDied() { 10831 synchronized (this) { 10832 notifyAll(); 10833 } 10834 } 10835 }; 10836 10837 try { 10838 who.linkToDeath(death, 0); 10839 } catch (RemoteException e) { 10840 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10841 return; 10842 } 10843 10844 synchronized (this) { 10845 Watchdog.getInstance().setAllowRestart(allowRestart); 10846 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10847 synchronized (death) { 10848 while (who.isBinderAlive()) { 10849 try { 10850 death.wait(); 10851 } catch (InterruptedException e) { 10852 } 10853 } 10854 } 10855 Watchdog.getInstance().setAllowRestart(true); 10856 } 10857 } 10858 10859 @Override 10860 public void restart() { 10861 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10862 != PackageManager.PERMISSION_GRANTED) { 10863 throw new SecurityException("Requires permission " 10864 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10865 } 10866 10867 Log.i(TAG, "Sending shutdown broadcast..."); 10868 10869 BroadcastReceiver br = new BroadcastReceiver() { 10870 @Override public void onReceive(Context context, Intent intent) { 10871 // Now the broadcast is done, finish up the low-level shutdown. 10872 Log.i(TAG, "Shutting down activity manager..."); 10873 shutdown(10000); 10874 Log.i(TAG, "Shutdown complete, restarting!"); 10875 Process.killProcess(Process.myPid()); 10876 System.exit(10); 10877 } 10878 }; 10879 10880 // First send the high-level shut down broadcast. 10881 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10882 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10883 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10884 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10885 mContext.sendOrderedBroadcastAsUser(intent, 10886 UserHandle.ALL, null, br, mHandler, 0, null, null); 10887 */ 10888 br.onReceive(mContext, intent); 10889 } 10890 10891 private long getLowRamTimeSinceIdle(long now) { 10892 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10893 } 10894 10895 @Override 10896 public void performIdleMaintenance() { 10897 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10898 != PackageManager.PERMISSION_GRANTED) { 10899 throw new SecurityException("Requires permission " 10900 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10901 } 10902 10903 synchronized (this) { 10904 final long now = SystemClock.uptimeMillis(); 10905 final long timeSinceLastIdle = now - mLastIdleTime; 10906 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10907 mLastIdleTime = now; 10908 mLowRamTimeSinceLastIdle = 0; 10909 if (mLowRamStartTime != 0) { 10910 mLowRamStartTime = now; 10911 } 10912 10913 StringBuilder sb = new StringBuilder(128); 10914 sb.append("Idle maintenance over "); 10915 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10916 sb.append(" low RAM for "); 10917 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10918 Slog.i(TAG, sb.toString()); 10919 10920 // If at least 1/3 of our time since the last idle period has been spent 10921 // with RAM low, then we want to kill processes. 10922 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10923 10924 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10925 ProcessRecord proc = mLruProcesses.get(i); 10926 if (proc.notCachedSinceIdle) { 10927 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10928 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10929 if (doKilling && proc.initialIdlePss != 0 10930 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10931 sb = new StringBuilder(128); 10932 sb.append("Kill"); 10933 sb.append(proc.processName); 10934 sb.append(" in idle maint: pss="); 10935 sb.append(proc.lastPss); 10936 sb.append(", initialPss="); 10937 sb.append(proc.initialIdlePss); 10938 sb.append(", period="); 10939 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10940 sb.append(", lowRamPeriod="); 10941 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10942 Slog.wtfQuiet(TAG, sb.toString()); 10943 proc.kill("idle maint (pss " + proc.lastPss 10944 + " from " + proc.initialIdlePss + ")", true); 10945 } 10946 } 10947 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10948 proc.notCachedSinceIdle = true; 10949 proc.initialIdlePss = 0; 10950 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10951 mTestPssMode, isSleeping(), now); 10952 } 10953 } 10954 10955 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10956 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10957 } 10958 } 10959 10960 private void retrieveSettings() { 10961 final ContentResolver resolver = mContext.getContentResolver(); 10962 String debugApp = Settings.Global.getString( 10963 resolver, Settings.Global.DEBUG_APP); 10964 boolean waitForDebugger = Settings.Global.getInt( 10965 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10966 boolean alwaysFinishActivities = Settings.Global.getInt( 10967 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10968 boolean forceRtl = Settings.Global.getInt( 10969 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10970 // Transfer any global setting for forcing RTL layout, into a System Property 10971 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10972 10973 Configuration configuration = new Configuration(); 10974 Settings.System.getConfiguration(resolver, configuration); 10975 if (forceRtl) { 10976 // This will take care of setting the correct layout direction flags 10977 configuration.setLayoutDirection(configuration.locale); 10978 } 10979 10980 synchronized (this) { 10981 mDebugApp = mOrigDebugApp = debugApp; 10982 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10983 mAlwaysFinishActivities = alwaysFinishActivities; 10984 // This happens before any activities are started, so we can 10985 // change mConfiguration in-place. 10986 updateConfigurationLocked(configuration, null, false, true); 10987 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10988 } 10989 } 10990 10991 /** Loads resources after the current configuration has been set. */ 10992 private void loadResourcesOnSystemReady() { 10993 final Resources res = mContext.getResources(); 10994 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10995 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10996 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10997 } 10998 10999 public boolean testIsSystemReady() { 11000 // no need to synchronize(this) just to read & return the value 11001 return mSystemReady; 11002 } 11003 11004 private static File getCalledPreBootReceiversFile() { 11005 File dataDir = Environment.getDataDirectory(); 11006 File systemDir = new File(dataDir, "system"); 11007 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11008 return fname; 11009 } 11010 11011 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11012 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11013 File file = getCalledPreBootReceiversFile(); 11014 FileInputStream fis = null; 11015 try { 11016 fis = new FileInputStream(file); 11017 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11018 int fvers = dis.readInt(); 11019 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11020 String vers = dis.readUTF(); 11021 String codename = dis.readUTF(); 11022 String build = dis.readUTF(); 11023 if (android.os.Build.VERSION.RELEASE.equals(vers) 11024 && android.os.Build.VERSION.CODENAME.equals(codename) 11025 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11026 int num = dis.readInt(); 11027 while (num > 0) { 11028 num--; 11029 String pkg = dis.readUTF(); 11030 String cls = dis.readUTF(); 11031 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11032 } 11033 } 11034 } 11035 } catch (FileNotFoundException e) { 11036 } catch (IOException e) { 11037 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11038 } finally { 11039 if (fis != null) { 11040 try { 11041 fis.close(); 11042 } catch (IOException e) { 11043 } 11044 } 11045 } 11046 return lastDoneReceivers; 11047 } 11048 11049 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11050 File file = getCalledPreBootReceiversFile(); 11051 FileOutputStream fos = null; 11052 DataOutputStream dos = null; 11053 try { 11054 fos = new FileOutputStream(file); 11055 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11056 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11057 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11058 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11059 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11060 dos.writeInt(list.size()); 11061 for (int i=0; i<list.size(); i++) { 11062 dos.writeUTF(list.get(i).getPackageName()); 11063 dos.writeUTF(list.get(i).getClassName()); 11064 } 11065 } catch (IOException e) { 11066 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11067 file.delete(); 11068 } finally { 11069 FileUtils.sync(fos); 11070 if (dos != null) { 11071 try { 11072 dos.close(); 11073 } catch (IOException e) { 11074 // TODO Auto-generated catch block 11075 e.printStackTrace(); 11076 } 11077 } 11078 } 11079 } 11080 11081 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11082 ArrayList<ComponentName> doneReceivers, int userId) { 11083 boolean waitingUpdate = false; 11084 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11085 List<ResolveInfo> ris = null; 11086 try { 11087 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11088 intent, null, 0, userId); 11089 } catch (RemoteException e) { 11090 } 11091 if (ris != null) { 11092 for (int i=ris.size()-1; i>=0; i--) { 11093 if ((ris.get(i).activityInfo.applicationInfo.flags 11094 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11095 ris.remove(i); 11096 } 11097 } 11098 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11099 11100 // For User 0, load the version number. When delivering to a new user, deliver 11101 // to all receivers. 11102 if (userId == UserHandle.USER_OWNER) { 11103 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11104 for (int i=0; i<ris.size(); i++) { 11105 ActivityInfo ai = ris.get(i).activityInfo; 11106 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11107 if (lastDoneReceivers.contains(comp)) { 11108 // We already did the pre boot receiver for this app with the current 11109 // platform version, so don't do it again... 11110 ris.remove(i); 11111 i--; 11112 // ...however, do keep it as one that has been done, so we don't 11113 // forget about it when rewriting the file of last done receivers. 11114 doneReceivers.add(comp); 11115 } 11116 } 11117 } 11118 11119 // If primary user, send broadcast to all available users, else just to userId 11120 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11121 : new int[] { userId }; 11122 for (int i = 0; i < ris.size(); i++) { 11123 ActivityInfo ai = ris.get(i).activityInfo; 11124 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11125 doneReceivers.add(comp); 11126 intent.setComponent(comp); 11127 for (int j=0; j<users.length; j++) { 11128 IIntentReceiver finisher = null; 11129 // On last receiver and user, set up a completion callback 11130 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11131 finisher = new IIntentReceiver.Stub() { 11132 public void performReceive(Intent intent, int resultCode, 11133 String data, Bundle extras, boolean ordered, 11134 boolean sticky, int sendingUser) { 11135 // The raw IIntentReceiver interface is called 11136 // with the AM lock held, so redispatch to 11137 // execute our code without the lock. 11138 mHandler.post(onFinishCallback); 11139 } 11140 }; 11141 } 11142 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11143 + " for user " + users[j]); 11144 broadcastIntentLocked(null, null, intent, null, finisher, 11145 0, null, null, null, AppOpsManager.OP_NONE, 11146 true, false, MY_PID, Process.SYSTEM_UID, 11147 users[j]); 11148 if (finisher != null) { 11149 waitingUpdate = true; 11150 } 11151 } 11152 } 11153 } 11154 11155 return waitingUpdate; 11156 } 11157 11158 public void systemReady(final Runnable goingCallback) { 11159 synchronized(this) { 11160 if (mSystemReady) { 11161 // If we're done calling all the receivers, run the next "boot phase" passed in 11162 // by the SystemServer 11163 if (goingCallback != null) { 11164 goingCallback.run(); 11165 } 11166 return; 11167 } 11168 11169 // Make sure we have the current profile info, since it is needed for 11170 // security checks. 11171 updateCurrentProfileIdsLocked(); 11172 11173 if (mRecentTasks == null) { 11174 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11175 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11176 if (!mRecentTasks.isEmpty()) { 11177 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11178 } 11179 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11180 mTaskPersister.startPersisting(); 11181 } 11182 11183 // Check to see if there are any update receivers to run. 11184 if (!mDidUpdate) { 11185 if (mWaitingUpdate) { 11186 return; 11187 } 11188 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11189 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11190 public void run() { 11191 synchronized (ActivityManagerService.this) { 11192 mDidUpdate = true; 11193 } 11194 writeLastDonePreBootReceivers(doneReceivers); 11195 showBootMessage(mContext.getText( 11196 R.string.android_upgrading_complete), 11197 false); 11198 systemReady(goingCallback); 11199 } 11200 }, doneReceivers, UserHandle.USER_OWNER); 11201 11202 if (mWaitingUpdate) { 11203 return; 11204 } 11205 mDidUpdate = true; 11206 } 11207 11208 mAppOpsService.systemReady(); 11209 mSystemReady = true; 11210 } 11211 11212 ArrayList<ProcessRecord> procsToKill = null; 11213 synchronized(mPidsSelfLocked) { 11214 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11215 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11216 if (!isAllowedWhileBooting(proc.info)){ 11217 if (procsToKill == null) { 11218 procsToKill = new ArrayList<ProcessRecord>(); 11219 } 11220 procsToKill.add(proc); 11221 } 11222 } 11223 } 11224 11225 synchronized(this) { 11226 if (procsToKill != null) { 11227 for (int i=procsToKill.size()-1; i>=0; i--) { 11228 ProcessRecord proc = procsToKill.get(i); 11229 Slog.i(TAG, "Removing system update proc: " + proc); 11230 removeProcessLocked(proc, true, false, "system update done"); 11231 } 11232 } 11233 11234 // Now that we have cleaned up any update processes, we 11235 // are ready to start launching real processes and know that 11236 // we won't trample on them any more. 11237 mProcessesReady = true; 11238 } 11239 11240 Slog.i(TAG, "System now ready"); 11241 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11242 SystemClock.uptimeMillis()); 11243 11244 synchronized(this) { 11245 // Make sure we have no pre-ready processes sitting around. 11246 11247 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11248 ResolveInfo ri = mContext.getPackageManager() 11249 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11250 STOCK_PM_FLAGS); 11251 CharSequence errorMsg = null; 11252 if (ri != null) { 11253 ActivityInfo ai = ri.activityInfo; 11254 ApplicationInfo app = ai.applicationInfo; 11255 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11256 mTopAction = Intent.ACTION_FACTORY_TEST; 11257 mTopData = null; 11258 mTopComponent = new ComponentName(app.packageName, 11259 ai.name); 11260 } else { 11261 errorMsg = mContext.getResources().getText( 11262 com.android.internal.R.string.factorytest_not_system); 11263 } 11264 } else { 11265 errorMsg = mContext.getResources().getText( 11266 com.android.internal.R.string.factorytest_no_action); 11267 } 11268 if (errorMsg != null) { 11269 mTopAction = null; 11270 mTopData = null; 11271 mTopComponent = null; 11272 Message msg = Message.obtain(); 11273 msg.what = SHOW_FACTORY_ERROR_MSG; 11274 msg.getData().putCharSequence("msg", errorMsg); 11275 mHandler.sendMessage(msg); 11276 } 11277 } 11278 } 11279 11280 retrieveSettings(); 11281 loadResourcesOnSystemReady(); 11282 11283 synchronized (this) { 11284 readGrantedUriPermissionsLocked(); 11285 } 11286 11287 if (goingCallback != null) goingCallback.run(); 11288 11289 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11290 Integer.toString(mCurrentUserId), mCurrentUserId); 11291 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11292 Integer.toString(mCurrentUserId), mCurrentUserId); 11293 mSystemServiceManager.startUser(mCurrentUserId); 11294 11295 synchronized (this) { 11296 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11297 try { 11298 List apps = AppGlobals.getPackageManager(). 11299 getPersistentApplications(STOCK_PM_FLAGS); 11300 if (apps != null) { 11301 int N = apps.size(); 11302 int i; 11303 for (i=0; i<N; i++) { 11304 ApplicationInfo info 11305 = (ApplicationInfo)apps.get(i); 11306 if (info != null && 11307 !info.packageName.equals("android")) { 11308 addAppLocked(info, false, null /* ABI override */); 11309 } 11310 } 11311 } 11312 } catch (RemoteException ex) { 11313 // pm is in same process, this will never happen. 11314 } 11315 } 11316 11317 // Start up initial activity. 11318 mBooting = true; 11319 startHomeActivityLocked(mCurrentUserId); 11320 11321 try { 11322 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11323 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11324 + " data partition or your device will be unstable."); 11325 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11326 } 11327 } catch (RemoteException e) { 11328 } 11329 11330 if (!Build.isFingerprintConsistent()) { 11331 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11332 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11333 } 11334 11335 long ident = Binder.clearCallingIdentity(); 11336 try { 11337 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11338 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11339 | Intent.FLAG_RECEIVER_FOREGROUND); 11340 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11341 broadcastIntentLocked(null, null, intent, 11342 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11343 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11344 intent = new Intent(Intent.ACTION_USER_STARTING); 11345 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11346 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11347 broadcastIntentLocked(null, null, intent, 11348 null, new IIntentReceiver.Stub() { 11349 @Override 11350 public void performReceive(Intent intent, int resultCode, String data, 11351 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11352 throws RemoteException { 11353 } 11354 }, 0, null, null, 11355 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11356 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11357 } catch (Throwable t) { 11358 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11359 } finally { 11360 Binder.restoreCallingIdentity(ident); 11361 } 11362 mStackSupervisor.resumeTopActivitiesLocked(); 11363 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11364 } 11365 } 11366 11367 private boolean makeAppCrashingLocked(ProcessRecord app, 11368 String shortMsg, String longMsg, String stackTrace) { 11369 app.crashing = true; 11370 app.crashingReport = generateProcessError(app, 11371 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11372 startAppProblemLocked(app); 11373 app.stopFreezingAllLocked(); 11374 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11375 } 11376 11377 private void makeAppNotRespondingLocked(ProcessRecord app, 11378 String activity, String shortMsg, String longMsg) { 11379 app.notResponding = true; 11380 app.notRespondingReport = generateProcessError(app, 11381 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11382 activity, shortMsg, longMsg, null); 11383 startAppProblemLocked(app); 11384 app.stopFreezingAllLocked(); 11385 } 11386 11387 /** 11388 * Generate a process error record, suitable for attachment to a ProcessRecord. 11389 * 11390 * @param app The ProcessRecord in which the error occurred. 11391 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11392 * ActivityManager.AppErrorStateInfo 11393 * @param activity The activity associated with the crash, if known. 11394 * @param shortMsg Short message describing the crash. 11395 * @param longMsg Long message describing the crash. 11396 * @param stackTrace Full crash stack trace, may be null. 11397 * 11398 * @return Returns a fully-formed AppErrorStateInfo record. 11399 */ 11400 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11401 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11402 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11403 11404 report.condition = condition; 11405 report.processName = app.processName; 11406 report.pid = app.pid; 11407 report.uid = app.info.uid; 11408 report.tag = activity; 11409 report.shortMsg = shortMsg; 11410 report.longMsg = longMsg; 11411 report.stackTrace = stackTrace; 11412 11413 return report; 11414 } 11415 11416 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11417 synchronized (this) { 11418 app.crashing = false; 11419 app.crashingReport = null; 11420 app.notResponding = false; 11421 app.notRespondingReport = null; 11422 if (app.anrDialog == fromDialog) { 11423 app.anrDialog = null; 11424 } 11425 if (app.waitDialog == fromDialog) { 11426 app.waitDialog = null; 11427 } 11428 if (app.pid > 0 && app.pid != MY_PID) { 11429 handleAppCrashLocked(app, null, null, null); 11430 app.kill("user request after error", true); 11431 } 11432 } 11433 } 11434 11435 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11436 String stackTrace) { 11437 long now = SystemClock.uptimeMillis(); 11438 11439 Long crashTime; 11440 if (!app.isolated) { 11441 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11442 } else { 11443 crashTime = null; 11444 } 11445 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11446 // This process loses! 11447 Slog.w(TAG, "Process " + app.info.processName 11448 + " has crashed too many times: killing!"); 11449 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11450 app.userId, app.info.processName, app.uid); 11451 mStackSupervisor.handleAppCrashLocked(app); 11452 if (!app.persistent) { 11453 // We don't want to start this process again until the user 11454 // explicitly does so... but for persistent process, we really 11455 // need to keep it running. If a persistent process is actually 11456 // repeatedly crashing, then badness for everyone. 11457 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11458 app.info.processName); 11459 if (!app.isolated) { 11460 // XXX We don't have a way to mark isolated processes 11461 // as bad, since they don't have a peristent identity. 11462 mBadProcesses.put(app.info.processName, app.uid, 11463 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11464 mProcessCrashTimes.remove(app.info.processName, app.uid); 11465 } 11466 app.bad = true; 11467 app.removed = true; 11468 // Don't let services in this process be restarted and potentially 11469 // annoy the user repeatedly. Unless it is persistent, since those 11470 // processes run critical code. 11471 removeProcessLocked(app, false, false, "crash"); 11472 mStackSupervisor.resumeTopActivitiesLocked(); 11473 return false; 11474 } 11475 mStackSupervisor.resumeTopActivitiesLocked(); 11476 } else { 11477 mStackSupervisor.finishTopRunningActivityLocked(app); 11478 } 11479 11480 // Bump up the crash count of any services currently running in the proc. 11481 for (int i=app.services.size()-1; i>=0; i--) { 11482 // Any services running in the application need to be placed 11483 // back in the pending list. 11484 ServiceRecord sr = app.services.valueAt(i); 11485 sr.crashCount++; 11486 } 11487 11488 // If the crashing process is what we consider to be the "home process" and it has been 11489 // replaced by a third-party app, clear the package preferred activities from packages 11490 // with a home activity running in the process to prevent a repeatedly crashing app 11491 // from blocking the user to manually clear the list. 11492 final ArrayList<ActivityRecord> activities = app.activities; 11493 if (app == mHomeProcess && activities.size() > 0 11494 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11495 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11496 final ActivityRecord r = activities.get(activityNdx); 11497 if (r.isHomeActivity()) { 11498 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11499 try { 11500 ActivityThread.getPackageManager() 11501 .clearPackagePreferredActivities(r.packageName); 11502 } catch (RemoteException c) { 11503 // pm is in same process, this will never happen. 11504 } 11505 } 11506 } 11507 } 11508 11509 if (!app.isolated) { 11510 // XXX Can't keep track of crash times for isolated processes, 11511 // because they don't have a perisistent identity. 11512 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11513 } 11514 11515 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11516 return true; 11517 } 11518 11519 void startAppProblemLocked(ProcessRecord app) { 11520 // If this app is not running under the current user, then we 11521 // can't give it a report button because that would require 11522 // launching the report UI under a different user. 11523 app.errorReportReceiver = null; 11524 11525 for (int userId : mCurrentProfileIds) { 11526 if (app.userId == userId) { 11527 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11528 mContext, app.info.packageName, app.info.flags); 11529 } 11530 } 11531 skipCurrentReceiverLocked(app); 11532 } 11533 11534 void skipCurrentReceiverLocked(ProcessRecord app) { 11535 for (BroadcastQueue queue : mBroadcastQueues) { 11536 queue.skipCurrentReceiverLocked(app); 11537 } 11538 } 11539 11540 /** 11541 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11542 * The application process will exit immediately after this call returns. 11543 * @param app object of the crashing app, null for the system server 11544 * @param crashInfo describing the exception 11545 */ 11546 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11547 ProcessRecord r = findAppProcess(app, "Crash"); 11548 final String processName = app == null ? "system_server" 11549 : (r == null ? "unknown" : r.processName); 11550 11551 handleApplicationCrashInner("crash", r, processName, crashInfo); 11552 } 11553 11554 /* Native crash reporting uses this inner version because it needs to be somewhat 11555 * decoupled from the AM-managed cleanup lifecycle 11556 */ 11557 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11558 ApplicationErrorReport.CrashInfo crashInfo) { 11559 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11560 UserHandle.getUserId(Binder.getCallingUid()), processName, 11561 r == null ? -1 : r.info.flags, 11562 crashInfo.exceptionClassName, 11563 crashInfo.exceptionMessage, 11564 crashInfo.throwFileName, 11565 crashInfo.throwLineNumber); 11566 11567 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11568 11569 crashApplication(r, crashInfo); 11570 } 11571 11572 public void handleApplicationStrictModeViolation( 11573 IBinder app, 11574 int violationMask, 11575 StrictMode.ViolationInfo info) { 11576 ProcessRecord r = findAppProcess(app, "StrictMode"); 11577 if (r == null) { 11578 return; 11579 } 11580 11581 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11582 Integer stackFingerprint = info.hashCode(); 11583 boolean logIt = true; 11584 synchronized (mAlreadyLoggedViolatedStacks) { 11585 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11586 logIt = false; 11587 // TODO: sub-sample into EventLog for these, with 11588 // the info.durationMillis? Then we'd get 11589 // the relative pain numbers, without logging all 11590 // the stack traces repeatedly. We'd want to do 11591 // likewise in the client code, which also does 11592 // dup suppression, before the Binder call. 11593 } else { 11594 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11595 mAlreadyLoggedViolatedStacks.clear(); 11596 } 11597 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11598 } 11599 } 11600 if (logIt) { 11601 logStrictModeViolationToDropBox(r, info); 11602 } 11603 } 11604 11605 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11606 AppErrorResult result = new AppErrorResult(); 11607 synchronized (this) { 11608 final long origId = Binder.clearCallingIdentity(); 11609 11610 Message msg = Message.obtain(); 11611 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11612 HashMap<String, Object> data = new HashMap<String, Object>(); 11613 data.put("result", result); 11614 data.put("app", r); 11615 data.put("violationMask", violationMask); 11616 data.put("info", info); 11617 msg.obj = data; 11618 mHandler.sendMessage(msg); 11619 11620 Binder.restoreCallingIdentity(origId); 11621 } 11622 int res = result.get(); 11623 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11624 } 11625 } 11626 11627 // Depending on the policy in effect, there could be a bunch of 11628 // these in quick succession so we try to batch these together to 11629 // minimize disk writes, number of dropbox entries, and maximize 11630 // compression, by having more fewer, larger records. 11631 private void logStrictModeViolationToDropBox( 11632 ProcessRecord process, 11633 StrictMode.ViolationInfo info) { 11634 if (info == null) { 11635 return; 11636 } 11637 final boolean isSystemApp = process == null || 11638 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11639 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11640 final String processName = process == null ? "unknown" : process.processName; 11641 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11642 final DropBoxManager dbox = (DropBoxManager) 11643 mContext.getSystemService(Context.DROPBOX_SERVICE); 11644 11645 // Exit early if the dropbox isn't configured to accept this report type. 11646 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11647 11648 boolean bufferWasEmpty; 11649 boolean needsFlush; 11650 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11651 synchronized (sb) { 11652 bufferWasEmpty = sb.length() == 0; 11653 appendDropBoxProcessHeaders(process, processName, sb); 11654 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11655 sb.append("System-App: ").append(isSystemApp).append("\n"); 11656 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11657 if (info.violationNumThisLoop != 0) { 11658 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11659 } 11660 if (info.numAnimationsRunning != 0) { 11661 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11662 } 11663 if (info.broadcastIntentAction != null) { 11664 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11665 } 11666 if (info.durationMillis != -1) { 11667 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11668 } 11669 if (info.numInstances != -1) { 11670 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11671 } 11672 if (info.tags != null) { 11673 for (String tag : info.tags) { 11674 sb.append("Span-Tag: ").append(tag).append("\n"); 11675 } 11676 } 11677 sb.append("\n"); 11678 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11679 sb.append(info.crashInfo.stackTrace); 11680 } 11681 sb.append("\n"); 11682 11683 // Only buffer up to ~64k. Various logging bits truncate 11684 // things at 128k. 11685 needsFlush = (sb.length() > 64 * 1024); 11686 } 11687 11688 // Flush immediately if the buffer's grown too large, or this 11689 // is a non-system app. Non-system apps are isolated with a 11690 // different tag & policy and not batched. 11691 // 11692 // Batching is useful during internal testing with 11693 // StrictMode settings turned up high. Without batching, 11694 // thousands of separate files could be created on boot. 11695 if (!isSystemApp || needsFlush) { 11696 new Thread("Error dump: " + dropboxTag) { 11697 @Override 11698 public void run() { 11699 String report; 11700 synchronized (sb) { 11701 report = sb.toString(); 11702 sb.delete(0, sb.length()); 11703 sb.trimToSize(); 11704 } 11705 if (report.length() != 0) { 11706 dbox.addText(dropboxTag, report); 11707 } 11708 } 11709 }.start(); 11710 return; 11711 } 11712 11713 // System app batching: 11714 if (!bufferWasEmpty) { 11715 // An existing dropbox-writing thread is outstanding, so 11716 // we don't need to start it up. The existing thread will 11717 // catch the buffer appends we just did. 11718 return; 11719 } 11720 11721 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11722 // (After this point, we shouldn't access AMS internal data structures.) 11723 new Thread("Error dump: " + dropboxTag) { 11724 @Override 11725 public void run() { 11726 // 5 second sleep to let stacks arrive and be batched together 11727 try { 11728 Thread.sleep(5000); // 5 seconds 11729 } catch (InterruptedException e) {} 11730 11731 String errorReport; 11732 synchronized (mStrictModeBuffer) { 11733 errorReport = mStrictModeBuffer.toString(); 11734 if (errorReport.length() == 0) { 11735 return; 11736 } 11737 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11738 mStrictModeBuffer.trimToSize(); 11739 } 11740 dbox.addText(dropboxTag, errorReport); 11741 } 11742 }.start(); 11743 } 11744 11745 /** 11746 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11747 * @param app object of the crashing app, null for the system server 11748 * @param tag reported by the caller 11749 * @param system whether this wtf is coming from the system 11750 * @param crashInfo describing the context of the error 11751 * @return true if the process should exit immediately (WTF is fatal) 11752 */ 11753 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11754 final ApplicationErrorReport.CrashInfo crashInfo) { 11755 final int callingUid = Binder.getCallingUid(); 11756 final int callingPid = Binder.getCallingPid(); 11757 11758 if (system) { 11759 // If this is coming from the system, we could very well have low-level 11760 // system locks held, so we want to do this all asynchronously. And we 11761 // never want this to become fatal, so there is that too. 11762 mHandler.post(new Runnable() { 11763 @Override public void run() { 11764 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11765 } 11766 }); 11767 return false; 11768 } 11769 11770 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11771 crashInfo); 11772 11773 if (r != null && r.pid != Process.myPid() && 11774 Settings.Global.getInt(mContext.getContentResolver(), 11775 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11776 crashApplication(r, crashInfo); 11777 return true; 11778 } else { 11779 return false; 11780 } 11781 } 11782 11783 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11784 final ApplicationErrorReport.CrashInfo crashInfo) { 11785 final ProcessRecord r = findAppProcess(app, "WTF"); 11786 final String processName = app == null ? "system_server" 11787 : (r == null ? "unknown" : r.processName); 11788 11789 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11790 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11791 11792 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11793 11794 return r; 11795 } 11796 11797 /** 11798 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11799 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11800 */ 11801 private ProcessRecord findAppProcess(IBinder app, String reason) { 11802 if (app == null) { 11803 return null; 11804 } 11805 11806 synchronized (this) { 11807 final int NP = mProcessNames.getMap().size(); 11808 for (int ip=0; ip<NP; ip++) { 11809 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11810 final int NA = apps.size(); 11811 for (int ia=0; ia<NA; ia++) { 11812 ProcessRecord p = apps.valueAt(ia); 11813 if (p.thread != null && p.thread.asBinder() == app) { 11814 return p; 11815 } 11816 } 11817 } 11818 11819 Slog.w(TAG, "Can't find mystery application for " + reason 11820 + " from pid=" + Binder.getCallingPid() 11821 + " uid=" + Binder.getCallingUid() + ": " + app); 11822 return null; 11823 } 11824 } 11825 11826 /** 11827 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11828 * to append various headers to the dropbox log text. 11829 */ 11830 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11831 StringBuilder sb) { 11832 // Watchdog thread ends up invoking this function (with 11833 // a null ProcessRecord) to add the stack file to dropbox. 11834 // Do not acquire a lock on this (am) in such cases, as it 11835 // could cause a potential deadlock, if and when watchdog 11836 // is invoked due to unavailability of lock on am and it 11837 // would prevent watchdog from killing system_server. 11838 if (process == null) { 11839 sb.append("Process: ").append(processName).append("\n"); 11840 return; 11841 } 11842 // Note: ProcessRecord 'process' is guarded by the service 11843 // instance. (notably process.pkgList, which could otherwise change 11844 // concurrently during execution of this method) 11845 synchronized (this) { 11846 sb.append("Process: ").append(processName).append("\n"); 11847 int flags = process.info.flags; 11848 IPackageManager pm = AppGlobals.getPackageManager(); 11849 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11850 for (int ip=0; ip<process.pkgList.size(); ip++) { 11851 String pkg = process.pkgList.keyAt(ip); 11852 sb.append("Package: ").append(pkg); 11853 try { 11854 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11855 if (pi != null) { 11856 sb.append(" v").append(pi.versionCode); 11857 if (pi.versionName != null) { 11858 sb.append(" (").append(pi.versionName).append(")"); 11859 } 11860 } 11861 } catch (RemoteException e) { 11862 Slog.e(TAG, "Error getting package info: " + pkg, e); 11863 } 11864 sb.append("\n"); 11865 } 11866 } 11867 } 11868 11869 private static String processClass(ProcessRecord process) { 11870 if (process == null || process.pid == MY_PID) { 11871 return "system_server"; 11872 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11873 return "system_app"; 11874 } else { 11875 return "data_app"; 11876 } 11877 } 11878 11879 /** 11880 * Write a description of an error (crash, WTF, ANR) to the drop box. 11881 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11882 * @param process which caused the error, null means the system server 11883 * @param activity which triggered the error, null if unknown 11884 * @param parent activity related to the error, null if unknown 11885 * @param subject line related to the error, null if absent 11886 * @param report in long form describing the error, null if absent 11887 * @param logFile to include in the report, null if none 11888 * @param crashInfo giving an application stack trace, null if absent 11889 */ 11890 public void addErrorToDropBox(String eventType, 11891 ProcessRecord process, String processName, ActivityRecord activity, 11892 ActivityRecord parent, String subject, 11893 final String report, final File logFile, 11894 final ApplicationErrorReport.CrashInfo crashInfo) { 11895 // NOTE -- this must never acquire the ActivityManagerService lock, 11896 // otherwise the watchdog may be prevented from resetting the system. 11897 11898 final String dropboxTag = processClass(process) + "_" + eventType; 11899 final DropBoxManager dbox = (DropBoxManager) 11900 mContext.getSystemService(Context.DROPBOX_SERVICE); 11901 11902 // Exit early if the dropbox isn't configured to accept this report type. 11903 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11904 11905 final StringBuilder sb = new StringBuilder(1024); 11906 appendDropBoxProcessHeaders(process, processName, sb); 11907 if (activity != null) { 11908 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11909 } 11910 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11911 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11912 } 11913 if (parent != null && parent != activity) { 11914 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11915 } 11916 if (subject != null) { 11917 sb.append("Subject: ").append(subject).append("\n"); 11918 } 11919 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11920 if (Debug.isDebuggerConnected()) { 11921 sb.append("Debugger: Connected\n"); 11922 } 11923 sb.append("\n"); 11924 11925 // Do the rest in a worker thread to avoid blocking the caller on I/O 11926 // (After this point, we shouldn't access AMS internal data structures.) 11927 Thread worker = new Thread("Error dump: " + dropboxTag) { 11928 @Override 11929 public void run() { 11930 if (report != null) { 11931 sb.append(report); 11932 } 11933 if (logFile != null) { 11934 try { 11935 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11936 "\n\n[[TRUNCATED]]")); 11937 } catch (IOException e) { 11938 Slog.e(TAG, "Error reading " + logFile, e); 11939 } 11940 } 11941 if (crashInfo != null && crashInfo.stackTrace != null) { 11942 sb.append(crashInfo.stackTrace); 11943 } 11944 11945 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11946 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11947 if (lines > 0) { 11948 sb.append("\n"); 11949 11950 // Merge several logcat streams, and take the last N lines 11951 InputStreamReader input = null; 11952 try { 11953 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11954 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11955 "-b", "crash", 11956 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11957 11958 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11959 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11960 input = new InputStreamReader(logcat.getInputStream()); 11961 11962 int num; 11963 char[] buf = new char[8192]; 11964 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11965 } catch (IOException e) { 11966 Slog.e(TAG, "Error running logcat", e); 11967 } finally { 11968 if (input != null) try { input.close(); } catch (IOException e) {} 11969 } 11970 } 11971 11972 dbox.addText(dropboxTag, sb.toString()); 11973 } 11974 }; 11975 11976 if (process == null) { 11977 // If process is null, we are being called from some internal code 11978 // and may be about to die -- run this synchronously. 11979 worker.run(); 11980 } else { 11981 worker.start(); 11982 } 11983 } 11984 11985 /** 11986 * Bring up the "unexpected error" dialog box for a crashing app. 11987 * Deal with edge cases (intercepts from instrumented applications, 11988 * ActivityController, error intent receivers, that sort of thing). 11989 * @param r the application crashing 11990 * @param crashInfo describing the failure 11991 */ 11992 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11993 long timeMillis = System.currentTimeMillis(); 11994 String shortMsg = crashInfo.exceptionClassName; 11995 String longMsg = crashInfo.exceptionMessage; 11996 String stackTrace = crashInfo.stackTrace; 11997 if (shortMsg != null && longMsg != null) { 11998 longMsg = shortMsg + ": " + longMsg; 11999 } else if (shortMsg != null) { 12000 longMsg = shortMsg; 12001 } 12002 12003 AppErrorResult result = new AppErrorResult(); 12004 synchronized (this) { 12005 if (mController != null) { 12006 try { 12007 String name = r != null ? r.processName : null; 12008 int pid = r != null ? r.pid : Binder.getCallingPid(); 12009 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12010 if (!mController.appCrashed(name, pid, 12011 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12012 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12013 && "Native crash".equals(crashInfo.exceptionClassName)) { 12014 Slog.w(TAG, "Skip killing native crashed app " + name 12015 + "(" + pid + ") during testing"); 12016 } else { 12017 Slog.w(TAG, "Force-killing crashed app " + name 12018 + " at watcher's request"); 12019 if (r != null) { 12020 r.kill("crash", true); 12021 } else { 12022 // Huh. 12023 Process.killProcess(pid); 12024 Process.killProcessGroup(uid, pid); 12025 } 12026 } 12027 return; 12028 } 12029 } catch (RemoteException e) { 12030 mController = null; 12031 Watchdog.getInstance().setActivityController(null); 12032 } 12033 } 12034 12035 final long origId = Binder.clearCallingIdentity(); 12036 12037 // If this process is running instrumentation, finish it. 12038 if (r != null && r.instrumentationClass != null) { 12039 Slog.w(TAG, "Error in app " + r.processName 12040 + " running instrumentation " + r.instrumentationClass + ":"); 12041 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12042 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12043 Bundle info = new Bundle(); 12044 info.putString("shortMsg", shortMsg); 12045 info.putString("longMsg", longMsg); 12046 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12047 Binder.restoreCallingIdentity(origId); 12048 return; 12049 } 12050 12051 // Log crash in battery stats. 12052 if (r != null) { 12053 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12054 } 12055 12056 // If we can't identify the process or it's already exceeded its crash quota, 12057 // quit right away without showing a crash dialog. 12058 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12059 Binder.restoreCallingIdentity(origId); 12060 return; 12061 } 12062 12063 Message msg = Message.obtain(); 12064 msg.what = SHOW_ERROR_MSG; 12065 HashMap data = new HashMap(); 12066 data.put("result", result); 12067 data.put("app", r); 12068 msg.obj = data; 12069 mHandler.sendMessage(msg); 12070 12071 Binder.restoreCallingIdentity(origId); 12072 } 12073 12074 int res = result.get(); 12075 12076 Intent appErrorIntent = null; 12077 synchronized (this) { 12078 if (r != null && !r.isolated) { 12079 // XXX Can't keep track of crash time for isolated processes, 12080 // since they don't have a persistent identity. 12081 mProcessCrashTimes.put(r.info.processName, r.uid, 12082 SystemClock.uptimeMillis()); 12083 } 12084 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12085 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12086 } 12087 } 12088 12089 if (appErrorIntent != null) { 12090 try { 12091 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12092 } catch (ActivityNotFoundException e) { 12093 Slog.w(TAG, "bug report receiver dissappeared", e); 12094 } 12095 } 12096 } 12097 12098 Intent createAppErrorIntentLocked(ProcessRecord r, 12099 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12100 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12101 if (report == null) { 12102 return null; 12103 } 12104 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12105 result.setComponent(r.errorReportReceiver); 12106 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12107 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12108 return result; 12109 } 12110 12111 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12112 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12113 if (r.errorReportReceiver == null) { 12114 return null; 12115 } 12116 12117 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12118 return null; 12119 } 12120 12121 ApplicationErrorReport report = new ApplicationErrorReport(); 12122 report.packageName = r.info.packageName; 12123 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12124 report.processName = r.processName; 12125 report.time = timeMillis; 12126 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12127 12128 if (r.crashing || r.forceCrashReport) { 12129 report.type = ApplicationErrorReport.TYPE_CRASH; 12130 report.crashInfo = crashInfo; 12131 } else if (r.notResponding) { 12132 report.type = ApplicationErrorReport.TYPE_ANR; 12133 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12134 12135 report.anrInfo.activity = r.notRespondingReport.tag; 12136 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12137 report.anrInfo.info = r.notRespondingReport.longMsg; 12138 } 12139 12140 return report; 12141 } 12142 12143 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12144 enforceNotIsolatedCaller("getProcessesInErrorState"); 12145 // assume our apps are happy - lazy create the list 12146 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12147 12148 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12149 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12150 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12151 12152 synchronized (this) { 12153 12154 // iterate across all processes 12155 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12156 ProcessRecord app = mLruProcesses.get(i); 12157 if (!allUsers && app.userId != userId) { 12158 continue; 12159 } 12160 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12161 // This one's in trouble, so we'll generate a report for it 12162 // crashes are higher priority (in case there's a crash *and* an anr) 12163 ActivityManager.ProcessErrorStateInfo report = null; 12164 if (app.crashing) { 12165 report = app.crashingReport; 12166 } else if (app.notResponding) { 12167 report = app.notRespondingReport; 12168 } 12169 12170 if (report != null) { 12171 if (errList == null) { 12172 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12173 } 12174 errList.add(report); 12175 } else { 12176 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12177 " crashing = " + app.crashing + 12178 " notResponding = " + app.notResponding); 12179 } 12180 } 12181 } 12182 } 12183 12184 return errList; 12185 } 12186 12187 static int procStateToImportance(int procState, int memAdj, 12188 ActivityManager.RunningAppProcessInfo currApp) { 12189 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12190 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12191 currApp.lru = memAdj; 12192 } else { 12193 currApp.lru = 0; 12194 } 12195 return imp; 12196 } 12197 12198 private void fillInProcMemInfo(ProcessRecord app, 12199 ActivityManager.RunningAppProcessInfo outInfo) { 12200 outInfo.pid = app.pid; 12201 outInfo.uid = app.info.uid; 12202 if (mHeavyWeightProcess == app) { 12203 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12204 } 12205 if (app.persistent) { 12206 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12207 } 12208 if (app.activities.size() > 0) { 12209 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12210 } 12211 outInfo.lastTrimLevel = app.trimMemoryLevel; 12212 int adj = app.curAdj; 12213 int procState = app.curProcState; 12214 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12215 outInfo.importanceReasonCode = app.adjTypeCode; 12216 outInfo.processState = app.curProcState; 12217 } 12218 12219 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12220 enforceNotIsolatedCaller("getRunningAppProcesses"); 12221 // Lazy instantiation of list 12222 List<ActivityManager.RunningAppProcessInfo> runList = null; 12223 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12224 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12225 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12226 synchronized (this) { 12227 // Iterate across all processes 12228 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12229 ProcessRecord app = mLruProcesses.get(i); 12230 if (!allUsers && app.userId != userId) { 12231 continue; 12232 } 12233 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12234 // Generate process state info for running application 12235 ActivityManager.RunningAppProcessInfo currApp = 12236 new ActivityManager.RunningAppProcessInfo(app.processName, 12237 app.pid, app.getPackageList()); 12238 fillInProcMemInfo(app, currApp); 12239 if (app.adjSource instanceof ProcessRecord) { 12240 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12241 currApp.importanceReasonImportance = 12242 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12243 app.adjSourceProcState); 12244 } else if (app.adjSource instanceof ActivityRecord) { 12245 ActivityRecord r = (ActivityRecord)app.adjSource; 12246 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12247 } 12248 if (app.adjTarget instanceof ComponentName) { 12249 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12250 } 12251 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12252 // + " lru=" + currApp.lru); 12253 if (runList == null) { 12254 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12255 } 12256 runList.add(currApp); 12257 } 12258 } 12259 } 12260 return runList; 12261 } 12262 12263 public List<ApplicationInfo> getRunningExternalApplications() { 12264 enforceNotIsolatedCaller("getRunningExternalApplications"); 12265 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12266 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12267 if (runningApps != null && runningApps.size() > 0) { 12268 Set<String> extList = new HashSet<String>(); 12269 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12270 if (app.pkgList != null) { 12271 for (String pkg : app.pkgList) { 12272 extList.add(pkg); 12273 } 12274 } 12275 } 12276 IPackageManager pm = AppGlobals.getPackageManager(); 12277 for (String pkg : extList) { 12278 try { 12279 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12280 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12281 retList.add(info); 12282 } 12283 } catch (RemoteException e) { 12284 } 12285 } 12286 } 12287 return retList; 12288 } 12289 12290 @Override 12291 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12292 enforceNotIsolatedCaller("getMyMemoryState"); 12293 synchronized (this) { 12294 ProcessRecord proc; 12295 synchronized (mPidsSelfLocked) { 12296 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12297 } 12298 fillInProcMemInfo(proc, outInfo); 12299 } 12300 } 12301 12302 @Override 12303 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12304 if (checkCallingPermission(android.Manifest.permission.DUMP) 12305 != PackageManager.PERMISSION_GRANTED) { 12306 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12307 + Binder.getCallingPid() 12308 + ", uid=" + Binder.getCallingUid() 12309 + " without permission " 12310 + android.Manifest.permission.DUMP); 12311 return; 12312 } 12313 12314 boolean dumpAll = false; 12315 boolean dumpClient = false; 12316 String dumpPackage = null; 12317 12318 int opti = 0; 12319 while (opti < args.length) { 12320 String opt = args[opti]; 12321 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12322 break; 12323 } 12324 opti++; 12325 if ("-a".equals(opt)) { 12326 dumpAll = true; 12327 } else if ("-c".equals(opt)) { 12328 dumpClient = true; 12329 } else if ("-h".equals(opt)) { 12330 pw.println("Activity manager dump options:"); 12331 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12332 pw.println(" cmd may be one of:"); 12333 pw.println(" a[ctivities]: activity stack state"); 12334 pw.println(" r[recents]: recent activities state"); 12335 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12336 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12337 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12338 pw.println(" o[om]: out of memory management"); 12339 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12340 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12341 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12342 pw.println(" service [COMP_SPEC]: service client-side state"); 12343 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12344 pw.println(" all: dump all activities"); 12345 pw.println(" top: dump the top activity"); 12346 pw.println(" write: write all pending state to storage"); 12347 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12348 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12349 pw.println(" a partial substring in a component name, a"); 12350 pw.println(" hex object identifier."); 12351 pw.println(" -a: include all available server state."); 12352 pw.println(" -c: include client state."); 12353 return; 12354 } else { 12355 pw.println("Unknown argument: " + opt + "; use -h for help"); 12356 } 12357 } 12358 12359 long origId = Binder.clearCallingIdentity(); 12360 boolean more = false; 12361 // Is the caller requesting to dump a particular piece of data? 12362 if (opti < args.length) { 12363 String cmd = args[opti]; 12364 opti++; 12365 if ("activities".equals(cmd) || "a".equals(cmd)) { 12366 synchronized (this) { 12367 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12368 } 12369 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12370 synchronized (this) { 12371 dumpRecentsLocked(fd, pw, args, opti, true, null); 12372 } 12373 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12374 String[] newArgs; 12375 String name; 12376 if (opti >= args.length) { 12377 name = null; 12378 newArgs = EMPTY_STRING_ARRAY; 12379 } else { 12380 name = args[opti]; 12381 opti++; 12382 newArgs = new String[args.length - opti]; 12383 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12384 args.length - opti); 12385 } 12386 synchronized (this) { 12387 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12388 } 12389 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12390 String[] newArgs; 12391 String name; 12392 if (opti >= args.length) { 12393 name = null; 12394 newArgs = EMPTY_STRING_ARRAY; 12395 } else { 12396 name = args[opti]; 12397 opti++; 12398 newArgs = new String[args.length - opti]; 12399 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12400 args.length - opti); 12401 } 12402 synchronized (this) { 12403 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12404 } 12405 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12406 String[] newArgs; 12407 String name; 12408 if (opti >= args.length) { 12409 name = null; 12410 newArgs = EMPTY_STRING_ARRAY; 12411 } else { 12412 name = args[opti]; 12413 opti++; 12414 newArgs = new String[args.length - opti]; 12415 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12416 args.length - opti); 12417 } 12418 synchronized (this) { 12419 dumpProcessesLocked(fd, pw, args, opti, true, name); 12420 } 12421 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12422 synchronized (this) { 12423 dumpOomLocked(fd, pw, args, opti, true); 12424 } 12425 } else if ("provider".equals(cmd)) { 12426 String[] newArgs; 12427 String name; 12428 if (opti >= args.length) { 12429 name = null; 12430 newArgs = EMPTY_STRING_ARRAY; 12431 } else { 12432 name = args[opti]; 12433 opti++; 12434 newArgs = new String[args.length - opti]; 12435 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12436 } 12437 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12438 pw.println("No providers match: " + name); 12439 pw.println("Use -h for help."); 12440 } 12441 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12442 synchronized (this) { 12443 dumpProvidersLocked(fd, pw, args, opti, true, null); 12444 } 12445 } else if ("service".equals(cmd)) { 12446 String[] newArgs; 12447 String name; 12448 if (opti >= args.length) { 12449 name = null; 12450 newArgs = EMPTY_STRING_ARRAY; 12451 } else { 12452 name = args[opti]; 12453 opti++; 12454 newArgs = new String[args.length - opti]; 12455 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12456 args.length - opti); 12457 } 12458 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12459 pw.println("No services match: " + name); 12460 pw.println("Use -h for help."); 12461 } 12462 } else if ("package".equals(cmd)) { 12463 String[] newArgs; 12464 if (opti >= args.length) { 12465 pw.println("package: no package name specified"); 12466 pw.println("Use -h for help."); 12467 } else { 12468 dumpPackage = args[opti]; 12469 opti++; 12470 newArgs = new String[args.length - opti]; 12471 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12472 args.length - opti); 12473 args = newArgs; 12474 opti = 0; 12475 more = true; 12476 } 12477 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12478 synchronized (this) { 12479 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12480 } 12481 } else if ("write".equals(cmd)) { 12482 mTaskPersister.flush(); 12483 pw.println("All tasks persisted."); 12484 return; 12485 } else { 12486 // Dumping a single activity? 12487 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12488 pw.println("Bad activity command, or no activities match: " + cmd); 12489 pw.println("Use -h for help."); 12490 } 12491 } 12492 if (!more) { 12493 Binder.restoreCallingIdentity(origId); 12494 return; 12495 } 12496 } 12497 12498 // No piece of data specified, dump everything. 12499 synchronized (this) { 12500 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12501 pw.println(); 12502 if (dumpAll) { 12503 pw.println("-------------------------------------------------------------------------------"); 12504 } 12505 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12506 pw.println(); 12507 if (dumpAll) { 12508 pw.println("-------------------------------------------------------------------------------"); 12509 } 12510 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12511 pw.println(); 12512 if (dumpAll) { 12513 pw.println("-------------------------------------------------------------------------------"); 12514 } 12515 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12516 pw.println(); 12517 if (dumpAll) { 12518 pw.println("-------------------------------------------------------------------------------"); 12519 } 12520 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12521 pw.println(); 12522 if (dumpAll) { 12523 pw.println("-------------------------------------------------------------------------------"); 12524 } 12525 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12526 pw.println(); 12527 if (dumpAll) { 12528 pw.println("-------------------------------------------------------------------------------"); 12529 } 12530 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12531 } 12532 Binder.restoreCallingIdentity(origId); 12533 } 12534 12535 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12536 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12537 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12538 12539 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12540 dumpPackage); 12541 boolean needSep = printedAnything; 12542 12543 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12544 dumpPackage, needSep, " mFocusedActivity: "); 12545 if (printed) { 12546 printedAnything = true; 12547 needSep = false; 12548 } 12549 12550 if (dumpPackage == null) { 12551 if (needSep) { 12552 pw.println(); 12553 } 12554 needSep = true; 12555 printedAnything = true; 12556 mStackSupervisor.dump(pw, " "); 12557 } 12558 12559 if (!printedAnything) { 12560 pw.println(" (nothing)"); 12561 } 12562 } 12563 12564 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12565 int opti, boolean dumpAll, String dumpPackage) { 12566 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12567 12568 boolean printedAnything = false; 12569 12570 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12571 boolean printedHeader = false; 12572 12573 final int N = mRecentTasks.size(); 12574 for (int i=0; i<N; i++) { 12575 TaskRecord tr = mRecentTasks.get(i); 12576 if (dumpPackage != null) { 12577 if (tr.realActivity == null || 12578 !dumpPackage.equals(tr.realActivity)) { 12579 continue; 12580 } 12581 } 12582 if (!printedHeader) { 12583 pw.println(" Recent tasks:"); 12584 printedHeader = true; 12585 printedAnything = true; 12586 } 12587 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12588 pw.println(tr); 12589 if (dumpAll) { 12590 mRecentTasks.get(i).dump(pw, " "); 12591 } 12592 } 12593 } 12594 12595 if (!printedAnything) { 12596 pw.println(" (nothing)"); 12597 } 12598 } 12599 12600 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12601 int opti, boolean dumpAll, String dumpPackage) { 12602 boolean needSep = false; 12603 boolean printedAnything = false; 12604 int numPers = 0; 12605 12606 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12607 12608 if (dumpAll) { 12609 final int NP = mProcessNames.getMap().size(); 12610 for (int ip=0; ip<NP; ip++) { 12611 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12612 final int NA = procs.size(); 12613 for (int ia=0; ia<NA; ia++) { 12614 ProcessRecord r = procs.valueAt(ia); 12615 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12616 continue; 12617 } 12618 if (!needSep) { 12619 pw.println(" All known processes:"); 12620 needSep = true; 12621 printedAnything = true; 12622 } 12623 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12624 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12625 pw.print(" "); pw.println(r); 12626 r.dump(pw, " "); 12627 if (r.persistent) { 12628 numPers++; 12629 } 12630 } 12631 } 12632 } 12633 12634 if (mIsolatedProcesses.size() > 0) { 12635 boolean printed = false; 12636 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12637 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12638 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12639 continue; 12640 } 12641 if (!printed) { 12642 if (needSep) { 12643 pw.println(); 12644 } 12645 pw.println(" Isolated process list (sorted by uid):"); 12646 printedAnything = true; 12647 printed = true; 12648 needSep = true; 12649 } 12650 pw.println(String.format("%sIsolated #%2d: %s", 12651 " ", i, r.toString())); 12652 } 12653 } 12654 12655 if (mLruProcesses.size() > 0) { 12656 if (needSep) { 12657 pw.println(); 12658 } 12659 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12660 pw.print(" total, non-act at "); 12661 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12662 pw.print(", non-svc at "); 12663 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12664 pw.println("):"); 12665 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12666 needSep = true; 12667 printedAnything = true; 12668 } 12669 12670 if (dumpAll || dumpPackage != null) { 12671 synchronized (mPidsSelfLocked) { 12672 boolean printed = false; 12673 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12674 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12675 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12676 continue; 12677 } 12678 if (!printed) { 12679 if (needSep) pw.println(); 12680 needSep = true; 12681 pw.println(" PID mappings:"); 12682 printed = true; 12683 printedAnything = true; 12684 } 12685 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12686 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12687 } 12688 } 12689 } 12690 12691 if (mForegroundProcesses.size() > 0) { 12692 synchronized (mPidsSelfLocked) { 12693 boolean printed = false; 12694 for (int i=0; i<mForegroundProcesses.size(); i++) { 12695 ProcessRecord r = mPidsSelfLocked.get( 12696 mForegroundProcesses.valueAt(i).pid); 12697 if (dumpPackage != null && (r == null 12698 || !r.pkgList.containsKey(dumpPackage))) { 12699 continue; 12700 } 12701 if (!printed) { 12702 if (needSep) pw.println(); 12703 needSep = true; 12704 pw.println(" Foreground Processes:"); 12705 printed = true; 12706 printedAnything = true; 12707 } 12708 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12709 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12710 } 12711 } 12712 } 12713 12714 if (mPersistentStartingProcesses.size() > 0) { 12715 if (needSep) pw.println(); 12716 needSep = true; 12717 printedAnything = true; 12718 pw.println(" Persisent processes that are starting:"); 12719 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12720 "Starting Norm", "Restarting PERS", dumpPackage); 12721 } 12722 12723 if (mRemovedProcesses.size() > 0) { 12724 if (needSep) pw.println(); 12725 needSep = true; 12726 printedAnything = true; 12727 pw.println(" Processes that are being removed:"); 12728 dumpProcessList(pw, this, mRemovedProcesses, " ", 12729 "Removed Norm", "Removed PERS", dumpPackage); 12730 } 12731 12732 if (mProcessesOnHold.size() > 0) { 12733 if (needSep) pw.println(); 12734 needSep = true; 12735 printedAnything = true; 12736 pw.println(" Processes that are on old until the system is ready:"); 12737 dumpProcessList(pw, this, mProcessesOnHold, " ", 12738 "OnHold Norm", "OnHold PERS", dumpPackage); 12739 } 12740 12741 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12742 12743 if (mProcessCrashTimes.getMap().size() > 0) { 12744 boolean printed = false; 12745 long now = SystemClock.uptimeMillis(); 12746 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12747 final int NP = pmap.size(); 12748 for (int ip=0; ip<NP; ip++) { 12749 String pname = pmap.keyAt(ip); 12750 SparseArray<Long> uids = pmap.valueAt(ip); 12751 final int N = uids.size(); 12752 for (int i=0; i<N; i++) { 12753 int puid = uids.keyAt(i); 12754 ProcessRecord r = mProcessNames.get(pname, puid); 12755 if (dumpPackage != null && (r == null 12756 || !r.pkgList.containsKey(dumpPackage))) { 12757 continue; 12758 } 12759 if (!printed) { 12760 if (needSep) pw.println(); 12761 needSep = true; 12762 pw.println(" Time since processes crashed:"); 12763 printed = true; 12764 printedAnything = true; 12765 } 12766 pw.print(" Process "); pw.print(pname); 12767 pw.print(" uid "); pw.print(puid); 12768 pw.print(": last crashed "); 12769 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12770 pw.println(" ago"); 12771 } 12772 } 12773 } 12774 12775 if (mBadProcesses.getMap().size() > 0) { 12776 boolean printed = false; 12777 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12778 final int NP = pmap.size(); 12779 for (int ip=0; ip<NP; ip++) { 12780 String pname = pmap.keyAt(ip); 12781 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12782 final int N = uids.size(); 12783 for (int i=0; i<N; i++) { 12784 int puid = uids.keyAt(i); 12785 ProcessRecord r = mProcessNames.get(pname, puid); 12786 if (dumpPackage != null && (r == null 12787 || !r.pkgList.containsKey(dumpPackage))) { 12788 continue; 12789 } 12790 if (!printed) { 12791 if (needSep) pw.println(); 12792 needSep = true; 12793 pw.println(" Bad processes:"); 12794 printedAnything = true; 12795 } 12796 BadProcessInfo info = uids.valueAt(i); 12797 pw.print(" Bad process "); pw.print(pname); 12798 pw.print(" uid "); pw.print(puid); 12799 pw.print(": crashed at time "); pw.println(info.time); 12800 if (info.shortMsg != null) { 12801 pw.print(" Short msg: "); pw.println(info.shortMsg); 12802 } 12803 if (info.longMsg != null) { 12804 pw.print(" Long msg: "); pw.println(info.longMsg); 12805 } 12806 if (info.stack != null) { 12807 pw.println(" Stack:"); 12808 int lastPos = 0; 12809 for (int pos=0; pos<info.stack.length(); pos++) { 12810 if (info.stack.charAt(pos) == '\n') { 12811 pw.print(" "); 12812 pw.write(info.stack, lastPos, pos-lastPos); 12813 pw.println(); 12814 lastPos = pos+1; 12815 } 12816 } 12817 if (lastPos < info.stack.length()) { 12818 pw.print(" "); 12819 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12820 pw.println(); 12821 } 12822 } 12823 } 12824 } 12825 } 12826 12827 if (dumpPackage == null) { 12828 pw.println(); 12829 needSep = false; 12830 pw.println(" mStartedUsers:"); 12831 for (int i=0; i<mStartedUsers.size(); i++) { 12832 UserStartedState uss = mStartedUsers.valueAt(i); 12833 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12834 pw.print(": "); uss.dump("", pw); 12835 } 12836 pw.print(" mStartedUserArray: ["); 12837 for (int i=0; i<mStartedUserArray.length; i++) { 12838 if (i > 0) pw.print(", "); 12839 pw.print(mStartedUserArray[i]); 12840 } 12841 pw.println("]"); 12842 pw.print(" mUserLru: ["); 12843 for (int i=0; i<mUserLru.size(); i++) { 12844 if (i > 0) pw.print(", "); 12845 pw.print(mUserLru.get(i)); 12846 } 12847 pw.println("]"); 12848 if (dumpAll) { 12849 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12850 } 12851 synchronized (mUserProfileGroupIdsSelfLocked) { 12852 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12853 pw.println(" mUserProfileGroupIds:"); 12854 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12855 pw.print(" User #"); 12856 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12857 pw.print(" -> profile #"); 12858 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12859 } 12860 } 12861 } 12862 } 12863 if (mHomeProcess != null && (dumpPackage == null 12864 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12865 if (needSep) { 12866 pw.println(); 12867 needSep = false; 12868 } 12869 pw.println(" mHomeProcess: " + mHomeProcess); 12870 } 12871 if (mPreviousProcess != null && (dumpPackage == null 12872 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12873 if (needSep) { 12874 pw.println(); 12875 needSep = false; 12876 } 12877 pw.println(" mPreviousProcess: " + mPreviousProcess); 12878 } 12879 if (dumpAll) { 12880 StringBuilder sb = new StringBuilder(128); 12881 sb.append(" mPreviousProcessVisibleTime: "); 12882 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12883 pw.println(sb); 12884 } 12885 if (mHeavyWeightProcess != null && (dumpPackage == null 12886 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12887 if (needSep) { 12888 pw.println(); 12889 needSep = false; 12890 } 12891 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12892 } 12893 if (dumpPackage == null) { 12894 pw.println(" mConfiguration: " + mConfiguration); 12895 } 12896 if (dumpAll) { 12897 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12898 if (mCompatModePackages.getPackages().size() > 0) { 12899 boolean printed = false; 12900 for (Map.Entry<String, Integer> entry 12901 : mCompatModePackages.getPackages().entrySet()) { 12902 String pkg = entry.getKey(); 12903 int mode = entry.getValue(); 12904 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12905 continue; 12906 } 12907 if (!printed) { 12908 pw.println(" mScreenCompatPackages:"); 12909 printed = true; 12910 } 12911 pw.print(" "); pw.print(pkg); pw.print(": "); 12912 pw.print(mode); pw.println(); 12913 } 12914 } 12915 } 12916 if (dumpPackage == null) { 12917 pw.println(" mWakefulness=" 12918 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12919 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12920 + lockScreenShownToString()); 12921 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 12922 + " mTestPssMode=" + mTestPssMode); 12923 } 12924 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12925 || mOrigWaitForDebugger) { 12926 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12927 || dumpPackage.equals(mOrigDebugApp)) { 12928 if (needSep) { 12929 pw.println(); 12930 needSep = false; 12931 } 12932 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12933 + " mDebugTransient=" + mDebugTransient 12934 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12935 } 12936 } 12937 if (mOpenGlTraceApp != null) { 12938 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12939 if (needSep) { 12940 pw.println(); 12941 needSep = false; 12942 } 12943 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12944 } 12945 } 12946 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12947 || mProfileFd != null) { 12948 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12949 if (needSep) { 12950 pw.println(); 12951 needSep = false; 12952 } 12953 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12954 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12955 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12956 + mAutoStopProfiler); 12957 pw.println(" mProfileType=" + mProfileType); 12958 } 12959 } 12960 if (dumpPackage == null) { 12961 if (mAlwaysFinishActivities || mController != null) { 12962 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12963 + " mController=" + mController); 12964 } 12965 if (dumpAll) { 12966 pw.println(" Total persistent processes: " + numPers); 12967 pw.println(" mProcessesReady=" + mProcessesReady 12968 + " mSystemReady=" + mSystemReady 12969 + " mBooted=" + mBooted 12970 + " mFactoryTest=" + mFactoryTest); 12971 pw.println(" mBooting=" + mBooting 12972 + " mCallFinishBooting=" + mCallFinishBooting 12973 + " mBootAnimationComplete=" + mBootAnimationComplete); 12974 pw.print(" mLastPowerCheckRealtime="); 12975 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12976 pw.println(""); 12977 pw.print(" mLastPowerCheckUptime="); 12978 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12979 pw.println(""); 12980 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12981 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12982 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12983 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12984 + " (" + mLruProcesses.size() + " total)" 12985 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12986 + " mNumServiceProcs=" + mNumServiceProcs 12987 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12988 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12989 + " mLastMemoryLevel" + mLastMemoryLevel 12990 + " mLastNumProcesses" + mLastNumProcesses); 12991 long now = SystemClock.uptimeMillis(); 12992 pw.print(" mLastIdleTime="); 12993 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12994 pw.print(" mLowRamSinceLastIdle="); 12995 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12996 pw.println(); 12997 } 12998 } 12999 13000 if (!printedAnything) { 13001 pw.println(" (nothing)"); 13002 } 13003 } 13004 13005 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13006 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13007 if (mProcessesToGc.size() > 0) { 13008 boolean printed = false; 13009 long now = SystemClock.uptimeMillis(); 13010 for (int i=0; i<mProcessesToGc.size(); i++) { 13011 ProcessRecord proc = mProcessesToGc.get(i); 13012 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13013 continue; 13014 } 13015 if (!printed) { 13016 if (needSep) pw.println(); 13017 needSep = true; 13018 pw.println(" Processes that are waiting to GC:"); 13019 printed = true; 13020 } 13021 pw.print(" Process "); pw.println(proc); 13022 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13023 pw.print(", last gced="); 13024 pw.print(now-proc.lastRequestedGc); 13025 pw.print(" ms ago, last lowMem="); 13026 pw.print(now-proc.lastLowMemory); 13027 pw.println(" ms ago"); 13028 13029 } 13030 } 13031 return needSep; 13032 } 13033 13034 void printOomLevel(PrintWriter pw, String name, int adj) { 13035 pw.print(" "); 13036 if (adj >= 0) { 13037 pw.print(' '); 13038 if (adj < 10) pw.print(' '); 13039 } else { 13040 if (adj > -10) pw.print(' '); 13041 } 13042 pw.print(adj); 13043 pw.print(": "); 13044 pw.print(name); 13045 pw.print(" ("); 13046 pw.print(mProcessList.getMemLevel(adj)/1024); 13047 pw.println(" kB)"); 13048 } 13049 13050 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13051 int opti, boolean dumpAll) { 13052 boolean needSep = false; 13053 13054 if (mLruProcesses.size() > 0) { 13055 if (needSep) pw.println(); 13056 needSep = true; 13057 pw.println(" OOM levels:"); 13058 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13059 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13060 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13061 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13062 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13063 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13064 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13065 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13066 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13067 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13068 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13069 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13070 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13071 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13072 13073 if (needSep) pw.println(); 13074 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13075 pw.print(" total, non-act at "); 13076 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13077 pw.print(", non-svc at "); 13078 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13079 pw.println("):"); 13080 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13081 needSep = true; 13082 } 13083 13084 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13085 13086 pw.println(); 13087 pw.println(" mHomeProcess: " + mHomeProcess); 13088 pw.println(" mPreviousProcess: " + mPreviousProcess); 13089 if (mHeavyWeightProcess != null) { 13090 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13091 } 13092 13093 return true; 13094 } 13095 13096 /** 13097 * There are three ways to call this: 13098 * - no provider specified: dump all the providers 13099 * - a flattened component name that matched an existing provider was specified as the 13100 * first arg: dump that one provider 13101 * - the first arg isn't the flattened component name of an existing provider: 13102 * dump all providers whose component contains the first arg as a substring 13103 */ 13104 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13105 int opti, boolean dumpAll) { 13106 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13107 } 13108 13109 static class ItemMatcher { 13110 ArrayList<ComponentName> components; 13111 ArrayList<String> strings; 13112 ArrayList<Integer> objects; 13113 boolean all; 13114 13115 ItemMatcher() { 13116 all = true; 13117 } 13118 13119 void build(String name) { 13120 ComponentName componentName = ComponentName.unflattenFromString(name); 13121 if (componentName != null) { 13122 if (components == null) { 13123 components = new ArrayList<ComponentName>(); 13124 } 13125 components.add(componentName); 13126 all = false; 13127 } else { 13128 int objectId = 0; 13129 // Not a '/' separated full component name; maybe an object ID? 13130 try { 13131 objectId = Integer.parseInt(name, 16); 13132 if (objects == null) { 13133 objects = new ArrayList<Integer>(); 13134 } 13135 objects.add(objectId); 13136 all = false; 13137 } catch (RuntimeException e) { 13138 // Not an integer; just do string match. 13139 if (strings == null) { 13140 strings = new ArrayList<String>(); 13141 } 13142 strings.add(name); 13143 all = false; 13144 } 13145 } 13146 } 13147 13148 int build(String[] args, int opti) { 13149 for (; opti<args.length; opti++) { 13150 String name = args[opti]; 13151 if ("--".equals(name)) { 13152 return opti+1; 13153 } 13154 build(name); 13155 } 13156 return opti; 13157 } 13158 13159 boolean match(Object object, ComponentName comp) { 13160 if (all) { 13161 return true; 13162 } 13163 if (components != null) { 13164 for (int i=0; i<components.size(); i++) { 13165 if (components.get(i).equals(comp)) { 13166 return true; 13167 } 13168 } 13169 } 13170 if (objects != null) { 13171 for (int i=0; i<objects.size(); i++) { 13172 if (System.identityHashCode(object) == objects.get(i)) { 13173 return true; 13174 } 13175 } 13176 } 13177 if (strings != null) { 13178 String flat = comp.flattenToString(); 13179 for (int i=0; i<strings.size(); i++) { 13180 if (flat.contains(strings.get(i))) { 13181 return true; 13182 } 13183 } 13184 } 13185 return false; 13186 } 13187 } 13188 13189 /** 13190 * There are three things that cmd can be: 13191 * - a flattened component name that matches an existing activity 13192 * - the cmd arg isn't the flattened component name of an existing activity: 13193 * dump all activity whose component contains the cmd as a substring 13194 * - A hex number of the ActivityRecord object instance. 13195 */ 13196 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13197 int opti, boolean dumpAll) { 13198 ArrayList<ActivityRecord> activities; 13199 13200 synchronized (this) { 13201 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13202 } 13203 13204 if (activities.size() <= 0) { 13205 return false; 13206 } 13207 13208 String[] newArgs = new String[args.length - opti]; 13209 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13210 13211 TaskRecord lastTask = null; 13212 boolean needSep = false; 13213 for (int i=activities.size()-1; i>=0; i--) { 13214 ActivityRecord r = activities.get(i); 13215 if (needSep) { 13216 pw.println(); 13217 } 13218 needSep = true; 13219 synchronized (this) { 13220 if (lastTask != r.task) { 13221 lastTask = r.task; 13222 pw.print("TASK "); pw.print(lastTask.affinity); 13223 pw.print(" id="); pw.println(lastTask.taskId); 13224 if (dumpAll) { 13225 lastTask.dump(pw, " "); 13226 } 13227 } 13228 } 13229 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13230 } 13231 return true; 13232 } 13233 13234 /** 13235 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13236 * there is a thread associated with the activity. 13237 */ 13238 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13239 final ActivityRecord r, String[] args, boolean dumpAll) { 13240 String innerPrefix = prefix + " "; 13241 synchronized (this) { 13242 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13243 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13244 pw.print(" pid="); 13245 if (r.app != null) pw.println(r.app.pid); 13246 else pw.println("(not running)"); 13247 if (dumpAll) { 13248 r.dump(pw, innerPrefix); 13249 } 13250 } 13251 if (r.app != null && r.app.thread != null) { 13252 // flush anything that is already in the PrintWriter since the thread is going 13253 // to write to the file descriptor directly 13254 pw.flush(); 13255 try { 13256 TransferPipe tp = new TransferPipe(); 13257 try { 13258 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13259 r.appToken, innerPrefix, args); 13260 tp.go(fd); 13261 } finally { 13262 tp.kill(); 13263 } 13264 } catch (IOException e) { 13265 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13266 } catch (RemoteException e) { 13267 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13268 } 13269 } 13270 } 13271 13272 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13273 int opti, boolean dumpAll, String dumpPackage) { 13274 boolean needSep = false; 13275 boolean onlyHistory = false; 13276 boolean printedAnything = false; 13277 13278 if ("history".equals(dumpPackage)) { 13279 if (opti < args.length && "-s".equals(args[opti])) { 13280 dumpAll = false; 13281 } 13282 onlyHistory = true; 13283 dumpPackage = null; 13284 } 13285 13286 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13287 if (!onlyHistory && dumpAll) { 13288 if (mRegisteredReceivers.size() > 0) { 13289 boolean printed = false; 13290 Iterator it = mRegisteredReceivers.values().iterator(); 13291 while (it.hasNext()) { 13292 ReceiverList r = (ReceiverList)it.next(); 13293 if (dumpPackage != null && (r.app == null || 13294 !dumpPackage.equals(r.app.info.packageName))) { 13295 continue; 13296 } 13297 if (!printed) { 13298 pw.println(" Registered Receivers:"); 13299 needSep = true; 13300 printed = true; 13301 printedAnything = true; 13302 } 13303 pw.print(" * "); pw.println(r); 13304 r.dump(pw, " "); 13305 } 13306 } 13307 13308 if (mReceiverResolver.dump(pw, needSep ? 13309 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13310 " ", dumpPackage, false, false)) { 13311 needSep = true; 13312 printedAnything = true; 13313 } 13314 } 13315 13316 for (BroadcastQueue q : mBroadcastQueues) { 13317 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13318 printedAnything |= needSep; 13319 } 13320 13321 needSep = true; 13322 13323 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13324 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13325 if (needSep) { 13326 pw.println(); 13327 } 13328 needSep = true; 13329 printedAnything = true; 13330 pw.print(" Sticky broadcasts for user "); 13331 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13332 StringBuilder sb = new StringBuilder(128); 13333 for (Map.Entry<String, ArrayList<Intent>> ent 13334 : mStickyBroadcasts.valueAt(user).entrySet()) { 13335 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13336 if (dumpAll) { 13337 pw.println(":"); 13338 ArrayList<Intent> intents = ent.getValue(); 13339 final int N = intents.size(); 13340 for (int i=0; i<N; i++) { 13341 sb.setLength(0); 13342 sb.append(" Intent: "); 13343 intents.get(i).toShortString(sb, false, true, false, false); 13344 pw.println(sb.toString()); 13345 Bundle bundle = intents.get(i).getExtras(); 13346 if (bundle != null) { 13347 pw.print(" "); 13348 pw.println(bundle.toString()); 13349 } 13350 } 13351 } else { 13352 pw.println(""); 13353 } 13354 } 13355 } 13356 } 13357 13358 if (!onlyHistory && dumpAll) { 13359 pw.println(); 13360 for (BroadcastQueue queue : mBroadcastQueues) { 13361 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13362 + queue.mBroadcastsScheduled); 13363 } 13364 pw.println(" mHandler:"); 13365 mHandler.dump(new PrintWriterPrinter(pw), " "); 13366 needSep = true; 13367 printedAnything = true; 13368 } 13369 13370 if (!printedAnything) { 13371 pw.println(" (nothing)"); 13372 } 13373 } 13374 13375 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13376 int opti, boolean dumpAll, String dumpPackage) { 13377 boolean needSep; 13378 boolean printedAnything = false; 13379 13380 ItemMatcher matcher = new ItemMatcher(); 13381 matcher.build(args, opti); 13382 13383 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13384 13385 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13386 printedAnything |= needSep; 13387 13388 if (mLaunchingProviders.size() > 0) { 13389 boolean printed = false; 13390 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13391 ContentProviderRecord r = mLaunchingProviders.get(i); 13392 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13393 continue; 13394 } 13395 if (!printed) { 13396 if (needSep) pw.println(); 13397 needSep = true; 13398 pw.println(" Launching content providers:"); 13399 printed = true; 13400 printedAnything = true; 13401 } 13402 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13403 pw.println(r); 13404 } 13405 } 13406 13407 if (mGrantedUriPermissions.size() > 0) { 13408 boolean printed = false; 13409 int dumpUid = -2; 13410 if (dumpPackage != null) { 13411 try { 13412 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13413 } catch (NameNotFoundException e) { 13414 dumpUid = -1; 13415 } 13416 } 13417 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13418 int uid = mGrantedUriPermissions.keyAt(i); 13419 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13420 continue; 13421 } 13422 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13423 if (!printed) { 13424 if (needSep) pw.println(); 13425 needSep = true; 13426 pw.println(" Granted Uri Permissions:"); 13427 printed = true; 13428 printedAnything = true; 13429 } 13430 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13431 for (UriPermission perm : perms.values()) { 13432 pw.print(" "); pw.println(perm); 13433 if (dumpAll) { 13434 perm.dump(pw, " "); 13435 } 13436 } 13437 } 13438 } 13439 13440 if (!printedAnything) { 13441 pw.println(" (nothing)"); 13442 } 13443 } 13444 13445 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13446 int opti, boolean dumpAll, String dumpPackage) { 13447 boolean printed = false; 13448 13449 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13450 13451 if (mIntentSenderRecords.size() > 0) { 13452 Iterator<WeakReference<PendingIntentRecord>> it 13453 = mIntentSenderRecords.values().iterator(); 13454 while (it.hasNext()) { 13455 WeakReference<PendingIntentRecord> ref = it.next(); 13456 PendingIntentRecord rec = ref != null ? ref.get(): null; 13457 if (dumpPackage != null && (rec == null 13458 || !dumpPackage.equals(rec.key.packageName))) { 13459 continue; 13460 } 13461 printed = true; 13462 if (rec != null) { 13463 pw.print(" * "); pw.println(rec); 13464 if (dumpAll) { 13465 rec.dump(pw, " "); 13466 } 13467 } else { 13468 pw.print(" * "); pw.println(ref); 13469 } 13470 } 13471 } 13472 13473 if (!printed) { 13474 pw.println(" (nothing)"); 13475 } 13476 } 13477 13478 private static final int dumpProcessList(PrintWriter pw, 13479 ActivityManagerService service, List list, 13480 String prefix, String normalLabel, String persistentLabel, 13481 String dumpPackage) { 13482 int numPers = 0; 13483 final int N = list.size()-1; 13484 for (int i=N; i>=0; i--) { 13485 ProcessRecord r = (ProcessRecord)list.get(i); 13486 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13487 continue; 13488 } 13489 pw.println(String.format("%s%s #%2d: %s", 13490 prefix, (r.persistent ? persistentLabel : normalLabel), 13491 i, r.toString())); 13492 if (r.persistent) { 13493 numPers++; 13494 } 13495 } 13496 return numPers; 13497 } 13498 13499 private static final boolean dumpProcessOomList(PrintWriter pw, 13500 ActivityManagerService service, List<ProcessRecord> origList, 13501 String prefix, String normalLabel, String persistentLabel, 13502 boolean inclDetails, String dumpPackage) { 13503 13504 ArrayList<Pair<ProcessRecord, Integer>> list 13505 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13506 for (int i=0; i<origList.size(); i++) { 13507 ProcessRecord r = origList.get(i); 13508 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13509 continue; 13510 } 13511 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13512 } 13513 13514 if (list.size() <= 0) { 13515 return false; 13516 } 13517 13518 Comparator<Pair<ProcessRecord, Integer>> comparator 13519 = new Comparator<Pair<ProcessRecord, Integer>>() { 13520 @Override 13521 public int compare(Pair<ProcessRecord, Integer> object1, 13522 Pair<ProcessRecord, Integer> object2) { 13523 if (object1.first.setAdj != object2.first.setAdj) { 13524 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13525 } 13526 if (object1.second.intValue() != object2.second.intValue()) { 13527 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13528 } 13529 return 0; 13530 } 13531 }; 13532 13533 Collections.sort(list, comparator); 13534 13535 final long curRealtime = SystemClock.elapsedRealtime(); 13536 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13537 final long curUptime = SystemClock.uptimeMillis(); 13538 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13539 13540 for (int i=list.size()-1; i>=0; i--) { 13541 ProcessRecord r = list.get(i).first; 13542 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13543 char schedGroup; 13544 switch (r.setSchedGroup) { 13545 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13546 schedGroup = 'B'; 13547 break; 13548 case Process.THREAD_GROUP_DEFAULT: 13549 schedGroup = 'F'; 13550 break; 13551 default: 13552 schedGroup = '?'; 13553 break; 13554 } 13555 char foreground; 13556 if (r.foregroundActivities) { 13557 foreground = 'A'; 13558 } else if (r.foregroundServices) { 13559 foreground = 'S'; 13560 } else { 13561 foreground = ' '; 13562 } 13563 String procState = ProcessList.makeProcStateString(r.curProcState); 13564 pw.print(prefix); 13565 pw.print(r.persistent ? persistentLabel : normalLabel); 13566 pw.print(" #"); 13567 int num = (origList.size()-1)-list.get(i).second; 13568 if (num < 10) pw.print(' '); 13569 pw.print(num); 13570 pw.print(": "); 13571 pw.print(oomAdj); 13572 pw.print(' '); 13573 pw.print(schedGroup); 13574 pw.print('/'); 13575 pw.print(foreground); 13576 pw.print('/'); 13577 pw.print(procState); 13578 pw.print(" trm:"); 13579 if (r.trimMemoryLevel < 10) pw.print(' '); 13580 pw.print(r.trimMemoryLevel); 13581 pw.print(' '); 13582 pw.print(r.toShortString()); 13583 pw.print(" ("); 13584 pw.print(r.adjType); 13585 pw.println(')'); 13586 if (r.adjSource != null || r.adjTarget != null) { 13587 pw.print(prefix); 13588 pw.print(" "); 13589 if (r.adjTarget instanceof ComponentName) { 13590 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13591 } else if (r.adjTarget != null) { 13592 pw.print(r.adjTarget.toString()); 13593 } else { 13594 pw.print("{null}"); 13595 } 13596 pw.print("<="); 13597 if (r.adjSource instanceof ProcessRecord) { 13598 pw.print("Proc{"); 13599 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13600 pw.println("}"); 13601 } else if (r.adjSource != null) { 13602 pw.println(r.adjSource.toString()); 13603 } else { 13604 pw.println("{null}"); 13605 } 13606 } 13607 if (inclDetails) { 13608 pw.print(prefix); 13609 pw.print(" "); 13610 pw.print("oom: max="); pw.print(r.maxAdj); 13611 pw.print(" curRaw="); pw.print(r.curRawAdj); 13612 pw.print(" setRaw="); pw.print(r.setRawAdj); 13613 pw.print(" cur="); pw.print(r.curAdj); 13614 pw.print(" set="); pw.println(r.setAdj); 13615 pw.print(prefix); 13616 pw.print(" "); 13617 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13618 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13619 pw.print(" lastPss="); pw.print(r.lastPss); 13620 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13621 pw.print(prefix); 13622 pw.print(" "); 13623 pw.print("cached="); pw.print(r.cached); 13624 pw.print(" empty="); pw.print(r.empty); 13625 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13626 13627 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13628 if (r.lastWakeTime != 0) { 13629 long wtime; 13630 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13631 synchronized (stats) { 13632 wtime = stats.getProcessWakeTime(r.info.uid, 13633 r.pid, curRealtime); 13634 } 13635 long timeUsed = wtime - r.lastWakeTime; 13636 pw.print(prefix); 13637 pw.print(" "); 13638 pw.print("keep awake over "); 13639 TimeUtils.formatDuration(realtimeSince, pw); 13640 pw.print(" used "); 13641 TimeUtils.formatDuration(timeUsed, pw); 13642 pw.print(" ("); 13643 pw.print((timeUsed*100)/realtimeSince); 13644 pw.println("%)"); 13645 } 13646 if (r.lastCpuTime != 0) { 13647 long timeUsed = r.curCpuTime - r.lastCpuTime; 13648 pw.print(prefix); 13649 pw.print(" "); 13650 pw.print("run cpu over "); 13651 TimeUtils.formatDuration(uptimeSince, pw); 13652 pw.print(" used "); 13653 TimeUtils.formatDuration(timeUsed, pw); 13654 pw.print(" ("); 13655 pw.print((timeUsed*100)/uptimeSince); 13656 pw.println("%)"); 13657 } 13658 } 13659 } 13660 } 13661 return true; 13662 } 13663 13664 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13665 String[] args) { 13666 ArrayList<ProcessRecord> procs; 13667 synchronized (this) { 13668 if (args != null && args.length > start 13669 && args[start].charAt(0) != '-') { 13670 procs = new ArrayList<ProcessRecord>(); 13671 int pid = -1; 13672 try { 13673 pid = Integer.parseInt(args[start]); 13674 } catch (NumberFormatException e) { 13675 } 13676 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13677 ProcessRecord proc = mLruProcesses.get(i); 13678 if (proc.pid == pid) { 13679 procs.add(proc); 13680 } else if (allPkgs && proc.pkgList != null 13681 && proc.pkgList.containsKey(args[start])) { 13682 procs.add(proc); 13683 } else if (proc.processName.equals(args[start])) { 13684 procs.add(proc); 13685 } 13686 } 13687 if (procs.size() <= 0) { 13688 return null; 13689 } 13690 } else { 13691 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13692 } 13693 } 13694 return procs; 13695 } 13696 13697 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13698 PrintWriter pw, String[] args) { 13699 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13700 if (procs == null) { 13701 pw.println("No process found for: " + args[0]); 13702 return; 13703 } 13704 13705 long uptime = SystemClock.uptimeMillis(); 13706 long realtime = SystemClock.elapsedRealtime(); 13707 pw.println("Applications Graphics Acceleration Info:"); 13708 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13709 13710 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13711 ProcessRecord r = procs.get(i); 13712 if (r.thread != null) { 13713 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13714 pw.flush(); 13715 try { 13716 TransferPipe tp = new TransferPipe(); 13717 try { 13718 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13719 tp.go(fd); 13720 } finally { 13721 tp.kill(); 13722 } 13723 } catch (IOException e) { 13724 pw.println("Failure while dumping the app: " + r); 13725 pw.flush(); 13726 } catch (RemoteException e) { 13727 pw.println("Got a RemoteException while dumping the app " + r); 13728 pw.flush(); 13729 } 13730 } 13731 } 13732 } 13733 13734 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13735 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13736 if (procs == null) { 13737 pw.println("No process found for: " + args[0]); 13738 return; 13739 } 13740 13741 pw.println("Applications Database Info:"); 13742 13743 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13744 ProcessRecord r = procs.get(i); 13745 if (r.thread != null) { 13746 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13747 pw.flush(); 13748 try { 13749 TransferPipe tp = new TransferPipe(); 13750 try { 13751 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13752 tp.go(fd); 13753 } finally { 13754 tp.kill(); 13755 } 13756 } catch (IOException e) { 13757 pw.println("Failure while dumping the app: " + r); 13758 pw.flush(); 13759 } catch (RemoteException e) { 13760 pw.println("Got a RemoteException while dumping the app " + r); 13761 pw.flush(); 13762 } 13763 } 13764 } 13765 } 13766 13767 final static class MemItem { 13768 final boolean isProc; 13769 final String label; 13770 final String shortLabel; 13771 final long pss; 13772 final int id; 13773 final boolean hasActivities; 13774 ArrayList<MemItem> subitems; 13775 13776 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13777 boolean _hasActivities) { 13778 isProc = true; 13779 label = _label; 13780 shortLabel = _shortLabel; 13781 pss = _pss; 13782 id = _id; 13783 hasActivities = _hasActivities; 13784 } 13785 13786 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13787 isProc = false; 13788 label = _label; 13789 shortLabel = _shortLabel; 13790 pss = _pss; 13791 id = _id; 13792 hasActivities = false; 13793 } 13794 } 13795 13796 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13797 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13798 if (sort && !isCompact) { 13799 Collections.sort(items, new Comparator<MemItem>() { 13800 @Override 13801 public int compare(MemItem lhs, MemItem rhs) { 13802 if (lhs.pss < rhs.pss) { 13803 return 1; 13804 } else if (lhs.pss > rhs.pss) { 13805 return -1; 13806 } 13807 return 0; 13808 } 13809 }); 13810 } 13811 13812 for (int i=0; i<items.size(); i++) { 13813 MemItem mi = items.get(i); 13814 if (!isCompact) { 13815 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13816 } else if (mi.isProc) { 13817 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13818 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13819 pw.println(mi.hasActivities ? ",a" : ",e"); 13820 } else { 13821 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13822 pw.println(mi.pss); 13823 } 13824 if (mi.subitems != null) { 13825 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13826 true, isCompact); 13827 } 13828 } 13829 } 13830 13831 // These are in KB. 13832 static final long[] DUMP_MEM_BUCKETS = new long[] { 13833 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13834 120*1024, 160*1024, 200*1024, 13835 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13836 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13837 }; 13838 13839 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13840 boolean stackLike) { 13841 int start = label.lastIndexOf('.'); 13842 if (start >= 0) start++; 13843 else start = 0; 13844 int end = label.length(); 13845 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13846 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13847 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13848 out.append(bucket); 13849 out.append(stackLike ? "MB." : "MB "); 13850 out.append(label, start, end); 13851 return; 13852 } 13853 } 13854 out.append(memKB/1024); 13855 out.append(stackLike ? "MB." : "MB "); 13856 out.append(label, start, end); 13857 } 13858 13859 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13860 ProcessList.NATIVE_ADJ, 13861 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13862 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13863 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13864 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13865 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13866 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13867 }; 13868 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13869 "Native", 13870 "System", "Persistent", "Persistent Service", "Foreground", 13871 "Visible", "Perceptible", 13872 "Heavy Weight", "Backup", 13873 "A Services", "Home", 13874 "Previous", "B Services", "Cached" 13875 }; 13876 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13877 "native", 13878 "sys", "pers", "persvc", "fore", 13879 "vis", "percept", 13880 "heavy", "backup", 13881 "servicea", "home", 13882 "prev", "serviceb", "cached" 13883 }; 13884 13885 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13886 long realtime, boolean isCheckinRequest, boolean isCompact) { 13887 if (isCheckinRequest || isCompact) { 13888 // short checkin version 13889 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13890 } else { 13891 pw.println("Applications Memory Usage (kB):"); 13892 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13893 } 13894 } 13895 13896 private static final int KSM_SHARED = 0; 13897 private static final int KSM_SHARING = 1; 13898 private static final int KSM_UNSHARED = 2; 13899 private static final int KSM_VOLATILE = 3; 13900 13901 private final long[] getKsmInfo() { 13902 long[] longOut = new long[4]; 13903 final int[] SINGLE_LONG_FORMAT = new int[] { 13904 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13905 }; 13906 long[] longTmp = new long[1]; 13907 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13908 SINGLE_LONG_FORMAT, null, longTmp, null); 13909 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13910 longTmp[0] = 0; 13911 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13912 SINGLE_LONG_FORMAT, null, longTmp, null); 13913 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13914 longTmp[0] = 0; 13915 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13916 SINGLE_LONG_FORMAT, null, longTmp, null); 13917 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13918 longTmp[0] = 0; 13919 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13920 SINGLE_LONG_FORMAT, null, longTmp, null); 13921 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13922 return longOut; 13923 } 13924 13925 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13926 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13927 boolean dumpDetails = false; 13928 boolean dumpFullDetails = false; 13929 boolean dumpDalvik = false; 13930 boolean oomOnly = false; 13931 boolean isCompact = false; 13932 boolean localOnly = false; 13933 boolean packages = false; 13934 13935 int opti = 0; 13936 while (opti < args.length) { 13937 String opt = args[opti]; 13938 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13939 break; 13940 } 13941 opti++; 13942 if ("-a".equals(opt)) { 13943 dumpDetails = true; 13944 dumpFullDetails = true; 13945 dumpDalvik = true; 13946 } else if ("-d".equals(opt)) { 13947 dumpDalvik = true; 13948 } else if ("-c".equals(opt)) { 13949 isCompact = true; 13950 } else if ("--oom".equals(opt)) { 13951 oomOnly = true; 13952 } else if ("--local".equals(opt)) { 13953 localOnly = true; 13954 } else if ("--package".equals(opt)) { 13955 packages = true; 13956 } else if ("-h".equals(opt)) { 13957 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13958 pw.println(" -a: include all available information for each process."); 13959 pw.println(" -d: include dalvik details when dumping process details."); 13960 pw.println(" -c: dump in a compact machine-parseable representation."); 13961 pw.println(" --oom: only show processes organized by oom adj."); 13962 pw.println(" --local: only collect details locally, don't call process."); 13963 pw.println(" --package: interpret process arg as package, dumping all"); 13964 pw.println(" processes that have loaded that package."); 13965 pw.println("If [process] is specified it can be the name or "); 13966 pw.println("pid of a specific process to dump."); 13967 return; 13968 } else { 13969 pw.println("Unknown argument: " + opt + "; use -h for help"); 13970 } 13971 } 13972 13973 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13974 long uptime = SystemClock.uptimeMillis(); 13975 long realtime = SystemClock.elapsedRealtime(); 13976 final long[] tmpLong = new long[1]; 13977 13978 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13979 if (procs == null) { 13980 // No Java processes. Maybe they want to print a native process. 13981 if (args != null && args.length > opti 13982 && args[opti].charAt(0) != '-') { 13983 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13984 = new ArrayList<ProcessCpuTracker.Stats>(); 13985 updateCpuStatsNow(); 13986 int findPid = -1; 13987 try { 13988 findPid = Integer.parseInt(args[opti]); 13989 } catch (NumberFormatException e) { 13990 } 13991 synchronized (mProcessCpuTracker) { 13992 final int N = mProcessCpuTracker.countStats(); 13993 for (int i=0; i<N; i++) { 13994 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13995 if (st.pid == findPid || (st.baseName != null 13996 && st.baseName.equals(args[opti]))) { 13997 nativeProcs.add(st); 13998 } 13999 } 14000 } 14001 if (nativeProcs.size() > 0) { 14002 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14003 isCompact); 14004 Debug.MemoryInfo mi = null; 14005 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14006 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14007 final int pid = r.pid; 14008 if (!isCheckinRequest && dumpDetails) { 14009 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14010 } 14011 if (mi == null) { 14012 mi = new Debug.MemoryInfo(); 14013 } 14014 if (dumpDetails || (!brief && !oomOnly)) { 14015 Debug.getMemoryInfo(pid, mi); 14016 } else { 14017 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14018 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14019 } 14020 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14021 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14022 if (isCheckinRequest) { 14023 pw.println(); 14024 } 14025 } 14026 return; 14027 } 14028 } 14029 pw.println("No process found for: " + args[opti]); 14030 return; 14031 } 14032 14033 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14034 dumpDetails = true; 14035 } 14036 14037 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14038 14039 String[] innerArgs = new String[args.length-opti]; 14040 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14041 14042 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14043 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14044 long nativePss = 0; 14045 long dalvikPss = 0; 14046 long otherPss = 0; 14047 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14048 14049 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14050 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14051 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14052 14053 long totalPss = 0; 14054 long cachedPss = 0; 14055 14056 Debug.MemoryInfo mi = null; 14057 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14058 final ProcessRecord r = procs.get(i); 14059 final IApplicationThread thread; 14060 final int pid; 14061 final int oomAdj; 14062 final boolean hasActivities; 14063 synchronized (this) { 14064 thread = r.thread; 14065 pid = r.pid; 14066 oomAdj = r.getSetAdjWithServices(); 14067 hasActivities = r.activities.size() > 0; 14068 } 14069 if (thread != null) { 14070 if (!isCheckinRequest && dumpDetails) { 14071 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14072 } 14073 if (mi == null) { 14074 mi = new Debug.MemoryInfo(); 14075 } 14076 if (dumpDetails || (!brief && !oomOnly)) { 14077 Debug.getMemoryInfo(pid, mi); 14078 } else { 14079 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14080 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14081 } 14082 if (dumpDetails) { 14083 if (localOnly) { 14084 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14085 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14086 if (isCheckinRequest) { 14087 pw.println(); 14088 } 14089 } else { 14090 try { 14091 pw.flush(); 14092 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14093 dumpDalvik, innerArgs); 14094 } catch (RemoteException e) { 14095 if (!isCheckinRequest) { 14096 pw.println("Got RemoteException!"); 14097 pw.flush(); 14098 } 14099 } 14100 } 14101 } 14102 14103 final long myTotalPss = mi.getTotalPss(); 14104 final long myTotalUss = mi.getTotalUss(); 14105 14106 synchronized (this) { 14107 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14108 // Record this for posterity if the process has been stable. 14109 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14110 } 14111 } 14112 14113 if (!isCheckinRequest && mi != null) { 14114 totalPss += myTotalPss; 14115 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14116 (hasActivities ? " / activities)" : ")"), 14117 r.processName, myTotalPss, pid, hasActivities); 14118 procMems.add(pssItem); 14119 procMemsMap.put(pid, pssItem); 14120 14121 nativePss += mi.nativePss; 14122 dalvikPss += mi.dalvikPss; 14123 otherPss += mi.otherPss; 14124 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14125 long mem = mi.getOtherPss(j); 14126 miscPss[j] += mem; 14127 otherPss -= mem; 14128 } 14129 14130 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14131 cachedPss += myTotalPss; 14132 } 14133 14134 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14135 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14136 || oomIndex == (oomPss.length-1)) { 14137 oomPss[oomIndex] += myTotalPss; 14138 if (oomProcs[oomIndex] == null) { 14139 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14140 } 14141 oomProcs[oomIndex].add(pssItem); 14142 break; 14143 } 14144 } 14145 } 14146 } 14147 } 14148 14149 long nativeProcTotalPss = 0; 14150 14151 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14152 // If we are showing aggregations, also look for native processes to 14153 // include so that our aggregations are more accurate. 14154 updateCpuStatsNow(); 14155 mi = null; 14156 synchronized (mProcessCpuTracker) { 14157 final int N = mProcessCpuTracker.countStats(); 14158 for (int i=0; i<N; i++) { 14159 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14160 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14161 if (mi == null) { 14162 mi = new Debug.MemoryInfo(); 14163 } 14164 if (!brief && !oomOnly) { 14165 Debug.getMemoryInfo(st.pid, mi); 14166 } else { 14167 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14168 mi.nativePrivateDirty = (int)tmpLong[0]; 14169 } 14170 14171 final long myTotalPss = mi.getTotalPss(); 14172 totalPss += myTotalPss; 14173 nativeProcTotalPss += myTotalPss; 14174 14175 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14176 st.name, myTotalPss, st.pid, false); 14177 procMems.add(pssItem); 14178 14179 nativePss += mi.nativePss; 14180 dalvikPss += mi.dalvikPss; 14181 otherPss += mi.otherPss; 14182 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14183 long mem = mi.getOtherPss(j); 14184 miscPss[j] += mem; 14185 otherPss -= mem; 14186 } 14187 oomPss[0] += myTotalPss; 14188 if (oomProcs[0] == null) { 14189 oomProcs[0] = new ArrayList<MemItem>(); 14190 } 14191 oomProcs[0].add(pssItem); 14192 } 14193 } 14194 } 14195 14196 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14197 14198 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14199 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14200 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14201 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14202 String label = Debug.MemoryInfo.getOtherLabel(j); 14203 catMems.add(new MemItem(label, label, miscPss[j], j)); 14204 } 14205 14206 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14207 for (int j=0; j<oomPss.length; j++) { 14208 if (oomPss[j] != 0) { 14209 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14210 : DUMP_MEM_OOM_LABEL[j]; 14211 MemItem item = new MemItem(label, label, oomPss[j], 14212 DUMP_MEM_OOM_ADJ[j]); 14213 item.subitems = oomProcs[j]; 14214 oomMems.add(item); 14215 } 14216 } 14217 14218 if (!brief && !oomOnly && !isCompact) { 14219 pw.println(); 14220 pw.println("Total PSS by process:"); 14221 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14222 pw.println(); 14223 } 14224 if (!isCompact) { 14225 pw.println("Total PSS by OOM adjustment:"); 14226 } 14227 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14228 if (!brief && !oomOnly) { 14229 PrintWriter out = categoryPw != null ? categoryPw : pw; 14230 if (!isCompact) { 14231 out.println(); 14232 out.println("Total PSS by category:"); 14233 } 14234 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14235 } 14236 if (!isCompact) { 14237 pw.println(); 14238 } 14239 MemInfoReader memInfo = new MemInfoReader(); 14240 memInfo.readMemInfo(); 14241 if (nativeProcTotalPss > 0) { 14242 synchronized (this) { 14243 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14244 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14245 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14246 } 14247 } 14248 if (!brief) { 14249 if (!isCompact) { 14250 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14251 pw.print(" kB (status "); 14252 switch (mLastMemoryLevel) { 14253 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14254 pw.println("normal)"); 14255 break; 14256 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14257 pw.println("moderate)"); 14258 break; 14259 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14260 pw.println("low)"); 14261 break; 14262 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14263 pw.println("critical)"); 14264 break; 14265 default: 14266 pw.print(mLastMemoryLevel); 14267 pw.println(")"); 14268 break; 14269 } 14270 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14271 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14272 pw.print(cachedPss); pw.print(" cached pss + "); 14273 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14274 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14275 } else { 14276 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14277 pw.print(cachedPss + memInfo.getCachedSizeKb() 14278 + memInfo.getFreeSizeKb()); pw.print(","); 14279 pw.println(totalPss - cachedPss); 14280 } 14281 } 14282 if (!isCompact) { 14283 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14284 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14285 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14286 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14287 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14288 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14289 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14290 } 14291 if (!brief) { 14292 if (memInfo.getZramTotalSizeKb() != 0) { 14293 if (!isCompact) { 14294 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14295 pw.print(" kB physical used for "); 14296 pw.print(memInfo.getSwapTotalSizeKb() 14297 - memInfo.getSwapFreeSizeKb()); 14298 pw.print(" kB in swap ("); 14299 pw.print(memInfo.getSwapTotalSizeKb()); 14300 pw.println(" kB total swap)"); 14301 } else { 14302 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14303 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14304 pw.println(memInfo.getSwapFreeSizeKb()); 14305 } 14306 } 14307 final long[] ksm = getKsmInfo(); 14308 if (!isCompact) { 14309 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14310 || ksm[KSM_VOLATILE] != 0) { 14311 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14312 pw.print(" kB saved from shared "); 14313 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14314 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14315 pw.print(" kB unshared; "); 14316 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14317 } 14318 pw.print(" Tuning: "); 14319 pw.print(ActivityManager.staticGetMemoryClass()); 14320 pw.print(" (large "); 14321 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14322 pw.print("), oom "); 14323 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14324 pw.print(" kB"); 14325 pw.print(", restore limit "); 14326 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14327 pw.print(" kB"); 14328 if (ActivityManager.isLowRamDeviceStatic()) { 14329 pw.print(" (low-ram)"); 14330 } 14331 if (ActivityManager.isHighEndGfx()) { 14332 pw.print(" (high-end-gfx)"); 14333 } 14334 pw.println(); 14335 } else { 14336 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14337 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14338 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14339 pw.print("tuning,"); 14340 pw.print(ActivityManager.staticGetMemoryClass()); 14341 pw.print(','); 14342 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14343 pw.print(','); 14344 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14345 if (ActivityManager.isLowRamDeviceStatic()) { 14346 pw.print(",low-ram"); 14347 } 14348 if (ActivityManager.isHighEndGfx()) { 14349 pw.print(",high-end-gfx"); 14350 } 14351 pw.println(); 14352 } 14353 } 14354 } 14355 } 14356 14357 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14358 long memtrack, String name) { 14359 sb.append(" "); 14360 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14361 sb.append(' '); 14362 sb.append(ProcessList.makeProcStateString(procState)); 14363 sb.append(' '); 14364 ProcessList.appendRamKb(sb, pss); 14365 sb.append(" kB: "); 14366 sb.append(name); 14367 if (memtrack > 0) { 14368 sb.append(" ("); 14369 sb.append(memtrack); 14370 sb.append(" kB memtrack)"); 14371 } 14372 } 14373 14374 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14375 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14376 sb.append(" (pid "); 14377 sb.append(mi.pid); 14378 sb.append(") "); 14379 sb.append(mi.adjType); 14380 sb.append('\n'); 14381 if (mi.adjReason != null) { 14382 sb.append(" "); 14383 sb.append(mi.adjReason); 14384 sb.append('\n'); 14385 } 14386 } 14387 14388 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14389 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14390 for (int i=0, N=memInfos.size(); i<N; i++) { 14391 ProcessMemInfo mi = memInfos.get(i); 14392 infoMap.put(mi.pid, mi); 14393 } 14394 updateCpuStatsNow(); 14395 long[] memtrackTmp = new long[1]; 14396 synchronized (mProcessCpuTracker) { 14397 final int N = mProcessCpuTracker.countStats(); 14398 for (int i=0; i<N; i++) { 14399 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14400 if (st.vsize > 0) { 14401 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14402 if (pss > 0) { 14403 if (infoMap.indexOfKey(st.pid) < 0) { 14404 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14405 ProcessList.NATIVE_ADJ, -1, "native", null); 14406 mi.pss = pss; 14407 mi.memtrack = memtrackTmp[0]; 14408 memInfos.add(mi); 14409 } 14410 } 14411 } 14412 } 14413 } 14414 14415 long totalPss = 0; 14416 long totalMemtrack = 0; 14417 for (int i=0, N=memInfos.size(); i<N; i++) { 14418 ProcessMemInfo mi = memInfos.get(i); 14419 if (mi.pss == 0) { 14420 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14421 mi.memtrack = memtrackTmp[0]; 14422 } 14423 totalPss += mi.pss; 14424 totalMemtrack += mi.memtrack; 14425 } 14426 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14427 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14428 if (lhs.oomAdj != rhs.oomAdj) { 14429 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14430 } 14431 if (lhs.pss != rhs.pss) { 14432 return lhs.pss < rhs.pss ? 1 : -1; 14433 } 14434 return 0; 14435 } 14436 }); 14437 14438 StringBuilder tag = new StringBuilder(128); 14439 StringBuilder stack = new StringBuilder(128); 14440 tag.append("Low on memory -- "); 14441 appendMemBucket(tag, totalPss, "total", false); 14442 appendMemBucket(stack, totalPss, "total", true); 14443 14444 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14445 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14446 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14447 14448 boolean firstLine = true; 14449 int lastOomAdj = Integer.MIN_VALUE; 14450 long extraNativeRam = 0; 14451 long extraNativeMemtrack = 0; 14452 long cachedPss = 0; 14453 for (int i=0, N=memInfos.size(); i<N; i++) { 14454 ProcessMemInfo mi = memInfos.get(i); 14455 14456 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14457 cachedPss += mi.pss; 14458 } 14459 14460 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14461 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14462 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14463 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14464 if (lastOomAdj != mi.oomAdj) { 14465 lastOomAdj = mi.oomAdj; 14466 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14467 tag.append(" / "); 14468 } 14469 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14470 if (firstLine) { 14471 stack.append(":"); 14472 firstLine = false; 14473 } 14474 stack.append("\n\t at "); 14475 } else { 14476 stack.append("$"); 14477 } 14478 } else { 14479 tag.append(" "); 14480 stack.append("$"); 14481 } 14482 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14483 appendMemBucket(tag, mi.pss, mi.name, false); 14484 } 14485 appendMemBucket(stack, mi.pss, mi.name, true); 14486 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14487 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14488 stack.append("("); 14489 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14490 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14491 stack.append(DUMP_MEM_OOM_LABEL[k]); 14492 stack.append(":"); 14493 stack.append(DUMP_MEM_OOM_ADJ[k]); 14494 } 14495 } 14496 stack.append(")"); 14497 } 14498 } 14499 14500 appendMemInfo(fullNativeBuilder, mi); 14501 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14502 // The short form only has native processes that are >= 512K. 14503 if (mi.pss >= 512) { 14504 appendMemInfo(shortNativeBuilder, mi); 14505 } else { 14506 extraNativeRam += mi.pss; 14507 extraNativeMemtrack += mi.memtrack; 14508 } 14509 } else { 14510 // Short form has all other details, but if we have collected RAM 14511 // from smaller native processes let's dump a summary of that. 14512 if (extraNativeRam > 0) { 14513 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14514 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14515 shortNativeBuilder.append('\n'); 14516 extraNativeRam = 0; 14517 } 14518 appendMemInfo(fullJavaBuilder, mi); 14519 } 14520 } 14521 14522 fullJavaBuilder.append(" "); 14523 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14524 fullJavaBuilder.append(" kB: TOTAL"); 14525 if (totalMemtrack > 0) { 14526 fullJavaBuilder.append(" ("); 14527 fullJavaBuilder.append(totalMemtrack); 14528 fullJavaBuilder.append(" kB memtrack)"); 14529 } else { 14530 } 14531 fullJavaBuilder.append("\n"); 14532 14533 MemInfoReader memInfo = new MemInfoReader(); 14534 memInfo.readMemInfo(); 14535 final long[] infos = memInfo.getRawInfo(); 14536 14537 StringBuilder memInfoBuilder = new StringBuilder(1024); 14538 Debug.getMemInfo(infos); 14539 memInfoBuilder.append(" MemInfo: "); 14540 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14541 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14542 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14543 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14544 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14545 memInfoBuilder.append(" "); 14546 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14547 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14548 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14549 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14550 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14551 memInfoBuilder.append(" ZRAM: "); 14552 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14553 memInfoBuilder.append(" kB RAM, "); 14554 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14555 memInfoBuilder.append(" kB swap total, "); 14556 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14557 memInfoBuilder.append(" kB swap free\n"); 14558 } 14559 final long[] ksm = getKsmInfo(); 14560 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14561 || ksm[KSM_VOLATILE] != 0) { 14562 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14563 memInfoBuilder.append(" kB saved from shared "); 14564 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14565 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14566 memInfoBuilder.append(" kB unshared; "); 14567 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14568 } 14569 memInfoBuilder.append(" Free RAM: "); 14570 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14571 + memInfo.getFreeSizeKb()); 14572 memInfoBuilder.append(" kB\n"); 14573 memInfoBuilder.append(" Used RAM: "); 14574 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14575 memInfoBuilder.append(" kB\n"); 14576 memInfoBuilder.append(" Lost RAM: "); 14577 memInfoBuilder.append(memInfo.getTotalSizeKb() 14578 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14579 - memInfo.getKernelUsedSizeKb()); 14580 memInfoBuilder.append(" kB\n"); 14581 Slog.i(TAG, "Low on memory:"); 14582 Slog.i(TAG, shortNativeBuilder.toString()); 14583 Slog.i(TAG, fullJavaBuilder.toString()); 14584 Slog.i(TAG, memInfoBuilder.toString()); 14585 14586 StringBuilder dropBuilder = new StringBuilder(1024); 14587 /* 14588 StringWriter oomSw = new StringWriter(); 14589 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14590 StringWriter catSw = new StringWriter(); 14591 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14592 String[] emptyArgs = new String[] { }; 14593 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14594 oomPw.flush(); 14595 String oomString = oomSw.toString(); 14596 */ 14597 dropBuilder.append("Low on memory:"); 14598 dropBuilder.append(stack); 14599 dropBuilder.append('\n'); 14600 dropBuilder.append(fullNativeBuilder); 14601 dropBuilder.append(fullJavaBuilder); 14602 dropBuilder.append('\n'); 14603 dropBuilder.append(memInfoBuilder); 14604 dropBuilder.append('\n'); 14605 /* 14606 dropBuilder.append(oomString); 14607 dropBuilder.append('\n'); 14608 */ 14609 StringWriter catSw = new StringWriter(); 14610 synchronized (ActivityManagerService.this) { 14611 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14612 String[] emptyArgs = new String[] { }; 14613 catPw.println(); 14614 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14615 catPw.println(); 14616 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14617 false, false, null); 14618 catPw.println(); 14619 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14620 catPw.flush(); 14621 } 14622 dropBuilder.append(catSw.toString()); 14623 addErrorToDropBox("lowmem", null, "system_server", null, 14624 null, tag.toString(), dropBuilder.toString(), null, null); 14625 //Slog.i(TAG, "Sent to dropbox:"); 14626 //Slog.i(TAG, dropBuilder.toString()); 14627 synchronized (ActivityManagerService.this) { 14628 long now = SystemClock.uptimeMillis(); 14629 if (mLastMemUsageReportTime < now) { 14630 mLastMemUsageReportTime = now; 14631 } 14632 } 14633 } 14634 14635 /** 14636 * Searches array of arguments for the specified string 14637 * @param args array of argument strings 14638 * @param value value to search for 14639 * @return true if the value is contained in the array 14640 */ 14641 private static boolean scanArgs(String[] args, String value) { 14642 if (args != null) { 14643 for (String arg : args) { 14644 if (value.equals(arg)) { 14645 return true; 14646 } 14647 } 14648 } 14649 return false; 14650 } 14651 14652 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14653 ContentProviderRecord cpr, boolean always) { 14654 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14655 14656 if (!inLaunching || always) { 14657 synchronized (cpr) { 14658 cpr.launchingApp = null; 14659 cpr.notifyAll(); 14660 } 14661 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14662 String names[] = cpr.info.authority.split(";"); 14663 for (int j = 0; j < names.length; j++) { 14664 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14665 } 14666 } 14667 14668 for (int i=0; i<cpr.connections.size(); i++) { 14669 ContentProviderConnection conn = cpr.connections.get(i); 14670 if (conn.waiting) { 14671 // If this connection is waiting for the provider, then we don't 14672 // need to mess with its process unless we are always removing 14673 // or for some reason the provider is not currently launching. 14674 if (inLaunching && !always) { 14675 continue; 14676 } 14677 } 14678 ProcessRecord capp = conn.client; 14679 conn.dead = true; 14680 if (conn.stableCount > 0) { 14681 if (!capp.persistent && capp.thread != null 14682 && capp.pid != 0 14683 && capp.pid != MY_PID) { 14684 capp.kill("depends on provider " 14685 + cpr.name.flattenToShortString() 14686 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14687 } 14688 } else if (capp.thread != null && conn.provider.provider != null) { 14689 try { 14690 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14691 } catch (RemoteException e) { 14692 } 14693 // In the protocol here, we don't expect the client to correctly 14694 // clean up this connection, we'll just remove it. 14695 cpr.connections.remove(i); 14696 conn.client.conProviders.remove(conn); 14697 } 14698 } 14699 14700 if (inLaunching && always) { 14701 mLaunchingProviders.remove(cpr); 14702 } 14703 return inLaunching; 14704 } 14705 14706 /** 14707 * Main code for cleaning up a process when it has gone away. This is 14708 * called both as a result of the process dying, or directly when stopping 14709 * a process when running in single process mode. 14710 * 14711 * @return Returns true if the given process has been restarted, so the 14712 * app that was passed in must remain on the process lists. 14713 */ 14714 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14715 boolean restarting, boolean allowRestart, int index) { 14716 if (index >= 0) { 14717 removeLruProcessLocked(app); 14718 ProcessList.remove(app.pid); 14719 } 14720 14721 mProcessesToGc.remove(app); 14722 mPendingPssProcesses.remove(app); 14723 14724 // Dismiss any open dialogs. 14725 if (app.crashDialog != null && !app.forceCrashReport) { 14726 app.crashDialog.dismiss(); 14727 app.crashDialog = null; 14728 } 14729 if (app.anrDialog != null) { 14730 app.anrDialog.dismiss(); 14731 app.anrDialog = null; 14732 } 14733 if (app.waitDialog != null) { 14734 app.waitDialog.dismiss(); 14735 app.waitDialog = null; 14736 } 14737 14738 app.crashing = false; 14739 app.notResponding = false; 14740 14741 app.resetPackageList(mProcessStats); 14742 app.unlinkDeathRecipient(); 14743 app.makeInactive(mProcessStats); 14744 app.waitingToKill = null; 14745 app.forcingToForeground = null; 14746 updateProcessForegroundLocked(app, false, false); 14747 app.foregroundActivities = false; 14748 app.hasShownUi = false; 14749 app.treatLikeActivity = false; 14750 app.hasAboveClient = false; 14751 app.hasClientActivities = false; 14752 14753 mServices.killServicesLocked(app, allowRestart); 14754 14755 boolean restart = false; 14756 14757 // Remove published content providers. 14758 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14759 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14760 final boolean always = app.bad || !allowRestart; 14761 if (removeDyingProviderLocked(app, cpr, always) || always) { 14762 // We left the provider in the launching list, need to 14763 // restart it. 14764 restart = true; 14765 } 14766 14767 cpr.provider = null; 14768 cpr.proc = null; 14769 } 14770 app.pubProviders.clear(); 14771 14772 // Take care of any launching providers waiting for this process. 14773 if (checkAppInLaunchingProvidersLocked(app, false)) { 14774 restart = true; 14775 } 14776 14777 // Unregister from connected content providers. 14778 if (!app.conProviders.isEmpty()) { 14779 for (int i=0; i<app.conProviders.size(); i++) { 14780 ContentProviderConnection conn = app.conProviders.get(i); 14781 conn.provider.connections.remove(conn); 14782 } 14783 app.conProviders.clear(); 14784 } 14785 14786 // At this point there may be remaining entries in mLaunchingProviders 14787 // where we were the only one waiting, so they are no longer of use. 14788 // Look for these and clean up if found. 14789 // XXX Commented out for now. Trying to figure out a way to reproduce 14790 // the actual situation to identify what is actually going on. 14791 if (false) { 14792 for (int i=0; i<mLaunchingProviders.size(); i++) { 14793 ContentProviderRecord cpr = (ContentProviderRecord) 14794 mLaunchingProviders.get(i); 14795 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14796 synchronized (cpr) { 14797 cpr.launchingApp = null; 14798 cpr.notifyAll(); 14799 } 14800 } 14801 } 14802 } 14803 14804 skipCurrentReceiverLocked(app); 14805 14806 // Unregister any receivers. 14807 for (int i=app.receivers.size()-1; i>=0; i--) { 14808 removeReceiverLocked(app.receivers.valueAt(i)); 14809 } 14810 app.receivers.clear(); 14811 14812 // If the app is undergoing backup, tell the backup manager about it 14813 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14814 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14815 + mBackupTarget.appInfo + " died during backup"); 14816 try { 14817 IBackupManager bm = IBackupManager.Stub.asInterface( 14818 ServiceManager.getService(Context.BACKUP_SERVICE)); 14819 bm.agentDisconnected(app.info.packageName); 14820 } catch (RemoteException e) { 14821 // can't happen; backup manager is local 14822 } 14823 } 14824 14825 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14826 ProcessChangeItem item = mPendingProcessChanges.get(i); 14827 if (item.pid == app.pid) { 14828 mPendingProcessChanges.remove(i); 14829 mAvailProcessChanges.add(item); 14830 } 14831 } 14832 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14833 14834 // If the caller is restarting this app, then leave it in its 14835 // current lists and let the caller take care of it. 14836 if (restarting) { 14837 return false; 14838 } 14839 14840 if (!app.persistent || app.isolated) { 14841 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14842 "Removing non-persistent process during cleanup: " + app); 14843 mProcessNames.remove(app.processName, app.uid); 14844 mIsolatedProcesses.remove(app.uid); 14845 if (mHeavyWeightProcess == app) { 14846 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14847 mHeavyWeightProcess.userId, 0)); 14848 mHeavyWeightProcess = null; 14849 } 14850 } else if (!app.removed) { 14851 // This app is persistent, so we need to keep its record around. 14852 // If it is not already on the pending app list, add it there 14853 // and start a new process for it. 14854 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14855 mPersistentStartingProcesses.add(app); 14856 restart = true; 14857 } 14858 } 14859 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14860 "Clean-up removing on hold: " + app); 14861 mProcessesOnHold.remove(app); 14862 14863 if (app == mHomeProcess) { 14864 mHomeProcess = null; 14865 } 14866 if (app == mPreviousProcess) { 14867 mPreviousProcess = null; 14868 } 14869 14870 if (restart && !app.isolated) { 14871 // We have components that still need to be running in the 14872 // process, so re-launch it. 14873 if (index < 0) { 14874 ProcessList.remove(app.pid); 14875 } 14876 mProcessNames.put(app.processName, app.uid, app); 14877 startProcessLocked(app, "restart", app.processName); 14878 return true; 14879 } else if (app.pid > 0 && app.pid != MY_PID) { 14880 // Goodbye! 14881 boolean removed; 14882 synchronized (mPidsSelfLocked) { 14883 mPidsSelfLocked.remove(app.pid); 14884 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14885 } 14886 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14887 if (app.isolated) { 14888 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14889 } 14890 app.setPid(0); 14891 } 14892 return false; 14893 } 14894 14895 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14896 // Look through the content providers we are waiting to have launched, 14897 // and if any run in this process then either schedule a restart of 14898 // the process or kill the client waiting for it if this process has 14899 // gone bad. 14900 int NL = mLaunchingProviders.size(); 14901 boolean restart = false; 14902 for (int i=0; i<NL; i++) { 14903 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14904 if (cpr.launchingApp == app) { 14905 if (!alwaysBad && !app.bad) { 14906 restart = true; 14907 } else { 14908 removeDyingProviderLocked(app, cpr, true); 14909 // cpr should have been removed from mLaunchingProviders 14910 NL = mLaunchingProviders.size(); 14911 i--; 14912 } 14913 } 14914 } 14915 return restart; 14916 } 14917 14918 // ========================================================= 14919 // SERVICES 14920 // ========================================================= 14921 14922 @Override 14923 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14924 int flags) { 14925 enforceNotIsolatedCaller("getServices"); 14926 synchronized (this) { 14927 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14928 } 14929 } 14930 14931 @Override 14932 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14933 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14934 synchronized (this) { 14935 return mServices.getRunningServiceControlPanelLocked(name); 14936 } 14937 } 14938 14939 @Override 14940 public ComponentName startService(IApplicationThread caller, Intent service, 14941 String resolvedType, int userId) { 14942 enforceNotIsolatedCaller("startService"); 14943 // Refuse possible leaked file descriptors 14944 if (service != null && service.hasFileDescriptors() == true) { 14945 throw new IllegalArgumentException("File descriptors passed in Intent"); 14946 } 14947 14948 if (DEBUG_SERVICE) 14949 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14950 synchronized(this) { 14951 final int callingPid = Binder.getCallingPid(); 14952 final int callingUid = Binder.getCallingUid(); 14953 final long origId = Binder.clearCallingIdentity(); 14954 ComponentName res = mServices.startServiceLocked(caller, service, 14955 resolvedType, callingPid, callingUid, userId); 14956 Binder.restoreCallingIdentity(origId); 14957 return res; 14958 } 14959 } 14960 14961 ComponentName startServiceInPackage(int uid, 14962 Intent service, String resolvedType, int userId) { 14963 synchronized(this) { 14964 if (DEBUG_SERVICE) 14965 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14966 final long origId = Binder.clearCallingIdentity(); 14967 ComponentName res = mServices.startServiceLocked(null, service, 14968 resolvedType, -1, uid, userId); 14969 Binder.restoreCallingIdentity(origId); 14970 return res; 14971 } 14972 } 14973 14974 @Override 14975 public int stopService(IApplicationThread caller, Intent service, 14976 String resolvedType, int userId) { 14977 enforceNotIsolatedCaller("stopService"); 14978 // Refuse possible leaked file descriptors 14979 if (service != null && service.hasFileDescriptors() == true) { 14980 throw new IllegalArgumentException("File descriptors passed in Intent"); 14981 } 14982 14983 synchronized(this) { 14984 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14985 } 14986 } 14987 14988 @Override 14989 public IBinder peekService(Intent service, String resolvedType) { 14990 enforceNotIsolatedCaller("peekService"); 14991 // Refuse possible leaked file descriptors 14992 if (service != null && service.hasFileDescriptors() == true) { 14993 throw new IllegalArgumentException("File descriptors passed in Intent"); 14994 } 14995 synchronized(this) { 14996 return mServices.peekServiceLocked(service, resolvedType); 14997 } 14998 } 14999 15000 @Override 15001 public boolean stopServiceToken(ComponentName className, IBinder token, 15002 int startId) { 15003 synchronized(this) { 15004 return mServices.stopServiceTokenLocked(className, token, startId); 15005 } 15006 } 15007 15008 @Override 15009 public void setServiceForeground(ComponentName className, IBinder token, 15010 int id, Notification notification, boolean removeNotification) { 15011 synchronized(this) { 15012 mServices.setServiceForegroundLocked(className, token, id, notification, 15013 removeNotification); 15014 } 15015 } 15016 15017 @Override 15018 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15019 boolean requireFull, String name, String callerPackage) { 15020 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15021 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15022 } 15023 15024 int unsafeConvertIncomingUser(int userId) { 15025 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15026 ? mCurrentUserId : userId; 15027 } 15028 15029 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15030 int allowMode, String name, String callerPackage) { 15031 final int callingUserId = UserHandle.getUserId(callingUid); 15032 if (callingUserId == userId) { 15033 return userId; 15034 } 15035 15036 // Note that we may be accessing mCurrentUserId outside of a lock... 15037 // shouldn't be a big deal, if this is being called outside 15038 // of a locked context there is intrinsically a race with 15039 // the value the caller will receive and someone else changing it. 15040 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15041 // we will switch to the calling user if access to the current user fails. 15042 int targetUserId = unsafeConvertIncomingUser(userId); 15043 15044 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15045 final boolean allow; 15046 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15047 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15048 // If the caller has this permission, they always pass go. And collect $200. 15049 allow = true; 15050 } else if (allowMode == ALLOW_FULL_ONLY) { 15051 // We require full access, sucks to be you. 15052 allow = false; 15053 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15054 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15055 // If the caller does not have either permission, they are always doomed. 15056 allow = false; 15057 } else if (allowMode == ALLOW_NON_FULL) { 15058 // We are blanket allowing non-full access, you lucky caller! 15059 allow = true; 15060 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15061 // We may or may not allow this depending on whether the two users are 15062 // in the same profile. 15063 synchronized (mUserProfileGroupIdsSelfLocked) { 15064 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15065 UserInfo.NO_PROFILE_GROUP_ID); 15066 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15067 UserInfo.NO_PROFILE_GROUP_ID); 15068 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15069 && callingProfile == targetProfile; 15070 } 15071 } else { 15072 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15073 } 15074 if (!allow) { 15075 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15076 // In this case, they would like to just execute as their 15077 // owner user instead of failing. 15078 targetUserId = callingUserId; 15079 } else { 15080 StringBuilder builder = new StringBuilder(128); 15081 builder.append("Permission Denial: "); 15082 builder.append(name); 15083 if (callerPackage != null) { 15084 builder.append(" from "); 15085 builder.append(callerPackage); 15086 } 15087 builder.append(" asks to run as user "); 15088 builder.append(userId); 15089 builder.append(" but is calling from user "); 15090 builder.append(UserHandle.getUserId(callingUid)); 15091 builder.append("; this requires "); 15092 builder.append(INTERACT_ACROSS_USERS_FULL); 15093 if (allowMode != ALLOW_FULL_ONLY) { 15094 builder.append(" or "); 15095 builder.append(INTERACT_ACROSS_USERS); 15096 } 15097 String msg = builder.toString(); 15098 Slog.w(TAG, msg); 15099 throw new SecurityException(msg); 15100 } 15101 } 15102 } 15103 if (!allowAll && targetUserId < 0) { 15104 throw new IllegalArgumentException( 15105 "Call does not support special user #" + targetUserId); 15106 } 15107 // Check shell permission 15108 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15109 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15110 targetUserId)) { 15111 throw new SecurityException("Shell does not have permission to access user " 15112 + targetUserId + "\n " + Debug.getCallers(3)); 15113 } 15114 } 15115 return targetUserId; 15116 } 15117 15118 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15119 String className, int flags) { 15120 boolean result = false; 15121 // For apps that don't have pre-defined UIDs, check for permission 15122 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15123 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15124 if (ActivityManager.checkUidPermission( 15125 INTERACT_ACROSS_USERS, 15126 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15127 ComponentName comp = new ComponentName(aInfo.packageName, className); 15128 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15129 + " requests FLAG_SINGLE_USER, but app does not hold " 15130 + INTERACT_ACROSS_USERS; 15131 Slog.w(TAG, msg); 15132 throw new SecurityException(msg); 15133 } 15134 // Permission passed 15135 result = true; 15136 } 15137 } else if ("system".equals(componentProcessName)) { 15138 result = true; 15139 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15140 // Phone app and persistent apps are allowed to export singleuser providers. 15141 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15142 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15143 } 15144 if (DEBUG_MU) { 15145 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15146 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15147 } 15148 return result; 15149 } 15150 15151 /** 15152 * Checks to see if the caller is in the same app as the singleton 15153 * component, or the component is in a special app. It allows special apps 15154 * to export singleton components but prevents exporting singleton 15155 * components for regular apps. 15156 */ 15157 boolean isValidSingletonCall(int callingUid, int componentUid) { 15158 int componentAppId = UserHandle.getAppId(componentUid); 15159 return UserHandle.isSameApp(callingUid, componentUid) 15160 || componentAppId == Process.SYSTEM_UID 15161 || componentAppId == Process.PHONE_UID 15162 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15163 == PackageManager.PERMISSION_GRANTED; 15164 } 15165 15166 public int bindService(IApplicationThread caller, IBinder token, 15167 Intent service, String resolvedType, 15168 IServiceConnection connection, int flags, int userId) { 15169 enforceNotIsolatedCaller("bindService"); 15170 15171 // Refuse possible leaked file descriptors 15172 if (service != null && service.hasFileDescriptors() == true) { 15173 throw new IllegalArgumentException("File descriptors passed in Intent"); 15174 } 15175 15176 synchronized(this) { 15177 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15178 connection, flags, userId); 15179 } 15180 } 15181 15182 public boolean unbindService(IServiceConnection connection) { 15183 synchronized (this) { 15184 return mServices.unbindServiceLocked(connection); 15185 } 15186 } 15187 15188 public void publishService(IBinder token, Intent intent, IBinder service) { 15189 // Refuse possible leaked file descriptors 15190 if (intent != null && intent.hasFileDescriptors() == true) { 15191 throw new IllegalArgumentException("File descriptors passed in Intent"); 15192 } 15193 15194 synchronized(this) { 15195 if (!(token instanceof ServiceRecord)) { 15196 throw new IllegalArgumentException("Invalid service token"); 15197 } 15198 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15199 } 15200 } 15201 15202 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15203 // Refuse possible leaked file descriptors 15204 if (intent != null && intent.hasFileDescriptors() == true) { 15205 throw new IllegalArgumentException("File descriptors passed in Intent"); 15206 } 15207 15208 synchronized(this) { 15209 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15210 } 15211 } 15212 15213 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15214 synchronized(this) { 15215 if (!(token instanceof ServiceRecord)) { 15216 throw new IllegalArgumentException("Invalid service token"); 15217 } 15218 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15219 } 15220 } 15221 15222 // ========================================================= 15223 // BACKUP AND RESTORE 15224 // ========================================================= 15225 15226 // Cause the target app to be launched if necessary and its backup agent 15227 // instantiated. The backup agent will invoke backupAgentCreated() on the 15228 // activity manager to announce its creation. 15229 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15230 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15231 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15232 15233 synchronized(this) { 15234 // !!! TODO: currently no check here that we're already bound 15235 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15236 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15237 synchronized (stats) { 15238 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15239 } 15240 15241 // Backup agent is now in use, its package can't be stopped. 15242 try { 15243 AppGlobals.getPackageManager().setPackageStoppedState( 15244 app.packageName, false, UserHandle.getUserId(app.uid)); 15245 } catch (RemoteException e) { 15246 } catch (IllegalArgumentException e) { 15247 Slog.w(TAG, "Failed trying to unstop package " 15248 + app.packageName + ": " + e); 15249 } 15250 15251 BackupRecord r = new BackupRecord(ss, app, backupMode); 15252 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15253 ? new ComponentName(app.packageName, app.backupAgentName) 15254 : new ComponentName("android", "FullBackupAgent"); 15255 // startProcessLocked() returns existing proc's record if it's already running 15256 ProcessRecord proc = startProcessLocked(app.processName, app, 15257 false, 0, "backup", hostingName, false, false, false); 15258 if (proc == null) { 15259 Slog.e(TAG, "Unable to start backup agent process " + r); 15260 return false; 15261 } 15262 15263 r.app = proc; 15264 mBackupTarget = r; 15265 mBackupAppName = app.packageName; 15266 15267 // Try not to kill the process during backup 15268 updateOomAdjLocked(proc); 15269 15270 // If the process is already attached, schedule the creation of the backup agent now. 15271 // If it is not yet live, this will be done when it attaches to the framework. 15272 if (proc.thread != null) { 15273 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15274 try { 15275 proc.thread.scheduleCreateBackupAgent(app, 15276 compatibilityInfoForPackageLocked(app), backupMode); 15277 } catch (RemoteException e) { 15278 // Will time out on the backup manager side 15279 } 15280 } else { 15281 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15282 } 15283 // Invariants: at this point, the target app process exists and the application 15284 // is either already running or in the process of coming up. mBackupTarget and 15285 // mBackupAppName describe the app, so that when it binds back to the AM we 15286 // know that it's scheduled for a backup-agent operation. 15287 } 15288 15289 return true; 15290 } 15291 15292 @Override 15293 public void clearPendingBackup() { 15294 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15295 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15296 15297 synchronized (this) { 15298 mBackupTarget = null; 15299 mBackupAppName = null; 15300 } 15301 } 15302 15303 // A backup agent has just come up 15304 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15305 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15306 + " = " + agent); 15307 15308 synchronized(this) { 15309 if (!agentPackageName.equals(mBackupAppName)) { 15310 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15311 return; 15312 } 15313 } 15314 15315 long oldIdent = Binder.clearCallingIdentity(); 15316 try { 15317 IBackupManager bm = IBackupManager.Stub.asInterface( 15318 ServiceManager.getService(Context.BACKUP_SERVICE)); 15319 bm.agentConnected(agentPackageName, agent); 15320 } catch (RemoteException e) { 15321 // can't happen; the backup manager service is local 15322 } catch (Exception e) { 15323 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15324 e.printStackTrace(); 15325 } finally { 15326 Binder.restoreCallingIdentity(oldIdent); 15327 } 15328 } 15329 15330 // done with this agent 15331 public void unbindBackupAgent(ApplicationInfo appInfo) { 15332 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15333 if (appInfo == null) { 15334 Slog.w(TAG, "unbind backup agent for null app"); 15335 return; 15336 } 15337 15338 synchronized(this) { 15339 try { 15340 if (mBackupAppName == null) { 15341 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15342 return; 15343 } 15344 15345 if (!mBackupAppName.equals(appInfo.packageName)) { 15346 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15347 return; 15348 } 15349 15350 // Not backing this app up any more; reset its OOM adjustment 15351 final ProcessRecord proc = mBackupTarget.app; 15352 updateOomAdjLocked(proc); 15353 15354 // If the app crashed during backup, 'thread' will be null here 15355 if (proc.thread != null) { 15356 try { 15357 proc.thread.scheduleDestroyBackupAgent(appInfo, 15358 compatibilityInfoForPackageLocked(appInfo)); 15359 } catch (Exception e) { 15360 Slog.e(TAG, "Exception when unbinding backup agent:"); 15361 e.printStackTrace(); 15362 } 15363 } 15364 } finally { 15365 mBackupTarget = null; 15366 mBackupAppName = null; 15367 } 15368 } 15369 } 15370 // ========================================================= 15371 // BROADCASTS 15372 // ========================================================= 15373 15374 private final List getStickiesLocked(String action, IntentFilter filter, 15375 List cur, int userId) { 15376 final ContentResolver resolver = mContext.getContentResolver(); 15377 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15378 if (stickies == null) { 15379 return cur; 15380 } 15381 final ArrayList<Intent> list = stickies.get(action); 15382 if (list == null) { 15383 return cur; 15384 } 15385 int N = list.size(); 15386 for (int i=0; i<N; i++) { 15387 Intent intent = list.get(i); 15388 if (filter.match(resolver, intent, true, TAG) >= 0) { 15389 if (cur == null) { 15390 cur = new ArrayList<Intent>(); 15391 } 15392 cur.add(intent); 15393 } 15394 } 15395 return cur; 15396 } 15397 15398 boolean isPendingBroadcastProcessLocked(int pid) { 15399 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15400 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15401 } 15402 15403 void skipPendingBroadcastLocked(int pid) { 15404 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15405 for (BroadcastQueue queue : mBroadcastQueues) { 15406 queue.skipPendingBroadcastLocked(pid); 15407 } 15408 } 15409 15410 // The app just attached; send any pending broadcasts that it should receive 15411 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15412 boolean didSomething = false; 15413 for (BroadcastQueue queue : mBroadcastQueues) { 15414 didSomething |= queue.sendPendingBroadcastsLocked(app); 15415 } 15416 return didSomething; 15417 } 15418 15419 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15420 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15421 enforceNotIsolatedCaller("registerReceiver"); 15422 int callingUid; 15423 int callingPid; 15424 synchronized(this) { 15425 ProcessRecord callerApp = null; 15426 if (caller != null) { 15427 callerApp = getRecordForAppLocked(caller); 15428 if (callerApp == null) { 15429 throw new SecurityException( 15430 "Unable to find app for caller " + caller 15431 + " (pid=" + Binder.getCallingPid() 15432 + ") when registering receiver " + receiver); 15433 } 15434 if (callerApp.info.uid != Process.SYSTEM_UID && 15435 !callerApp.pkgList.containsKey(callerPackage) && 15436 !"android".equals(callerPackage)) { 15437 throw new SecurityException("Given caller package " + callerPackage 15438 + " is not running in process " + callerApp); 15439 } 15440 callingUid = callerApp.info.uid; 15441 callingPid = callerApp.pid; 15442 } else { 15443 callerPackage = null; 15444 callingUid = Binder.getCallingUid(); 15445 callingPid = Binder.getCallingPid(); 15446 } 15447 15448 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15449 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15450 15451 List allSticky = null; 15452 15453 // Look for any matching sticky broadcasts... 15454 Iterator actions = filter.actionsIterator(); 15455 if (actions != null) { 15456 while (actions.hasNext()) { 15457 String action = (String)actions.next(); 15458 allSticky = getStickiesLocked(action, filter, allSticky, 15459 UserHandle.USER_ALL); 15460 allSticky = getStickiesLocked(action, filter, allSticky, 15461 UserHandle.getUserId(callingUid)); 15462 } 15463 } else { 15464 allSticky = getStickiesLocked(null, filter, allSticky, 15465 UserHandle.USER_ALL); 15466 allSticky = getStickiesLocked(null, filter, allSticky, 15467 UserHandle.getUserId(callingUid)); 15468 } 15469 15470 // The first sticky in the list is returned directly back to 15471 // the client. 15472 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15473 15474 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15475 + ": " + sticky); 15476 15477 if (receiver == null) { 15478 return sticky; 15479 } 15480 15481 ReceiverList rl 15482 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15483 if (rl == null) { 15484 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15485 userId, receiver); 15486 if (rl.app != null) { 15487 rl.app.receivers.add(rl); 15488 } else { 15489 try { 15490 receiver.asBinder().linkToDeath(rl, 0); 15491 } catch (RemoteException e) { 15492 return sticky; 15493 } 15494 rl.linkedToDeath = true; 15495 } 15496 mRegisteredReceivers.put(receiver.asBinder(), rl); 15497 } else if (rl.uid != callingUid) { 15498 throw new IllegalArgumentException( 15499 "Receiver requested to register for uid " + callingUid 15500 + " was previously registered for uid " + rl.uid); 15501 } else if (rl.pid != callingPid) { 15502 throw new IllegalArgumentException( 15503 "Receiver requested to register for pid " + callingPid 15504 + " was previously registered for pid " + rl.pid); 15505 } else if (rl.userId != userId) { 15506 throw new IllegalArgumentException( 15507 "Receiver requested to register for user " + userId 15508 + " was previously registered for user " + rl.userId); 15509 } 15510 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15511 permission, callingUid, userId); 15512 rl.add(bf); 15513 if (!bf.debugCheck()) { 15514 Slog.w(TAG, "==> For Dynamic broadast"); 15515 } 15516 mReceiverResolver.addFilter(bf); 15517 15518 // Enqueue broadcasts for all existing stickies that match 15519 // this filter. 15520 if (allSticky != null) { 15521 ArrayList receivers = new ArrayList(); 15522 receivers.add(bf); 15523 15524 int N = allSticky.size(); 15525 for (int i=0; i<N; i++) { 15526 Intent intent = (Intent)allSticky.get(i); 15527 BroadcastQueue queue = broadcastQueueForIntent(intent); 15528 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15529 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15530 null, null, false, true, true, -1); 15531 queue.enqueueParallelBroadcastLocked(r); 15532 queue.scheduleBroadcastsLocked(); 15533 } 15534 } 15535 15536 return sticky; 15537 } 15538 } 15539 15540 public void unregisterReceiver(IIntentReceiver receiver) { 15541 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15542 15543 final long origId = Binder.clearCallingIdentity(); 15544 try { 15545 boolean doTrim = false; 15546 15547 synchronized(this) { 15548 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15549 if (rl != null) { 15550 if (rl.curBroadcast != null) { 15551 BroadcastRecord r = rl.curBroadcast; 15552 final boolean doNext = finishReceiverLocked( 15553 receiver.asBinder(), r.resultCode, r.resultData, 15554 r.resultExtras, r.resultAbort); 15555 if (doNext) { 15556 doTrim = true; 15557 r.queue.processNextBroadcast(false); 15558 } 15559 } 15560 15561 if (rl.app != null) { 15562 rl.app.receivers.remove(rl); 15563 } 15564 removeReceiverLocked(rl); 15565 if (rl.linkedToDeath) { 15566 rl.linkedToDeath = false; 15567 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15568 } 15569 } 15570 } 15571 15572 // If we actually concluded any broadcasts, we might now be able 15573 // to trim the recipients' apps from our working set 15574 if (doTrim) { 15575 trimApplications(); 15576 return; 15577 } 15578 15579 } finally { 15580 Binder.restoreCallingIdentity(origId); 15581 } 15582 } 15583 15584 void removeReceiverLocked(ReceiverList rl) { 15585 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15586 int N = rl.size(); 15587 for (int i=0; i<N; i++) { 15588 mReceiverResolver.removeFilter(rl.get(i)); 15589 } 15590 } 15591 15592 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15593 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15594 ProcessRecord r = mLruProcesses.get(i); 15595 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15596 try { 15597 r.thread.dispatchPackageBroadcast(cmd, packages); 15598 } catch (RemoteException ex) { 15599 } 15600 } 15601 } 15602 } 15603 15604 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15605 int callingUid, int[] users) { 15606 List<ResolveInfo> receivers = null; 15607 try { 15608 HashSet<ComponentName> singleUserReceivers = null; 15609 boolean scannedFirstReceivers = false; 15610 for (int user : users) { 15611 // Skip users that have Shell restrictions 15612 if (callingUid == Process.SHELL_UID 15613 && getUserManagerLocked().hasUserRestriction( 15614 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15615 continue; 15616 } 15617 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15618 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15619 if (user != 0 && newReceivers != null) { 15620 // If this is not the primary user, we need to check for 15621 // any receivers that should be filtered out. 15622 for (int i=0; i<newReceivers.size(); i++) { 15623 ResolveInfo ri = newReceivers.get(i); 15624 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15625 newReceivers.remove(i); 15626 i--; 15627 } 15628 } 15629 } 15630 if (newReceivers != null && newReceivers.size() == 0) { 15631 newReceivers = null; 15632 } 15633 if (receivers == null) { 15634 receivers = newReceivers; 15635 } else if (newReceivers != null) { 15636 // We need to concatenate the additional receivers 15637 // found with what we have do far. This would be easy, 15638 // but we also need to de-dup any receivers that are 15639 // singleUser. 15640 if (!scannedFirstReceivers) { 15641 // Collect any single user receivers we had already retrieved. 15642 scannedFirstReceivers = true; 15643 for (int i=0; i<receivers.size(); i++) { 15644 ResolveInfo ri = receivers.get(i); 15645 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15646 ComponentName cn = new ComponentName( 15647 ri.activityInfo.packageName, ri.activityInfo.name); 15648 if (singleUserReceivers == null) { 15649 singleUserReceivers = new HashSet<ComponentName>(); 15650 } 15651 singleUserReceivers.add(cn); 15652 } 15653 } 15654 } 15655 // Add the new results to the existing results, tracking 15656 // and de-dupping single user receivers. 15657 for (int i=0; i<newReceivers.size(); i++) { 15658 ResolveInfo ri = newReceivers.get(i); 15659 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15660 ComponentName cn = new ComponentName( 15661 ri.activityInfo.packageName, ri.activityInfo.name); 15662 if (singleUserReceivers == null) { 15663 singleUserReceivers = new HashSet<ComponentName>(); 15664 } 15665 if (!singleUserReceivers.contains(cn)) { 15666 singleUserReceivers.add(cn); 15667 receivers.add(ri); 15668 } 15669 } else { 15670 receivers.add(ri); 15671 } 15672 } 15673 } 15674 } 15675 } catch (RemoteException ex) { 15676 // pm is in same process, this will never happen. 15677 } 15678 return receivers; 15679 } 15680 15681 private final int broadcastIntentLocked(ProcessRecord callerApp, 15682 String callerPackage, Intent intent, String resolvedType, 15683 IIntentReceiver resultTo, int resultCode, String resultData, 15684 Bundle map, String requiredPermission, int appOp, 15685 boolean ordered, boolean sticky, int callingPid, int callingUid, 15686 int userId) { 15687 intent = new Intent(intent); 15688 15689 // By default broadcasts do not go to stopped apps. 15690 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15691 15692 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15693 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15694 + " ordered=" + ordered + " userid=" + userId); 15695 if ((resultTo != null) && !ordered) { 15696 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15697 } 15698 15699 userId = handleIncomingUser(callingPid, callingUid, userId, 15700 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15701 15702 // Make sure that the user who is receiving this broadcast is running. 15703 // If not, we will just skip it. 15704 15705 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15706 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15707 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15708 Slog.w(TAG, "Skipping broadcast of " + intent 15709 + ": user " + userId + " is stopped"); 15710 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15711 } 15712 } 15713 15714 /* 15715 * Prevent non-system code (defined here to be non-persistent 15716 * processes) from sending protected broadcasts. 15717 */ 15718 int callingAppId = UserHandle.getAppId(callingUid); 15719 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15720 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15721 || callingAppId == Process.NFC_UID || callingUid == 0) { 15722 // Always okay. 15723 } else if (callerApp == null || !callerApp.persistent) { 15724 try { 15725 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15726 intent.getAction())) { 15727 String msg = "Permission Denial: not allowed to send broadcast " 15728 + intent.getAction() + " from pid=" 15729 + callingPid + ", uid=" + callingUid; 15730 Slog.w(TAG, msg); 15731 throw new SecurityException(msg); 15732 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15733 // Special case for compatibility: we don't want apps to send this, 15734 // but historically it has not been protected and apps may be using it 15735 // to poke their own app widget. So, instead of making it protected, 15736 // just limit it to the caller. 15737 if (callerApp == null) { 15738 String msg = "Permission Denial: not allowed to send broadcast " 15739 + intent.getAction() + " from unknown caller."; 15740 Slog.w(TAG, msg); 15741 throw new SecurityException(msg); 15742 } else if (intent.getComponent() != null) { 15743 // They are good enough to send to an explicit component... verify 15744 // it is being sent to the calling app. 15745 if (!intent.getComponent().getPackageName().equals( 15746 callerApp.info.packageName)) { 15747 String msg = "Permission Denial: not allowed to send broadcast " 15748 + intent.getAction() + " to " 15749 + intent.getComponent().getPackageName() + " from " 15750 + callerApp.info.packageName; 15751 Slog.w(TAG, msg); 15752 throw new SecurityException(msg); 15753 } 15754 } else { 15755 // Limit broadcast to their own package. 15756 intent.setPackage(callerApp.info.packageName); 15757 } 15758 } 15759 } catch (RemoteException e) { 15760 Slog.w(TAG, "Remote exception", e); 15761 return ActivityManager.BROADCAST_SUCCESS; 15762 } 15763 } 15764 15765 final String action = intent.getAction(); 15766 if (action != null) { 15767 switch (action) { 15768 case Intent.ACTION_UID_REMOVED: 15769 case Intent.ACTION_PACKAGE_REMOVED: 15770 case Intent.ACTION_PACKAGE_CHANGED: 15771 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15772 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15773 // Handle special intents: if this broadcast is from the package 15774 // manager about a package being removed, we need to remove all of 15775 // its activities from the history stack. 15776 if (checkComponentPermission( 15777 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15778 callingPid, callingUid, -1, true) 15779 != PackageManager.PERMISSION_GRANTED) { 15780 String msg = "Permission Denial: " + intent.getAction() 15781 + " broadcast from " + callerPackage + " (pid=" + callingPid 15782 + ", uid=" + callingUid + ")" 15783 + " requires " 15784 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15785 Slog.w(TAG, msg); 15786 throw new SecurityException(msg); 15787 } 15788 switch (action) { 15789 case Intent.ACTION_UID_REMOVED: 15790 final Bundle intentExtras = intent.getExtras(); 15791 final int uid = intentExtras != null 15792 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15793 if (uid >= 0) { 15794 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15795 synchronized (bs) { 15796 bs.removeUidStatsLocked(uid); 15797 } 15798 mAppOpsService.uidRemoved(uid); 15799 } 15800 break; 15801 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15802 // If resources are unavailable just force stop all those packages 15803 // and flush the attribute cache as well. 15804 String list[] = 15805 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15806 if (list != null && list.length > 0) { 15807 for (int i = 0; i < list.length; i++) { 15808 forceStopPackageLocked(list[i], -1, false, true, true, 15809 false, false, userId, "storage unmount"); 15810 } 15811 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15812 sendPackageBroadcastLocked( 15813 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15814 userId); 15815 } 15816 break; 15817 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15818 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15819 break; 15820 case Intent.ACTION_PACKAGE_REMOVED: 15821 case Intent.ACTION_PACKAGE_CHANGED: 15822 Uri data = intent.getData(); 15823 String ssp; 15824 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15825 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15826 boolean fullUninstall = removed && 15827 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15828 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15829 forceStopPackageLocked(ssp, UserHandle.getAppId( 15830 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15831 false, true, true, false, fullUninstall, userId, 15832 removed ? "pkg removed" : "pkg changed"); 15833 } 15834 if (removed) { 15835 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15836 new String[] {ssp}, userId); 15837 if (fullUninstall) { 15838 mAppOpsService.packageRemoved( 15839 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15840 15841 // Remove all permissions granted from/to this package 15842 removeUriPermissionsForPackageLocked(ssp, userId, true); 15843 15844 removeTasksByPackageNameLocked(ssp, userId); 15845 } 15846 } else { 15847 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15848 if (userId == UserHandle.USER_OWNER) { 15849 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15850 } 15851 } 15852 } 15853 break; 15854 } 15855 break; 15856 case Intent.ACTION_PACKAGE_ADDED: 15857 // Special case for adding a package: by default turn on compatibility mode. 15858 Uri data = intent.getData(); 15859 String ssp; 15860 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15861 final boolean replacing = 15862 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15863 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15864 15865 if (replacing) { 15866 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15867 } 15868 if (userId == UserHandle.USER_OWNER) { 15869 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15870 } 15871 } 15872 break; 15873 case Intent.ACTION_TIMEZONE_CHANGED: 15874 // If this is the time zone changed action, queue up a message that will reset 15875 // the timezone of all currently running processes. This message will get 15876 // queued up before the broadcast happens. 15877 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15878 break; 15879 case Intent.ACTION_TIME_CHANGED: 15880 // If the user set the time, let all running processes know. 15881 final int is24Hour = 15882 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15883 : 0; 15884 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15885 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15886 synchronized (stats) { 15887 stats.noteCurrentTimeChangedLocked(); 15888 } 15889 break; 15890 case Intent.ACTION_CLEAR_DNS_CACHE: 15891 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15892 break; 15893 case Proxy.PROXY_CHANGE_ACTION: 15894 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15895 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15896 break; 15897 } 15898 } 15899 15900 // Add to the sticky list if requested. 15901 if (sticky) { 15902 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15903 callingPid, callingUid) 15904 != PackageManager.PERMISSION_GRANTED) { 15905 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15906 + callingPid + ", uid=" + callingUid 15907 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15908 Slog.w(TAG, msg); 15909 throw new SecurityException(msg); 15910 } 15911 if (requiredPermission != null) { 15912 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15913 + " and enforce permission " + requiredPermission); 15914 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15915 } 15916 if (intent.getComponent() != null) { 15917 throw new SecurityException( 15918 "Sticky broadcasts can't target a specific component"); 15919 } 15920 // We use userId directly here, since the "all" target is maintained 15921 // as a separate set of sticky broadcasts. 15922 if (userId != UserHandle.USER_ALL) { 15923 // But first, if this is not a broadcast to all users, then 15924 // make sure it doesn't conflict with an existing broadcast to 15925 // all users. 15926 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15927 UserHandle.USER_ALL); 15928 if (stickies != null) { 15929 ArrayList<Intent> list = stickies.get(intent.getAction()); 15930 if (list != null) { 15931 int N = list.size(); 15932 int i; 15933 for (i=0; i<N; i++) { 15934 if (intent.filterEquals(list.get(i))) { 15935 throw new IllegalArgumentException( 15936 "Sticky broadcast " + intent + " for user " 15937 + userId + " conflicts with existing global broadcast"); 15938 } 15939 } 15940 } 15941 } 15942 } 15943 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15944 if (stickies == null) { 15945 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15946 mStickyBroadcasts.put(userId, stickies); 15947 } 15948 ArrayList<Intent> list = stickies.get(intent.getAction()); 15949 if (list == null) { 15950 list = new ArrayList<Intent>(); 15951 stickies.put(intent.getAction(), list); 15952 } 15953 int N = list.size(); 15954 int i; 15955 for (i=0; i<N; i++) { 15956 if (intent.filterEquals(list.get(i))) { 15957 // This sticky already exists, replace it. 15958 list.set(i, new Intent(intent)); 15959 break; 15960 } 15961 } 15962 if (i >= N) { 15963 list.add(new Intent(intent)); 15964 } 15965 } 15966 15967 int[] users; 15968 if (userId == UserHandle.USER_ALL) { 15969 // Caller wants broadcast to go to all started users. 15970 users = mStartedUserArray; 15971 } else { 15972 // Caller wants broadcast to go to one specific user. 15973 users = new int[] {userId}; 15974 } 15975 15976 // Figure out who all will receive this broadcast. 15977 List receivers = null; 15978 List<BroadcastFilter> registeredReceivers = null; 15979 // Need to resolve the intent to interested receivers... 15980 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15981 == 0) { 15982 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15983 } 15984 if (intent.getComponent() == null) { 15985 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15986 // Query one target user at a time, excluding shell-restricted users 15987 UserManagerService ums = getUserManagerLocked(); 15988 for (int i = 0; i < users.length; i++) { 15989 if (ums.hasUserRestriction( 15990 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15991 continue; 15992 } 15993 List<BroadcastFilter> registeredReceiversForUser = 15994 mReceiverResolver.queryIntent(intent, 15995 resolvedType, false, users[i]); 15996 if (registeredReceivers == null) { 15997 registeredReceivers = registeredReceiversForUser; 15998 } else if (registeredReceiversForUser != null) { 15999 registeredReceivers.addAll(registeredReceiversForUser); 16000 } 16001 } 16002 } else { 16003 registeredReceivers = mReceiverResolver.queryIntent(intent, 16004 resolvedType, false, userId); 16005 } 16006 } 16007 16008 final boolean replacePending = 16009 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16010 16011 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16012 + " replacePending=" + replacePending); 16013 16014 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16015 if (!ordered && NR > 0) { 16016 // If we are not serializing this broadcast, then send the 16017 // registered receivers separately so they don't wait for the 16018 // components to be launched. 16019 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16020 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16021 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16022 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16023 ordered, sticky, false, userId); 16024 if (DEBUG_BROADCAST) Slog.v( 16025 TAG, "Enqueueing parallel broadcast " + r); 16026 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16027 if (!replaced) { 16028 queue.enqueueParallelBroadcastLocked(r); 16029 queue.scheduleBroadcastsLocked(); 16030 } 16031 registeredReceivers = null; 16032 NR = 0; 16033 } 16034 16035 // Merge into one list. 16036 int ir = 0; 16037 if (receivers != null) { 16038 // A special case for PACKAGE_ADDED: do not allow the package 16039 // being added to see this broadcast. This prevents them from 16040 // using this as a back door to get run as soon as they are 16041 // installed. Maybe in the future we want to have a special install 16042 // broadcast or such for apps, but we'd like to deliberately make 16043 // this decision. 16044 String skipPackages[] = null; 16045 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16046 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16047 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16048 Uri data = intent.getData(); 16049 if (data != null) { 16050 String pkgName = data.getSchemeSpecificPart(); 16051 if (pkgName != null) { 16052 skipPackages = new String[] { pkgName }; 16053 } 16054 } 16055 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16056 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16057 } 16058 if (skipPackages != null && (skipPackages.length > 0)) { 16059 for (String skipPackage : skipPackages) { 16060 if (skipPackage != null) { 16061 int NT = receivers.size(); 16062 for (int it=0; it<NT; it++) { 16063 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16064 if (curt.activityInfo.packageName.equals(skipPackage)) { 16065 receivers.remove(it); 16066 it--; 16067 NT--; 16068 } 16069 } 16070 } 16071 } 16072 } 16073 16074 int NT = receivers != null ? receivers.size() : 0; 16075 int it = 0; 16076 ResolveInfo curt = null; 16077 BroadcastFilter curr = null; 16078 while (it < NT && ir < NR) { 16079 if (curt == null) { 16080 curt = (ResolveInfo)receivers.get(it); 16081 } 16082 if (curr == null) { 16083 curr = registeredReceivers.get(ir); 16084 } 16085 if (curr.getPriority() >= curt.priority) { 16086 // Insert this broadcast record into the final list. 16087 receivers.add(it, curr); 16088 ir++; 16089 curr = null; 16090 it++; 16091 NT++; 16092 } else { 16093 // Skip to the next ResolveInfo in the final list. 16094 it++; 16095 curt = null; 16096 } 16097 } 16098 } 16099 while (ir < NR) { 16100 if (receivers == null) { 16101 receivers = new ArrayList(); 16102 } 16103 receivers.add(registeredReceivers.get(ir)); 16104 ir++; 16105 } 16106 16107 if ((receivers != null && receivers.size() > 0) 16108 || resultTo != null) { 16109 BroadcastQueue queue = broadcastQueueForIntent(intent); 16110 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16111 callerPackage, callingPid, callingUid, resolvedType, 16112 requiredPermission, appOp, receivers, resultTo, resultCode, 16113 resultData, map, ordered, sticky, false, userId); 16114 if (DEBUG_BROADCAST) Slog.v( 16115 TAG, "Enqueueing ordered broadcast " + r 16116 + ": prev had " + queue.mOrderedBroadcasts.size()); 16117 if (DEBUG_BROADCAST) { 16118 int seq = r.intent.getIntExtra("seq", -1); 16119 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16120 } 16121 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16122 if (!replaced) { 16123 queue.enqueueOrderedBroadcastLocked(r); 16124 queue.scheduleBroadcastsLocked(); 16125 } 16126 } 16127 16128 return ActivityManager.BROADCAST_SUCCESS; 16129 } 16130 16131 final Intent verifyBroadcastLocked(Intent intent) { 16132 // Refuse possible leaked file descriptors 16133 if (intent != null && intent.hasFileDescriptors() == true) { 16134 throw new IllegalArgumentException("File descriptors passed in Intent"); 16135 } 16136 16137 int flags = intent.getFlags(); 16138 16139 if (!mProcessesReady) { 16140 // if the caller really truly claims to know what they're doing, go 16141 // ahead and allow the broadcast without launching any receivers 16142 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16143 intent = new Intent(intent); 16144 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16145 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16146 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16147 + " before boot completion"); 16148 throw new IllegalStateException("Cannot broadcast before boot completed"); 16149 } 16150 } 16151 16152 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16153 throw new IllegalArgumentException( 16154 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16155 } 16156 16157 return intent; 16158 } 16159 16160 public final int broadcastIntent(IApplicationThread caller, 16161 Intent intent, String resolvedType, IIntentReceiver resultTo, 16162 int resultCode, String resultData, Bundle map, 16163 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16164 enforceNotIsolatedCaller("broadcastIntent"); 16165 synchronized(this) { 16166 intent = verifyBroadcastLocked(intent); 16167 16168 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16169 final int callingPid = Binder.getCallingPid(); 16170 final int callingUid = Binder.getCallingUid(); 16171 final long origId = Binder.clearCallingIdentity(); 16172 int res = broadcastIntentLocked(callerApp, 16173 callerApp != null ? callerApp.info.packageName : null, 16174 intent, resolvedType, resultTo, 16175 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16176 callingPid, callingUid, userId); 16177 Binder.restoreCallingIdentity(origId); 16178 return res; 16179 } 16180 } 16181 16182 int broadcastIntentInPackage(String packageName, int uid, 16183 Intent intent, String resolvedType, IIntentReceiver resultTo, 16184 int resultCode, String resultData, Bundle map, 16185 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16186 synchronized(this) { 16187 intent = verifyBroadcastLocked(intent); 16188 16189 final long origId = Binder.clearCallingIdentity(); 16190 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16191 resultTo, resultCode, resultData, map, requiredPermission, 16192 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16193 Binder.restoreCallingIdentity(origId); 16194 return res; 16195 } 16196 } 16197 16198 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16199 // Refuse possible leaked file descriptors 16200 if (intent != null && intent.hasFileDescriptors() == true) { 16201 throw new IllegalArgumentException("File descriptors passed in Intent"); 16202 } 16203 16204 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16205 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16206 16207 synchronized(this) { 16208 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16209 != PackageManager.PERMISSION_GRANTED) { 16210 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16211 + Binder.getCallingPid() 16212 + ", uid=" + Binder.getCallingUid() 16213 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16214 Slog.w(TAG, msg); 16215 throw new SecurityException(msg); 16216 } 16217 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16218 if (stickies != null) { 16219 ArrayList<Intent> list = stickies.get(intent.getAction()); 16220 if (list != null) { 16221 int N = list.size(); 16222 int i; 16223 for (i=0; i<N; i++) { 16224 if (intent.filterEquals(list.get(i))) { 16225 list.remove(i); 16226 break; 16227 } 16228 } 16229 if (list.size() <= 0) { 16230 stickies.remove(intent.getAction()); 16231 } 16232 } 16233 if (stickies.size() <= 0) { 16234 mStickyBroadcasts.remove(userId); 16235 } 16236 } 16237 } 16238 } 16239 16240 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16241 String resultData, Bundle resultExtras, boolean resultAbort) { 16242 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16243 if (r == null) { 16244 Slog.w(TAG, "finishReceiver called but not found on queue"); 16245 return false; 16246 } 16247 16248 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16249 } 16250 16251 void backgroundServicesFinishedLocked(int userId) { 16252 for (BroadcastQueue queue : mBroadcastQueues) { 16253 queue.backgroundServicesFinishedLocked(userId); 16254 } 16255 } 16256 16257 public void finishReceiver(IBinder who, int resultCode, String resultData, 16258 Bundle resultExtras, boolean resultAbort) { 16259 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16260 16261 // Refuse possible leaked file descriptors 16262 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16263 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16264 } 16265 16266 final long origId = Binder.clearCallingIdentity(); 16267 try { 16268 boolean doNext = false; 16269 BroadcastRecord r; 16270 16271 synchronized(this) { 16272 r = broadcastRecordForReceiverLocked(who); 16273 if (r != null) { 16274 doNext = r.queue.finishReceiverLocked(r, resultCode, 16275 resultData, resultExtras, resultAbort, true); 16276 } 16277 } 16278 16279 if (doNext) { 16280 r.queue.processNextBroadcast(false); 16281 } 16282 trimApplications(); 16283 } finally { 16284 Binder.restoreCallingIdentity(origId); 16285 } 16286 } 16287 16288 // ========================================================= 16289 // INSTRUMENTATION 16290 // ========================================================= 16291 16292 public boolean startInstrumentation(ComponentName className, 16293 String profileFile, int flags, Bundle arguments, 16294 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16295 int userId, String abiOverride) { 16296 enforceNotIsolatedCaller("startInstrumentation"); 16297 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16298 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16299 // Refuse possible leaked file descriptors 16300 if (arguments != null && arguments.hasFileDescriptors()) { 16301 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16302 } 16303 16304 synchronized(this) { 16305 InstrumentationInfo ii = null; 16306 ApplicationInfo ai = null; 16307 try { 16308 ii = mContext.getPackageManager().getInstrumentationInfo( 16309 className, STOCK_PM_FLAGS); 16310 ai = AppGlobals.getPackageManager().getApplicationInfo( 16311 ii.targetPackage, STOCK_PM_FLAGS, userId); 16312 } catch (PackageManager.NameNotFoundException e) { 16313 } catch (RemoteException e) { 16314 } 16315 if (ii == null) { 16316 reportStartInstrumentationFailure(watcher, className, 16317 "Unable to find instrumentation info for: " + className); 16318 return false; 16319 } 16320 if (ai == null) { 16321 reportStartInstrumentationFailure(watcher, className, 16322 "Unable to find instrumentation target package: " + ii.targetPackage); 16323 return false; 16324 } 16325 16326 int match = mContext.getPackageManager().checkSignatures( 16327 ii.targetPackage, ii.packageName); 16328 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16329 String msg = "Permission Denial: starting instrumentation " 16330 + className + " from pid=" 16331 + Binder.getCallingPid() 16332 + ", uid=" + Binder.getCallingPid() 16333 + " not allowed because package " + ii.packageName 16334 + " does not have a signature matching the target " 16335 + ii.targetPackage; 16336 reportStartInstrumentationFailure(watcher, className, msg); 16337 throw new SecurityException(msg); 16338 } 16339 16340 final long origId = Binder.clearCallingIdentity(); 16341 // Instrumentation can kill and relaunch even persistent processes 16342 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16343 "start instr"); 16344 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16345 app.instrumentationClass = className; 16346 app.instrumentationInfo = ai; 16347 app.instrumentationProfileFile = profileFile; 16348 app.instrumentationArguments = arguments; 16349 app.instrumentationWatcher = watcher; 16350 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16351 app.instrumentationResultClass = className; 16352 Binder.restoreCallingIdentity(origId); 16353 } 16354 16355 return true; 16356 } 16357 16358 /** 16359 * Report errors that occur while attempting to start Instrumentation. Always writes the 16360 * error to the logs, but if somebody is watching, send the report there too. This enables 16361 * the "am" command to report errors with more information. 16362 * 16363 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16364 * @param cn The component name of the instrumentation. 16365 * @param report The error report. 16366 */ 16367 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16368 ComponentName cn, String report) { 16369 Slog.w(TAG, report); 16370 try { 16371 if (watcher != null) { 16372 Bundle results = new Bundle(); 16373 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16374 results.putString("Error", report); 16375 watcher.instrumentationStatus(cn, -1, results); 16376 } 16377 } catch (RemoteException e) { 16378 Slog.w(TAG, e); 16379 } 16380 } 16381 16382 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16383 if (app.instrumentationWatcher != null) { 16384 try { 16385 // NOTE: IInstrumentationWatcher *must* be oneway here 16386 app.instrumentationWatcher.instrumentationFinished( 16387 app.instrumentationClass, 16388 resultCode, 16389 results); 16390 } catch (RemoteException e) { 16391 } 16392 } 16393 if (app.instrumentationUiAutomationConnection != null) { 16394 try { 16395 app.instrumentationUiAutomationConnection.shutdown(); 16396 } catch (RemoteException re) { 16397 /* ignore */ 16398 } 16399 // Only a UiAutomation can set this flag and now that 16400 // it is finished we make sure it is reset to its default. 16401 mUserIsMonkey = false; 16402 } 16403 app.instrumentationWatcher = null; 16404 app.instrumentationUiAutomationConnection = null; 16405 app.instrumentationClass = null; 16406 app.instrumentationInfo = null; 16407 app.instrumentationProfileFile = null; 16408 app.instrumentationArguments = null; 16409 16410 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16411 "finished inst"); 16412 } 16413 16414 public void finishInstrumentation(IApplicationThread target, 16415 int resultCode, Bundle results) { 16416 int userId = UserHandle.getCallingUserId(); 16417 // Refuse possible leaked file descriptors 16418 if (results != null && results.hasFileDescriptors()) { 16419 throw new IllegalArgumentException("File descriptors passed in Intent"); 16420 } 16421 16422 synchronized(this) { 16423 ProcessRecord app = getRecordForAppLocked(target); 16424 if (app == null) { 16425 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16426 return; 16427 } 16428 final long origId = Binder.clearCallingIdentity(); 16429 finishInstrumentationLocked(app, resultCode, results); 16430 Binder.restoreCallingIdentity(origId); 16431 } 16432 } 16433 16434 // ========================================================= 16435 // CONFIGURATION 16436 // ========================================================= 16437 16438 public ConfigurationInfo getDeviceConfigurationInfo() { 16439 ConfigurationInfo config = new ConfigurationInfo(); 16440 synchronized (this) { 16441 config.reqTouchScreen = mConfiguration.touchscreen; 16442 config.reqKeyboardType = mConfiguration.keyboard; 16443 config.reqNavigation = mConfiguration.navigation; 16444 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16445 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16446 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16447 } 16448 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16449 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16450 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16451 } 16452 config.reqGlEsVersion = GL_ES_VERSION; 16453 } 16454 return config; 16455 } 16456 16457 ActivityStack getFocusedStack() { 16458 return mStackSupervisor.getFocusedStack(); 16459 } 16460 16461 public Configuration getConfiguration() { 16462 Configuration ci; 16463 synchronized(this) { 16464 ci = new Configuration(mConfiguration); 16465 } 16466 return ci; 16467 } 16468 16469 public void updatePersistentConfiguration(Configuration values) { 16470 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16471 "updateConfiguration()"); 16472 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16473 "updateConfiguration()"); 16474 if (values == null) { 16475 throw new NullPointerException("Configuration must not be null"); 16476 } 16477 16478 synchronized(this) { 16479 final long origId = Binder.clearCallingIdentity(); 16480 updateConfigurationLocked(values, null, true, false); 16481 Binder.restoreCallingIdentity(origId); 16482 } 16483 } 16484 16485 public void updateConfiguration(Configuration values) { 16486 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16487 "updateConfiguration()"); 16488 16489 synchronized(this) { 16490 if (values == null && mWindowManager != null) { 16491 // sentinel: fetch the current configuration from the window manager 16492 values = mWindowManager.computeNewConfiguration(); 16493 } 16494 16495 if (mWindowManager != null) { 16496 mProcessList.applyDisplaySize(mWindowManager); 16497 } 16498 16499 final long origId = Binder.clearCallingIdentity(); 16500 if (values != null) { 16501 Settings.System.clearConfiguration(values); 16502 } 16503 updateConfigurationLocked(values, null, false, false); 16504 Binder.restoreCallingIdentity(origId); 16505 } 16506 } 16507 16508 /** 16509 * Do either or both things: (1) change the current configuration, and (2) 16510 * make sure the given activity is running with the (now) current 16511 * configuration. Returns true if the activity has been left running, or 16512 * false if <var>starting</var> is being destroyed to match the new 16513 * configuration. 16514 * @param persistent TODO 16515 */ 16516 boolean updateConfigurationLocked(Configuration values, 16517 ActivityRecord starting, boolean persistent, boolean initLocale) { 16518 int changes = 0; 16519 16520 if (values != null) { 16521 Configuration newConfig = new Configuration(mConfiguration); 16522 changes = newConfig.updateFrom(values); 16523 if (changes != 0) { 16524 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16525 Slog.i(TAG, "Updating configuration to: " + values); 16526 } 16527 16528 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16529 16530 if (values.locale != null && !initLocale) { 16531 saveLocaleLocked(values.locale, 16532 !values.locale.equals(mConfiguration.locale), 16533 values.userSetLocale); 16534 } 16535 16536 mConfigurationSeq++; 16537 if (mConfigurationSeq <= 0) { 16538 mConfigurationSeq = 1; 16539 } 16540 newConfig.seq = mConfigurationSeq; 16541 mConfiguration = newConfig; 16542 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16543 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16544 //mUsageStatsService.noteStartConfig(newConfig); 16545 16546 final Configuration configCopy = new Configuration(mConfiguration); 16547 16548 // TODO: If our config changes, should we auto dismiss any currently 16549 // showing dialogs? 16550 mShowDialogs = shouldShowDialogs(newConfig); 16551 16552 AttributeCache ac = AttributeCache.instance(); 16553 if (ac != null) { 16554 ac.updateConfiguration(configCopy); 16555 } 16556 16557 // Make sure all resources in our process are updated 16558 // right now, so that anyone who is going to retrieve 16559 // resource values after we return will be sure to get 16560 // the new ones. This is especially important during 16561 // boot, where the first config change needs to guarantee 16562 // all resources have that config before following boot 16563 // code is executed. 16564 mSystemThread.applyConfigurationToResources(configCopy); 16565 16566 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16567 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16568 msg.obj = new Configuration(configCopy); 16569 mHandler.sendMessage(msg); 16570 } 16571 16572 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16573 ProcessRecord app = mLruProcesses.get(i); 16574 try { 16575 if (app.thread != null) { 16576 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16577 + app.processName + " new config " + mConfiguration); 16578 app.thread.scheduleConfigurationChanged(configCopy); 16579 } 16580 } catch (Exception e) { 16581 } 16582 } 16583 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16584 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16585 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16586 | Intent.FLAG_RECEIVER_FOREGROUND); 16587 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16588 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16589 Process.SYSTEM_UID, UserHandle.USER_ALL); 16590 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16591 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16592 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16593 broadcastIntentLocked(null, null, intent, 16594 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16595 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16596 } 16597 } 16598 } 16599 16600 boolean kept = true; 16601 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16602 // mainStack is null during startup. 16603 if (mainStack != null) { 16604 if (changes != 0 && starting == null) { 16605 // If the configuration changed, and the caller is not already 16606 // in the process of starting an activity, then find the top 16607 // activity to check if its configuration needs to change. 16608 starting = mainStack.topRunningActivityLocked(null); 16609 } 16610 16611 if (starting != null) { 16612 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16613 // And we need to make sure at this point that all other activities 16614 // are made visible with the correct configuration. 16615 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16616 } 16617 } 16618 16619 if (values != null && mWindowManager != null) { 16620 mWindowManager.setNewConfiguration(mConfiguration); 16621 } 16622 16623 return kept; 16624 } 16625 16626 /** 16627 * Decide based on the configuration whether we should shouw the ANR, 16628 * crash, etc dialogs. The idea is that if there is no affordnace to 16629 * press the on-screen buttons, we shouldn't show the dialog. 16630 * 16631 * A thought: SystemUI might also want to get told about this, the Power 16632 * dialog / global actions also might want different behaviors. 16633 */ 16634 private static final boolean shouldShowDialogs(Configuration config) { 16635 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16636 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16637 } 16638 16639 /** 16640 * Save the locale. You must be inside a synchronized (this) block. 16641 */ 16642 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16643 if(isDiff) { 16644 SystemProperties.set("user.language", l.getLanguage()); 16645 SystemProperties.set("user.region", l.getCountry()); 16646 } 16647 16648 if(isPersist) { 16649 SystemProperties.set("persist.sys.language", l.getLanguage()); 16650 SystemProperties.set("persist.sys.country", l.getCountry()); 16651 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16652 16653 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16654 } 16655 } 16656 16657 @Override 16658 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16659 synchronized (this) { 16660 ActivityRecord srec = ActivityRecord.forToken(token); 16661 if (srec.task != null && srec.task.stack != null) { 16662 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16663 } 16664 } 16665 return false; 16666 } 16667 16668 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16669 Intent resultData) { 16670 16671 synchronized (this) { 16672 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16673 if (stack != null) { 16674 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16675 } 16676 return false; 16677 } 16678 } 16679 16680 public int getLaunchedFromUid(IBinder activityToken) { 16681 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16682 if (srec == null) { 16683 return -1; 16684 } 16685 return srec.launchedFromUid; 16686 } 16687 16688 public String getLaunchedFromPackage(IBinder activityToken) { 16689 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16690 if (srec == null) { 16691 return null; 16692 } 16693 return srec.launchedFromPackage; 16694 } 16695 16696 // ========================================================= 16697 // LIFETIME MANAGEMENT 16698 // ========================================================= 16699 16700 // Returns which broadcast queue the app is the current [or imminent] receiver 16701 // on, or 'null' if the app is not an active broadcast recipient. 16702 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16703 BroadcastRecord r = app.curReceiver; 16704 if (r != null) { 16705 return r.queue; 16706 } 16707 16708 // It's not the current receiver, but it might be starting up to become one 16709 synchronized (this) { 16710 for (BroadcastQueue queue : mBroadcastQueues) { 16711 r = queue.mPendingBroadcast; 16712 if (r != null && r.curApp == app) { 16713 // found it; report which queue it's in 16714 return queue; 16715 } 16716 } 16717 } 16718 16719 return null; 16720 } 16721 16722 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16723 boolean doingAll, long now) { 16724 if (mAdjSeq == app.adjSeq) { 16725 // This adjustment has already been computed. 16726 return app.curRawAdj; 16727 } 16728 16729 if (app.thread == null) { 16730 app.adjSeq = mAdjSeq; 16731 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16732 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16733 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16734 } 16735 16736 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16737 app.adjSource = null; 16738 app.adjTarget = null; 16739 app.empty = false; 16740 app.cached = false; 16741 16742 final int activitiesSize = app.activities.size(); 16743 16744 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16745 // The max adjustment doesn't allow this app to be anything 16746 // below foreground, so it is not worth doing work for it. 16747 app.adjType = "fixed"; 16748 app.adjSeq = mAdjSeq; 16749 app.curRawAdj = app.maxAdj; 16750 app.foregroundActivities = false; 16751 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16752 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16753 // System processes can do UI, and when they do we want to have 16754 // them trim their memory after the user leaves the UI. To 16755 // facilitate this, here we need to determine whether or not it 16756 // is currently showing UI. 16757 app.systemNoUi = true; 16758 if (app == TOP_APP) { 16759 app.systemNoUi = false; 16760 } else if (activitiesSize > 0) { 16761 for (int j = 0; j < activitiesSize; j++) { 16762 final ActivityRecord r = app.activities.get(j); 16763 if (r.visible) { 16764 app.systemNoUi = false; 16765 } 16766 } 16767 } 16768 if (!app.systemNoUi) { 16769 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16770 } 16771 return (app.curAdj=app.maxAdj); 16772 } 16773 16774 app.systemNoUi = false; 16775 16776 // Determine the importance of the process, starting with most 16777 // important to least, and assign an appropriate OOM adjustment. 16778 int adj; 16779 int schedGroup; 16780 int procState; 16781 boolean foregroundActivities = false; 16782 BroadcastQueue queue; 16783 if (app == TOP_APP) { 16784 // The last app on the list is the foreground app. 16785 adj = ProcessList.FOREGROUND_APP_ADJ; 16786 schedGroup = Process.THREAD_GROUP_DEFAULT; 16787 app.adjType = "top-activity"; 16788 foregroundActivities = true; 16789 procState = ActivityManager.PROCESS_STATE_TOP; 16790 } else if (app.instrumentationClass != null) { 16791 // Don't want to kill running instrumentation. 16792 adj = ProcessList.FOREGROUND_APP_ADJ; 16793 schedGroup = Process.THREAD_GROUP_DEFAULT; 16794 app.adjType = "instrumentation"; 16795 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16796 } else if ((queue = isReceivingBroadcast(app)) != null) { 16797 // An app that is currently receiving a broadcast also 16798 // counts as being in the foreground for OOM killer purposes. 16799 // It's placed in a sched group based on the nature of the 16800 // broadcast as reflected by which queue it's active in. 16801 adj = ProcessList.FOREGROUND_APP_ADJ; 16802 schedGroup = (queue == mFgBroadcastQueue) 16803 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16804 app.adjType = "broadcast"; 16805 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16806 } else if (app.executingServices.size() > 0) { 16807 // An app that is currently executing a service callback also 16808 // counts as being in the foreground. 16809 adj = ProcessList.FOREGROUND_APP_ADJ; 16810 schedGroup = app.execServicesFg ? 16811 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16812 app.adjType = "exec-service"; 16813 procState = ActivityManager.PROCESS_STATE_SERVICE; 16814 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16815 } else { 16816 // As far as we know the process is empty. We may change our mind later. 16817 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16818 // At this point we don't actually know the adjustment. Use the cached adj 16819 // value that the caller wants us to. 16820 adj = cachedAdj; 16821 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16822 app.cached = true; 16823 app.empty = true; 16824 app.adjType = "cch-empty"; 16825 } 16826 16827 // Examine all activities if not already foreground. 16828 if (!foregroundActivities && activitiesSize > 0) { 16829 for (int j = 0; j < activitiesSize; j++) { 16830 final ActivityRecord r = app.activities.get(j); 16831 if (r.app != app) { 16832 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16833 + app + "?!?"); 16834 continue; 16835 } 16836 if (r.visible) { 16837 // App has a visible activity; only upgrade adjustment. 16838 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16839 adj = ProcessList.VISIBLE_APP_ADJ; 16840 app.adjType = "visible"; 16841 } 16842 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16843 procState = ActivityManager.PROCESS_STATE_TOP; 16844 } 16845 schedGroup = Process.THREAD_GROUP_DEFAULT; 16846 app.cached = false; 16847 app.empty = false; 16848 foregroundActivities = true; 16849 break; 16850 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16851 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16852 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16853 app.adjType = "pausing"; 16854 } 16855 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16856 procState = ActivityManager.PROCESS_STATE_TOP; 16857 } 16858 schedGroup = Process.THREAD_GROUP_DEFAULT; 16859 app.cached = false; 16860 app.empty = false; 16861 foregroundActivities = true; 16862 } else if (r.state == ActivityState.STOPPING) { 16863 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16864 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16865 app.adjType = "stopping"; 16866 } 16867 // For the process state, we will at this point consider the 16868 // process to be cached. It will be cached either as an activity 16869 // or empty depending on whether the activity is finishing. We do 16870 // this so that we can treat the process as cached for purposes of 16871 // memory trimming (determing current memory level, trim command to 16872 // send to process) since there can be an arbitrary number of stopping 16873 // processes and they should soon all go into the cached state. 16874 if (!r.finishing) { 16875 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16876 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16877 } 16878 } 16879 app.cached = false; 16880 app.empty = false; 16881 foregroundActivities = true; 16882 } else { 16883 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16884 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16885 app.adjType = "cch-act"; 16886 } 16887 } 16888 } 16889 } 16890 16891 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16892 if (app.foregroundServices) { 16893 // The user is aware of this app, so make it visible. 16894 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16895 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16896 app.cached = false; 16897 app.adjType = "fg-service"; 16898 schedGroup = Process.THREAD_GROUP_DEFAULT; 16899 } else if (app.forcingToForeground != null) { 16900 // The user is aware of this app, so make it visible. 16901 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16902 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16903 app.cached = false; 16904 app.adjType = "force-fg"; 16905 app.adjSource = app.forcingToForeground; 16906 schedGroup = Process.THREAD_GROUP_DEFAULT; 16907 } 16908 } 16909 16910 if (app == mHeavyWeightProcess) { 16911 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16912 // We don't want to kill the current heavy-weight process. 16913 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16914 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16915 app.cached = false; 16916 app.adjType = "heavy"; 16917 } 16918 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16919 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16920 } 16921 } 16922 16923 if (app == mHomeProcess) { 16924 if (adj > ProcessList.HOME_APP_ADJ) { 16925 // This process is hosting what we currently consider to be the 16926 // home app, so we don't want to let it go into the background. 16927 adj = ProcessList.HOME_APP_ADJ; 16928 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16929 app.cached = false; 16930 app.adjType = "home"; 16931 } 16932 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16933 procState = ActivityManager.PROCESS_STATE_HOME; 16934 } 16935 } 16936 16937 if (app == mPreviousProcess && app.activities.size() > 0) { 16938 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16939 // This was the previous process that showed UI to the user. 16940 // We want to try to keep it around more aggressively, to give 16941 // a good experience around switching between two apps. 16942 adj = ProcessList.PREVIOUS_APP_ADJ; 16943 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16944 app.cached = false; 16945 app.adjType = "previous"; 16946 } 16947 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16948 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16949 } 16950 } 16951 16952 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16953 + " reason=" + app.adjType); 16954 16955 // By default, we use the computed adjustment. It may be changed if 16956 // there are applications dependent on our services or providers, but 16957 // this gives us a baseline and makes sure we don't get into an 16958 // infinite recursion. 16959 app.adjSeq = mAdjSeq; 16960 app.curRawAdj = adj; 16961 app.hasStartedServices = false; 16962 16963 if (mBackupTarget != null && app == mBackupTarget.app) { 16964 // If possible we want to avoid killing apps while they're being backed up 16965 if (adj > ProcessList.BACKUP_APP_ADJ) { 16966 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16967 adj = ProcessList.BACKUP_APP_ADJ; 16968 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16969 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16970 } 16971 app.adjType = "backup"; 16972 app.cached = false; 16973 } 16974 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16975 procState = ActivityManager.PROCESS_STATE_BACKUP; 16976 } 16977 } 16978 16979 boolean mayBeTop = false; 16980 16981 for (int is = app.services.size()-1; 16982 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16983 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16984 || procState > ActivityManager.PROCESS_STATE_TOP); 16985 is--) { 16986 ServiceRecord s = app.services.valueAt(is); 16987 if (s.startRequested) { 16988 app.hasStartedServices = true; 16989 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16990 procState = ActivityManager.PROCESS_STATE_SERVICE; 16991 } 16992 if (app.hasShownUi && app != mHomeProcess) { 16993 // If this process has shown some UI, let it immediately 16994 // go to the LRU list because it may be pretty heavy with 16995 // UI stuff. We'll tag it with a label just to help 16996 // debug and understand what is going on. 16997 if (adj > ProcessList.SERVICE_ADJ) { 16998 app.adjType = "cch-started-ui-services"; 16999 } 17000 } else { 17001 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17002 // This service has seen some activity within 17003 // recent memory, so we will keep its process ahead 17004 // of the background processes. 17005 if (adj > ProcessList.SERVICE_ADJ) { 17006 adj = ProcessList.SERVICE_ADJ; 17007 app.adjType = "started-services"; 17008 app.cached = false; 17009 } 17010 } 17011 // If we have let the service slide into the background 17012 // state, still have some text describing what it is doing 17013 // even though the service no longer has an impact. 17014 if (adj > ProcessList.SERVICE_ADJ) { 17015 app.adjType = "cch-started-services"; 17016 } 17017 } 17018 } 17019 for (int conni = s.connections.size()-1; 17020 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17021 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17022 || procState > ActivityManager.PROCESS_STATE_TOP); 17023 conni--) { 17024 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17025 for (int i = 0; 17026 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17027 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17028 || procState > ActivityManager.PROCESS_STATE_TOP); 17029 i++) { 17030 // XXX should compute this based on the max of 17031 // all connected clients. 17032 ConnectionRecord cr = clist.get(i); 17033 if (cr.binding.client == app) { 17034 // Binding to ourself is not interesting. 17035 continue; 17036 } 17037 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17038 ProcessRecord client = cr.binding.client; 17039 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17040 TOP_APP, doingAll, now); 17041 int clientProcState = client.curProcState; 17042 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17043 // If the other app is cached for any reason, for purposes here 17044 // we are going to consider it empty. The specific cached state 17045 // doesn't propagate except under certain conditions. 17046 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17047 } 17048 String adjType = null; 17049 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17050 // Not doing bind OOM management, so treat 17051 // this guy more like a started service. 17052 if (app.hasShownUi && app != mHomeProcess) { 17053 // If this process has shown some UI, let it immediately 17054 // go to the LRU list because it may be pretty heavy with 17055 // UI stuff. We'll tag it with a label just to help 17056 // debug and understand what is going on. 17057 if (adj > clientAdj) { 17058 adjType = "cch-bound-ui-services"; 17059 } 17060 app.cached = false; 17061 clientAdj = adj; 17062 clientProcState = procState; 17063 } else { 17064 if (now >= (s.lastActivity 17065 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17066 // This service has not seen activity within 17067 // recent memory, so allow it to drop to the 17068 // LRU list if there is no other reason to keep 17069 // it around. We'll also tag it with a label just 17070 // to help debug and undertand what is going on. 17071 if (adj > clientAdj) { 17072 adjType = "cch-bound-services"; 17073 } 17074 clientAdj = adj; 17075 } 17076 } 17077 } 17078 if (adj > clientAdj) { 17079 // If this process has recently shown UI, and 17080 // the process that is binding to it is less 17081 // important than being visible, then we don't 17082 // care about the binding as much as we care 17083 // about letting this process get into the LRU 17084 // list to be killed and restarted if needed for 17085 // memory. 17086 if (app.hasShownUi && app != mHomeProcess 17087 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17088 adjType = "cch-bound-ui-services"; 17089 } else { 17090 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17091 |Context.BIND_IMPORTANT)) != 0) { 17092 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17093 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17094 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17095 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17096 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17097 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17098 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17099 adj = clientAdj; 17100 } else { 17101 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17102 adj = ProcessList.VISIBLE_APP_ADJ; 17103 } 17104 } 17105 if (!client.cached) { 17106 app.cached = false; 17107 } 17108 adjType = "service"; 17109 } 17110 } 17111 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17112 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17113 schedGroup = Process.THREAD_GROUP_DEFAULT; 17114 } 17115 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17116 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17117 // Special handling of clients who are in the top state. 17118 // We *may* want to consider this process to be in the 17119 // top state as well, but only if there is not another 17120 // reason for it to be running. Being on the top is a 17121 // special state, meaning you are specifically running 17122 // for the current top app. If the process is already 17123 // running in the background for some other reason, it 17124 // is more important to continue considering it to be 17125 // in the background state. 17126 mayBeTop = true; 17127 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17128 } else { 17129 // Special handling for above-top states (persistent 17130 // processes). These should not bring the current process 17131 // into the top state, since they are not on top. Instead 17132 // give them the best state after that. 17133 clientProcState = 17134 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17135 } 17136 } 17137 } else { 17138 if (clientProcState < 17139 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17140 clientProcState = 17141 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17142 } 17143 } 17144 if (procState > clientProcState) { 17145 procState = clientProcState; 17146 } 17147 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17148 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17149 app.pendingUiClean = true; 17150 } 17151 if (adjType != null) { 17152 app.adjType = adjType; 17153 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17154 .REASON_SERVICE_IN_USE; 17155 app.adjSource = cr.binding.client; 17156 app.adjSourceProcState = clientProcState; 17157 app.adjTarget = s.name; 17158 } 17159 } 17160 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17161 app.treatLikeActivity = true; 17162 } 17163 final ActivityRecord a = cr.activity; 17164 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17165 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17166 (a.visible || a.state == ActivityState.RESUMED 17167 || a.state == ActivityState.PAUSING)) { 17168 adj = ProcessList.FOREGROUND_APP_ADJ; 17169 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17170 schedGroup = Process.THREAD_GROUP_DEFAULT; 17171 } 17172 app.cached = false; 17173 app.adjType = "service"; 17174 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17175 .REASON_SERVICE_IN_USE; 17176 app.adjSource = a; 17177 app.adjSourceProcState = procState; 17178 app.adjTarget = s.name; 17179 } 17180 } 17181 } 17182 } 17183 } 17184 17185 for (int provi = app.pubProviders.size()-1; 17186 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17187 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17188 || procState > ActivityManager.PROCESS_STATE_TOP); 17189 provi--) { 17190 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17191 for (int i = cpr.connections.size()-1; 17192 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17193 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17194 || procState > ActivityManager.PROCESS_STATE_TOP); 17195 i--) { 17196 ContentProviderConnection conn = cpr.connections.get(i); 17197 ProcessRecord client = conn.client; 17198 if (client == app) { 17199 // Being our own client is not interesting. 17200 continue; 17201 } 17202 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17203 int clientProcState = client.curProcState; 17204 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17205 // If the other app is cached for any reason, for purposes here 17206 // we are going to consider it empty. 17207 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17208 } 17209 if (adj > clientAdj) { 17210 if (app.hasShownUi && app != mHomeProcess 17211 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17212 app.adjType = "cch-ui-provider"; 17213 } else { 17214 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17215 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17216 app.adjType = "provider"; 17217 } 17218 app.cached &= client.cached; 17219 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17220 .REASON_PROVIDER_IN_USE; 17221 app.adjSource = client; 17222 app.adjSourceProcState = clientProcState; 17223 app.adjTarget = cpr.name; 17224 } 17225 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17226 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17227 // Special handling of clients who are in the top state. 17228 // We *may* want to consider this process to be in the 17229 // top state as well, but only if there is not another 17230 // reason for it to be running. Being on the top is a 17231 // special state, meaning you are specifically running 17232 // for the current top app. If the process is already 17233 // running in the background for some other reason, it 17234 // is more important to continue considering it to be 17235 // in the background state. 17236 mayBeTop = true; 17237 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17238 } else { 17239 // Special handling for above-top states (persistent 17240 // processes). These should not bring the current process 17241 // into the top state, since they are not on top. Instead 17242 // give them the best state after that. 17243 clientProcState = 17244 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17245 } 17246 } 17247 if (procState > clientProcState) { 17248 procState = clientProcState; 17249 } 17250 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17251 schedGroup = Process.THREAD_GROUP_DEFAULT; 17252 } 17253 } 17254 // If the provider has external (non-framework) process 17255 // dependencies, ensure that its adjustment is at least 17256 // FOREGROUND_APP_ADJ. 17257 if (cpr.hasExternalProcessHandles()) { 17258 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17259 adj = ProcessList.FOREGROUND_APP_ADJ; 17260 schedGroup = Process.THREAD_GROUP_DEFAULT; 17261 app.cached = false; 17262 app.adjType = "provider"; 17263 app.adjTarget = cpr.name; 17264 } 17265 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17266 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17267 } 17268 } 17269 } 17270 17271 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17272 // A client of one of our services or providers is in the top state. We 17273 // *may* want to be in the top state, but not if we are already running in 17274 // the background for some other reason. For the decision here, we are going 17275 // to pick out a few specific states that we want to remain in when a client 17276 // is top (states that tend to be longer-term) and otherwise allow it to go 17277 // to the top state. 17278 switch (procState) { 17279 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17280 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17281 case ActivityManager.PROCESS_STATE_SERVICE: 17282 // These all are longer-term states, so pull them up to the top 17283 // of the background states, but not all the way to the top state. 17284 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17285 break; 17286 default: 17287 // Otherwise, top is a better choice, so take it. 17288 procState = ActivityManager.PROCESS_STATE_TOP; 17289 break; 17290 } 17291 } 17292 17293 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17294 if (app.hasClientActivities) { 17295 // This is a cached process, but with client activities. Mark it so. 17296 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17297 app.adjType = "cch-client-act"; 17298 } else if (app.treatLikeActivity) { 17299 // This is a cached process, but somebody wants us to treat it like it has 17300 // an activity, okay! 17301 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17302 app.adjType = "cch-as-act"; 17303 } 17304 } 17305 17306 if (adj == ProcessList.SERVICE_ADJ) { 17307 if (doingAll) { 17308 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17309 mNewNumServiceProcs++; 17310 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17311 if (!app.serviceb) { 17312 // This service isn't far enough down on the LRU list to 17313 // normally be a B service, but if we are low on RAM and it 17314 // is large we want to force it down since we would prefer to 17315 // keep launcher over it. 17316 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17317 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17318 app.serviceHighRam = true; 17319 app.serviceb = true; 17320 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17321 } else { 17322 mNewNumAServiceProcs++; 17323 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17324 } 17325 } else { 17326 app.serviceHighRam = false; 17327 } 17328 } 17329 if (app.serviceb) { 17330 adj = ProcessList.SERVICE_B_ADJ; 17331 } 17332 } 17333 17334 app.curRawAdj = adj; 17335 17336 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17337 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17338 if (adj > app.maxAdj) { 17339 adj = app.maxAdj; 17340 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17341 schedGroup = Process.THREAD_GROUP_DEFAULT; 17342 } 17343 } 17344 17345 // Do final modification to adj. Everything we do between here and applying 17346 // the final setAdj must be done in this function, because we will also use 17347 // it when computing the final cached adj later. Note that we don't need to 17348 // worry about this for max adj above, since max adj will always be used to 17349 // keep it out of the cached vaues. 17350 app.curAdj = app.modifyRawOomAdj(adj); 17351 app.curSchedGroup = schedGroup; 17352 app.curProcState = procState; 17353 app.foregroundActivities = foregroundActivities; 17354 17355 return app.curRawAdj; 17356 } 17357 17358 /** 17359 * Record new PSS sample for a process. 17360 */ 17361 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17362 proc.lastPssTime = now; 17363 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17364 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17365 + ": " + pss + " lastPss=" + proc.lastPss 17366 + " state=" + ProcessList.makeProcStateString(procState)); 17367 if (proc.initialIdlePss == 0) { 17368 proc.initialIdlePss = pss; 17369 } 17370 proc.lastPss = pss; 17371 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17372 proc.lastCachedPss = pss; 17373 } 17374 } 17375 17376 /** 17377 * Schedule PSS collection of a process. 17378 */ 17379 void requestPssLocked(ProcessRecord proc, int procState) { 17380 if (mPendingPssProcesses.contains(proc)) { 17381 return; 17382 } 17383 if (mPendingPssProcesses.size() == 0) { 17384 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17385 } 17386 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17387 proc.pssProcState = procState; 17388 mPendingPssProcesses.add(proc); 17389 } 17390 17391 /** 17392 * Schedule PSS collection of all processes. 17393 */ 17394 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17395 if (!always) { 17396 if (now < (mLastFullPssTime + 17397 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17398 return; 17399 } 17400 } 17401 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17402 mLastFullPssTime = now; 17403 mFullPssPending = true; 17404 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17405 mPendingPssProcesses.clear(); 17406 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17407 ProcessRecord app = mLruProcesses.get(i); 17408 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17409 app.pssProcState = app.setProcState; 17410 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17411 mTestPssMode, isSleeping(), now); 17412 mPendingPssProcesses.add(app); 17413 } 17414 } 17415 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17416 } 17417 17418 public void setTestPssMode(boolean enabled) { 17419 synchronized (this) { 17420 mTestPssMode = enabled; 17421 if (enabled) { 17422 // Whenever we enable the mode, we want to take a snapshot all of current 17423 // process mem use. 17424 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17425 } 17426 } 17427 } 17428 17429 /** 17430 * Ask a given process to GC right now. 17431 */ 17432 final void performAppGcLocked(ProcessRecord app) { 17433 try { 17434 app.lastRequestedGc = SystemClock.uptimeMillis(); 17435 if (app.thread != null) { 17436 if (app.reportLowMemory) { 17437 app.reportLowMemory = false; 17438 app.thread.scheduleLowMemory(); 17439 } else { 17440 app.thread.processInBackground(); 17441 } 17442 } 17443 } catch (Exception e) { 17444 // whatever. 17445 } 17446 } 17447 17448 /** 17449 * Returns true if things are idle enough to perform GCs. 17450 */ 17451 private final boolean canGcNowLocked() { 17452 boolean processingBroadcasts = false; 17453 for (BroadcastQueue q : mBroadcastQueues) { 17454 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17455 processingBroadcasts = true; 17456 } 17457 } 17458 return !processingBroadcasts 17459 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17460 } 17461 17462 /** 17463 * Perform GCs on all processes that are waiting for it, but only 17464 * if things are idle. 17465 */ 17466 final void performAppGcsLocked() { 17467 final int N = mProcessesToGc.size(); 17468 if (N <= 0) { 17469 return; 17470 } 17471 if (canGcNowLocked()) { 17472 while (mProcessesToGc.size() > 0) { 17473 ProcessRecord proc = mProcessesToGc.remove(0); 17474 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17475 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17476 <= SystemClock.uptimeMillis()) { 17477 // To avoid spamming the system, we will GC processes one 17478 // at a time, waiting a few seconds between each. 17479 performAppGcLocked(proc); 17480 scheduleAppGcsLocked(); 17481 return; 17482 } else { 17483 // It hasn't been long enough since we last GCed this 17484 // process... put it in the list to wait for its time. 17485 addProcessToGcListLocked(proc); 17486 break; 17487 } 17488 } 17489 } 17490 17491 scheduleAppGcsLocked(); 17492 } 17493 } 17494 17495 /** 17496 * If all looks good, perform GCs on all processes waiting for them. 17497 */ 17498 final void performAppGcsIfAppropriateLocked() { 17499 if (canGcNowLocked()) { 17500 performAppGcsLocked(); 17501 return; 17502 } 17503 // Still not idle, wait some more. 17504 scheduleAppGcsLocked(); 17505 } 17506 17507 /** 17508 * Schedule the execution of all pending app GCs. 17509 */ 17510 final void scheduleAppGcsLocked() { 17511 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17512 17513 if (mProcessesToGc.size() > 0) { 17514 // Schedule a GC for the time to the next process. 17515 ProcessRecord proc = mProcessesToGc.get(0); 17516 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17517 17518 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17519 long now = SystemClock.uptimeMillis(); 17520 if (when < (now+GC_TIMEOUT)) { 17521 when = now + GC_TIMEOUT; 17522 } 17523 mHandler.sendMessageAtTime(msg, when); 17524 } 17525 } 17526 17527 /** 17528 * Add a process to the array of processes waiting to be GCed. Keeps the 17529 * list in sorted order by the last GC time. The process can't already be 17530 * on the list. 17531 */ 17532 final void addProcessToGcListLocked(ProcessRecord proc) { 17533 boolean added = false; 17534 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17535 if (mProcessesToGc.get(i).lastRequestedGc < 17536 proc.lastRequestedGc) { 17537 added = true; 17538 mProcessesToGc.add(i+1, proc); 17539 break; 17540 } 17541 } 17542 if (!added) { 17543 mProcessesToGc.add(0, proc); 17544 } 17545 } 17546 17547 /** 17548 * Set up to ask a process to GC itself. This will either do it 17549 * immediately, or put it on the list of processes to gc the next 17550 * time things are idle. 17551 */ 17552 final void scheduleAppGcLocked(ProcessRecord app) { 17553 long now = SystemClock.uptimeMillis(); 17554 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17555 return; 17556 } 17557 if (!mProcessesToGc.contains(app)) { 17558 addProcessToGcListLocked(app); 17559 scheduleAppGcsLocked(); 17560 } 17561 } 17562 17563 final void checkExcessivePowerUsageLocked(boolean doKills) { 17564 updateCpuStatsNow(); 17565 17566 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17567 boolean doWakeKills = doKills; 17568 boolean doCpuKills = doKills; 17569 if (mLastPowerCheckRealtime == 0) { 17570 doWakeKills = false; 17571 } 17572 if (mLastPowerCheckUptime == 0) { 17573 doCpuKills = false; 17574 } 17575 if (stats.isScreenOn()) { 17576 doWakeKills = false; 17577 } 17578 final long curRealtime = SystemClock.elapsedRealtime(); 17579 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17580 final long curUptime = SystemClock.uptimeMillis(); 17581 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17582 mLastPowerCheckRealtime = curRealtime; 17583 mLastPowerCheckUptime = curUptime; 17584 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17585 doWakeKills = false; 17586 } 17587 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17588 doCpuKills = false; 17589 } 17590 int i = mLruProcesses.size(); 17591 while (i > 0) { 17592 i--; 17593 ProcessRecord app = mLruProcesses.get(i); 17594 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17595 long wtime; 17596 synchronized (stats) { 17597 wtime = stats.getProcessWakeTime(app.info.uid, 17598 app.pid, curRealtime); 17599 } 17600 long wtimeUsed = wtime - app.lastWakeTime; 17601 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17602 if (DEBUG_POWER) { 17603 StringBuilder sb = new StringBuilder(128); 17604 sb.append("Wake for "); 17605 app.toShortString(sb); 17606 sb.append(": over "); 17607 TimeUtils.formatDuration(realtimeSince, sb); 17608 sb.append(" used "); 17609 TimeUtils.formatDuration(wtimeUsed, sb); 17610 sb.append(" ("); 17611 sb.append((wtimeUsed*100)/realtimeSince); 17612 sb.append("%)"); 17613 Slog.i(TAG, sb.toString()); 17614 sb.setLength(0); 17615 sb.append("CPU for "); 17616 app.toShortString(sb); 17617 sb.append(": over "); 17618 TimeUtils.formatDuration(uptimeSince, sb); 17619 sb.append(" used "); 17620 TimeUtils.formatDuration(cputimeUsed, sb); 17621 sb.append(" ("); 17622 sb.append((cputimeUsed*100)/uptimeSince); 17623 sb.append("%)"); 17624 Slog.i(TAG, sb.toString()); 17625 } 17626 // If a process has held a wake lock for more 17627 // than 50% of the time during this period, 17628 // that sounds bad. Kill! 17629 if (doWakeKills && realtimeSince > 0 17630 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17631 synchronized (stats) { 17632 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17633 realtimeSince, wtimeUsed); 17634 } 17635 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17636 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17637 } else if (doCpuKills && uptimeSince > 0 17638 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17639 synchronized (stats) { 17640 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17641 uptimeSince, cputimeUsed); 17642 } 17643 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17644 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17645 } else { 17646 app.lastWakeTime = wtime; 17647 app.lastCpuTime = app.curCpuTime; 17648 } 17649 } 17650 } 17651 } 17652 17653 private final boolean applyOomAdjLocked(ProcessRecord app, 17654 ProcessRecord TOP_APP, boolean doingAll, long now) { 17655 boolean success = true; 17656 17657 if (app.curRawAdj != app.setRawAdj) { 17658 app.setRawAdj = app.curRawAdj; 17659 } 17660 17661 int changes = 0; 17662 17663 if (app.curAdj != app.setAdj) { 17664 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17665 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17666 TAG, "Set " + app.pid + " " + app.processName + 17667 " adj " + app.curAdj + ": " + app.adjType); 17668 app.setAdj = app.curAdj; 17669 } 17670 17671 if (app.setSchedGroup != app.curSchedGroup) { 17672 app.setSchedGroup = app.curSchedGroup; 17673 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17674 "Setting process group of " + app.processName 17675 + " to " + app.curSchedGroup); 17676 if (app.waitingToKill != null && 17677 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17678 app.kill(app.waitingToKill, true); 17679 success = false; 17680 } else { 17681 if (true) { 17682 long oldId = Binder.clearCallingIdentity(); 17683 try { 17684 Process.setProcessGroup(app.pid, app.curSchedGroup); 17685 } catch (Exception e) { 17686 Slog.w(TAG, "Failed setting process group of " + app.pid 17687 + " to " + app.curSchedGroup); 17688 e.printStackTrace(); 17689 } finally { 17690 Binder.restoreCallingIdentity(oldId); 17691 } 17692 } else { 17693 if (app.thread != null) { 17694 try { 17695 app.thread.setSchedulingGroup(app.curSchedGroup); 17696 } catch (RemoteException e) { 17697 } 17698 } 17699 } 17700 Process.setSwappiness(app.pid, 17701 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17702 } 17703 } 17704 if (app.repForegroundActivities != app.foregroundActivities) { 17705 app.repForegroundActivities = app.foregroundActivities; 17706 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17707 } 17708 if (app.repProcState != app.curProcState) { 17709 app.repProcState = app.curProcState; 17710 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17711 if (app.thread != null) { 17712 try { 17713 if (false) { 17714 //RuntimeException h = new RuntimeException("here"); 17715 Slog.i(TAG, "Sending new process state " + app.repProcState 17716 + " to " + app /*, h*/); 17717 } 17718 app.thread.setProcessState(app.repProcState); 17719 } catch (RemoteException e) { 17720 } 17721 } 17722 } 17723 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17724 app.setProcState)) { 17725 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17726 // Experimental code to more aggressively collect pss while 17727 // running test... the problem is that this tends to collect 17728 // the data right when a process is transitioning between process 17729 // states, which well tend to give noisy data. 17730 long start = SystemClock.uptimeMillis(); 17731 long pss = Debug.getPss(app.pid, mTmpLong, null); 17732 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17733 mPendingPssProcesses.remove(app); 17734 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17735 + " to " + app.curProcState + ": " 17736 + (SystemClock.uptimeMillis()-start) + "ms"); 17737 } 17738 app.lastStateTime = now; 17739 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17740 mTestPssMode, isSleeping(), now); 17741 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17742 + ProcessList.makeProcStateString(app.setProcState) + " to " 17743 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17744 + (app.nextPssTime-now) + ": " + app); 17745 } else { 17746 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17747 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17748 requestPssLocked(app, app.setProcState); 17749 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17750 mTestPssMode, isSleeping(), now); 17751 } else if (false && DEBUG_PSS) { 17752 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17753 } 17754 } 17755 if (app.setProcState != app.curProcState) { 17756 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17757 "Proc state change of " + app.processName 17758 + " to " + app.curProcState); 17759 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17760 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17761 if (setImportant && !curImportant) { 17762 // This app is no longer something we consider important enough to allow to 17763 // use arbitrary amounts of battery power. Note 17764 // its current wake lock time to later know to kill it if 17765 // it is not behaving well. 17766 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17767 synchronized (stats) { 17768 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17769 app.pid, SystemClock.elapsedRealtime()); 17770 } 17771 app.lastCpuTime = app.curCpuTime; 17772 17773 } 17774 app.setProcState = app.curProcState; 17775 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17776 app.notCachedSinceIdle = false; 17777 } 17778 if (!doingAll) { 17779 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17780 } else { 17781 app.procStateChanged = true; 17782 } 17783 } 17784 17785 if (changes != 0) { 17786 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17787 int i = mPendingProcessChanges.size()-1; 17788 ProcessChangeItem item = null; 17789 while (i >= 0) { 17790 item = mPendingProcessChanges.get(i); 17791 if (item.pid == app.pid) { 17792 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17793 break; 17794 } 17795 i--; 17796 } 17797 if (i < 0) { 17798 // No existing item in pending changes; need a new one. 17799 final int NA = mAvailProcessChanges.size(); 17800 if (NA > 0) { 17801 item = mAvailProcessChanges.remove(NA-1); 17802 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17803 } else { 17804 item = new ProcessChangeItem(); 17805 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17806 } 17807 item.changes = 0; 17808 item.pid = app.pid; 17809 item.uid = app.info.uid; 17810 if (mPendingProcessChanges.size() == 0) { 17811 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17812 "*** Enqueueing dispatch processes changed!"); 17813 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17814 } 17815 mPendingProcessChanges.add(item); 17816 } 17817 item.changes |= changes; 17818 item.processState = app.repProcState; 17819 item.foregroundActivities = app.repForegroundActivities; 17820 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17821 + Integer.toHexString(System.identityHashCode(item)) 17822 + " " + app.toShortString() + ": changes=" + item.changes 17823 + " procState=" + item.processState 17824 + " foreground=" + item.foregroundActivities 17825 + " type=" + app.adjType + " source=" + app.adjSource 17826 + " target=" + app.adjTarget); 17827 } 17828 17829 return success; 17830 } 17831 17832 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17833 if (proc.thread != null) { 17834 if (proc.baseProcessTracker != null) { 17835 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17836 } 17837 if (proc.repProcState >= 0) { 17838 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17839 proc.repProcState); 17840 } 17841 } 17842 } 17843 17844 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17845 ProcessRecord TOP_APP, boolean doingAll, long now) { 17846 if (app.thread == null) { 17847 return false; 17848 } 17849 17850 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17851 17852 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17853 } 17854 17855 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17856 boolean oomAdj) { 17857 if (isForeground != proc.foregroundServices) { 17858 proc.foregroundServices = isForeground; 17859 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17860 proc.info.uid); 17861 if (isForeground) { 17862 if (curProcs == null) { 17863 curProcs = new ArrayList<ProcessRecord>(); 17864 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17865 } 17866 if (!curProcs.contains(proc)) { 17867 curProcs.add(proc); 17868 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17869 proc.info.packageName, proc.info.uid); 17870 } 17871 } else { 17872 if (curProcs != null) { 17873 if (curProcs.remove(proc)) { 17874 mBatteryStatsService.noteEvent( 17875 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17876 proc.info.packageName, proc.info.uid); 17877 if (curProcs.size() <= 0) { 17878 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17879 } 17880 } 17881 } 17882 } 17883 if (oomAdj) { 17884 updateOomAdjLocked(); 17885 } 17886 } 17887 } 17888 17889 private final ActivityRecord resumedAppLocked() { 17890 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17891 String pkg; 17892 int uid; 17893 if (act != null) { 17894 pkg = act.packageName; 17895 uid = act.info.applicationInfo.uid; 17896 } else { 17897 pkg = null; 17898 uid = -1; 17899 } 17900 // Has the UID or resumed package name changed? 17901 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17902 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17903 if (mCurResumedPackage != null) { 17904 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17905 mCurResumedPackage, mCurResumedUid); 17906 } 17907 mCurResumedPackage = pkg; 17908 mCurResumedUid = uid; 17909 if (mCurResumedPackage != null) { 17910 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17911 mCurResumedPackage, mCurResumedUid); 17912 } 17913 } 17914 return act; 17915 } 17916 17917 final boolean updateOomAdjLocked(ProcessRecord app) { 17918 final ActivityRecord TOP_ACT = resumedAppLocked(); 17919 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17920 final boolean wasCached = app.cached; 17921 17922 mAdjSeq++; 17923 17924 // This is the desired cached adjusment we want to tell it to use. 17925 // If our app is currently cached, we know it, and that is it. Otherwise, 17926 // we don't know it yet, and it needs to now be cached we will then 17927 // need to do a complete oom adj. 17928 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17929 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17930 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17931 SystemClock.uptimeMillis()); 17932 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17933 // Changed to/from cached state, so apps after it in the LRU 17934 // list may also be changed. 17935 updateOomAdjLocked(); 17936 } 17937 return success; 17938 } 17939 17940 final void updateOomAdjLocked() { 17941 final ActivityRecord TOP_ACT = resumedAppLocked(); 17942 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17943 final long now = SystemClock.uptimeMillis(); 17944 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17945 final int N = mLruProcesses.size(); 17946 17947 if (false) { 17948 RuntimeException e = new RuntimeException(); 17949 e.fillInStackTrace(); 17950 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17951 } 17952 17953 mAdjSeq++; 17954 mNewNumServiceProcs = 0; 17955 mNewNumAServiceProcs = 0; 17956 17957 final int emptyProcessLimit; 17958 final int cachedProcessLimit; 17959 if (mProcessLimit <= 0) { 17960 emptyProcessLimit = cachedProcessLimit = 0; 17961 } else if (mProcessLimit == 1) { 17962 emptyProcessLimit = 1; 17963 cachedProcessLimit = 0; 17964 } else { 17965 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17966 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17967 } 17968 17969 // Let's determine how many processes we have running vs. 17970 // how many slots we have for background processes; we may want 17971 // to put multiple processes in a slot of there are enough of 17972 // them. 17973 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17974 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17975 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17976 if (numEmptyProcs > cachedProcessLimit) { 17977 // If there are more empty processes than our limit on cached 17978 // processes, then use the cached process limit for the factor. 17979 // This ensures that the really old empty processes get pushed 17980 // down to the bottom, so if we are running low on memory we will 17981 // have a better chance at keeping around more cached processes 17982 // instead of a gazillion empty processes. 17983 numEmptyProcs = cachedProcessLimit; 17984 } 17985 int emptyFactor = numEmptyProcs/numSlots; 17986 if (emptyFactor < 1) emptyFactor = 1; 17987 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17988 if (cachedFactor < 1) cachedFactor = 1; 17989 int stepCached = 0; 17990 int stepEmpty = 0; 17991 int numCached = 0; 17992 int numEmpty = 0; 17993 int numTrimming = 0; 17994 17995 mNumNonCachedProcs = 0; 17996 mNumCachedHiddenProcs = 0; 17997 17998 // First update the OOM adjustment for each of the 17999 // application processes based on their current state. 18000 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18001 int nextCachedAdj = curCachedAdj+1; 18002 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18003 int nextEmptyAdj = curEmptyAdj+2; 18004 for (int i=N-1; i>=0; i--) { 18005 ProcessRecord app = mLruProcesses.get(i); 18006 if (!app.killedByAm && app.thread != null) { 18007 app.procStateChanged = false; 18008 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18009 18010 // If we haven't yet assigned the final cached adj 18011 // to the process, do that now. 18012 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18013 switch (app.curProcState) { 18014 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18015 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18016 // This process is a cached process holding activities... 18017 // assign it the next cached value for that type, and then 18018 // step that cached level. 18019 app.curRawAdj = curCachedAdj; 18020 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18021 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18022 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18023 + ")"); 18024 if (curCachedAdj != nextCachedAdj) { 18025 stepCached++; 18026 if (stepCached >= cachedFactor) { 18027 stepCached = 0; 18028 curCachedAdj = nextCachedAdj; 18029 nextCachedAdj += 2; 18030 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18031 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18032 } 18033 } 18034 } 18035 break; 18036 default: 18037 // For everything else, assign next empty cached process 18038 // level and bump that up. Note that this means that 18039 // long-running services that have dropped down to the 18040 // cached level will be treated as empty (since their process 18041 // state is still as a service), which is what we want. 18042 app.curRawAdj = curEmptyAdj; 18043 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18044 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18045 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18046 + ")"); 18047 if (curEmptyAdj != nextEmptyAdj) { 18048 stepEmpty++; 18049 if (stepEmpty >= emptyFactor) { 18050 stepEmpty = 0; 18051 curEmptyAdj = nextEmptyAdj; 18052 nextEmptyAdj += 2; 18053 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18054 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18055 } 18056 } 18057 } 18058 break; 18059 } 18060 } 18061 18062 applyOomAdjLocked(app, TOP_APP, true, now); 18063 18064 // Count the number of process types. 18065 switch (app.curProcState) { 18066 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18067 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18068 mNumCachedHiddenProcs++; 18069 numCached++; 18070 if (numCached > cachedProcessLimit) { 18071 app.kill("cached #" + numCached, true); 18072 } 18073 break; 18074 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18075 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18076 && app.lastActivityTime < oldTime) { 18077 app.kill("empty for " 18078 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18079 / 1000) + "s", true); 18080 } else { 18081 numEmpty++; 18082 if (numEmpty > emptyProcessLimit) { 18083 app.kill("empty #" + numEmpty, true); 18084 } 18085 } 18086 break; 18087 default: 18088 mNumNonCachedProcs++; 18089 break; 18090 } 18091 18092 if (app.isolated && app.services.size() <= 0) { 18093 // If this is an isolated process, and there are no 18094 // services running in it, then the process is no longer 18095 // needed. We agressively kill these because we can by 18096 // definition not re-use the same process again, and it is 18097 // good to avoid having whatever code was running in them 18098 // left sitting around after no longer needed. 18099 app.kill("isolated not needed", true); 18100 } 18101 18102 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18103 && !app.killedByAm) { 18104 numTrimming++; 18105 } 18106 } 18107 } 18108 18109 mNumServiceProcs = mNewNumServiceProcs; 18110 18111 // Now determine the memory trimming level of background processes. 18112 // Unfortunately we need to start at the back of the list to do this 18113 // properly. We only do this if the number of background apps we 18114 // are managing to keep around is less than half the maximum we desire; 18115 // if we are keeping a good number around, we'll let them use whatever 18116 // memory they want. 18117 final int numCachedAndEmpty = numCached + numEmpty; 18118 int memFactor; 18119 if (numCached <= ProcessList.TRIM_CACHED_APPS 18120 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18121 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18122 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18123 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18124 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18125 } else { 18126 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18127 } 18128 } else { 18129 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18130 } 18131 // We always allow the memory level to go up (better). We only allow it to go 18132 // down if we are in a state where that is allowed, *and* the total number of processes 18133 // has gone down since last time. 18134 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18135 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18136 + " last=" + mLastNumProcesses); 18137 if (memFactor > mLastMemoryLevel) { 18138 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18139 memFactor = mLastMemoryLevel; 18140 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18141 } 18142 } 18143 mLastMemoryLevel = memFactor; 18144 mLastNumProcesses = mLruProcesses.size(); 18145 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18146 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18147 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18148 if (mLowRamStartTime == 0) { 18149 mLowRamStartTime = now; 18150 } 18151 int step = 0; 18152 int fgTrimLevel; 18153 switch (memFactor) { 18154 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18155 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18156 break; 18157 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18158 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18159 break; 18160 default: 18161 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18162 break; 18163 } 18164 int factor = numTrimming/3; 18165 int minFactor = 2; 18166 if (mHomeProcess != null) minFactor++; 18167 if (mPreviousProcess != null) minFactor++; 18168 if (factor < minFactor) factor = minFactor; 18169 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18170 for (int i=N-1; i>=0; i--) { 18171 ProcessRecord app = mLruProcesses.get(i); 18172 if (allChanged || app.procStateChanged) { 18173 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18174 app.procStateChanged = false; 18175 } 18176 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18177 && !app.killedByAm) { 18178 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18179 try { 18180 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18181 "Trimming memory of " + app.processName 18182 + " to " + curLevel); 18183 app.thread.scheduleTrimMemory(curLevel); 18184 } catch (RemoteException e) { 18185 } 18186 if (false) { 18187 // For now we won't do this; our memory trimming seems 18188 // to be good enough at this point that destroying 18189 // activities causes more harm than good. 18190 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18191 && app != mHomeProcess && app != mPreviousProcess) { 18192 // Need to do this on its own message because the stack may not 18193 // be in a consistent state at this point. 18194 // For these apps we will also finish their activities 18195 // to help them free memory. 18196 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18197 } 18198 } 18199 } 18200 app.trimMemoryLevel = curLevel; 18201 step++; 18202 if (step >= factor) { 18203 step = 0; 18204 switch (curLevel) { 18205 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18206 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18207 break; 18208 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18209 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18210 break; 18211 } 18212 } 18213 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18214 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18215 && app.thread != null) { 18216 try { 18217 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18218 "Trimming memory of heavy-weight " + app.processName 18219 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18220 app.thread.scheduleTrimMemory( 18221 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18222 } catch (RemoteException e) { 18223 } 18224 } 18225 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18226 } else { 18227 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18228 || app.systemNoUi) && app.pendingUiClean) { 18229 // If this application is now in the background and it 18230 // had done UI, then give it the special trim level to 18231 // have it free UI resources. 18232 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18233 if (app.trimMemoryLevel < level && app.thread != null) { 18234 try { 18235 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18236 "Trimming memory of bg-ui " + app.processName 18237 + " to " + level); 18238 app.thread.scheduleTrimMemory(level); 18239 } catch (RemoteException e) { 18240 } 18241 } 18242 app.pendingUiClean = false; 18243 } 18244 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18245 try { 18246 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18247 "Trimming memory of fg " + app.processName 18248 + " to " + fgTrimLevel); 18249 app.thread.scheduleTrimMemory(fgTrimLevel); 18250 } catch (RemoteException e) { 18251 } 18252 } 18253 app.trimMemoryLevel = fgTrimLevel; 18254 } 18255 } 18256 } else { 18257 if (mLowRamStartTime != 0) { 18258 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18259 mLowRamStartTime = 0; 18260 } 18261 for (int i=N-1; i>=0; i--) { 18262 ProcessRecord app = mLruProcesses.get(i); 18263 if (allChanged || app.procStateChanged) { 18264 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18265 app.procStateChanged = false; 18266 } 18267 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18268 || app.systemNoUi) && app.pendingUiClean) { 18269 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18270 && app.thread != null) { 18271 try { 18272 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18273 "Trimming memory of ui hidden " + app.processName 18274 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18275 app.thread.scheduleTrimMemory( 18276 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18277 } catch (RemoteException e) { 18278 } 18279 } 18280 app.pendingUiClean = false; 18281 } 18282 app.trimMemoryLevel = 0; 18283 } 18284 } 18285 18286 if (mAlwaysFinishActivities) { 18287 // Need to do this on its own message because the stack may not 18288 // be in a consistent state at this point. 18289 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18290 } 18291 18292 if (allChanged) { 18293 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18294 } 18295 18296 if (mProcessStats.shouldWriteNowLocked(now)) { 18297 mHandler.post(new Runnable() { 18298 @Override public void run() { 18299 synchronized (ActivityManagerService.this) { 18300 mProcessStats.writeStateAsyncLocked(); 18301 } 18302 } 18303 }); 18304 } 18305 18306 if (DEBUG_OOM_ADJ) { 18307 if (false) { 18308 RuntimeException here = new RuntimeException("here"); 18309 here.fillInStackTrace(); 18310 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18311 } else { 18312 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18313 } 18314 } 18315 } 18316 18317 final void trimApplications() { 18318 synchronized (this) { 18319 int i; 18320 18321 // First remove any unused application processes whose package 18322 // has been removed. 18323 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18324 final ProcessRecord app = mRemovedProcesses.get(i); 18325 if (app.activities.size() == 0 18326 && app.curReceiver == null && app.services.size() == 0) { 18327 Slog.i( 18328 TAG, "Exiting empty application process " 18329 + app.processName + " (" 18330 + (app.thread != null ? app.thread.asBinder() : null) 18331 + ")\n"); 18332 if (app.pid > 0 && app.pid != MY_PID) { 18333 app.kill("empty", false); 18334 } else { 18335 try { 18336 app.thread.scheduleExit(); 18337 } catch (Exception e) { 18338 // Ignore exceptions. 18339 } 18340 } 18341 cleanUpApplicationRecordLocked(app, false, true, -1); 18342 mRemovedProcesses.remove(i); 18343 18344 if (app.persistent) { 18345 addAppLocked(app.info, false, null /* ABI override */); 18346 } 18347 } 18348 } 18349 18350 // Now update the oom adj for all processes. 18351 updateOomAdjLocked(); 18352 } 18353 } 18354 18355 /** This method sends the specified signal to each of the persistent apps */ 18356 public void signalPersistentProcesses(int sig) throws RemoteException { 18357 if (sig != Process.SIGNAL_USR1) { 18358 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18359 } 18360 18361 synchronized (this) { 18362 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18363 != PackageManager.PERMISSION_GRANTED) { 18364 throw new SecurityException("Requires permission " 18365 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18366 } 18367 18368 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18369 ProcessRecord r = mLruProcesses.get(i); 18370 if (r.thread != null && r.persistent) { 18371 Process.sendSignal(r.pid, sig); 18372 } 18373 } 18374 } 18375 } 18376 18377 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18378 if (proc == null || proc == mProfileProc) { 18379 proc = mProfileProc; 18380 profileType = mProfileType; 18381 clearProfilerLocked(); 18382 } 18383 if (proc == null) { 18384 return; 18385 } 18386 try { 18387 proc.thread.profilerControl(false, null, profileType); 18388 } catch (RemoteException e) { 18389 throw new IllegalStateException("Process disappeared"); 18390 } 18391 } 18392 18393 private void clearProfilerLocked() { 18394 if (mProfileFd != null) { 18395 try { 18396 mProfileFd.close(); 18397 } catch (IOException e) { 18398 } 18399 } 18400 mProfileApp = null; 18401 mProfileProc = null; 18402 mProfileFile = null; 18403 mProfileType = 0; 18404 mAutoStopProfiler = false; 18405 mSamplingInterval = 0; 18406 } 18407 18408 public boolean profileControl(String process, int userId, boolean start, 18409 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18410 18411 try { 18412 synchronized (this) { 18413 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18414 // its own permission. 18415 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18416 != PackageManager.PERMISSION_GRANTED) { 18417 throw new SecurityException("Requires permission " 18418 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18419 } 18420 18421 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18422 throw new IllegalArgumentException("null profile info or fd"); 18423 } 18424 18425 ProcessRecord proc = null; 18426 if (process != null) { 18427 proc = findProcessLocked(process, userId, "profileControl"); 18428 } 18429 18430 if (start && (proc == null || proc.thread == null)) { 18431 throw new IllegalArgumentException("Unknown process: " + process); 18432 } 18433 18434 if (start) { 18435 stopProfilerLocked(null, 0); 18436 setProfileApp(proc.info, proc.processName, profilerInfo); 18437 mProfileProc = proc; 18438 mProfileType = profileType; 18439 ParcelFileDescriptor fd = profilerInfo.profileFd; 18440 try { 18441 fd = fd.dup(); 18442 } catch (IOException e) { 18443 fd = null; 18444 } 18445 profilerInfo.profileFd = fd; 18446 proc.thread.profilerControl(start, profilerInfo, profileType); 18447 fd = null; 18448 mProfileFd = null; 18449 } else { 18450 stopProfilerLocked(proc, profileType); 18451 if (profilerInfo != null && profilerInfo.profileFd != null) { 18452 try { 18453 profilerInfo.profileFd.close(); 18454 } catch (IOException e) { 18455 } 18456 } 18457 } 18458 18459 return true; 18460 } 18461 } catch (RemoteException e) { 18462 throw new IllegalStateException("Process disappeared"); 18463 } finally { 18464 if (profilerInfo != null && profilerInfo.profileFd != null) { 18465 try { 18466 profilerInfo.profileFd.close(); 18467 } catch (IOException e) { 18468 } 18469 } 18470 } 18471 } 18472 18473 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18474 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18475 userId, true, ALLOW_FULL_ONLY, callName, null); 18476 ProcessRecord proc = null; 18477 try { 18478 int pid = Integer.parseInt(process); 18479 synchronized (mPidsSelfLocked) { 18480 proc = mPidsSelfLocked.get(pid); 18481 } 18482 } catch (NumberFormatException e) { 18483 } 18484 18485 if (proc == null) { 18486 ArrayMap<String, SparseArray<ProcessRecord>> all 18487 = mProcessNames.getMap(); 18488 SparseArray<ProcessRecord> procs = all.get(process); 18489 if (procs != null && procs.size() > 0) { 18490 proc = procs.valueAt(0); 18491 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18492 for (int i=1; i<procs.size(); i++) { 18493 ProcessRecord thisProc = procs.valueAt(i); 18494 if (thisProc.userId == userId) { 18495 proc = thisProc; 18496 break; 18497 } 18498 } 18499 } 18500 } 18501 } 18502 18503 return proc; 18504 } 18505 18506 public boolean dumpHeap(String process, int userId, boolean managed, 18507 String path, ParcelFileDescriptor fd) throws RemoteException { 18508 18509 try { 18510 synchronized (this) { 18511 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18512 // its own permission (same as profileControl). 18513 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18514 != PackageManager.PERMISSION_GRANTED) { 18515 throw new SecurityException("Requires permission " 18516 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18517 } 18518 18519 if (fd == null) { 18520 throw new IllegalArgumentException("null fd"); 18521 } 18522 18523 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18524 if (proc == null || proc.thread == null) { 18525 throw new IllegalArgumentException("Unknown process: " + process); 18526 } 18527 18528 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18529 if (!isDebuggable) { 18530 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18531 throw new SecurityException("Process not debuggable: " + proc); 18532 } 18533 } 18534 18535 proc.thread.dumpHeap(managed, path, fd); 18536 fd = null; 18537 return true; 18538 } 18539 } catch (RemoteException e) { 18540 throw new IllegalStateException("Process disappeared"); 18541 } finally { 18542 if (fd != null) { 18543 try { 18544 fd.close(); 18545 } catch (IOException e) { 18546 } 18547 } 18548 } 18549 } 18550 18551 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18552 public void monitor() { 18553 synchronized (this) { } 18554 } 18555 18556 void onCoreSettingsChange(Bundle settings) { 18557 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18558 ProcessRecord processRecord = mLruProcesses.get(i); 18559 try { 18560 if (processRecord.thread != null) { 18561 processRecord.thread.setCoreSettings(settings); 18562 } 18563 } catch (RemoteException re) { 18564 /* ignore */ 18565 } 18566 } 18567 } 18568 18569 // Multi-user methods 18570 18571 /** 18572 * Start user, if its not already running, but don't bring it to foreground. 18573 */ 18574 @Override 18575 public boolean startUserInBackground(final int userId) { 18576 return startUser(userId, /* foreground */ false); 18577 } 18578 18579 /** 18580 * Start user, if its not already running, and bring it to foreground. 18581 */ 18582 boolean startUserInForeground(final int userId, Dialog dlg) { 18583 boolean result = startUser(userId, /* foreground */ true); 18584 dlg.dismiss(); 18585 return result; 18586 } 18587 18588 /** 18589 * Refreshes the list of users related to the current user when either a 18590 * user switch happens or when a new related user is started in the 18591 * background. 18592 */ 18593 private void updateCurrentProfileIdsLocked() { 18594 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18595 mCurrentUserId, false /* enabledOnly */); 18596 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18597 for (int i = 0; i < currentProfileIds.length; i++) { 18598 currentProfileIds[i] = profiles.get(i).id; 18599 } 18600 mCurrentProfileIds = currentProfileIds; 18601 18602 synchronized (mUserProfileGroupIdsSelfLocked) { 18603 mUserProfileGroupIdsSelfLocked.clear(); 18604 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18605 for (int i = 0; i < users.size(); i++) { 18606 UserInfo user = users.get(i); 18607 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18608 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18609 } 18610 } 18611 } 18612 } 18613 18614 private Set getProfileIdsLocked(int userId) { 18615 Set userIds = new HashSet<Integer>(); 18616 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18617 userId, false /* enabledOnly */); 18618 for (UserInfo user : profiles) { 18619 userIds.add(Integer.valueOf(user.id)); 18620 } 18621 return userIds; 18622 } 18623 18624 @Override 18625 public boolean switchUser(final int userId) { 18626 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18627 String userName; 18628 synchronized (this) { 18629 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18630 if (userInfo == null) { 18631 Slog.w(TAG, "No user info for user #" + userId); 18632 return false; 18633 } 18634 if (userInfo.isManagedProfile()) { 18635 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18636 return false; 18637 } 18638 userName = userInfo.name; 18639 mTargetUserId = userId; 18640 } 18641 mHandler.removeMessages(START_USER_SWITCH_MSG); 18642 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18643 return true; 18644 } 18645 18646 private void showUserSwitchDialog(int userId, String userName) { 18647 // The dialog will show and then initiate the user switch by calling startUserInForeground 18648 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18649 true /* above system */); 18650 d.show(); 18651 } 18652 18653 private boolean startUser(final int userId, final boolean foreground) { 18654 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18655 != PackageManager.PERMISSION_GRANTED) { 18656 String msg = "Permission Denial: switchUser() from pid=" 18657 + Binder.getCallingPid() 18658 + ", uid=" + Binder.getCallingUid() 18659 + " requires " + INTERACT_ACROSS_USERS_FULL; 18660 Slog.w(TAG, msg); 18661 throw new SecurityException(msg); 18662 } 18663 18664 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18665 18666 final long ident = Binder.clearCallingIdentity(); 18667 try { 18668 synchronized (this) { 18669 final int oldUserId = mCurrentUserId; 18670 if (oldUserId == userId) { 18671 return true; 18672 } 18673 18674 mStackSupervisor.setLockTaskModeLocked(null, false); 18675 18676 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18677 if (userInfo == null) { 18678 Slog.w(TAG, "No user info for user #" + userId); 18679 return false; 18680 } 18681 if (foreground && userInfo.isManagedProfile()) { 18682 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18683 return false; 18684 } 18685 18686 if (foreground) { 18687 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18688 R.anim.screen_user_enter); 18689 } 18690 18691 boolean needStart = false; 18692 18693 // If the user we are switching to is not currently started, then 18694 // we need to start it now. 18695 if (mStartedUsers.get(userId) == null) { 18696 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18697 updateStartedUserArrayLocked(); 18698 needStart = true; 18699 } 18700 18701 final Integer userIdInt = Integer.valueOf(userId); 18702 mUserLru.remove(userIdInt); 18703 mUserLru.add(userIdInt); 18704 18705 if (foreground) { 18706 mCurrentUserId = userId; 18707 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18708 updateCurrentProfileIdsLocked(); 18709 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18710 // Once the internal notion of the active user has switched, we lock the device 18711 // with the option to show the user switcher on the keyguard. 18712 mWindowManager.lockNow(null); 18713 } else { 18714 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18715 updateCurrentProfileIdsLocked(); 18716 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18717 mUserLru.remove(currentUserIdInt); 18718 mUserLru.add(currentUserIdInt); 18719 } 18720 18721 final UserStartedState uss = mStartedUsers.get(userId); 18722 18723 // Make sure user is in the started state. If it is currently 18724 // stopping, we need to knock that off. 18725 if (uss.mState == UserStartedState.STATE_STOPPING) { 18726 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18727 // so we can just fairly silently bring the user back from 18728 // the almost-dead. 18729 uss.mState = UserStartedState.STATE_RUNNING; 18730 updateStartedUserArrayLocked(); 18731 needStart = true; 18732 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18733 // This means ACTION_SHUTDOWN has been sent, so we will 18734 // need to treat this as a new boot of the user. 18735 uss.mState = UserStartedState.STATE_BOOTING; 18736 updateStartedUserArrayLocked(); 18737 needStart = true; 18738 } 18739 18740 if (uss.mState == UserStartedState.STATE_BOOTING) { 18741 // Booting up a new user, need to tell system services about it. 18742 // Note that this is on the same handler as scheduling of broadcasts, 18743 // which is important because it needs to go first. 18744 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18745 } 18746 18747 if (foreground) { 18748 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18749 oldUserId)); 18750 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18751 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18752 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18753 oldUserId, userId, uss)); 18754 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18755 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18756 } 18757 18758 if (needStart) { 18759 // Send USER_STARTED broadcast 18760 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18761 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18762 | Intent.FLAG_RECEIVER_FOREGROUND); 18763 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18764 broadcastIntentLocked(null, null, intent, 18765 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18766 false, false, MY_PID, Process.SYSTEM_UID, userId); 18767 } 18768 18769 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18770 if (userId != UserHandle.USER_OWNER) { 18771 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18772 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18773 broadcastIntentLocked(null, null, intent, null, 18774 new IIntentReceiver.Stub() { 18775 public void performReceive(Intent intent, int resultCode, 18776 String data, Bundle extras, boolean ordered, 18777 boolean sticky, int sendingUser) { 18778 onUserInitialized(uss, foreground, oldUserId, userId); 18779 } 18780 }, 0, null, null, null, AppOpsManager.OP_NONE, 18781 true, false, MY_PID, Process.SYSTEM_UID, 18782 userId); 18783 uss.initializing = true; 18784 } else { 18785 getUserManagerLocked().makeInitialized(userInfo.id); 18786 } 18787 } 18788 18789 if (foreground) { 18790 if (!uss.initializing) { 18791 moveUserToForeground(uss, oldUserId, userId); 18792 } 18793 } else { 18794 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18795 } 18796 18797 if (needStart) { 18798 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18799 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18800 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18801 broadcastIntentLocked(null, null, intent, 18802 null, new IIntentReceiver.Stub() { 18803 @Override 18804 public void performReceive(Intent intent, int resultCode, String data, 18805 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18806 throws RemoteException { 18807 } 18808 }, 0, null, null, 18809 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18810 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18811 } 18812 } 18813 } finally { 18814 Binder.restoreCallingIdentity(ident); 18815 } 18816 18817 return true; 18818 } 18819 18820 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18821 long ident = Binder.clearCallingIdentity(); 18822 try { 18823 Intent intent; 18824 if (oldUserId >= 0) { 18825 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18826 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18827 int count = profiles.size(); 18828 for (int i = 0; i < count; i++) { 18829 int profileUserId = profiles.get(i).id; 18830 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18831 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18832 | Intent.FLAG_RECEIVER_FOREGROUND); 18833 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18834 broadcastIntentLocked(null, null, intent, 18835 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18836 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18837 } 18838 } 18839 if (newUserId >= 0) { 18840 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18841 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18842 int count = profiles.size(); 18843 for (int i = 0; i < count; i++) { 18844 int profileUserId = profiles.get(i).id; 18845 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18846 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18847 | Intent.FLAG_RECEIVER_FOREGROUND); 18848 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18849 broadcastIntentLocked(null, null, intent, 18850 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18851 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18852 } 18853 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18854 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18855 | Intent.FLAG_RECEIVER_FOREGROUND); 18856 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18857 broadcastIntentLocked(null, null, intent, 18858 null, null, 0, null, null, 18859 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18860 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18861 } 18862 } finally { 18863 Binder.restoreCallingIdentity(ident); 18864 } 18865 } 18866 18867 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18868 final int newUserId) { 18869 final int N = mUserSwitchObservers.beginBroadcast(); 18870 if (N > 0) { 18871 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18872 int mCount = 0; 18873 @Override 18874 public void sendResult(Bundle data) throws RemoteException { 18875 synchronized (ActivityManagerService.this) { 18876 if (mCurUserSwitchCallback == this) { 18877 mCount++; 18878 if (mCount == N) { 18879 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18880 } 18881 } 18882 } 18883 } 18884 }; 18885 synchronized (this) { 18886 uss.switching = true; 18887 mCurUserSwitchCallback = callback; 18888 } 18889 for (int i=0; i<N; i++) { 18890 try { 18891 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18892 newUserId, callback); 18893 } catch (RemoteException e) { 18894 } 18895 } 18896 } else { 18897 synchronized (this) { 18898 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18899 } 18900 } 18901 mUserSwitchObservers.finishBroadcast(); 18902 } 18903 18904 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18905 synchronized (this) { 18906 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18907 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18908 } 18909 } 18910 18911 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18912 mCurUserSwitchCallback = null; 18913 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18914 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18915 oldUserId, newUserId, uss)); 18916 } 18917 18918 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18919 synchronized (this) { 18920 if (foreground) { 18921 moveUserToForeground(uss, oldUserId, newUserId); 18922 } 18923 } 18924 18925 completeSwitchAndInitalize(uss, newUserId, true, false); 18926 } 18927 18928 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18929 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18930 if (homeInFront) { 18931 startHomeActivityLocked(newUserId); 18932 } else { 18933 mStackSupervisor.resumeTopActivitiesLocked(); 18934 } 18935 EventLogTags.writeAmSwitchUser(newUserId); 18936 getUserManagerLocked().userForeground(newUserId); 18937 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18938 } 18939 18940 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18941 completeSwitchAndInitalize(uss, newUserId, false, true); 18942 } 18943 18944 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18945 boolean clearInitializing, boolean clearSwitching) { 18946 boolean unfrozen = false; 18947 synchronized (this) { 18948 if (clearInitializing) { 18949 uss.initializing = false; 18950 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18951 } 18952 if (clearSwitching) { 18953 uss.switching = false; 18954 } 18955 if (!uss.switching && !uss.initializing) { 18956 mWindowManager.stopFreezingScreen(); 18957 unfrozen = true; 18958 } 18959 } 18960 if (unfrozen) { 18961 final int N = mUserSwitchObservers.beginBroadcast(); 18962 for (int i=0; i<N; i++) { 18963 try { 18964 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18965 } catch (RemoteException e) { 18966 } 18967 } 18968 mUserSwitchObservers.finishBroadcast(); 18969 } 18970 } 18971 18972 void scheduleStartProfilesLocked() { 18973 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18974 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18975 DateUtils.SECOND_IN_MILLIS); 18976 } 18977 } 18978 18979 void startProfilesLocked() { 18980 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18981 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18982 mCurrentUserId, false /* enabledOnly */); 18983 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18984 for (UserInfo user : profiles) { 18985 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18986 && user.id != mCurrentUserId) { 18987 toStart.add(user); 18988 } 18989 } 18990 final int n = toStart.size(); 18991 int i = 0; 18992 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18993 startUserInBackground(toStart.get(i).id); 18994 } 18995 if (i < n) { 18996 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18997 } 18998 } 18999 19000 void finishUserBoot(UserStartedState uss) { 19001 synchronized (this) { 19002 if (uss.mState == UserStartedState.STATE_BOOTING 19003 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19004 uss.mState = UserStartedState.STATE_RUNNING; 19005 final int userId = uss.mHandle.getIdentifier(); 19006 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19007 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19008 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19009 broadcastIntentLocked(null, null, intent, 19010 null, null, 0, null, null, 19011 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19012 true, false, MY_PID, Process.SYSTEM_UID, userId); 19013 } 19014 } 19015 } 19016 19017 void finishUserSwitch(UserStartedState uss) { 19018 synchronized (this) { 19019 finishUserBoot(uss); 19020 19021 startProfilesLocked(); 19022 19023 int num = mUserLru.size(); 19024 int i = 0; 19025 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19026 Integer oldUserId = mUserLru.get(i); 19027 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19028 if (oldUss == null) { 19029 // Shouldn't happen, but be sane if it does. 19030 mUserLru.remove(i); 19031 num--; 19032 continue; 19033 } 19034 if (oldUss.mState == UserStartedState.STATE_STOPPING 19035 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19036 // This user is already stopping, doesn't count. 19037 num--; 19038 i++; 19039 continue; 19040 } 19041 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19042 // Owner and current can't be stopped, but count as running. 19043 i++; 19044 continue; 19045 } 19046 // This is a user to be stopped. 19047 stopUserLocked(oldUserId, null); 19048 num--; 19049 i++; 19050 } 19051 } 19052 } 19053 19054 @Override 19055 public int stopUser(final int userId, final IStopUserCallback callback) { 19056 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19057 != PackageManager.PERMISSION_GRANTED) { 19058 String msg = "Permission Denial: switchUser() from pid=" 19059 + Binder.getCallingPid() 19060 + ", uid=" + Binder.getCallingUid() 19061 + " requires " + INTERACT_ACROSS_USERS_FULL; 19062 Slog.w(TAG, msg); 19063 throw new SecurityException(msg); 19064 } 19065 if (userId <= 0) { 19066 throw new IllegalArgumentException("Can't stop primary user " + userId); 19067 } 19068 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19069 synchronized (this) { 19070 return stopUserLocked(userId, callback); 19071 } 19072 } 19073 19074 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19075 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19076 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19077 return ActivityManager.USER_OP_IS_CURRENT; 19078 } 19079 19080 final UserStartedState uss = mStartedUsers.get(userId); 19081 if (uss == null) { 19082 // User is not started, nothing to do... but we do need to 19083 // callback if requested. 19084 if (callback != null) { 19085 mHandler.post(new Runnable() { 19086 @Override 19087 public void run() { 19088 try { 19089 callback.userStopped(userId); 19090 } catch (RemoteException e) { 19091 } 19092 } 19093 }); 19094 } 19095 return ActivityManager.USER_OP_SUCCESS; 19096 } 19097 19098 if (callback != null) { 19099 uss.mStopCallbacks.add(callback); 19100 } 19101 19102 if (uss.mState != UserStartedState.STATE_STOPPING 19103 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19104 uss.mState = UserStartedState.STATE_STOPPING; 19105 updateStartedUserArrayLocked(); 19106 19107 long ident = Binder.clearCallingIdentity(); 19108 try { 19109 // We are going to broadcast ACTION_USER_STOPPING and then 19110 // once that is done send a final ACTION_SHUTDOWN and then 19111 // stop the user. 19112 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19113 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19114 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19115 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19116 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19117 // This is the result receiver for the final shutdown broadcast. 19118 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19119 @Override 19120 public void performReceive(Intent intent, int resultCode, String data, 19121 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19122 finishUserStop(uss); 19123 } 19124 }; 19125 // This is the result receiver for the initial stopping broadcast. 19126 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19127 @Override 19128 public void performReceive(Intent intent, int resultCode, String data, 19129 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19130 // On to the next. 19131 synchronized (ActivityManagerService.this) { 19132 if (uss.mState != UserStartedState.STATE_STOPPING) { 19133 // Whoops, we are being started back up. Abort, abort! 19134 return; 19135 } 19136 uss.mState = UserStartedState.STATE_SHUTDOWN; 19137 } 19138 mBatteryStatsService.noteEvent( 19139 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19140 Integer.toString(userId), userId); 19141 mSystemServiceManager.stopUser(userId); 19142 broadcastIntentLocked(null, null, shutdownIntent, 19143 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19144 true, false, MY_PID, Process.SYSTEM_UID, userId); 19145 } 19146 }; 19147 // Kick things off. 19148 broadcastIntentLocked(null, null, stoppingIntent, 19149 null, stoppingReceiver, 0, null, null, 19150 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19151 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19152 } finally { 19153 Binder.restoreCallingIdentity(ident); 19154 } 19155 } 19156 19157 return ActivityManager.USER_OP_SUCCESS; 19158 } 19159 19160 void finishUserStop(UserStartedState uss) { 19161 final int userId = uss.mHandle.getIdentifier(); 19162 boolean stopped; 19163 ArrayList<IStopUserCallback> callbacks; 19164 synchronized (this) { 19165 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19166 if (mStartedUsers.get(userId) != uss) { 19167 stopped = false; 19168 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19169 stopped = false; 19170 } else { 19171 stopped = true; 19172 // User can no longer run. 19173 mStartedUsers.remove(userId); 19174 mUserLru.remove(Integer.valueOf(userId)); 19175 updateStartedUserArrayLocked(); 19176 19177 // Clean up all state and processes associated with the user. 19178 // Kill all the processes for the user. 19179 forceStopUserLocked(userId, "finish user"); 19180 } 19181 19182 // Explicitly remove the old information in mRecentTasks. 19183 removeRecentTasksForUserLocked(userId); 19184 } 19185 19186 for (int i=0; i<callbacks.size(); i++) { 19187 try { 19188 if (stopped) callbacks.get(i).userStopped(userId); 19189 else callbacks.get(i).userStopAborted(userId); 19190 } catch (RemoteException e) { 19191 } 19192 } 19193 19194 if (stopped) { 19195 mSystemServiceManager.cleanupUser(userId); 19196 synchronized (this) { 19197 mStackSupervisor.removeUserLocked(userId); 19198 } 19199 } 19200 } 19201 19202 @Override 19203 public UserInfo getCurrentUser() { 19204 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19205 != PackageManager.PERMISSION_GRANTED) && ( 19206 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19207 != PackageManager.PERMISSION_GRANTED)) { 19208 String msg = "Permission Denial: getCurrentUser() from pid=" 19209 + Binder.getCallingPid() 19210 + ", uid=" + Binder.getCallingUid() 19211 + " requires " + INTERACT_ACROSS_USERS; 19212 Slog.w(TAG, msg); 19213 throw new SecurityException(msg); 19214 } 19215 synchronized (this) { 19216 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19217 return getUserManagerLocked().getUserInfo(userId); 19218 } 19219 } 19220 19221 int getCurrentUserIdLocked() { 19222 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19223 } 19224 19225 @Override 19226 public boolean isUserRunning(int userId, boolean orStopped) { 19227 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19228 != PackageManager.PERMISSION_GRANTED) { 19229 String msg = "Permission Denial: isUserRunning() from pid=" 19230 + Binder.getCallingPid() 19231 + ", uid=" + Binder.getCallingUid() 19232 + " requires " + INTERACT_ACROSS_USERS; 19233 Slog.w(TAG, msg); 19234 throw new SecurityException(msg); 19235 } 19236 synchronized (this) { 19237 return isUserRunningLocked(userId, orStopped); 19238 } 19239 } 19240 19241 boolean isUserRunningLocked(int userId, boolean orStopped) { 19242 UserStartedState state = mStartedUsers.get(userId); 19243 if (state == null) { 19244 return false; 19245 } 19246 if (orStopped) { 19247 return true; 19248 } 19249 return state.mState != UserStartedState.STATE_STOPPING 19250 && state.mState != UserStartedState.STATE_SHUTDOWN; 19251 } 19252 19253 @Override 19254 public int[] getRunningUserIds() { 19255 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19256 != PackageManager.PERMISSION_GRANTED) { 19257 String msg = "Permission Denial: isUserRunning() from pid=" 19258 + Binder.getCallingPid() 19259 + ", uid=" + Binder.getCallingUid() 19260 + " requires " + INTERACT_ACROSS_USERS; 19261 Slog.w(TAG, msg); 19262 throw new SecurityException(msg); 19263 } 19264 synchronized (this) { 19265 return mStartedUserArray; 19266 } 19267 } 19268 19269 private void updateStartedUserArrayLocked() { 19270 int num = 0; 19271 for (int i=0; i<mStartedUsers.size(); i++) { 19272 UserStartedState uss = mStartedUsers.valueAt(i); 19273 // This list does not include stopping users. 19274 if (uss.mState != UserStartedState.STATE_STOPPING 19275 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19276 num++; 19277 } 19278 } 19279 mStartedUserArray = new int[num]; 19280 num = 0; 19281 for (int i=0; i<mStartedUsers.size(); i++) { 19282 UserStartedState uss = mStartedUsers.valueAt(i); 19283 if (uss.mState != UserStartedState.STATE_STOPPING 19284 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19285 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19286 num++; 19287 } 19288 } 19289 } 19290 19291 @Override 19292 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19293 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19294 != PackageManager.PERMISSION_GRANTED) { 19295 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19296 + Binder.getCallingPid() 19297 + ", uid=" + Binder.getCallingUid() 19298 + " requires " + INTERACT_ACROSS_USERS_FULL; 19299 Slog.w(TAG, msg); 19300 throw new SecurityException(msg); 19301 } 19302 19303 mUserSwitchObservers.register(observer); 19304 } 19305 19306 @Override 19307 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19308 mUserSwitchObservers.unregister(observer); 19309 } 19310 19311 private boolean userExists(int userId) { 19312 if (userId == 0) { 19313 return true; 19314 } 19315 UserManagerService ums = getUserManagerLocked(); 19316 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19317 } 19318 19319 int[] getUsersLocked() { 19320 UserManagerService ums = getUserManagerLocked(); 19321 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19322 } 19323 19324 UserManagerService getUserManagerLocked() { 19325 if (mUserManager == null) { 19326 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19327 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19328 } 19329 return mUserManager; 19330 } 19331 19332 private int applyUserId(int uid, int userId) { 19333 return UserHandle.getUid(userId, uid); 19334 } 19335 19336 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19337 if (info == null) return null; 19338 ApplicationInfo newInfo = new ApplicationInfo(info); 19339 newInfo.uid = applyUserId(info.uid, userId); 19340 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19341 + info.packageName; 19342 return newInfo; 19343 } 19344 19345 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19346 if (aInfo == null 19347 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19348 return aInfo; 19349 } 19350 19351 ActivityInfo info = new ActivityInfo(aInfo); 19352 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19353 return info; 19354 } 19355 19356 private final class LocalService extends ActivityManagerInternal { 19357 @Override 19358 public void onWakefulnessChanged(int wakefulness) { 19359 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19360 } 19361 19362 @Override 19363 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19364 String processName, String abiOverride, int uid, Runnable crashHandler) { 19365 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19366 processName, abiOverride, uid, crashHandler); 19367 } 19368 } 19369 19370 /** 19371 * An implementation of IAppTask, that allows an app to manage its own tasks via 19372 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19373 * only the process that calls getAppTasks() can call the AppTask methods. 19374 */ 19375 class AppTaskImpl extends IAppTask.Stub { 19376 private int mTaskId; 19377 private int mCallingUid; 19378 19379 public AppTaskImpl(int taskId, int callingUid) { 19380 mTaskId = taskId; 19381 mCallingUid = callingUid; 19382 } 19383 19384 private void checkCaller() { 19385 if (mCallingUid != Binder.getCallingUid()) { 19386 throw new SecurityException("Caller " + mCallingUid 19387 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19388 } 19389 } 19390 19391 @Override 19392 public void finishAndRemoveTask() { 19393 checkCaller(); 19394 19395 synchronized (ActivityManagerService.this) { 19396 long origId = Binder.clearCallingIdentity(); 19397 try { 19398 if (!removeTaskByIdLocked(mTaskId, false)) { 19399 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19400 } 19401 } finally { 19402 Binder.restoreCallingIdentity(origId); 19403 } 19404 } 19405 } 19406 19407 @Override 19408 public ActivityManager.RecentTaskInfo getTaskInfo() { 19409 checkCaller(); 19410 19411 synchronized (ActivityManagerService.this) { 19412 long origId = Binder.clearCallingIdentity(); 19413 try { 19414 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19415 if (tr == null) { 19416 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19417 } 19418 return createRecentTaskInfoFromTaskRecord(tr); 19419 } finally { 19420 Binder.restoreCallingIdentity(origId); 19421 } 19422 } 19423 } 19424 19425 @Override 19426 public void moveToFront() { 19427 checkCaller(); 19428 19429 final TaskRecord tr; 19430 synchronized (ActivityManagerService.this) { 19431 tr = recentTaskForIdLocked(mTaskId); 19432 if (tr == null) { 19433 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19434 } 19435 if (tr.getRootActivity() != null) { 19436 moveTaskToFrontLocked(tr.taskId, 0, null); 19437 return; 19438 } 19439 } 19440 19441 startActivityFromRecentsInner(tr.taskId, null); 19442 } 19443 19444 @Override 19445 public int startActivity(IBinder whoThread, String callingPackage, 19446 Intent intent, String resolvedType, Bundle options) { 19447 checkCaller(); 19448 19449 int callingUser = UserHandle.getCallingUserId(); 19450 TaskRecord tr; 19451 IApplicationThread appThread; 19452 synchronized (ActivityManagerService.this) { 19453 tr = recentTaskForIdLocked(mTaskId); 19454 if (tr == null) { 19455 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19456 } 19457 appThread = ApplicationThreadNative.asInterface(whoThread); 19458 if (appThread == null) { 19459 throw new IllegalArgumentException("Bad app thread " + appThread); 19460 } 19461 } 19462 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19463 resolvedType, null, null, null, null, 0, 0, null, null, 19464 null, options, callingUser, null, tr); 19465 } 19466 19467 @Override 19468 public void setExcludeFromRecents(boolean exclude) { 19469 checkCaller(); 19470 19471 synchronized (ActivityManagerService.this) { 19472 long origId = Binder.clearCallingIdentity(); 19473 try { 19474 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19475 if (tr == null) { 19476 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19477 } 19478 Intent intent = tr.getBaseIntent(); 19479 if (exclude) { 19480 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19481 } else { 19482 intent.setFlags(intent.getFlags() 19483 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19484 } 19485 } finally { 19486 Binder.restoreCallingIdentity(origId); 19487 } 19488 } 19489 } 19490 } 19491} 19492