ActivityManagerService.java revision 1e01d16982e6b22ec4c0e2d6dc1e261eb6f92c8e
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 String mDebugApp = null; 1079 boolean mWaitForDebugger = false; 1080 boolean mDebugTransient = false; 1081 String mOrigDebugApp = null; 1082 boolean mOrigWaitForDebugger = false; 1083 boolean mAlwaysFinishActivities = false; 1084 IActivityController mController = null; 1085 String mProfileApp = null; 1086 ProcessRecord mProfileProc = null; 1087 String mProfileFile; 1088 ParcelFileDescriptor mProfileFd; 1089 int mSamplingInterval = 0; 1090 boolean mAutoStopProfiler = false; 1091 int mProfileType = 0; 1092 String mOpenGlTraceApp = null; 1093 1094 static class ProcessChangeItem { 1095 static final int CHANGE_ACTIVITIES = 1<<0; 1096 static final int CHANGE_PROCESS_STATE = 1<<1; 1097 int changes; 1098 int uid; 1099 int pid; 1100 int processState; 1101 boolean foregroundActivities; 1102 } 1103 1104 final RemoteCallbackList<IProcessObserver> mProcessObservers 1105 = new RemoteCallbackList<IProcessObserver>(); 1106 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1107 1108 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1109 = new ArrayList<ProcessChangeItem>(); 1110 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1111 = new ArrayList<ProcessChangeItem>(); 1112 1113 /** 1114 * Runtime CPU use collection thread. This object's lock is used to 1115 * perform synchronization with the thread (notifying it to run). 1116 */ 1117 final Thread mProcessCpuThread; 1118 1119 /** 1120 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1121 * Must acquire this object's lock when accessing it. 1122 * NOTE: this lock will be held while doing long operations (trawling 1123 * through all processes in /proc), so it should never be acquired by 1124 * any critical paths such as when holding the main activity manager lock. 1125 */ 1126 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1127 MONITOR_THREAD_CPU_USAGE); 1128 final AtomicLong mLastCpuTime = new AtomicLong(0); 1129 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1130 1131 long mLastWriteTime = 0; 1132 1133 /** 1134 * Used to retain an update lock when the foreground activity is in 1135 * immersive mode. 1136 */ 1137 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1138 1139 /** 1140 * Set to true after the system has finished booting. 1141 */ 1142 boolean mBooted = false; 1143 1144 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1145 int mProcessLimitOverride = -1; 1146 1147 WindowManagerService mWindowManager; 1148 1149 final ActivityThread mSystemThread; 1150 1151 // Holds the current foreground user's id 1152 int mCurrentUserId = 0; 1153 // Holds the target user's id during a user switch 1154 int mTargetUserId = UserHandle.USER_NULL; 1155 // If there are multiple profiles for the current user, their ids are here 1156 // Currently only the primary user can have managed profiles 1157 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1158 1159 /** 1160 * Mapping from each known user ID to the profile group ID it is associated with. 1161 */ 1162 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1163 1164 private UserManagerService mUserManager; 1165 1166 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1167 final ProcessRecord mApp; 1168 final int mPid; 1169 final IApplicationThread mAppThread; 1170 1171 AppDeathRecipient(ProcessRecord app, int pid, 1172 IApplicationThread thread) { 1173 if (localLOGV) Slog.v( 1174 TAG, "New death recipient " + this 1175 + " for thread " + thread.asBinder()); 1176 mApp = app; 1177 mPid = pid; 1178 mAppThread = thread; 1179 } 1180 1181 @Override 1182 public void binderDied() { 1183 if (localLOGV) Slog.v( 1184 TAG, "Death received in " + this 1185 + " for thread " + mAppThread.asBinder()); 1186 synchronized(ActivityManagerService.this) { 1187 appDiedLocked(mApp, mPid, mAppThread); 1188 } 1189 } 1190 } 1191 1192 static final int SHOW_ERROR_MSG = 1; 1193 static final int SHOW_NOT_RESPONDING_MSG = 2; 1194 static final int SHOW_FACTORY_ERROR_MSG = 3; 1195 static final int UPDATE_CONFIGURATION_MSG = 4; 1196 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1197 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1198 static final int SERVICE_TIMEOUT_MSG = 12; 1199 static final int UPDATE_TIME_ZONE = 13; 1200 static final int SHOW_UID_ERROR_MSG = 14; 1201 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1202 static final int PROC_START_TIMEOUT_MSG = 20; 1203 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1204 static final int KILL_APPLICATION_MSG = 22; 1205 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1206 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1207 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1208 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1209 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1210 static final int CLEAR_DNS_CACHE_MSG = 28; 1211 static final int UPDATE_HTTP_PROXY_MSG = 29; 1212 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1213 static final int DISPATCH_PROCESSES_CHANGED = 31; 1214 static final int DISPATCH_PROCESS_DIED = 32; 1215 static final int REPORT_MEM_USAGE_MSG = 33; 1216 static final int REPORT_USER_SWITCH_MSG = 34; 1217 static final int CONTINUE_USER_SWITCH_MSG = 35; 1218 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1219 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1220 static final int PERSIST_URI_GRANTS_MSG = 38; 1221 static final int REQUEST_ALL_PSS_MSG = 39; 1222 static final int START_PROFILES_MSG = 40; 1223 static final int UPDATE_TIME = 41; 1224 static final int SYSTEM_USER_START_MSG = 42; 1225 static final int SYSTEM_USER_CURRENT_MSG = 43; 1226 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1227 static final int FINISH_BOOTING_MSG = 45; 1228 static final int START_USER_SWITCH_MSG = 46; 1229 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1230 static final int DISMISS_DIALOG_MSG = 48; 1231 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1232 1233 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1234 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1235 static final int FIRST_COMPAT_MODE_MSG = 300; 1236 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1237 1238 CompatModeDialog mCompatModeDialog; 1239 long mLastMemUsageReportTime = 0; 1240 1241 /** 1242 * Flag whether the current user is a "monkey", i.e. whether 1243 * the UI is driven by a UI automation tool. 1244 */ 1245 private boolean mUserIsMonkey; 1246 1247 /** Flag whether the device has a Recents UI */ 1248 boolean mHasRecents; 1249 1250 /** The dimensions of the thumbnails in the Recents UI. */ 1251 int mThumbnailWidth; 1252 int mThumbnailHeight; 1253 1254 final ServiceThread mHandlerThread; 1255 final MainHandler mHandler; 1256 1257 final class MainHandler extends Handler { 1258 public MainHandler(Looper looper) { 1259 super(looper, null, true); 1260 } 1261 1262 @Override 1263 public void handleMessage(Message msg) { 1264 switch (msg.what) { 1265 case SHOW_ERROR_MSG: { 1266 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1267 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1268 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1269 synchronized (ActivityManagerService.this) { 1270 ProcessRecord proc = (ProcessRecord)data.get("app"); 1271 AppErrorResult res = (AppErrorResult) data.get("result"); 1272 if (proc != null && proc.crashDialog != null) { 1273 Slog.e(TAG, "App already has crash dialog: " + proc); 1274 if (res != null) { 1275 res.set(0); 1276 } 1277 return; 1278 } 1279 boolean isBackground = (UserHandle.getAppId(proc.uid) 1280 >= Process.FIRST_APPLICATION_UID 1281 && proc.pid != MY_PID); 1282 for (int userId : mCurrentProfileIds) { 1283 isBackground &= (proc.userId != userId); 1284 } 1285 if (isBackground && !showBackground) { 1286 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1287 if (res != null) { 1288 res.set(0); 1289 } 1290 return; 1291 } 1292 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1293 Dialog d = new AppErrorDialog(mContext, 1294 ActivityManagerService.this, res, proc); 1295 d.show(); 1296 proc.crashDialog = d; 1297 } else { 1298 // The device is asleep, so just pretend that the user 1299 // saw a crash dialog and hit "force quit". 1300 if (res != null) { 1301 res.set(0); 1302 } 1303 } 1304 } 1305 1306 ensureBootCompleted(); 1307 } break; 1308 case SHOW_NOT_RESPONDING_MSG: { 1309 synchronized (ActivityManagerService.this) { 1310 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1311 ProcessRecord proc = (ProcessRecord)data.get("app"); 1312 if (proc != null && proc.anrDialog != null) { 1313 Slog.e(TAG, "App already has anr dialog: " + proc); 1314 return; 1315 } 1316 1317 Intent intent = new Intent("android.intent.action.ANR"); 1318 if (!mProcessesReady) { 1319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1320 | Intent.FLAG_RECEIVER_FOREGROUND); 1321 } 1322 broadcastIntentLocked(null, null, intent, 1323 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1324 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1325 1326 if (mShowDialogs) { 1327 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1328 mContext, proc, (ActivityRecord)data.get("activity"), 1329 msg.arg1 != 0); 1330 d.show(); 1331 proc.anrDialog = d; 1332 } else { 1333 // Just kill the app if there is no dialog to be shown. 1334 killAppAtUsersRequest(proc, null); 1335 } 1336 } 1337 1338 ensureBootCompleted(); 1339 } break; 1340 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1341 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1342 synchronized (ActivityManagerService.this) { 1343 ProcessRecord proc = (ProcessRecord) data.get("app"); 1344 if (proc == null) { 1345 Slog.e(TAG, "App not found when showing strict mode dialog."); 1346 break; 1347 } 1348 if (proc.crashDialog != null) { 1349 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1350 return; 1351 } 1352 AppErrorResult res = (AppErrorResult) data.get("result"); 1353 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1354 Dialog d = new StrictModeViolationDialog(mContext, 1355 ActivityManagerService.this, res, proc); 1356 d.show(); 1357 proc.crashDialog = d; 1358 } else { 1359 // The device is asleep, so just pretend that the user 1360 // saw a crash dialog and hit "force quit". 1361 res.set(0); 1362 } 1363 } 1364 ensureBootCompleted(); 1365 } break; 1366 case SHOW_FACTORY_ERROR_MSG: { 1367 Dialog d = new FactoryErrorDialog( 1368 mContext, msg.getData().getCharSequence("msg")); 1369 d.show(); 1370 ensureBootCompleted(); 1371 } break; 1372 case UPDATE_CONFIGURATION_MSG: { 1373 final ContentResolver resolver = mContext.getContentResolver(); 1374 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1375 } break; 1376 case GC_BACKGROUND_PROCESSES_MSG: { 1377 synchronized (ActivityManagerService.this) { 1378 performAppGcsIfAppropriateLocked(); 1379 } 1380 } break; 1381 case WAIT_FOR_DEBUGGER_MSG: { 1382 synchronized (ActivityManagerService.this) { 1383 ProcessRecord app = (ProcessRecord)msg.obj; 1384 if (msg.arg1 != 0) { 1385 if (!app.waitedForDebugger) { 1386 Dialog d = new AppWaitingForDebuggerDialog( 1387 ActivityManagerService.this, 1388 mContext, app); 1389 app.waitDialog = d; 1390 app.waitedForDebugger = true; 1391 d.show(); 1392 } 1393 } else { 1394 if (app.waitDialog != null) { 1395 app.waitDialog.dismiss(); 1396 app.waitDialog = null; 1397 } 1398 } 1399 } 1400 } break; 1401 case SERVICE_TIMEOUT_MSG: { 1402 if (mDidDexOpt) { 1403 mDidDexOpt = false; 1404 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1405 nmsg.obj = msg.obj; 1406 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1407 return; 1408 } 1409 mServices.serviceTimeout((ProcessRecord)msg.obj); 1410 } break; 1411 case UPDATE_TIME_ZONE: { 1412 synchronized (ActivityManagerService.this) { 1413 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1414 ProcessRecord r = mLruProcesses.get(i); 1415 if (r.thread != null) { 1416 try { 1417 r.thread.updateTimeZone(); 1418 } catch (RemoteException ex) { 1419 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1420 } 1421 } 1422 } 1423 } 1424 } break; 1425 case CLEAR_DNS_CACHE_MSG: { 1426 synchronized (ActivityManagerService.this) { 1427 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1428 ProcessRecord r = mLruProcesses.get(i); 1429 if (r.thread != null) { 1430 try { 1431 r.thread.clearDnsCache(); 1432 } catch (RemoteException ex) { 1433 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1434 } 1435 } 1436 } 1437 } 1438 } break; 1439 case UPDATE_HTTP_PROXY_MSG: { 1440 ProxyInfo proxy = (ProxyInfo)msg.obj; 1441 String host = ""; 1442 String port = ""; 1443 String exclList = ""; 1444 Uri pacFileUrl = Uri.EMPTY; 1445 if (proxy != null) { 1446 host = proxy.getHost(); 1447 port = Integer.toString(proxy.getPort()); 1448 exclList = proxy.getExclusionListAsString(); 1449 pacFileUrl = proxy.getPacFileUrl(); 1450 } 1451 synchronized (ActivityManagerService.this) { 1452 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1453 ProcessRecord r = mLruProcesses.get(i); 1454 if (r.thread != null) { 1455 try { 1456 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1457 } catch (RemoteException ex) { 1458 Slog.w(TAG, "Failed to update http proxy for: " + 1459 r.info.processName); 1460 } 1461 } 1462 } 1463 } 1464 } break; 1465 case SHOW_UID_ERROR_MSG: { 1466 if (mShowDialogs) { 1467 AlertDialog d = new BaseErrorDialog(mContext); 1468 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1469 d.setCancelable(false); 1470 d.setTitle(mContext.getText(R.string.android_system_label)); 1471 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1472 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1473 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1474 d.show(); 1475 } 1476 } break; 1477 case SHOW_FINGERPRINT_ERROR_MSG: { 1478 if (mShowDialogs) { 1479 AlertDialog d = new BaseErrorDialog(mContext); 1480 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1481 d.setCancelable(false); 1482 d.setTitle(mContext.getText(R.string.android_system_label)); 1483 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1484 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1485 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1486 d.show(); 1487 } 1488 } break; 1489 case PROC_START_TIMEOUT_MSG: { 1490 if (mDidDexOpt) { 1491 mDidDexOpt = false; 1492 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1493 nmsg.obj = msg.obj; 1494 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1495 return; 1496 } 1497 ProcessRecord app = (ProcessRecord)msg.obj; 1498 synchronized (ActivityManagerService.this) { 1499 processStartTimedOutLocked(app); 1500 } 1501 } break; 1502 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1503 synchronized (ActivityManagerService.this) { 1504 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1505 } 1506 } break; 1507 case KILL_APPLICATION_MSG: { 1508 synchronized (ActivityManagerService.this) { 1509 int appid = msg.arg1; 1510 boolean restart = (msg.arg2 == 1); 1511 Bundle bundle = (Bundle)msg.obj; 1512 String pkg = bundle.getString("pkg"); 1513 String reason = bundle.getString("reason"); 1514 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1515 false, UserHandle.USER_ALL, reason); 1516 } 1517 } break; 1518 case FINALIZE_PENDING_INTENT_MSG: { 1519 ((PendingIntentRecord)msg.obj).completeFinalize(); 1520 } break; 1521 case POST_HEAVY_NOTIFICATION_MSG: { 1522 INotificationManager inm = NotificationManager.getService(); 1523 if (inm == null) { 1524 return; 1525 } 1526 1527 ActivityRecord root = (ActivityRecord)msg.obj; 1528 ProcessRecord process = root.app; 1529 if (process == null) { 1530 return; 1531 } 1532 1533 try { 1534 Context context = mContext.createPackageContext(process.info.packageName, 0); 1535 String text = mContext.getString(R.string.heavy_weight_notification, 1536 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1537 Notification notification = new Notification(); 1538 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1539 notification.when = 0; 1540 notification.flags = Notification.FLAG_ONGOING_EVENT; 1541 notification.tickerText = text; 1542 notification.defaults = 0; // please be quiet 1543 notification.sound = null; 1544 notification.vibrate = null; 1545 notification.color = mContext.getResources().getColor( 1546 com.android.internal.R.color.system_notification_accent_color); 1547 notification.setLatestEventInfo(context, text, 1548 mContext.getText(R.string.heavy_weight_notification_detail), 1549 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1550 PendingIntent.FLAG_CANCEL_CURRENT, null, 1551 new UserHandle(root.userId))); 1552 1553 try { 1554 int[] outId = new int[1]; 1555 inm.enqueueNotificationWithTag("android", "android", null, 1556 R.string.heavy_weight_notification, 1557 notification, outId, root.userId); 1558 } catch (RuntimeException e) { 1559 Slog.w(ActivityManagerService.TAG, 1560 "Error showing notification for heavy-weight app", e); 1561 } catch (RemoteException e) { 1562 } 1563 } catch (NameNotFoundException e) { 1564 Slog.w(TAG, "Unable to create context for heavy notification", e); 1565 } 1566 } break; 1567 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1568 INotificationManager inm = NotificationManager.getService(); 1569 if (inm == null) { 1570 return; 1571 } 1572 try { 1573 inm.cancelNotificationWithTag("android", null, 1574 R.string.heavy_weight_notification, msg.arg1); 1575 } catch (RuntimeException e) { 1576 Slog.w(ActivityManagerService.TAG, 1577 "Error canceling notification for service", e); 1578 } catch (RemoteException e) { 1579 } 1580 } break; 1581 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1582 synchronized (ActivityManagerService.this) { 1583 checkExcessivePowerUsageLocked(true); 1584 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1585 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1586 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1587 } 1588 } break; 1589 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1590 synchronized (ActivityManagerService.this) { 1591 ActivityRecord ar = (ActivityRecord)msg.obj; 1592 if (mCompatModeDialog != null) { 1593 if (mCompatModeDialog.mAppInfo.packageName.equals( 1594 ar.info.applicationInfo.packageName)) { 1595 return; 1596 } 1597 mCompatModeDialog.dismiss(); 1598 mCompatModeDialog = null; 1599 } 1600 if (ar != null && false) { 1601 if (mCompatModePackages.getPackageAskCompatModeLocked( 1602 ar.packageName)) { 1603 int mode = mCompatModePackages.computeCompatModeLocked( 1604 ar.info.applicationInfo); 1605 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1606 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1607 mCompatModeDialog = new CompatModeDialog( 1608 ActivityManagerService.this, mContext, 1609 ar.info.applicationInfo); 1610 mCompatModeDialog.show(); 1611 } 1612 } 1613 } 1614 } 1615 break; 1616 } 1617 case DISPATCH_PROCESSES_CHANGED: { 1618 dispatchProcessesChanged(); 1619 break; 1620 } 1621 case DISPATCH_PROCESS_DIED: { 1622 final int pid = msg.arg1; 1623 final int uid = msg.arg2; 1624 dispatchProcessDied(pid, uid); 1625 break; 1626 } 1627 case REPORT_MEM_USAGE_MSG: { 1628 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1629 Thread thread = new Thread() { 1630 @Override public void run() { 1631 reportMemUsage(memInfos); 1632 } 1633 }; 1634 thread.start(); 1635 break; 1636 } 1637 case START_USER_SWITCH_MSG: { 1638 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1639 break; 1640 } 1641 case REPORT_USER_SWITCH_MSG: { 1642 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1643 break; 1644 } 1645 case CONTINUE_USER_SWITCH_MSG: { 1646 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1647 break; 1648 } 1649 case USER_SWITCH_TIMEOUT_MSG: { 1650 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1651 break; 1652 } 1653 case IMMERSIVE_MODE_LOCK_MSG: { 1654 final boolean nextState = (msg.arg1 != 0); 1655 if (mUpdateLock.isHeld() != nextState) { 1656 if (DEBUG_IMMERSIVE) { 1657 final ActivityRecord r = (ActivityRecord) msg.obj; 1658 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1659 } 1660 if (nextState) { 1661 mUpdateLock.acquire(); 1662 } else { 1663 mUpdateLock.release(); 1664 } 1665 } 1666 break; 1667 } 1668 case PERSIST_URI_GRANTS_MSG: { 1669 writeGrantedUriPermissions(); 1670 break; 1671 } 1672 case REQUEST_ALL_PSS_MSG: { 1673 synchronized (ActivityManagerService.this) { 1674 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1675 } 1676 break; 1677 } 1678 case START_PROFILES_MSG: { 1679 synchronized (ActivityManagerService.this) { 1680 startProfilesLocked(); 1681 } 1682 break; 1683 } 1684 case UPDATE_TIME: { 1685 synchronized (ActivityManagerService.this) { 1686 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1687 ProcessRecord r = mLruProcesses.get(i); 1688 if (r.thread != null) { 1689 try { 1690 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1691 } catch (RemoteException ex) { 1692 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1693 } 1694 } 1695 } 1696 } 1697 break; 1698 } 1699 case SYSTEM_USER_START_MSG: { 1700 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1701 Integer.toString(msg.arg1), msg.arg1); 1702 mSystemServiceManager.startUser(msg.arg1); 1703 break; 1704 } 1705 case SYSTEM_USER_CURRENT_MSG: { 1706 mBatteryStatsService.noteEvent( 1707 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1708 Integer.toString(msg.arg2), msg.arg2); 1709 mBatteryStatsService.noteEvent( 1710 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1711 Integer.toString(msg.arg1), msg.arg1); 1712 mSystemServiceManager.switchUser(msg.arg1); 1713 break; 1714 } 1715 case ENTER_ANIMATION_COMPLETE_MSG: { 1716 synchronized (ActivityManagerService.this) { 1717 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1718 if (r != null && r.app != null && r.app.thread != null) { 1719 try { 1720 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1721 } catch (RemoteException e) { 1722 } 1723 } 1724 } 1725 break; 1726 } 1727 case FINISH_BOOTING_MSG: { 1728 if (msg.arg1 != 0) { 1729 finishBooting(); 1730 } 1731 if (msg.arg2 != 0) { 1732 enableScreenAfterBoot(); 1733 } 1734 break; 1735 } 1736 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1737 try { 1738 Locale l = (Locale) msg.obj; 1739 IBinder service = ServiceManager.getService("mount"); 1740 IMountService mountService = IMountService.Stub.asInterface(service); 1741 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1742 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1743 } catch (RemoteException e) { 1744 Log.e(TAG, "Error storing locale for decryption UI", e); 1745 } 1746 break; 1747 } 1748 case DISMISS_DIALOG_MSG: { 1749 final Dialog d = (Dialog) msg.obj; 1750 d.dismiss(); 1751 break; 1752 } 1753 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1754 synchronized (ActivityManagerService.this) { 1755 int i = mTaskStackListeners.beginBroadcast(); 1756 while (i > 0) { 1757 i--; 1758 try { 1759 // Make a one-way callback to the listener 1760 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1761 } catch (RemoteException e){ 1762 // Handled by the RemoteCallbackList 1763 } 1764 } 1765 mTaskStackListeners.finishBroadcast(); 1766 } 1767 break; 1768 } 1769 } 1770 } 1771 }; 1772 1773 static final int COLLECT_PSS_BG_MSG = 1; 1774 1775 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1776 @Override 1777 public void handleMessage(Message msg) { 1778 switch (msg.what) { 1779 case COLLECT_PSS_BG_MSG: { 1780 long start = SystemClock.uptimeMillis(); 1781 MemInfoReader memInfo = null; 1782 synchronized (ActivityManagerService.this) { 1783 if (mFullPssPending) { 1784 mFullPssPending = false; 1785 memInfo = new MemInfoReader(); 1786 } 1787 } 1788 if (memInfo != null) { 1789 updateCpuStatsNow(); 1790 long nativeTotalPss = 0; 1791 synchronized (mProcessCpuTracker) { 1792 final int N = mProcessCpuTracker.countStats(); 1793 for (int j=0; j<N; j++) { 1794 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1795 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1796 // This is definitely an application process; skip it. 1797 continue; 1798 } 1799 synchronized (mPidsSelfLocked) { 1800 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1801 // This is one of our own processes; skip it. 1802 continue; 1803 } 1804 } 1805 nativeTotalPss += Debug.getPss(st.pid, null); 1806 } 1807 } 1808 memInfo.readMemInfo(); 1809 synchronized (ActivityManagerService.this) { 1810 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1811 + (SystemClock.uptimeMillis()-start) + "ms"); 1812 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1813 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1814 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1815 } 1816 } 1817 1818 int i = 0; 1819 int num = 0; 1820 long[] tmp = new long[1]; 1821 do { 1822 ProcessRecord proc; 1823 int procState; 1824 int pid; 1825 synchronized (ActivityManagerService.this) { 1826 if (i >= mPendingPssProcesses.size()) { 1827 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1828 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1829 mPendingPssProcesses.clear(); 1830 return; 1831 } 1832 proc = mPendingPssProcesses.get(i); 1833 procState = proc.pssProcState; 1834 if (proc.thread != null && procState == proc.setProcState) { 1835 pid = proc.pid; 1836 } else { 1837 proc = null; 1838 pid = 0; 1839 } 1840 i++; 1841 } 1842 if (proc != null) { 1843 long pss = Debug.getPss(pid, tmp); 1844 synchronized (ActivityManagerService.this) { 1845 if (proc.thread != null && proc.setProcState == procState 1846 && proc.pid == pid) { 1847 num++; 1848 proc.lastPssTime = SystemClock.uptimeMillis(); 1849 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1850 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1851 + ": " + pss + " lastPss=" + proc.lastPss 1852 + " state=" + ProcessList.makeProcStateString(procState)); 1853 if (proc.initialIdlePss == 0) { 1854 proc.initialIdlePss = pss; 1855 } 1856 proc.lastPss = pss; 1857 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1858 proc.lastCachedPss = pss; 1859 } 1860 } 1861 } 1862 } 1863 } while (true); 1864 } 1865 } 1866 } 1867 }; 1868 1869 public void setSystemProcess() { 1870 try { 1871 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1872 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1873 ServiceManager.addService("meminfo", new MemBinder(this)); 1874 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1875 ServiceManager.addService("dbinfo", new DbBinder(this)); 1876 if (MONITOR_CPU_USAGE) { 1877 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1878 } 1879 ServiceManager.addService("permission", new PermissionController(this)); 1880 1881 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1882 "android", STOCK_PM_FLAGS); 1883 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1884 1885 synchronized (this) { 1886 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1887 app.persistent = true; 1888 app.pid = MY_PID; 1889 app.maxAdj = ProcessList.SYSTEM_ADJ; 1890 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1891 mProcessNames.put(app.processName, app.uid, app); 1892 synchronized (mPidsSelfLocked) { 1893 mPidsSelfLocked.put(app.pid, app); 1894 } 1895 updateLruProcessLocked(app, false, null); 1896 updateOomAdjLocked(); 1897 } 1898 } catch (PackageManager.NameNotFoundException e) { 1899 throw new RuntimeException( 1900 "Unable to find android system package", e); 1901 } 1902 } 1903 1904 public void setWindowManager(WindowManagerService wm) { 1905 mWindowManager = wm; 1906 mStackSupervisor.setWindowManager(wm); 1907 } 1908 1909 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1910 mUsageStatsService = usageStatsManager; 1911 } 1912 1913 public void startObservingNativeCrashes() { 1914 final NativeCrashListener ncl = new NativeCrashListener(this); 1915 ncl.start(); 1916 } 1917 1918 public IAppOpsService getAppOpsService() { 1919 return mAppOpsService; 1920 } 1921 1922 static class MemBinder extends Binder { 1923 ActivityManagerService mActivityManagerService; 1924 MemBinder(ActivityManagerService activityManagerService) { 1925 mActivityManagerService = activityManagerService; 1926 } 1927 1928 @Override 1929 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1930 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1931 != PackageManager.PERMISSION_GRANTED) { 1932 pw.println("Permission Denial: can't dump meminfo from from pid=" 1933 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1934 + " without permission " + android.Manifest.permission.DUMP); 1935 return; 1936 } 1937 1938 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1939 } 1940 } 1941 1942 static class GraphicsBinder extends Binder { 1943 ActivityManagerService mActivityManagerService; 1944 GraphicsBinder(ActivityManagerService activityManagerService) { 1945 mActivityManagerService = activityManagerService; 1946 } 1947 1948 @Override 1949 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1950 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1951 != PackageManager.PERMISSION_GRANTED) { 1952 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1953 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1954 + " without permission " + android.Manifest.permission.DUMP); 1955 return; 1956 } 1957 1958 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1959 } 1960 } 1961 1962 static class DbBinder extends Binder { 1963 ActivityManagerService mActivityManagerService; 1964 DbBinder(ActivityManagerService activityManagerService) { 1965 mActivityManagerService = activityManagerService; 1966 } 1967 1968 @Override 1969 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1970 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1971 != PackageManager.PERMISSION_GRANTED) { 1972 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1973 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1974 + " without permission " + android.Manifest.permission.DUMP); 1975 return; 1976 } 1977 1978 mActivityManagerService.dumpDbInfo(fd, pw, args); 1979 } 1980 } 1981 1982 static class CpuBinder extends Binder { 1983 ActivityManagerService mActivityManagerService; 1984 CpuBinder(ActivityManagerService activityManagerService) { 1985 mActivityManagerService = activityManagerService; 1986 } 1987 1988 @Override 1989 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1990 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1991 != PackageManager.PERMISSION_GRANTED) { 1992 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1993 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1994 + " without permission " + android.Manifest.permission.DUMP); 1995 return; 1996 } 1997 1998 synchronized (mActivityManagerService.mProcessCpuTracker) { 1999 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2000 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2001 SystemClock.uptimeMillis())); 2002 } 2003 } 2004 } 2005 2006 public static final class Lifecycle extends SystemService { 2007 private final ActivityManagerService mService; 2008 2009 public Lifecycle(Context context) { 2010 super(context); 2011 mService = new ActivityManagerService(context); 2012 } 2013 2014 @Override 2015 public void onStart() { 2016 mService.start(); 2017 } 2018 2019 public ActivityManagerService getService() { 2020 return mService; 2021 } 2022 } 2023 2024 // Note: This method is invoked on the main thread but may need to attach various 2025 // handlers to other threads. So take care to be explicit about the looper. 2026 public ActivityManagerService(Context systemContext) { 2027 mContext = systemContext; 2028 mFactoryTest = FactoryTest.getMode(); 2029 mSystemThread = ActivityThread.currentActivityThread(); 2030 2031 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2032 2033 mHandlerThread = new ServiceThread(TAG, 2034 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2035 mHandlerThread.start(); 2036 mHandler = new MainHandler(mHandlerThread.getLooper()); 2037 2038 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2039 "foreground", BROADCAST_FG_TIMEOUT, false); 2040 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2041 "background", BROADCAST_BG_TIMEOUT, true); 2042 mBroadcastQueues[0] = mFgBroadcastQueue; 2043 mBroadcastQueues[1] = mBgBroadcastQueue; 2044 2045 mServices = new ActiveServices(this); 2046 mProviderMap = new ProviderMap(this); 2047 2048 // TODO: Move creation of battery stats service outside of activity manager service. 2049 File dataDir = Environment.getDataDirectory(); 2050 File systemDir = new File(dataDir, "system"); 2051 systemDir.mkdirs(); 2052 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2053 mBatteryStatsService.getActiveStatistics().readLocked(); 2054 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2055 mOnBattery = DEBUG_POWER ? true 2056 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2057 mBatteryStatsService.getActiveStatistics().setCallback(this); 2058 2059 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2060 2061 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2062 2063 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2064 2065 // User 0 is the first and only user that runs at boot. 2066 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2067 mUserLru.add(Integer.valueOf(0)); 2068 updateStartedUserArrayLocked(); 2069 2070 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2071 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2072 2073 mConfiguration.setToDefaults(); 2074 mConfiguration.setLocale(Locale.getDefault()); 2075 2076 mConfigurationSeq = mConfiguration.seq = 1; 2077 mProcessCpuTracker.init(); 2078 2079 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2080 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2081 mStackSupervisor = new ActivityStackSupervisor(this); 2082 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2083 2084 mProcessCpuThread = new Thread("CpuTracker") { 2085 @Override 2086 public void run() { 2087 while (true) { 2088 try { 2089 try { 2090 synchronized(this) { 2091 final long now = SystemClock.uptimeMillis(); 2092 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2093 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2094 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2095 // + ", write delay=" + nextWriteDelay); 2096 if (nextWriteDelay < nextCpuDelay) { 2097 nextCpuDelay = nextWriteDelay; 2098 } 2099 if (nextCpuDelay > 0) { 2100 mProcessCpuMutexFree.set(true); 2101 this.wait(nextCpuDelay); 2102 } 2103 } 2104 } catch (InterruptedException e) { 2105 } 2106 updateCpuStatsNow(); 2107 } catch (Exception e) { 2108 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2109 } 2110 } 2111 } 2112 }; 2113 2114 Watchdog.getInstance().addMonitor(this); 2115 Watchdog.getInstance().addThread(mHandler); 2116 } 2117 2118 public void setSystemServiceManager(SystemServiceManager mgr) { 2119 mSystemServiceManager = mgr; 2120 } 2121 2122 public void setInstaller(Installer installer) { 2123 mInstaller = installer; 2124 } 2125 2126 private void start() { 2127 Process.removeAllProcessGroups(); 2128 mProcessCpuThread.start(); 2129 2130 mBatteryStatsService.publish(mContext); 2131 mAppOpsService.publish(mContext); 2132 Slog.d("AppOps", "AppOpsService published"); 2133 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2134 } 2135 2136 public void initPowerManagement() { 2137 mStackSupervisor.initPowerManagement(); 2138 mBatteryStatsService.initPowerManagement(); 2139 } 2140 2141 @Override 2142 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2143 throws RemoteException { 2144 if (code == SYSPROPS_TRANSACTION) { 2145 // We need to tell all apps about the system property change. 2146 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2147 synchronized(this) { 2148 final int NP = mProcessNames.getMap().size(); 2149 for (int ip=0; ip<NP; ip++) { 2150 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2151 final int NA = apps.size(); 2152 for (int ia=0; ia<NA; ia++) { 2153 ProcessRecord app = apps.valueAt(ia); 2154 if (app.thread != null) { 2155 procs.add(app.thread.asBinder()); 2156 } 2157 } 2158 } 2159 } 2160 2161 int N = procs.size(); 2162 for (int i=0; i<N; i++) { 2163 Parcel data2 = Parcel.obtain(); 2164 try { 2165 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2166 } catch (RemoteException e) { 2167 } 2168 data2.recycle(); 2169 } 2170 } 2171 try { 2172 return super.onTransact(code, data, reply, flags); 2173 } catch (RuntimeException e) { 2174 // The activity manager only throws security exceptions, so let's 2175 // log all others. 2176 if (!(e instanceof SecurityException)) { 2177 Slog.wtf(TAG, "Activity Manager Crash", e); 2178 } 2179 throw e; 2180 } 2181 } 2182 2183 void updateCpuStats() { 2184 final long now = SystemClock.uptimeMillis(); 2185 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2186 return; 2187 } 2188 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2189 synchronized (mProcessCpuThread) { 2190 mProcessCpuThread.notify(); 2191 } 2192 } 2193 } 2194 2195 void updateCpuStatsNow() { 2196 synchronized (mProcessCpuTracker) { 2197 mProcessCpuMutexFree.set(false); 2198 final long now = SystemClock.uptimeMillis(); 2199 boolean haveNewCpuStats = false; 2200 2201 if (MONITOR_CPU_USAGE && 2202 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2203 mLastCpuTime.set(now); 2204 haveNewCpuStats = true; 2205 mProcessCpuTracker.update(); 2206 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2207 //Slog.i(TAG, "Total CPU usage: " 2208 // + mProcessCpu.getTotalCpuPercent() + "%"); 2209 2210 // Slog the cpu usage if the property is set. 2211 if ("true".equals(SystemProperties.get("events.cpu"))) { 2212 int user = mProcessCpuTracker.getLastUserTime(); 2213 int system = mProcessCpuTracker.getLastSystemTime(); 2214 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2215 int irq = mProcessCpuTracker.getLastIrqTime(); 2216 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2217 int idle = mProcessCpuTracker.getLastIdleTime(); 2218 2219 int total = user + system + iowait + irq + softIrq + idle; 2220 if (total == 0) total = 1; 2221 2222 EventLog.writeEvent(EventLogTags.CPU, 2223 ((user+system+iowait+irq+softIrq) * 100) / total, 2224 (user * 100) / total, 2225 (system * 100) / total, 2226 (iowait * 100) / total, 2227 (irq * 100) / total, 2228 (softIrq * 100) / total); 2229 } 2230 } 2231 2232 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2233 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2234 synchronized(bstats) { 2235 synchronized(mPidsSelfLocked) { 2236 if (haveNewCpuStats) { 2237 if (mOnBattery) { 2238 int perc = bstats.startAddingCpuLocked(); 2239 int totalUTime = 0; 2240 int totalSTime = 0; 2241 final int N = mProcessCpuTracker.countStats(); 2242 for (int i=0; i<N; i++) { 2243 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2244 if (!st.working) { 2245 continue; 2246 } 2247 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2248 int otherUTime = (st.rel_utime*perc)/100; 2249 int otherSTime = (st.rel_stime*perc)/100; 2250 totalUTime += otherUTime; 2251 totalSTime += otherSTime; 2252 if (pr != null) { 2253 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2254 if (ps == null || !ps.isActive()) { 2255 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2256 pr.info.uid, pr.processName); 2257 } 2258 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2259 st.rel_stime-otherSTime); 2260 ps.addSpeedStepTimes(cpuSpeedTimes); 2261 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2262 } else { 2263 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2264 if (ps == null || !ps.isActive()) { 2265 st.batteryStats = ps = bstats.getProcessStatsLocked( 2266 bstats.mapUid(st.uid), st.name); 2267 } 2268 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2269 st.rel_stime-otherSTime); 2270 ps.addSpeedStepTimes(cpuSpeedTimes); 2271 } 2272 } 2273 bstats.finishAddingCpuLocked(perc, totalUTime, 2274 totalSTime, cpuSpeedTimes); 2275 } 2276 } 2277 } 2278 2279 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2280 mLastWriteTime = now; 2281 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2282 } 2283 } 2284 } 2285 } 2286 2287 @Override 2288 public void batteryNeedsCpuUpdate() { 2289 updateCpuStatsNow(); 2290 } 2291 2292 @Override 2293 public void batteryPowerChanged(boolean onBattery) { 2294 // When plugging in, update the CPU stats first before changing 2295 // the plug state. 2296 updateCpuStatsNow(); 2297 synchronized (this) { 2298 synchronized(mPidsSelfLocked) { 2299 mOnBattery = DEBUG_POWER ? true : onBattery; 2300 } 2301 } 2302 } 2303 2304 /** 2305 * Initialize the application bind args. These are passed to each 2306 * process when the bindApplication() IPC is sent to the process. They're 2307 * lazily setup to make sure the services are running when they're asked for. 2308 */ 2309 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2310 if (mAppBindArgs == null) { 2311 mAppBindArgs = new HashMap<>(); 2312 2313 // Isolated processes won't get this optimization, so that we don't 2314 // violate the rules about which services they have access to. 2315 if (!isolated) { 2316 // Setup the application init args 2317 mAppBindArgs.put("package", ServiceManager.getService("package")); 2318 mAppBindArgs.put("window", ServiceManager.getService("window")); 2319 mAppBindArgs.put(Context.ALARM_SERVICE, 2320 ServiceManager.getService(Context.ALARM_SERVICE)); 2321 } 2322 } 2323 return mAppBindArgs; 2324 } 2325 2326 final void setFocusedActivityLocked(ActivityRecord r) { 2327 if (mFocusedActivity != r) { 2328 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2329 mFocusedActivity = r; 2330 if (r.task != null && r.task.voiceInteractor != null) { 2331 startRunningVoiceLocked(); 2332 } else { 2333 finishRunningVoiceLocked(); 2334 } 2335 mStackSupervisor.setFocusedStack(r); 2336 if (r != null) { 2337 mWindowManager.setFocusedApp(r.appToken, true); 2338 } 2339 applyUpdateLockStateLocked(r); 2340 } 2341 } 2342 2343 final void clearFocusedActivity(ActivityRecord r) { 2344 if (mFocusedActivity == r) { 2345 mFocusedActivity = null; 2346 } 2347 } 2348 2349 @Override 2350 public void setFocusedStack(int stackId) { 2351 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2352 synchronized (ActivityManagerService.this) { 2353 ActivityStack stack = mStackSupervisor.getStack(stackId); 2354 if (stack != null) { 2355 ActivityRecord r = stack.topRunningActivityLocked(null); 2356 if (r != null) { 2357 setFocusedActivityLocked(r); 2358 } 2359 } 2360 } 2361 } 2362 2363 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2364 @Override 2365 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2366 synchronized (ActivityManagerService.this) { 2367 if (listener != null) { 2368 mTaskStackListeners.register(listener); 2369 } 2370 } 2371 } 2372 2373 @Override 2374 public void notifyActivityDrawn(IBinder token) { 2375 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2376 synchronized (this) { 2377 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2378 if (r != null) { 2379 r.task.stack.notifyActivityDrawnLocked(r); 2380 } 2381 } 2382 } 2383 2384 final void applyUpdateLockStateLocked(ActivityRecord r) { 2385 // Modifications to the UpdateLock state are done on our handler, outside 2386 // the activity manager's locks. The new state is determined based on the 2387 // state *now* of the relevant activity record. The object is passed to 2388 // the handler solely for logging detail, not to be consulted/modified. 2389 final boolean nextState = r != null && r.immersive; 2390 mHandler.sendMessage( 2391 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2392 } 2393 2394 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2395 Message msg = Message.obtain(); 2396 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2397 msg.obj = r.task.askedCompatMode ? null : r; 2398 mHandler.sendMessage(msg); 2399 } 2400 2401 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2402 String what, Object obj, ProcessRecord srcApp) { 2403 app.lastActivityTime = now; 2404 2405 if (app.activities.size() > 0) { 2406 // Don't want to touch dependent processes that are hosting activities. 2407 return index; 2408 } 2409 2410 int lrui = mLruProcesses.lastIndexOf(app); 2411 if (lrui < 0) { 2412 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2413 + what + " " + obj + " from " + srcApp); 2414 return index; 2415 } 2416 2417 if (lrui >= index) { 2418 // Don't want to cause this to move dependent processes *back* in the 2419 // list as if they were less frequently used. 2420 return index; 2421 } 2422 2423 if (lrui >= mLruProcessActivityStart) { 2424 // Don't want to touch dependent processes that are hosting activities. 2425 return index; 2426 } 2427 2428 mLruProcesses.remove(lrui); 2429 if (index > 0) { 2430 index--; 2431 } 2432 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2433 + " in LRU list: " + app); 2434 mLruProcesses.add(index, app); 2435 return index; 2436 } 2437 2438 final void removeLruProcessLocked(ProcessRecord app) { 2439 int lrui = mLruProcesses.lastIndexOf(app); 2440 if (lrui >= 0) { 2441 if (!app.killed) { 2442 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2443 Process.killProcessQuiet(app.pid); 2444 Process.killProcessGroup(app.info.uid, app.pid); 2445 } 2446 if (lrui <= mLruProcessActivityStart) { 2447 mLruProcessActivityStart--; 2448 } 2449 if (lrui <= mLruProcessServiceStart) { 2450 mLruProcessServiceStart--; 2451 } 2452 mLruProcesses.remove(lrui); 2453 } 2454 } 2455 2456 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2457 ProcessRecord client) { 2458 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2459 || app.treatLikeActivity; 2460 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2461 if (!activityChange && hasActivity) { 2462 // The process has activities, so we are only allowing activity-based adjustments 2463 // to move it. It should be kept in the front of the list with other 2464 // processes that have activities, and we don't want those to change their 2465 // order except due to activity operations. 2466 return; 2467 } 2468 2469 mLruSeq++; 2470 final long now = SystemClock.uptimeMillis(); 2471 app.lastActivityTime = now; 2472 2473 // First a quick reject: if the app is already at the position we will 2474 // put it, then there is nothing to do. 2475 if (hasActivity) { 2476 final int N = mLruProcesses.size(); 2477 if (N > 0 && mLruProcesses.get(N-1) == app) { 2478 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2479 return; 2480 } 2481 } else { 2482 if (mLruProcessServiceStart > 0 2483 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2484 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2485 return; 2486 } 2487 } 2488 2489 int lrui = mLruProcesses.lastIndexOf(app); 2490 2491 if (app.persistent && lrui >= 0) { 2492 // We don't care about the position of persistent processes, as long as 2493 // they are in the list. 2494 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2495 return; 2496 } 2497 2498 /* In progress: compute new position first, so we can avoid doing work 2499 if the process is not actually going to move. Not yet working. 2500 int addIndex; 2501 int nextIndex; 2502 boolean inActivity = false, inService = false; 2503 if (hasActivity) { 2504 // Process has activities, put it at the very tipsy-top. 2505 addIndex = mLruProcesses.size(); 2506 nextIndex = mLruProcessServiceStart; 2507 inActivity = true; 2508 } else if (hasService) { 2509 // Process has services, put it at the top of the service list. 2510 addIndex = mLruProcessActivityStart; 2511 nextIndex = mLruProcessServiceStart; 2512 inActivity = true; 2513 inService = true; 2514 } else { 2515 // Process not otherwise of interest, it goes to the top of the non-service area. 2516 addIndex = mLruProcessServiceStart; 2517 if (client != null) { 2518 int clientIndex = mLruProcesses.lastIndexOf(client); 2519 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2520 + app); 2521 if (clientIndex >= 0 && addIndex > clientIndex) { 2522 addIndex = clientIndex; 2523 } 2524 } 2525 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2526 } 2527 2528 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2529 + mLruProcessActivityStart + "): " + app); 2530 */ 2531 2532 if (lrui >= 0) { 2533 if (lrui < mLruProcessActivityStart) { 2534 mLruProcessActivityStart--; 2535 } 2536 if (lrui < mLruProcessServiceStart) { 2537 mLruProcessServiceStart--; 2538 } 2539 /* 2540 if (addIndex > lrui) { 2541 addIndex--; 2542 } 2543 if (nextIndex > lrui) { 2544 nextIndex--; 2545 } 2546 */ 2547 mLruProcesses.remove(lrui); 2548 } 2549 2550 /* 2551 mLruProcesses.add(addIndex, app); 2552 if (inActivity) { 2553 mLruProcessActivityStart++; 2554 } 2555 if (inService) { 2556 mLruProcessActivityStart++; 2557 } 2558 */ 2559 2560 int nextIndex; 2561 if (hasActivity) { 2562 final int N = mLruProcesses.size(); 2563 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2564 // Process doesn't have activities, but has clients with 2565 // activities... move it up, but one below the top (the top 2566 // should always have a real activity). 2567 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2568 mLruProcesses.add(N-1, app); 2569 // To keep it from spamming the LRU list (by making a bunch of clients), 2570 // we will push down any other entries owned by the app. 2571 final int uid = app.info.uid; 2572 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2573 ProcessRecord subProc = mLruProcesses.get(i); 2574 if (subProc.info.uid == uid) { 2575 // We want to push this one down the list. If the process after 2576 // it is for the same uid, however, don't do so, because we don't 2577 // want them internally to be re-ordered. 2578 if (mLruProcesses.get(i-1).info.uid != uid) { 2579 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2580 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2581 ProcessRecord tmp = mLruProcesses.get(i); 2582 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2583 mLruProcesses.set(i-1, tmp); 2584 i--; 2585 } 2586 } else { 2587 // A gap, we can stop here. 2588 break; 2589 } 2590 } 2591 } else { 2592 // Process has activities, put it at the very tipsy-top. 2593 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2594 mLruProcesses.add(app); 2595 } 2596 nextIndex = mLruProcessServiceStart; 2597 } else if (hasService) { 2598 // Process has services, put it at the top of the service list. 2599 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2600 mLruProcesses.add(mLruProcessActivityStart, app); 2601 nextIndex = mLruProcessServiceStart; 2602 mLruProcessActivityStart++; 2603 } else { 2604 // Process not otherwise of interest, it goes to the top of the non-service area. 2605 int index = mLruProcessServiceStart; 2606 if (client != null) { 2607 // If there is a client, don't allow the process to be moved up higher 2608 // in the list than that client. 2609 int clientIndex = mLruProcesses.lastIndexOf(client); 2610 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2611 + " when updating " + app); 2612 if (clientIndex <= lrui) { 2613 // Don't allow the client index restriction to push it down farther in the 2614 // list than it already is. 2615 clientIndex = lrui; 2616 } 2617 if (clientIndex >= 0 && index > clientIndex) { 2618 index = clientIndex; 2619 } 2620 } 2621 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2622 mLruProcesses.add(index, app); 2623 nextIndex = index-1; 2624 mLruProcessActivityStart++; 2625 mLruProcessServiceStart++; 2626 } 2627 2628 // If the app is currently using a content provider or service, 2629 // bump those processes as well. 2630 for (int j=app.connections.size()-1; j>=0; j--) { 2631 ConnectionRecord cr = app.connections.valueAt(j); 2632 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2633 && cr.binding.service.app != null 2634 && cr.binding.service.app.lruSeq != mLruSeq 2635 && !cr.binding.service.app.persistent) { 2636 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2637 "service connection", cr, app); 2638 } 2639 } 2640 for (int j=app.conProviders.size()-1; j>=0; j--) { 2641 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2642 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2643 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2644 "provider reference", cpr, app); 2645 } 2646 } 2647 } 2648 2649 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2650 if (uid == Process.SYSTEM_UID) { 2651 // The system gets to run in any process. If there are multiple 2652 // processes with the same uid, just pick the first (this 2653 // should never happen). 2654 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2655 if (procs == null) return null; 2656 final int N = procs.size(); 2657 for (int i = 0; i < N; i++) { 2658 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2659 } 2660 } 2661 ProcessRecord proc = mProcessNames.get(processName, uid); 2662 if (false && proc != null && !keepIfLarge 2663 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2664 && proc.lastCachedPss >= 4000) { 2665 // Turn this condition on to cause killing to happen regularly, for testing. 2666 if (proc.baseProcessTracker != null) { 2667 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2668 } 2669 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2670 } else if (proc != null && !keepIfLarge 2671 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2672 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2673 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2674 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2675 if (proc.baseProcessTracker != null) { 2676 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2677 } 2678 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2679 } 2680 } 2681 return proc; 2682 } 2683 2684 void ensurePackageDexOpt(String packageName) { 2685 IPackageManager pm = AppGlobals.getPackageManager(); 2686 try { 2687 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2688 mDidDexOpt = true; 2689 } 2690 } catch (RemoteException e) { 2691 } 2692 } 2693 2694 boolean isNextTransitionForward() { 2695 int transit = mWindowManager.getPendingAppTransition(); 2696 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2697 || transit == AppTransition.TRANSIT_TASK_OPEN 2698 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2699 } 2700 2701 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2702 String processName, String abiOverride, int uid, Runnable crashHandler) { 2703 synchronized(this) { 2704 ApplicationInfo info = new ApplicationInfo(); 2705 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2706 // For isolated processes, the former contains the parent's uid and the latter the 2707 // actual uid of the isolated process. 2708 // In the special case introduced by this method (which is, starting an isolated 2709 // process directly from the SystemServer without an actual parent app process) the 2710 // closest thing to a parent's uid is SYSTEM_UID. 2711 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2712 // the |isolated| logic in the ProcessRecord constructor. 2713 info.uid = Process.SYSTEM_UID; 2714 info.processName = processName; 2715 info.className = entryPoint; 2716 info.packageName = "android"; 2717 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2718 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2719 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2720 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2721 crashHandler); 2722 return proc != null ? proc.pid : 0; 2723 } 2724 } 2725 2726 final ProcessRecord startProcessLocked(String processName, 2727 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2728 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2729 boolean isolated, boolean keepIfLarge) { 2730 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2731 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2732 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2733 null /* crashHandler */); 2734 } 2735 2736 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2737 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2738 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2739 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2740 long startTime = SystemClock.elapsedRealtime(); 2741 ProcessRecord app; 2742 if (!isolated) { 2743 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2744 checkTime(startTime, "startProcess: after getProcessRecord"); 2745 } else { 2746 // If this is an isolated process, it can't re-use an existing process. 2747 app = null; 2748 } 2749 // We don't have to do anything more if: 2750 // (1) There is an existing application record; and 2751 // (2) The caller doesn't think it is dead, OR there is no thread 2752 // object attached to it so we know it couldn't have crashed; and 2753 // (3) There is a pid assigned to it, so it is either starting or 2754 // already running. 2755 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2756 + " app=" + app + " knownToBeDead=" + knownToBeDead 2757 + " thread=" + (app != null ? app.thread : null) 2758 + " pid=" + (app != null ? app.pid : -1)); 2759 if (app != null && app.pid > 0) { 2760 if (!knownToBeDead || app.thread == null) { 2761 // We already have the app running, or are waiting for it to 2762 // come up (we have a pid but not yet its thread), so keep it. 2763 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2764 // If this is a new package in the process, add the package to the list 2765 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2766 checkTime(startTime, "startProcess: done, added package to proc"); 2767 return app; 2768 } 2769 2770 // An application record is attached to a previous process, 2771 // clean it up now. 2772 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2773 checkTime(startTime, "startProcess: bad proc running, killing"); 2774 Process.killProcessGroup(app.info.uid, app.pid); 2775 handleAppDiedLocked(app, true, true); 2776 checkTime(startTime, "startProcess: done killing old proc"); 2777 } 2778 2779 String hostingNameStr = hostingName != null 2780 ? hostingName.flattenToShortString() : null; 2781 2782 if (!isolated) { 2783 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2784 // If we are in the background, then check to see if this process 2785 // is bad. If so, we will just silently fail. 2786 if (mBadProcesses.get(info.processName, info.uid) != null) { 2787 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2788 + "/" + info.processName); 2789 return null; 2790 } 2791 } else { 2792 // When the user is explicitly starting a process, then clear its 2793 // crash count so that we won't make it bad until they see at 2794 // least one crash dialog again, and make the process good again 2795 // if it had been bad. 2796 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2797 + "/" + info.processName); 2798 mProcessCrashTimes.remove(info.processName, info.uid); 2799 if (mBadProcesses.get(info.processName, info.uid) != null) { 2800 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2801 UserHandle.getUserId(info.uid), info.uid, 2802 info.processName); 2803 mBadProcesses.remove(info.processName, info.uid); 2804 if (app != null) { 2805 app.bad = false; 2806 } 2807 } 2808 } 2809 } 2810 2811 if (app == null) { 2812 checkTime(startTime, "startProcess: creating new process record"); 2813 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2814 if (app == null) { 2815 Slog.w(TAG, "Failed making new process record for " 2816 + processName + "/" + info.uid + " isolated=" + isolated); 2817 return null; 2818 } 2819 app.crashHandler = crashHandler; 2820 mProcessNames.put(processName, app.uid, app); 2821 if (isolated) { 2822 mIsolatedProcesses.put(app.uid, app); 2823 } 2824 checkTime(startTime, "startProcess: done creating new process record"); 2825 } else { 2826 // If this is a new package in the process, add the package to the list 2827 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2828 checkTime(startTime, "startProcess: added package to existing proc"); 2829 } 2830 2831 // If the system is not ready yet, then hold off on starting this 2832 // process until it is. 2833 if (!mProcessesReady 2834 && !isAllowedWhileBooting(info) 2835 && !allowWhileBooting) { 2836 if (!mProcessesOnHold.contains(app)) { 2837 mProcessesOnHold.add(app); 2838 } 2839 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2840 checkTime(startTime, "startProcess: returning with proc on hold"); 2841 return app; 2842 } 2843 2844 checkTime(startTime, "startProcess: stepping in to startProcess"); 2845 startProcessLocked( 2846 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2847 checkTime(startTime, "startProcess: done starting proc!"); 2848 return (app.pid != 0) ? app : null; 2849 } 2850 2851 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2852 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2853 } 2854 2855 private final void startProcessLocked(ProcessRecord app, 2856 String hostingType, String hostingNameStr) { 2857 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2858 null /* entryPoint */, null /* entryPointArgs */); 2859 } 2860 2861 private final void startProcessLocked(ProcessRecord app, String hostingType, 2862 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2863 long startTime = SystemClock.elapsedRealtime(); 2864 if (app.pid > 0 && app.pid != MY_PID) { 2865 checkTime(startTime, "startProcess: removing from pids map"); 2866 synchronized (mPidsSelfLocked) { 2867 mPidsSelfLocked.remove(app.pid); 2868 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2869 } 2870 checkTime(startTime, "startProcess: done removing from pids map"); 2871 app.setPid(0); 2872 } 2873 2874 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2875 "startProcessLocked removing on hold: " + app); 2876 mProcessesOnHold.remove(app); 2877 2878 checkTime(startTime, "startProcess: starting to update cpu stats"); 2879 updateCpuStats(); 2880 checkTime(startTime, "startProcess: done updating cpu stats"); 2881 2882 try { 2883 int uid = app.uid; 2884 2885 int[] gids = null; 2886 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2887 if (!app.isolated) { 2888 int[] permGids = null; 2889 try { 2890 checkTime(startTime, "startProcess: getting gids from package manager"); 2891 final PackageManager pm = mContext.getPackageManager(); 2892 permGids = pm.getPackageGids(app.info.packageName); 2893 2894 if (Environment.isExternalStorageEmulated()) { 2895 checkTime(startTime, "startProcess: checking external storage perm"); 2896 if (pm.checkPermission( 2897 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2898 app.info.packageName) == PERMISSION_GRANTED) { 2899 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2900 } else { 2901 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2902 } 2903 } 2904 } catch (PackageManager.NameNotFoundException e) { 2905 Slog.w(TAG, "Unable to retrieve gids", e); 2906 } 2907 2908 /* 2909 * Add shared application and profile GIDs so applications can share some 2910 * resources like shared libraries and access user-wide resources 2911 */ 2912 if (permGids == null) { 2913 gids = new int[2]; 2914 } else { 2915 gids = new int[permGids.length + 2]; 2916 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2917 } 2918 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2919 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2920 } 2921 checkTime(startTime, "startProcess: building args"); 2922 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2923 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2924 && mTopComponent != null 2925 && app.processName.equals(mTopComponent.getPackageName())) { 2926 uid = 0; 2927 } 2928 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2929 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2930 uid = 0; 2931 } 2932 } 2933 int debugFlags = 0; 2934 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2935 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2936 // Also turn on CheckJNI for debuggable apps. It's quite 2937 // awkward to turn on otherwise. 2938 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2939 } 2940 // Run the app in safe mode if its manifest requests so or the 2941 // system is booted in safe mode. 2942 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2943 mSafeMode == true) { 2944 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2945 } 2946 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2947 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2948 } 2949 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2950 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2951 } 2952 if ("1".equals(SystemProperties.get("debug.assert"))) { 2953 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2954 } 2955 2956 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2957 if (requiredAbi == null) { 2958 requiredAbi = Build.SUPPORTED_ABIS[0]; 2959 } 2960 2961 String instructionSet = null; 2962 if (app.info.primaryCpuAbi != null) { 2963 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2964 } 2965 2966 // Start the process. It will either succeed and return a result containing 2967 // the PID of the new process, or else throw a RuntimeException. 2968 boolean isActivityProcess = (entryPoint == null); 2969 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2970 checkTime(startTime, "startProcess: asking zygote to start proc"); 2971 Process.ProcessStartResult startResult = Process.start(entryPoint, 2972 app.processName, uid, uid, gids, debugFlags, mountExternal, 2973 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2974 app.info.dataDir, entryPointArgs); 2975 checkTime(startTime, "startProcess: returned from zygote!"); 2976 2977 if (app.isolated) { 2978 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2979 } 2980 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2981 checkTime(startTime, "startProcess: done updating battery stats"); 2982 2983 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2984 UserHandle.getUserId(uid), startResult.pid, uid, 2985 app.processName, hostingType, 2986 hostingNameStr != null ? hostingNameStr : ""); 2987 2988 if (app.persistent) { 2989 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2990 } 2991 2992 checkTime(startTime, "startProcess: building log message"); 2993 StringBuilder buf = mStringBuilder; 2994 buf.setLength(0); 2995 buf.append("Start proc "); 2996 buf.append(app.processName); 2997 if (!isActivityProcess) { 2998 buf.append(" ["); 2999 buf.append(entryPoint); 3000 buf.append("]"); 3001 } 3002 buf.append(" for "); 3003 buf.append(hostingType); 3004 if (hostingNameStr != null) { 3005 buf.append(" "); 3006 buf.append(hostingNameStr); 3007 } 3008 buf.append(": pid="); 3009 buf.append(startResult.pid); 3010 buf.append(" uid="); 3011 buf.append(uid); 3012 buf.append(" gids={"); 3013 if (gids != null) { 3014 for (int gi=0; gi<gids.length; gi++) { 3015 if (gi != 0) buf.append(", "); 3016 buf.append(gids[gi]); 3017 3018 } 3019 } 3020 buf.append("}"); 3021 if (requiredAbi != null) { 3022 buf.append(" abi="); 3023 buf.append(requiredAbi); 3024 } 3025 Slog.i(TAG, buf.toString()); 3026 app.setPid(startResult.pid); 3027 app.usingWrapper = startResult.usingWrapper; 3028 app.removed = false; 3029 app.killed = false; 3030 app.killedByAm = false; 3031 checkTime(startTime, "startProcess: starting to update pids map"); 3032 synchronized (mPidsSelfLocked) { 3033 this.mPidsSelfLocked.put(startResult.pid, app); 3034 if (isActivityProcess) { 3035 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3036 msg.obj = app; 3037 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3038 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3039 } 3040 } 3041 checkTime(startTime, "startProcess: done updating pids map"); 3042 } catch (RuntimeException e) { 3043 // XXX do better error recovery. 3044 app.setPid(0); 3045 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3046 if (app.isolated) { 3047 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3048 } 3049 Slog.e(TAG, "Failure starting process " + app.processName, e); 3050 } 3051 } 3052 3053 void updateUsageStats(ActivityRecord component, boolean resumed) { 3054 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3055 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3056 if (resumed) { 3057 if (mUsageStatsService != null) { 3058 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3059 UsageEvents.Event.MOVE_TO_FOREGROUND); 3060 } 3061 synchronized (stats) { 3062 stats.noteActivityResumedLocked(component.app.uid); 3063 } 3064 } else { 3065 if (mUsageStatsService != null) { 3066 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3067 UsageEvents.Event.MOVE_TO_BACKGROUND); 3068 } 3069 synchronized (stats) { 3070 stats.noteActivityPausedLocked(component.app.uid); 3071 } 3072 } 3073 } 3074 3075 Intent getHomeIntent() { 3076 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3077 intent.setComponent(mTopComponent); 3078 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3079 intent.addCategory(Intent.CATEGORY_HOME); 3080 } 3081 return intent; 3082 } 3083 3084 boolean startHomeActivityLocked(int userId) { 3085 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3086 && mTopAction == null) { 3087 // We are running in factory test mode, but unable to find 3088 // the factory test app, so just sit around displaying the 3089 // error message and don't try to start anything. 3090 return false; 3091 } 3092 Intent intent = getHomeIntent(); 3093 ActivityInfo aInfo = 3094 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3095 if (aInfo != null) { 3096 intent.setComponent(new ComponentName( 3097 aInfo.applicationInfo.packageName, aInfo.name)); 3098 // Don't do this if the home app is currently being 3099 // instrumented. 3100 aInfo = new ActivityInfo(aInfo); 3101 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3102 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3103 aInfo.applicationInfo.uid, true); 3104 if (app == null || app.instrumentationClass == null) { 3105 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3106 mStackSupervisor.startHomeActivity(intent, aInfo); 3107 } 3108 } 3109 3110 return true; 3111 } 3112 3113 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3114 ActivityInfo ai = null; 3115 ComponentName comp = intent.getComponent(); 3116 try { 3117 if (comp != null) { 3118 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3119 } else { 3120 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3121 intent, 3122 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3123 flags, userId); 3124 3125 if (info != null) { 3126 ai = info.activityInfo; 3127 } 3128 } 3129 } catch (RemoteException e) { 3130 // ignore 3131 } 3132 3133 return ai; 3134 } 3135 3136 /** 3137 * Starts the "new version setup screen" if appropriate. 3138 */ 3139 void startSetupActivityLocked() { 3140 // Only do this once per boot. 3141 if (mCheckedForSetup) { 3142 return; 3143 } 3144 3145 // We will show this screen if the current one is a different 3146 // version than the last one shown, and we are not running in 3147 // low-level factory test mode. 3148 final ContentResolver resolver = mContext.getContentResolver(); 3149 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3150 Settings.Global.getInt(resolver, 3151 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3152 mCheckedForSetup = true; 3153 3154 // See if we should be showing the platform update setup UI. 3155 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3156 List<ResolveInfo> ris = mContext.getPackageManager() 3157 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3158 3159 // We don't allow third party apps to replace this. 3160 ResolveInfo ri = null; 3161 for (int i=0; ris != null && i<ris.size(); i++) { 3162 if ((ris.get(i).activityInfo.applicationInfo.flags 3163 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3164 ri = ris.get(i); 3165 break; 3166 } 3167 } 3168 3169 if (ri != null) { 3170 String vers = ri.activityInfo.metaData != null 3171 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3172 : null; 3173 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3174 vers = ri.activityInfo.applicationInfo.metaData.getString( 3175 Intent.METADATA_SETUP_VERSION); 3176 } 3177 String lastVers = Settings.Secure.getString( 3178 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3179 if (vers != null && !vers.equals(lastVers)) { 3180 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3181 intent.setComponent(new ComponentName( 3182 ri.activityInfo.packageName, ri.activityInfo.name)); 3183 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3184 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3185 null); 3186 } 3187 } 3188 } 3189 } 3190 3191 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3192 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3193 } 3194 3195 void enforceNotIsolatedCaller(String caller) { 3196 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3197 throw new SecurityException("Isolated process not allowed to call " + caller); 3198 } 3199 } 3200 3201 void enforceShellRestriction(String restriction, int userHandle) { 3202 if (Binder.getCallingUid() == Process.SHELL_UID) { 3203 if (userHandle < 0 3204 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3205 throw new SecurityException("Shell does not have permission to access user " 3206 + userHandle); 3207 } 3208 } 3209 } 3210 3211 @Override 3212 public int getFrontActivityScreenCompatMode() { 3213 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3214 synchronized (this) { 3215 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3216 } 3217 } 3218 3219 @Override 3220 public void setFrontActivityScreenCompatMode(int mode) { 3221 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3222 "setFrontActivityScreenCompatMode"); 3223 synchronized (this) { 3224 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3225 } 3226 } 3227 3228 @Override 3229 public int getPackageScreenCompatMode(String packageName) { 3230 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3231 synchronized (this) { 3232 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3233 } 3234 } 3235 3236 @Override 3237 public void setPackageScreenCompatMode(String packageName, int mode) { 3238 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3239 "setPackageScreenCompatMode"); 3240 synchronized (this) { 3241 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3242 } 3243 } 3244 3245 @Override 3246 public boolean getPackageAskScreenCompat(String packageName) { 3247 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3248 synchronized (this) { 3249 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3250 } 3251 } 3252 3253 @Override 3254 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3255 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3256 "setPackageAskScreenCompat"); 3257 synchronized (this) { 3258 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3259 } 3260 } 3261 3262 private void dispatchProcessesChanged() { 3263 int N; 3264 synchronized (this) { 3265 N = mPendingProcessChanges.size(); 3266 if (mActiveProcessChanges.length < N) { 3267 mActiveProcessChanges = new ProcessChangeItem[N]; 3268 } 3269 mPendingProcessChanges.toArray(mActiveProcessChanges); 3270 mAvailProcessChanges.addAll(mPendingProcessChanges); 3271 mPendingProcessChanges.clear(); 3272 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3273 } 3274 3275 int i = mProcessObservers.beginBroadcast(); 3276 while (i > 0) { 3277 i--; 3278 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3279 if (observer != null) { 3280 try { 3281 for (int j=0; j<N; j++) { 3282 ProcessChangeItem item = mActiveProcessChanges[j]; 3283 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3284 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3285 + item.pid + " uid=" + item.uid + ": " 3286 + item.foregroundActivities); 3287 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3288 item.foregroundActivities); 3289 } 3290 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3291 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3292 + item.pid + " uid=" + item.uid + ": " + item.processState); 3293 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3294 } 3295 } 3296 } catch (RemoteException e) { 3297 } 3298 } 3299 } 3300 mProcessObservers.finishBroadcast(); 3301 } 3302 3303 private void dispatchProcessDied(int pid, int uid) { 3304 int i = mProcessObservers.beginBroadcast(); 3305 while (i > 0) { 3306 i--; 3307 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3308 if (observer != null) { 3309 try { 3310 observer.onProcessDied(pid, uid); 3311 } catch (RemoteException e) { 3312 } 3313 } 3314 } 3315 mProcessObservers.finishBroadcast(); 3316 } 3317 3318 @Override 3319 public final int startActivity(IApplicationThread caller, String callingPackage, 3320 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3321 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3322 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3323 resultWho, requestCode, startFlags, profilerInfo, options, 3324 UserHandle.getCallingUserId()); 3325 } 3326 3327 @Override 3328 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3329 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3330 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3331 enforceNotIsolatedCaller("startActivity"); 3332 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3333 false, ALLOW_FULL_ONLY, "startActivity", null); 3334 // TODO: Switch to user app stacks here. 3335 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3336 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3337 profilerInfo, null, null, options, userId, null, null); 3338 } 3339 3340 @Override 3341 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3342 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3343 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3344 3345 // This is very dangerous -- it allows you to perform a start activity (including 3346 // permission grants) as any app that may launch one of your own activities. So 3347 // we will only allow this to be done from activities that are part of the core framework, 3348 // and then only when they are running as the system. 3349 final ActivityRecord sourceRecord; 3350 final int targetUid; 3351 final String targetPackage; 3352 synchronized (this) { 3353 if (resultTo == null) { 3354 throw new SecurityException("Must be called from an activity"); 3355 } 3356 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3357 if (sourceRecord == null) { 3358 throw new SecurityException("Called with bad activity token: " + resultTo); 3359 } 3360 if (!sourceRecord.info.packageName.equals("android")) { 3361 throw new SecurityException( 3362 "Must be called from an activity that is declared in the android package"); 3363 } 3364 if (sourceRecord.app == null) { 3365 throw new SecurityException("Called without a process attached to activity"); 3366 } 3367 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3368 // This is still okay, as long as this activity is running under the 3369 // uid of the original calling activity. 3370 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3371 throw new SecurityException( 3372 "Calling activity in uid " + sourceRecord.app.uid 3373 + " must be system uid or original calling uid " 3374 + sourceRecord.launchedFromUid); 3375 } 3376 } 3377 targetUid = sourceRecord.launchedFromUid; 3378 targetPackage = sourceRecord.launchedFromPackage; 3379 } 3380 3381 if (userId == UserHandle.USER_NULL) { 3382 userId = UserHandle.getUserId(sourceRecord.app.uid); 3383 } 3384 3385 // TODO: Switch to user app stacks here. 3386 try { 3387 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3388 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3389 null, null, options, userId, null, null); 3390 return ret; 3391 } catch (SecurityException e) { 3392 // XXX need to figure out how to propagate to original app. 3393 // A SecurityException here is generally actually a fault of the original 3394 // calling activity (such as a fairly granting permissions), so propagate it 3395 // back to them. 3396 /* 3397 StringBuilder msg = new StringBuilder(); 3398 msg.append("While launching"); 3399 msg.append(intent.toString()); 3400 msg.append(": "); 3401 msg.append(e.getMessage()); 3402 */ 3403 throw e; 3404 } 3405 } 3406 3407 @Override 3408 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3409 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3410 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3411 enforceNotIsolatedCaller("startActivityAndWait"); 3412 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3413 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3414 WaitResult res = new WaitResult(); 3415 // TODO: Switch to user app stacks here. 3416 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3417 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3418 options, userId, null, null); 3419 return res; 3420 } 3421 3422 @Override 3423 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3424 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3425 int startFlags, Configuration config, Bundle options, int userId) { 3426 enforceNotIsolatedCaller("startActivityWithConfig"); 3427 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3428 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3429 // TODO: Switch to user app stacks here. 3430 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3431 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3432 null, null, config, options, userId, null, null); 3433 return ret; 3434 } 3435 3436 @Override 3437 public int startActivityIntentSender(IApplicationThread caller, 3438 IntentSender intent, Intent fillInIntent, String resolvedType, 3439 IBinder resultTo, String resultWho, int requestCode, 3440 int flagsMask, int flagsValues, Bundle options) { 3441 enforceNotIsolatedCaller("startActivityIntentSender"); 3442 // Refuse possible leaked file descriptors 3443 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3444 throw new IllegalArgumentException("File descriptors passed in Intent"); 3445 } 3446 3447 IIntentSender sender = intent.getTarget(); 3448 if (!(sender instanceof PendingIntentRecord)) { 3449 throw new IllegalArgumentException("Bad PendingIntent object"); 3450 } 3451 3452 PendingIntentRecord pir = (PendingIntentRecord)sender; 3453 3454 synchronized (this) { 3455 // If this is coming from the currently resumed activity, it is 3456 // effectively saying that app switches are allowed at this point. 3457 final ActivityStack stack = getFocusedStack(); 3458 if (stack.mResumedActivity != null && 3459 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3460 mAppSwitchesAllowedTime = 0; 3461 } 3462 } 3463 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3464 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3465 return ret; 3466 } 3467 3468 @Override 3469 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3470 Intent intent, String resolvedType, IVoiceInteractionSession session, 3471 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3472 Bundle options, int userId) { 3473 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3474 != PackageManager.PERMISSION_GRANTED) { 3475 String msg = "Permission Denial: startVoiceActivity() from pid=" 3476 + Binder.getCallingPid() 3477 + ", uid=" + Binder.getCallingUid() 3478 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3479 Slog.w(TAG, msg); 3480 throw new SecurityException(msg); 3481 } 3482 if (session == null || interactor == null) { 3483 throw new NullPointerException("null session or interactor"); 3484 } 3485 userId = handleIncomingUser(callingPid, callingUid, userId, 3486 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3487 // TODO: Switch to user app stacks here. 3488 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3489 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3490 null, options, userId, null, null); 3491 } 3492 3493 @Override 3494 public boolean startNextMatchingActivity(IBinder callingActivity, 3495 Intent intent, Bundle options) { 3496 // Refuse possible leaked file descriptors 3497 if (intent != null && intent.hasFileDescriptors() == true) { 3498 throw new IllegalArgumentException("File descriptors passed in Intent"); 3499 } 3500 3501 synchronized (this) { 3502 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3503 if (r == null) { 3504 ActivityOptions.abort(options); 3505 return false; 3506 } 3507 if (r.app == null || r.app.thread == null) { 3508 // The caller is not running... d'oh! 3509 ActivityOptions.abort(options); 3510 return false; 3511 } 3512 intent = new Intent(intent); 3513 // The caller is not allowed to change the data. 3514 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3515 // And we are resetting to find the next component... 3516 intent.setComponent(null); 3517 3518 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3519 3520 ActivityInfo aInfo = null; 3521 try { 3522 List<ResolveInfo> resolves = 3523 AppGlobals.getPackageManager().queryIntentActivities( 3524 intent, r.resolvedType, 3525 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3526 UserHandle.getCallingUserId()); 3527 3528 // Look for the original activity in the list... 3529 final int N = resolves != null ? resolves.size() : 0; 3530 for (int i=0; i<N; i++) { 3531 ResolveInfo rInfo = resolves.get(i); 3532 if (rInfo.activityInfo.packageName.equals(r.packageName) 3533 && rInfo.activityInfo.name.equals(r.info.name)) { 3534 // We found the current one... the next matching is 3535 // after it. 3536 i++; 3537 if (i<N) { 3538 aInfo = resolves.get(i).activityInfo; 3539 } 3540 if (debug) { 3541 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3542 + "/" + r.info.name); 3543 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3544 + "/" + aInfo.name); 3545 } 3546 break; 3547 } 3548 } 3549 } catch (RemoteException e) { 3550 } 3551 3552 if (aInfo == null) { 3553 // Nobody who is next! 3554 ActivityOptions.abort(options); 3555 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3556 return false; 3557 } 3558 3559 intent.setComponent(new ComponentName( 3560 aInfo.applicationInfo.packageName, aInfo.name)); 3561 intent.setFlags(intent.getFlags()&~( 3562 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3563 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3564 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3565 Intent.FLAG_ACTIVITY_NEW_TASK)); 3566 3567 // Okay now we need to start the new activity, replacing the 3568 // currently running activity. This is a little tricky because 3569 // we want to start the new one as if the current one is finished, 3570 // but not finish the current one first so that there is no flicker. 3571 // And thus... 3572 final boolean wasFinishing = r.finishing; 3573 r.finishing = true; 3574 3575 // Propagate reply information over to the new activity. 3576 final ActivityRecord resultTo = r.resultTo; 3577 final String resultWho = r.resultWho; 3578 final int requestCode = r.requestCode; 3579 r.resultTo = null; 3580 if (resultTo != null) { 3581 resultTo.removeResultsLocked(r, resultWho, requestCode); 3582 } 3583 3584 final long origId = Binder.clearCallingIdentity(); 3585 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3586 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3587 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3588 -1, r.launchedFromUid, 0, options, false, null, null, null); 3589 Binder.restoreCallingIdentity(origId); 3590 3591 r.finishing = wasFinishing; 3592 if (res != ActivityManager.START_SUCCESS) { 3593 return false; 3594 } 3595 return true; 3596 } 3597 } 3598 3599 @Override 3600 public final int startActivityFromRecents(int taskId, Bundle options) { 3601 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3602 String msg = "Permission Denial: startActivityFromRecents called without " + 3603 START_TASKS_FROM_RECENTS; 3604 Slog.w(TAG, msg); 3605 throw new SecurityException(msg); 3606 } 3607 return startActivityFromRecentsInner(taskId, options); 3608 } 3609 3610 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3611 final TaskRecord task; 3612 final int callingUid; 3613 final String callingPackage; 3614 final Intent intent; 3615 final int userId; 3616 synchronized (this) { 3617 task = recentTaskForIdLocked(taskId); 3618 if (task == null) { 3619 throw new IllegalArgumentException("Task " + taskId + " not found."); 3620 } 3621 callingUid = task.mCallingUid; 3622 callingPackage = task.mCallingPackage; 3623 intent = task.intent; 3624 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3625 userId = task.userId; 3626 } 3627 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3628 options, userId, null, task); 3629 } 3630 3631 final int startActivityInPackage(int uid, String callingPackage, 3632 Intent intent, String resolvedType, IBinder resultTo, 3633 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3634 IActivityContainer container, TaskRecord inTask) { 3635 3636 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3637 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3638 3639 // TODO: Switch to user app stacks here. 3640 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3641 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3642 null, null, null, options, userId, container, inTask); 3643 return ret; 3644 } 3645 3646 @Override 3647 public final int startActivities(IApplicationThread caller, String callingPackage, 3648 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3649 int userId) { 3650 enforceNotIsolatedCaller("startActivities"); 3651 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3652 false, ALLOW_FULL_ONLY, "startActivity", null); 3653 // TODO: Switch to user app stacks here. 3654 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3655 resolvedTypes, resultTo, options, userId); 3656 return ret; 3657 } 3658 3659 final int startActivitiesInPackage(int uid, String callingPackage, 3660 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3661 Bundle options, int userId) { 3662 3663 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3664 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3665 // TODO: Switch to user app stacks here. 3666 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3667 resultTo, options, userId); 3668 return ret; 3669 } 3670 3671 //explicitly remove thd old information in mRecentTasks when removing existing user. 3672 private void removeRecentTasksForUserLocked(int userId) { 3673 if(userId <= 0) { 3674 Slog.i(TAG, "Can't remove recent task on user " + userId); 3675 return; 3676 } 3677 3678 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3679 TaskRecord tr = mRecentTasks.get(i); 3680 if (tr.userId == userId) { 3681 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3682 + " when finishing user" + userId); 3683 mRecentTasks.remove(i); 3684 tr.removedFromRecents(); 3685 } 3686 } 3687 3688 // Remove tasks from persistent storage. 3689 notifyTaskPersisterLocked(null, true); 3690 } 3691 3692 // Sort by taskId 3693 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3694 @Override 3695 public int compare(TaskRecord lhs, TaskRecord rhs) { 3696 return rhs.taskId - lhs.taskId; 3697 } 3698 }; 3699 3700 // Extract the affiliates of the chain containing mRecentTasks[start]. 3701 private int processNextAffiliateChainLocked(int start) { 3702 final TaskRecord startTask = mRecentTasks.get(start); 3703 final int affiliateId = startTask.mAffiliatedTaskId; 3704 3705 // Quick identification of isolated tasks. I.e. those not launched behind. 3706 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3707 startTask.mNextAffiliate == null) { 3708 // There is still a slim chance that there are other tasks that point to this task 3709 // and that the chain is so messed up that this task no longer points to them but 3710 // the gain of this optimization outweighs the risk. 3711 startTask.inRecents = true; 3712 return start + 1; 3713 } 3714 3715 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3716 mTmpRecents.clear(); 3717 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3718 final TaskRecord task = mRecentTasks.get(i); 3719 if (task.mAffiliatedTaskId == affiliateId) { 3720 mRecentTasks.remove(i); 3721 mTmpRecents.add(task); 3722 } 3723 } 3724 3725 // Sort them all by taskId. That is the order they were create in and that order will 3726 // always be correct. 3727 Collections.sort(mTmpRecents, mTaskRecordComparator); 3728 3729 // Go through and fix up the linked list. 3730 // The first one is the end of the chain and has no next. 3731 final TaskRecord first = mTmpRecents.get(0); 3732 first.inRecents = true; 3733 if (first.mNextAffiliate != null) { 3734 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3735 first.setNextAffiliate(null); 3736 notifyTaskPersisterLocked(first, false); 3737 } 3738 // Everything in the middle is doubly linked from next to prev. 3739 final int tmpSize = mTmpRecents.size(); 3740 for (int i = 0; i < tmpSize - 1; ++i) { 3741 final TaskRecord next = mTmpRecents.get(i); 3742 final TaskRecord prev = mTmpRecents.get(i + 1); 3743 if (next.mPrevAffiliate != prev) { 3744 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3745 " setting prev=" + prev); 3746 next.setPrevAffiliate(prev); 3747 notifyTaskPersisterLocked(next, false); 3748 } 3749 if (prev.mNextAffiliate != next) { 3750 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3751 " setting next=" + next); 3752 prev.setNextAffiliate(next); 3753 notifyTaskPersisterLocked(prev, false); 3754 } 3755 prev.inRecents = true; 3756 } 3757 // The last one is the beginning of the list and has no prev. 3758 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3759 if (last.mPrevAffiliate != null) { 3760 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3761 last.setPrevAffiliate(null); 3762 notifyTaskPersisterLocked(last, false); 3763 } 3764 3765 // Insert the group back into mRecentTasks at start. 3766 mRecentTasks.addAll(start, mTmpRecents); 3767 3768 // Let the caller know where we left off. 3769 return start + tmpSize; 3770 } 3771 3772 /** 3773 * Update the recent tasks lists: make sure tasks should still be here (their 3774 * applications / activities still exist), update their availability, fixup ordering 3775 * of affiliations. 3776 */ 3777 void cleanupRecentTasksLocked(int userId) { 3778 if (mRecentTasks == null) { 3779 // Happens when called from the packagemanager broadcast before boot. 3780 return; 3781 } 3782 3783 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3784 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3785 final IPackageManager pm = AppGlobals.getPackageManager(); 3786 final ActivityInfo dummyAct = new ActivityInfo(); 3787 final ApplicationInfo dummyApp = new ApplicationInfo(); 3788 3789 int N = mRecentTasks.size(); 3790 3791 int[] users = userId == UserHandle.USER_ALL 3792 ? getUsersLocked() : new int[] { userId }; 3793 for (int user : users) { 3794 for (int i = 0; i < N; i++) { 3795 TaskRecord task = mRecentTasks.get(i); 3796 if (task.userId != user) { 3797 // Only look at tasks for the user ID of interest. 3798 continue; 3799 } 3800 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3801 // This situation is broken, and we should just get rid of it now. 3802 mRecentTasks.remove(i); 3803 task.removedFromRecents(); 3804 i--; 3805 N--; 3806 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3807 continue; 3808 } 3809 // Check whether this activity is currently available. 3810 if (task.realActivity != null) { 3811 ActivityInfo ai = availActCache.get(task.realActivity); 3812 if (ai == null) { 3813 try { 3814 ai = pm.getActivityInfo(task.realActivity, 3815 PackageManager.GET_UNINSTALLED_PACKAGES 3816 | PackageManager.GET_DISABLED_COMPONENTS, user); 3817 } catch (RemoteException e) { 3818 // Will never happen. 3819 continue; 3820 } 3821 if (ai == null) { 3822 ai = dummyAct; 3823 } 3824 availActCache.put(task.realActivity, ai); 3825 } 3826 if (ai == dummyAct) { 3827 // This could be either because the activity no longer exists, or the 3828 // app is temporarily gone. For the former we want to remove the recents 3829 // entry; for the latter we want to mark it as unavailable. 3830 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3831 if (app == null) { 3832 try { 3833 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3834 PackageManager.GET_UNINSTALLED_PACKAGES 3835 | PackageManager.GET_DISABLED_COMPONENTS, user); 3836 } catch (RemoteException e) { 3837 // Will never happen. 3838 continue; 3839 } 3840 if (app == null) { 3841 app = dummyApp; 3842 } 3843 availAppCache.put(task.realActivity.getPackageName(), app); 3844 } 3845 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3846 // Doesn't exist any more! Good-bye. 3847 mRecentTasks.remove(i); 3848 task.removedFromRecents(); 3849 i--; 3850 N--; 3851 Slog.w(TAG, "Removing no longer valid recent: " + task); 3852 continue; 3853 } else { 3854 // Otherwise just not available for now. 3855 if (task.isAvailable) { 3856 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3857 + task); 3858 } 3859 task.isAvailable = false; 3860 } 3861 } else { 3862 if (!ai.enabled || !ai.applicationInfo.enabled 3863 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3864 if (task.isAvailable) { 3865 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3866 + task + " (enabled=" + ai.enabled + "/" 3867 + ai.applicationInfo.enabled + " flags=" 3868 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3869 } 3870 task.isAvailable = false; 3871 } else { 3872 if (!task.isAvailable) { 3873 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3874 + task); 3875 } 3876 task.isAvailable = true; 3877 } 3878 } 3879 } 3880 } 3881 } 3882 3883 // Verify the affiliate chain for each task. 3884 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3885 } 3886 3887 mTmpRecents.clear(); 3888 // mRecentTasks is now in sorted, affiliated order. 3889 } 3890 3891 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3892 int N = mRecentTasks.size(); 3893 TaskRecord top = task; 3894 int topIndex = taskIndex; 3895 while (top.mNextAffiliate != null && topIndex > 0) { 3896 top = top.mNextAffiliate; 3897 topIndex--; 3898 } 3899 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3900 + topIndex + " from intial " + taskIndex); 3901 // Find the end of the chain, doing a sanity check along the way. 3902 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3903 int endIndex = topIndex; 3904 TaskRecord prev = top; 3905 while (endIndex < N) { 3906 TaskRecord cur = mRecentTasks.get(endIndex); 3907 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3908 + endIndex + " " + cur); 3909 if (cur == top) { 3910 // Verify start of the chain. 3911 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3912 Slog.wtf(TAG, "Bad chain @" + endIndex 3913 + ": first task has next affiliate: " + prev); 3914 sane = false; 3915 break; 3916 } 3917 } else { 3918 // Verify middle of the chain's next points back to the one before. 3919 if (cur.mNextAffiliate != prev 3920 || cur.mNextAffiliateTaskId != prev.taskId) { 3921 Slog.wtf(TAG, "Bad chain @" + endIndex 3922 + ": middle task " + cur + " @" + endIndex 3923 + " has bad next affiliate " 3924 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3925 + ", expected " + prev); 3926 sane = false; 3927 break; 3928 } 3929 } 3930 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3931 // Chain ends here. 3932 if (cur.mPrevAffiliate != null) { 3933 Slog.wtf(TAG, "Bad chain @" + endIndex 3934 + ": last task " + cur + " has previous affiliate " 3935 + cur.mPrevAffiliate); 3936 sane = false; 3937 } 3938 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3939 break; 3940 } else { 3941 // Verify middle of the chain's prev points to a valid item. 3942 if (cur.mPrevAffiliate == null) { 3943 Slog.wtf(TAG, "Bad chain @" + endIndex 3944 + ": task " + cur + " has previous affiliate " 3945 + cur.mPrevAffiliate + " but should be id " 3946 + cur.mPrevAffiliate); 3947 sane = false; 3948 break; 3949 } 3950 } 3951 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3952 Slog.wtf(TAG, "Bad chain @" + endIndex 3953 + ": task " + cur + " has affiliated id " 3954 + cur.mAffiliatedTaskId + " but should be " 3955 + task.mAffiliatedTaskId); 3956 sane = false; 3957 break; 3958 } 3959 prev = cur; 3960 endIndex++; 3961 if (endIndex >= N) { 3962 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3963 + ": last task " + prev); 3964 sane = false; 3965 break; 3966 } 3967 } 3968 if (sane) { 3969 if (endIndex < taskIndex) { 3970 Slog.wtf(TAG, "Bad chain @" + endIndex 3971 + ": did not extend to task " + task + " @" + taskIndex); 3972 sane = false; 3973 } 3974 } 3975 if (sane) { 3976 // All looks good, we can just move all of the affiliated tasks 3977 // to the top. 3978 for (int i=topIndex; i<=endIndex; i++) { 3979 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3980 + " from " + i + " to " + (i-topIndex)); 3981 TaskRecord cur = mRecentTasks.remove(i); 3982 mRecentTasks.add(i-topIndex, cur); 3983 } 3984 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3985 + " to " + endIndex); 3986 return true; 3987 } 3988 3989 // Whoops, couldn't do it. 3990 return false; 3991 } 3992 3993 final void addRecentTaskLocked(TaskRecord task) { 3994 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3995 || task.mNextAffiliateTaskId != INVALID_TASK_ID 3996 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 3997 3998 int N = mRecentTasks.size(); 3999 // Quick case: check if the top-most recent task is the same. 4000 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4001 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4002 return; 4003 } 4004 // Another quick case: check if this is part of a set of affiliated 4005 // tasks that are at the top. 4006 if (isAffiliated && N > 0 && task.inRecents 4007 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4008 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4009 + " at top when adding " + task); 4010 return; 4011 } 4012 // Another quick case: never add voice sessions. 4013 if (task.voiceSession != null) { 4014 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4015 return; 4016 } 4017 4018 boolean needAffiliationFix = false; 4019 4020 // Slightly less quick case: the task is already in recents, so all we need 4021 // to do is move it. 4022 if (task.inRecents) { 4023 int taskIndex = mRecentTasks.indexOf(task); 4024 if (taskIndex >= 0) { 4025 if (!isAffiliated) { 4026 // Simple case: this is not an affiliated task, so we just move it to the front. 4027 mRecentTasks.remove(taskIndex); 4028 mRecentTasks.add(0, task); 4029 notifyTaskPersisterLocked(task, false); 4030 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4031 + " from " + taskIndex); 4032 return; 4033 } else { 4034 // More complicated: need to keep all affiliated tasks together. 4035 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4036 // All went well. 4037 return; 4038 } 4039 4040 // Uh oh... something bad in the affiliation chain, try to rebuild 4041 // everything and then go through our general path of adding a new task. 4042 needAffiliationFix = true; 4043 } 4044 } else { 4045 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4046 needAffiliationFix = true; 4047 } 4048 } 4049 4050 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4051 trimRecentsForTaskLocked(task, true); 4052 4053 N = mRecentTasks.size(); 4054 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4055 final TaskRecord tr = mRecentTasks.remove(N - 1); 4056 tr.removedFromRecents(); 4057 N--; 4058 } 4059 task.inRecents = true; 4060 if (!isAffiliated || needAffiliationFix) { 4061 // If this is a simple non-affiliated task, or we had some failure trying to 4062 // handle it as part of an affilated task, then just place it at the top. 4063 mRecentTasks.add(0, task); 4064 } else if (isAffiliated) { 4065 // If this is a new affiliated task, then move all of the affiliated tasks 4066 // to the front and insert this new one. 4067 TaskRecord other = task.mNextAffiliate; 4068 if (other == null) { 4069 other = task.mPrevAffiliate; 4070 } 4071 if (other != null) { 4072 int otherIndex = mRecentTasks.indexOf(other); 4073 if (otherIndex >= 0) { 4074 // Insert new task at appropriate location. 4075 int taskIndex; 4076 if (other == task.mNextAffiliate) { 4077 // We found the index of our next affiliation, which is who is 4078 // before us in the list, so add after that point. 4079 taskIndex = otherIndex+1; 4080 } else { 4081 // We found the index of our previous affiliation, which is who is 4082 // after us in the list, so add at their position. 4083 taskIndex = otherIndex; 4084 } 4085 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4086 + taskIndex + ": " + task); 4087 mRecentTasks.add(taskIndex, task); 4088 4089 // Now move everything to the front. 4090 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4091 // All went well. 4092 return; 4093 } 4094 4095 // Uh oh... something bad in the affiliation chain, try to rebuild 4096 // everything and then go through our general path of adding a new task. 4097 needAffiliationFix = true; 4098 } else { 4099 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4100 + other); 4101 needAffiliationFix = true; 4102 } 4103 } else { 4104 if (DEBUG_RECENTS) Slog.d(TAG, 4105 "addRecent: adding affiliated task without next/prev:" + task); 4106 needAffiliationFix = true; 4107 } 4108 } 4109 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4110 4111 if (needAffiliationFix) { 4112 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4113 cleanupRecentTasksLocked(task.userId); 4114 } 4115 } 4116 4117 /** 4118 * If needed, remove oldest existing entries in recents that are for the same kind 4119 * of task as the given one. 4120 */ 4121 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4122 int N = mRecentTasks.size(); 4123 final Intent intent = task.intent; 4124 final boolean document = intent != null && intent.isDocument(); 4125 4126 int maxRecents = task.maxRecents - 1; 4127 for (int i=0; i<N; i++) { 4128 final TaskRecord tr = mRecentTasks.get(i); 4129 if (task != tr) { 4130 if (task.userId != tr.userId) { 4131 continue; 4132 } 4133 if (i > MAX_RECENT_BITMAPS) { 4134 tr.freeLastThumbnail(); 4135 } 4136 final Intent trIntent = tr.intent; 4137 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4138 (intent == null || !intent.filterEquals(trIntent))) { 4139 continue; 4140 } 4141 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4142 if (document && trIsDocument) { 4143 // These are the same document activity (not necessarily the same doc). 4144 if (maxRecents > 0) { 4145 --maxRecents; 4146 continue; 4147 } 4148 // Hit the maximum number of documents for this task. Fall through 4149 // and remove this document from recents. 4150 } else if (document || trIsDocument) { 4151 // Only one of these is a document. Not the droid we're looking for. 4152 continue; 4153 } 4154 } 4155 4156 if (!doTrim) { 4157 // If the caller is not actually asking for a trim, just tell them we reached 4158 // a point where the trim would happen. 4159 return i; 4160 } 4161 4162 // Either task and tr are the same or, their affinities match or their intents match 4163 // and neither of them is a document, or they are documents using the same activity 4164 // and their maxRecents has been reached. 4165 tr.disposeThumbnail(); 4166 mRecentTasks.remove(i); 4167 if (task != tr) { 4168 tr.removedFromRecents(); 4169 } 4170 i--; 4171 N--; 4172 if (task.intent == null) { 4173 // If the new recent task we are adding is not fully 4174 // specified, then replace it with the existing recent task. 4175 task = tr; 4176 } 4177 notifyTaskPersisterLocked(tr, false); 4178 } 4179 4180 return -1; 4181 } 4182 4183 @Override 4184 public void reportActivityFullyDrawn(IBinder token) { 4185 synchronized (this) { 4186 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4187 if (r == null) { 4188 return; 4189 } 4190 r.reportFullyDrawnLocked(); 4191 } 4192 } 4193 4194 @Override 4195 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4196 synchronized (this) { 4197 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4198 if (r == null) { 4199 return; 4200 } 4201 final long origId = Binder.clearCallingIdentity(); 4202 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4203 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4204 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4205 if (config != null) { 4206 r.frozenBeforeDestroy = true; 4207 if (!updateConfigurationLocked(config, r, false, false)) { 4208 mStackSupervisor.resumeTopActivitiesLocked(); 4209 } 4210 } 4211 Binder.restoreCallingIdentity(origId); 4212 } 4213 } 4214 4215 @Override 4216 public int getRequestedOrientation(IBinder token) { 4217 synchronized (this) { 4218 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4219 if (r == null) { 4220 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4221 } 4222 return mWindowManager.getAppOrientation(r.appToken); 4223 } 4224 } 4225 4226 /** 4227 * This is the internal entry point for handling Activity.finish(). 4228 * 4229 * @param token The Binder token referencing the Activity we want to finish. 4230 * @param resultCode Result code, if any, from this Activity. 4231 * @param resultData Result data (Intent), if any, from this Activity. 4232 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4233 * the root Activity in the task. 4234 * 4235 * @return Returns true if the activity successfully finished, or false if it is still running. 4236 */ 4237 @Override 4238 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4239 boolean finishTask) { 4240 // Refuse possible leaked file descriptors 4241 if (resultData != null && resultData.hasFileDescriptors() == true) { 4242 throw new IllegalArgumentException("File descriptors passed in Intent"); 4243 } 4244 4245 synchronized(this) { 4246 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4247 if (r == null) { 4248 return true; 4249 } 4250 // Keep track of the root activity of the task before we finish it 4251 TaskRecord tr = r.task; 4252 ActivityRecord rootR = tr.getRootActivity(); 4253 if (rootR == null) { 4254 Slog.w(TAG, "Finishing task with all activities already finished"); 4255 } 4256 // Do not allow task to finish in Lock Task mode. 4257 if (tr == mStackSupervisor.mLockTaskModeTask) { 4258 if (rootR == r) { 4259 Slog.i(TAG, "Not finishing task in lock task mode"); 4260 mStackSupervisor.showLockTaskToast(); 4261 return false; 4262 } 4263 } 4264 if (mController != null) { 4265 // Find the first activity that is not finishing. 4266 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4267 if (next != null) { 4268 // ask watcher if this is allowed 4269 boolean resumeOK = true; 4270 try { 4271 resumeOK = mController.activityResuming(next.packageName); 4272 } catch (RemoteException e) { 4273 mController = null; 4274 Watchdog.getInstance().setActivityController(null); 4275 } 4276 4277 if (!resumeOK) { 4278 Slog.i(TAG, "Not finishing activity because controller resumed"); 4279 return false; 4280 } 4281 } 4282 } 4283 final long origId = Binder.clearCallingIdentity(); 4284 try { 4285 boolean res; 4286 if (finishTask && r == rootR) { 4287 // If requested, remove the task that is associated to this activity only if it 4288 // was the root activity in the task. The result code and data is ignored 4289 // because we don't support returning them across task boundaries. 4290 res = removeTaskByIdLocked(tr.taskId, false); 4291 if (!res) { 4292 Slog.i(TAG, "Removing task failed to finish activity"); 4293 } 4294 } else { 4295 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4296 resultData, "app-request", true); 4297 if (!res) { 4298 Slog.i(TAG, "Failed to finish by app-request"); 4299 } 4300 } 4301 return res; 4302 } finally { 4303 Binder.restoreCallingIdentity(origId); 4304 } 4305 } 4306 } 4307 4308 @Override 4309 public final void finishHeavyWeightApp() { 4310 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4311 != PackageManager.PERMISSION_GRANTED) { 4312 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4313 + Binder.getCallingPid() 4314 + ", uid=" + Binder.getCallingUid() 4315 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4316 Slog.w(TAG, msg); 4317 throw new SecurityException(msg); 4318 } 4319 4320 synchronized(this) { 4321 if (mHeavyWeightProcess == null) { 4322 return; 4323 } 4324 4325 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4326 mHeavyWeightProcess.activities); 4327 for (int i=0; i<activities.size(); i++) { 4328 ActivityRecord r = activities.get(i); 4329 if (!r.finishing) { 4330 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4331 null, "finish-heavy", true); 4332 } 4333 } 4334 4335 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4336 mHeavyWeightProcess.userId, 0)); 4337 mHeavyWeightProcess = null; 4338 } 4339 } 4340 4341 @Override 4342 public void crashApplication(int uid, int initialPid, String packageName, 4343 String message) { 4344 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4345 != PackageManager.PERMISSION_GRANTED) { 4346 String msg = "Permission Denial: crashApplication() from pid=" 4347 + Binder.getCallingPid() 4348 + ", uid=" + Binder.getCallingUid() 4349 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4350 Slog.w(TAG, msg); 4351 throw new SecurityException(msg); 4352 } 4353 4354 synchronized(this) { 4355 ProcessRecord proc = null; 4356 4357 // Figure out which process to kill. We don't trust that initialPid 4358 // still has any relation to current pids, so must scan through the 4359 // list. 4360 synchronized (mPidsSelfLocked) { 4361 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4362 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4363 if (p.uid != uid) { 4364 continue; 4365 } 4366 if (p.pid == initialPid) { 4367 proc = p; 4368 break; 4369 } 4370 if (p.pkgList.containsKey(packageName)) { 4371 proc = p; 4372 } 4373 } 4374 } 4375 4376 if (proc == null) { 4377 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4378 + " initialPid=" + initialPid 4379 + " packageName=" + packageName); 4380 return; 4381 } 4382 4383 if (proc.thread != null) { 4384 if (proc.pid == Process.myPid()) { 4385 Log.w(TAG, "crashApplication: trying to crash self!"); 4386 return; 4387 } 4388 long ident = Binder.clearCallingIdentity(); 4389 try { 4390 proc.thread.scheduleCrash(message); 4391 } catch (RemoteException e) { 4392 } 4393 Binder.restoreCallingIdentity(ident); 4394 } 4395 } 4396 } 4397 4398 @Override 4399 public final void finishSubActivity(IBinder token, String resultWho, 4400 int requestCode) { 4401 synchronized(this) { 4402 final long origId = Binder.clearCallingIdentity(); 4403 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4404 if (r != null) { 4405 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4406 } 4407 Binder.restoreCallingIdentity(origId); 4408 } 4409 } 4410 4411 @Override 4412 public boolean finishActivityAffinity(IBinder token) { 4413 synchronized(this) { 4414 final long origId = Binder.clearCallingIdentity(); 4415 try { 4416 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4417 4418 ActivityRecord rootR = r.task.getRootActivity(); 4419 // Do not allow task to finish in Lock Task mode. 4420 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4421 if (rootR == r) { 4422 mStackSupervisor.showLockTaskToast(); 4423 return false; 4424 } 4425 } 4426 boolean res = false; 4427 if (r != null) { 4428 res = r.task.stack.finishActivityAffinityLocked(r); 4429 } 4430 return res; 4431 } finally { 4432 Binder.restoreCallingIdentity(origId); 4433 } 4434 } 4435 } 4436 4437 @Override 4438 public void finishVoiceTask(IVoiceInteractionSession session) { 4439 synchronized(this) { 4440 final long origId = Binder.clearCallingIdentity(); 4441 try { 4442 mStackSupervisor.finishVoiceTask(session); 4443 } finally { 4444 Binder.restoreCallingIdentity(origId); 4445 } 4446 } 4447 4448 } 4449 4450 @Override 4451 public boolean releaseActivityInstance(IBinder token) { 4452 synchronized(this) { 4453 final long origId = Binder.clearCallingIdentity(); 4454 try { 4455 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4456 if (r.task == null || r.task.stack == null) { 4457 return false; 4458 } 4459 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4460 } finally { 4461 Binder.restoreCallingIdentity(origId); 4462 } 4463 } 4464 } 4465 4466 @Override 4467 public void releaseSomeActivities(IApplicationThread appInt) { 4468 synchronized(this) { 4469 final long origId = Binder.clearCallingIdentity(); 4470 try { 4471 ProcessRecord app = getRecordForAppLocked(appInt); 4472 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4473 } finally { 4474 Binder.restoreCallingIdentity(origId); 4475 } 4476 } 4477 } 4478 4479 @Override 4480 public boolean willActivityBeVisible(IBinder token) { 4481 synchronized(this) { 4482 ActivityStack stack = ActivityRecord.getStackLocked(token); 4483 if (stack != null) { 4484 return stack.willActivityBeVisibleLocked(token); 4485 } 4486 return false; 4487 } 4488 } 4489 4490 @Override 4491 public void overridePendingTransition(IBinder token, String packageName, 4492 int enterAnim, int exitAnim) { 4493 synchronized(this) { 4494 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4495 if (self == null) { 4496 return; 4497 } 4498 4499 final long origId = Binder.clearCallingIdentity(); 4500 4501 if (self.state == ActivityState.RESUMED 4502 || self.state == ActivityState.PAUSING) { 4503 mWindowManager.overridePendingAppTransition(packageName, 4504 enterAnim, exitAnim, null); 4505 } 4506 4507 Binder.restoreCallingIdentity(origId); 4508 } 4509 } 4510 4511 /** 4512 * Main function for removing an existing process from the activity manager 4513 * as a result of that process going away. Clears out all connections 4514 * to the process. 4515 */ 4516 private final void handleAppDiedLocked(ProcessRecord app, 4517 boolean restarting, boolean allowRestart) { 4518 int pid = app.pid; 4519 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4520 if (!kept && !restarting) { 4521 removeLruProcessLocked(app); 4522 if (pid > 0) { 4523 ProcessList.remove(pid); 4524 } 4525 } 4526 4527 if (mProfileProc == app) { 4528 clearProfilerLocked(); 4529 } 4530 4531 // Remove this application's activities from active lists. 4532 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4533 4534 app.activities.clear(); 4535 4536 if (app.instrumentationClass != null) { 4537 Slog.w(TAG, "Crash of app " + app.processName 4538 + " running instrumentation " + app.instrumentationClass); 4539 Bundle info = new Bundle(); 4540 info.putString("shortMsg", "Process crashed."); 4541 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4542 } 4543 4544 if (!restarting) { 4545 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4546 // If there was nothing to resume, and we are not already 4547 // restarting this process, but there is a visible activity that 4548 // is hosted by the process... then make sure all visible 4549 // activities are running, taking care of restarting this 4550 // process. 4551 if (hasVisibleActivities) { 4552 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4553 } 4554 } 4555 } 4556 } 4557 4558 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4559 IBinder threadBinder = thread.asBinder(); 4560 // Find the application record. 4561 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4562 ProcessRecord rec = mLruProcesses.get(i); 4563 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4564 return i; 4565 } 4566 } 4567 return -1; 4568 } 4569 4570 final ProcessRecord getRecordForAppLocked( 4571 IApplicationThread thread) { 4572 if (thread == null) { 4573 return null; 4574 } 4575 4576 int appIndex = getLRURecordIndexForAppLocked(thread); 4577 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4578 } 4579 4580 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4581 // If there are no longer any background processes running, 4582 // and the app that died was not running instrumentation, 4583 // then tell everyone we are now low on memory. 4584 boolean haveBg = false; 4585 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4586 ProcessRecord rec = mLruProcesses.get(i); 4587 if (rec.thread != null 4588 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4589 haveBg = true; 4590 break; 4591 } 4592 } 4593 4594 if (!haveBg) { 4595 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4596 if (doReport) { 4597 long now = SystemClock.uptimeMillis(); 4598 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4599 doReport = false; 4600 } else { 4601 mLastMemUsageReportTime = now; 4602 } 4603 } 4604 final ArrayList<ProcessMemInfo> memInfos 4605 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4606 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4607 long now = SystemClock.uptimeMillis(); 4608 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4609 ProcessRecord rec = mLruProcesses.get(i); 4610 if (rec == dyingProc || rec.thread == null) { 4611 continue; 4612 } 4613 if (doReport) { 4614 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4615 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4616 } 4617 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4618 // The low memory report is overriding any current 4619 // state for a GC request. Make sure to do 4620 // heavy/important/visible/foreground processes first. 4621 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4622 rec.lastRequestedGc = 0; 4623 } else { 4624 rec.lastRequestedGc = rec.lastLowMemory; 4625 } 4626 rec.reportLowMemory = true; 4627 rec.lastLowMemory = now; 4628 mProcessesToGc.remove(rec); 4629 addProcessToGcListLocked(rec); 4630 } 4631 } 4632 if (doReport) { 4633 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4634 mHandler.sendMessage(msg); 4635 } 4636 scheduleAppGcsLocked(); 4637 } 4638 } 4639 4640 final void appDiedLocked(ProcessRecord app) { 4641 appDiedLocked(app, app.pid, app.thread); 4642 } 4643 4644 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4645 // First check if this ProcessRecord is actually active for the pid. 4646 synchronized (mPidsSelfLocked) { 4647 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4648 if (curProc != app) { 4649 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4650 return; 4651 } 4652 } 4653 4654 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4655 synchronized (stats) { 4656 stats.noteProcessDiedLocked(app.info.uid, pid); 4657 } 4658 4659 Process.killProcessQuiet(pid); 4660 Process.killProcessGroup(app.info.uid, pid); 4661 app.killed = true; 4662 4663 // Clean up already done if the process has been re-started. 4664 if (app.pid == pid && app.thread != null && 4665 app.thread.asBinder() == thread.asBinder()) { 4666 boolean doLowMem = app.instrumentationClass == null; 4667 boolean doOomAdj = doLowMem; 4668 if (!app.killedByAm) { 4669 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4670 + ") has died"); 4671 mAllowLowerMemLevel = true; 4672 } else { 4673 // Note that we always want to do oom adj to update our state with the 4674 // new number of procs. 4675 mAllowLowerMemLevel = false; 4676 doLowMem = false; 4677 } 4678 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4679 if (DEBUG_CLEANUP) Slog.v( 4680 TAG, "Dying app: " + app + ", pid: " + pid 4681 + ", thread: " + thread.asBinder()); 4682 handleAppDiedLocked(app, false, true); 4683 4684 if (doOomAdj) { 4685 updateOomAdjLocked(); 4686 } 4687 if (doLowMem) { 4688 doLowMemReportIfNeededLocked(app); 4689 } 4690 } else if (app.pid != pid) { 4691 // A new process has already been started. 4692 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4693 + ") has died and restarted (pid " + app.pid + ")."); 4694 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4695 } else if (DEBUG_PROCESSES) { 4696 Slog.d(TAG, "Received spurious death notification for thread " 4697 + thread.asBinder()); 4698 } 4699 } 4700 4701 /** 4702 * If a stack trace dump file is configured, dump process stack traces. 4703 * @param clearTraces causes the dump file to be erased prior to the new 4704 * traces being written, if true; when false, the new traces will be 4705 * appended to any existing file content. 4706 * @param firstPids of dalvik VM processes to dump stack traces for first 4707 * @param lastPids of dalvik VM processes to dump stack traces for last 4708 * @param nativeProcs optional list of native process names to dump stack crawls 4709 * @return file containing stack traces, or null if no dump file is configured 4710 */ 4711 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4712 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4713 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4714 if (tracesPath == null || tracesPath.length() == 0) { 4715 return null; 4716 } 4717 4718 File tracesFile = new File(tracesPath); 4719 try { 4720 File tracesDir = tracesFile.getParentFile(); 4721 if (!tracesDir.exists()) { 4722 tracesDir.mkdirs(); 4723 if (!SELinux.restorecon(tracesDir)) { 4724 return null; 4725 } 4726 } 4727 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4728 4729 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4730 tracesFile.createNewFile(); 4731 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4732 } catch (IOException e) { 4733 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4734 return null; 4735 } 4736 4737 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4738 return tracesFile; 4739 } 4740 4741 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4742 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4743 // Use a FileObserver to detect when traces finish writing. 4744 // The order of traces is considered important to maintain for legibility. 4745 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4746 @Override 4747 public synchronized void onEvent(int event, String path) { notify(); } 4748 }; 4749 4750 try { 4751 observer.startWatching(); 4752 4753 // First collect all of the stacks of the most important pids. 4754 if (firstPids != null) { 4755 try { 4756 int num = firstPids.size(); 4757 for (int i = 0; i < num; i++) { 4758 synchronized (observer) { 4759 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4760 observer.wait(200); // Wait for write-close, give up after 200msec 4761 } 4762 } 4763 } catch (InterruptedException e) { 4764 Slog.wtf(TAG, e); 4765 } 4766 } 4767 4768 // Next collect the stacks of the native pids 4769 if (nativeProcs != null) { 4770 int[] pids = Process.getPidsForCommands(nativeProcs); 4771 if (pids != null) { 4772 for (int pid : pids) { 4773 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4774 } 4775 } 4776 } 4777 4778 // Lastly, measure CPU usage. 4779 if (processCpuTracker != null) { 4780 processCpuTracker.init(); 4781 System.gc(); 4782 processCpuTracker.update(); 4783 try { 4784 synchronized (processCpuTracker) { 4785 processCpuTracker.wait(500); // measure over 1/2 second. 4786 } 4787 } catch (InterruptedException e) { 4788 } 4789 processCpuTracker.update(); 4790 4791 // We'll take the stack crawls of just the top apps using CPU. 4792 final int N = processCpuTracker.countWorkingStats(); 4793 int numProcs = 0; 4794 for (int i=0; i<N && numProcs<5; i++) { 4795 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4796 if (lastPids.indexOfKey(stats.pid) >= 0) { 4797 numProcs++; 4798 try { 4799 synchronized (observer) { 4800 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4801 observer.wait(200); // Wait for write-close, give up after 200msec 4802 } 4803 } catch (InterruptedException e) { 4804 Slog.wtf(TAG, e); 4805 } 4806 4807 } 4808 } 4809 } 4810 } finally { 4811 observer.stopWatching(); 4812 } 4813 } 4814 4815 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4816 if (true || IS_USER_BUILD) { 4817 return; 4818 } 4819 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4820 if (tracesPath == null || tracesPath.length() == 0) { 4821 return; 4822 } 4823 4824 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4825 StrictMode.allowThreadDiskWrites(); 4826 try { 4827 final File tracesFile = new File(tracesPath); 4828 final File tracesDir = tracesFile.getParentFile(); 4829 final File tracesTmp = new File(tracesDir, "__tmp__"); 4830 try { 4831 if (!tracesDir.exists()) { 4832 tracesDir.mkdirs(); 4833 if (!SELinux.restorecon(tracesDir.getPath())) { 4834 return; 4835 } 4836 } 4837 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4838 4839 if (tracesFile.exists()) { 4840 tracesTmp.delete(); 4841 tracesFile.renameTo(tracesTmp); 4842 } 4843 StringBuilder sb = new StringBuilder(); 4844 Time tobj = new Time(); 4845 tobj.set(System.currentTimeMillis()); 4846 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4847 sb.append(": "); 4848 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4849 sb.append(" since "); 4850 sb.append(msg); 4851 FileOutputStream fos = new FileOutputStream(tracesFile); 4852 fos.write(sb.toString().getBytes()); 4853 if (app == null) { 4854 fos.write("\n*** No application process!".getBytes()); 4855 } 4856 fos.close(); 4857 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4858 } catch (IOException e) { 4859 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4860 return; 4861 } 4862 4863 if (app != null) { 4864 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4865 firstPids.add(app.pid); 4866 dumpStackTraces(tracesPath, firstPids, null, null, null); 4867 } 4868 4869 File lastTracesFile = null; 4870 File curTracesFile = null; 4871 for (int i=9; i>=0; i--) { 4872 String name = String.format(Locale.US, "slow%02d.txt", i); 4873 curTracesFile = new File(tracesDir, name); 4874 if (curTracesFile.exists()) { 4875 if (lastTracesFile != null) { 4876 curTracesFile.renameTo(lastTracesFile); 4877 } else { 4878 curTracesFile.delete(); 4879 } 4880 } 4881 lastTracesFile = curTracesFile; 4882 } 4883 tracesFile.renameTo(curTracesFile); 4884 if (tracesTmp.exists()) { 4885 tracesTmp.renameTo(tracesFile); 4886 } 4887 } finally { 4888 StrictMode.setThreadPolicy(oldPolicy); 4889 } 4890 } 4891 4892 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4893 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4894 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4895 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4896 4897 if (mController != null) { 4898 try { 4899 // 0 == continue, -1 = kill process immediately 4900 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4901 if (res < 0 && app.pid != MY_PID) { 4902 app.kill("anr", true); 4903 } 4904 } catch (RemoteException e) { 4905 mController = null; 4906 Watchdog.getInstance().setActivityController(null); 4907 } 4908 } 4909 4910 long anrTime = SystemClock.uptimeMillis(); 4911 if (MONITOR_CPU_USAGE) { 4912 updateCpuStatsNow(); 4913 } 4914 4915 synchronized (this) { 4916 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4917 if (mShuttingDown) { 4918 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4919 return; 4920 } else if (app.notResponding) { 4921 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4922 return; 4923 } else if (app.crashing) { 4924 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4925 return; 4926 } 4927 4928 // In case we come through here for the same app before completing 4929 // this one, mark as anring now so we will bail out. 4930 app.notResponding = true; 4931 4932 // Log the ANR to the event log. 4933 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4934 app.processName, app.info.flags, annotation); 4935 4936 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4937 firstPids.add(app.pid); 4938 4939 int parentPid = app.pid; 4940 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4941 if (parentPid != app.pid) firstPids.add(parentPid); 4942 4943 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4944 4945 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4946 ProcessRecord r = mLruProcesses.get(i); 4947 if (r != null && r.thread != null) { 4948 int pid = r.pid; 4949 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4950 if (r.persistent) { 4951 firstPids.add(pid); 4952 } else { 4953 lastPids.put(pid, Boolean.TRUE); 4954 } 4955 } 4956 } 4957 } 4958 } 4959 4960 // Log the ANR to the main log. 4961 StringBuilder info = new StringBuilder(); 4962 info.setLength(0); 4963 info.append("ANR in ").append(app.processName); 4964 if (activity != null && activity.shortComponentName != null) { 4965 info.append(" (").append(activity.shortComponentName).append(")"); 4966 } 4967 info.append("\n"); 4968 info.append("PID: ").append(app.pid).append("\n"); 4969 if (annotation != null) { 4970 info.append("Reason: ").append(annotation).append("\n"); 4971 } 4972 if (parent != null && parent != activity) { 4973 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4974 } 4975 4976 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4977 4978 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4979 NATIVE_STACKS_OF_INTEREST); 4980 4981 String cpuInfo = null; 4982 if (MONITOR_CPU_USAGE) { 4983 updateCpuStatsNow(); 4984 synchronized (mProcessCpuTracker) { 4985 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4986 } 4987 info.append(processCpuTracker.printCurrentLoad()); 4988 info.append(cpuInfo); 4989 } 4990 4991 info.append(processCpuTracker.printCurrentState(anrTime)); 4992 4993 Slog.e(TAG, info.toString()); 4994 if (tracesFile == null) { 4995 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4996 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4997 } 4998 4999 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5000 cpuInfo, tracesFile, null); 5001 5002 if (mController != null) { 5003 try { 5004 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5005 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5006 if (res != 0) { 5007 if (res < 0 && app.pid != MY_PID) { 5008 app.kill("anr", true); 5009 } else { 5010 synchronized (this) { 5011 mServices.scheduleServiceTimeoutLocked(app); 5012 } 5013 } 5014 return; 5015 } 5016 } catch (RemoteException e) { 5017 mController = null; 5018 Watchdog.getInstance().setActivityController(null); 5019 } 5020 } 5021 5022 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5023 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5024 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5025 5026 synchronized (this) { 5027 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5028 5029 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5030 app.kill("bg anr", true); 5031 return; 5032 } 5033 5034 // Set the app's notResponding state, and look up the errorReportReceiver 5035 makeAppNotRespondingLocked(app, 5036 activity != null ? activity.shortComponentName : null, 5037 annotation != null ? "ANR " + annotation : "ANR", 5038 info.toString()); 5039 5040 // Bring up the infamous App Not Responding dialog 5041 Message msg = Message.obtain(); 5042 HashMap<String, Object> map = new HashMap<String, Object>(); 5043 msg.what = SHOW_NOT_RESPONDING_MSG; 5044 msg.obj = map; 5045 msg.arg1 = aboveSystem ? 1 : 0; 5046 map.put("app", app); 5047 if (activity != null) { 5048 map.put("activity", activity); 5049 } 5050 5051 mHandler.sendMessage(msg); 5052 } 5053 } 5054 5055 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5056 if (!mLaunchWarningShown) { 5057 mLaunchWarningShown = true; 5058 mHandler.post(new Runnable() { 5059 @Override 5060 public void run() { 5061 synchronized (ActivityManagerService.this) { 5062 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5063 d.show(); 5064 mHandler.postDelayed(new Runnable() { 5065 @Override 5066 public void run() { 5067 synchronized (ActivityManagerService.this) { 5068 d.dismiss(); 5069 mLaunchWarningShown = false; 5070 } 5071 } 5072 }, 4000); 5073 } 5074 } 5075 }); 5076 } 5077 } 5078 5079 @Override 5080 public boolean clearApplicationUserData(final String packageName, 5081 final IPackageDataObserver observer, int userId) { 5082 enforceNotIsolatedCaller("clearApplicationUserData"); 5083 int uid = Binder.getCallingUid(); 5084 int pid = Binder.getCallingPid(); 5085 userId = handleIncomingUser(pid, uid, 5086 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5087 long callingId = Binder.clearCallingIdentity(); 5088 try { 5089 IPackageManager pm = AppGlobals.getPackageManager(); 5090 int pkgUid = -1; 5091 synchronized(this) { 5092 try { 5093 pkgUid = pm.getPackageUid(packageName, userId); 5094 } catch (RemoteException e) { 5095 } 5096 if (pkgUid == -1) { 5097 Slog.w(TAG, "Invalid packageName: " + packageName); 5098 if (observer != null) { 5099 try { 5100 observer.onRemoveCompleted(packageName, false); 5101 } catch (RemoteException e) { 5102 Slog.i(TAG, "Observer no longer exists."); 5103 } 5104 } 5105 return false; 5106 } 5107 if (uid == pkgUid || checkComponentPermission( 5108 android.Manifest.permission.CLEAR_APP_USER_DATA, 5109 pid, uid, -1, true) 5110 == PackageManager.PERMISSION_GRANTED) { 5111 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5112 } else { 5113 throw new SecurityException("PID " + pid + " does not have permission " 5114 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5115 + " of package " + packageName); 5116 } 5117 5118 // Remove all tasks match the cleared application package and user 5119 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5120 final TaskRecord tr = mRecentTasks.get(i); 5121 final String taskPackageName = 5122 tr.getBaseIntent().getComponent().getPackageName(); 5123 if (tr.userId != userId) continue; 5124 if (!taskPackageName.equals(packageName)) continue; 5125 removeTaskByIdLocked(tr.taskId, false); 5126 } 5127 } 5128 5129 try { 5130 // Clear application user data 5131 pm.clearApplicationUserData(packageName, observer, userId); 5132 5133 synchronized(this) { 5134 // Remove all permissions granted from/to this package 5135 removeUriPermissionsForPackageLocked(packageName, userId, true); 5136 } 5137 5138 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5139 Uri.fromParts("package", packageName, null)); 5140 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5141 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5142 null, null, 0, null, null, null, false, false, userId); 5143 } catch (RemoteException e) { 5144 } 5145 } finally { 5146 Binder.restoreCallingIdentity(callingId); 5147 } 5148 return true; 5149 } 5150 5151 @Override 5152 public void killBackgroundProcesses(final String packageName, int userId) { 5153 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5154 != PackageManager.PERMISSION_GRANTED && 5155 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5156 != PackageManager.PERMISSION_GRANTED) { 5157 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5158 + Binder.getCallingPid() 5159 + ", uid=" + Binder.getCallingUid() 5160 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5161 Slog.w(TAG, msg); 5162 throw new SecurityException(msg); 5163 } 5164 5165 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5166 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5167 long callingId = Binder.clearCallingIdentity(); 5168 try { 5169 IPackageManager pm = AppGlobals.getPackageManager(); 5170 synchronized(this) { 5171 int appId = -1; 5172 try { 5173 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5174 } catch (RemoteException e) { 5175 } 5176 if (appId == -1) { 5177 Slog.w(TAG, "Invalid packageName: " + packageName); 5178 return; 5179 } 5180 killPackageProcessesLocked(packageName, appId, userId, 5181 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5182 } 5183 } finally { 5184 Binder.restoreCallingIdentity(callingId); 5185 } 5186 } 5187 5188 @Override 5189 public void killAllBackgroundProcesses() { 5190 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5191 != PackageManager.PERMISSION_GRANTED) { 5192 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5193 + Binder.getCallingPid() 5194 + ", uid=" + Binder.getCallingUid() 5195 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5196 Slog.w(TAG, msg); 5197 throw new SecurityException(msg); 5198 } 5199 5200 long callingId = Binder.clearCallingIdentity(); 5201 try { 5202 synchronized(this) { 5203 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5204 final int NP = mProcessNames.getMap().size(); 5205 for (int ip=0; ip<NP; ip++) { 5206 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5207 final int NA = apps.size(); 5208 for (int ia=0; ia<NA; ia++) { 5209 ProcessRecord app = apps.valueAt(ia); 5210 if (app.persistent) { 5211 // we don't kill persistent processes 5212 continue; 5213 } 5214 if (app.removed) { 5215 procs.add(app); 5216 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5217 app.removed = true; 5218 procs.add(app); 5219 } 5220 } 5221 } 5222 5223 int N = procs.size(); 5224 for (int i=0; i<N; i++) { 5225 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5226 } 5227 mAllowLowerMemLevel = true; 5228 updateOomAdjLocked(); 5229 doLowMemReportIfNeededLocked(null); 5230 } 5231 } finally { 5232 Binder.restoreCallingIdentity(callingId); 5233 } 5234 } 5235 5236 @Override 5237 public void forceStopPackage(final String packageName, int userId) { 5238 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5239 != PackageManager.PERMISSION_GRANTED) { 5240 String msg = "Permission Denial: forceStopPackage() from pid=" 5241 + Binder.getCallingPid() 5242 + ", uid=" + Binder.getCallingUid() 5243 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5244 Slog.w(TAG, msg); 5245 throw new SecurityException(msg); 5246 } 5247 final int callingPid = Binder.getCallingPid(); 5248 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5249 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5250 long callingId = Binder.clearCallingIdentity(); 5251 try { 5252 IPackageManager pm = AppGlobals.getPackageManager(); 5253 synchronized(this) { 5254 int[] users = userId == UserHandle.USER_ALL 5255 ? getUsersLocked() : new int[] { userId }; 5256 for (int user : users) { 5257 int pkgUid = -1; 5258 try { 5259 pkgUid = pm.getPackageUid(packageName, user); 5260 } catch (RemoteException e) { 5261 } 5262 if (pkgUid == -1) { 5263 Slog.w(TAG, "Invalid packageName: " + packageName); 5264 continue; 5265 } 5266 try { 5267 pm.setPackageStoppedState(packageName, true, user); 5268 } catch (RemoteException e) { 5269 } catch (IllegalArgumentException e) { 5270 Slog.w(TAG, "Failed trying to unstop package " 5271 + packageName + ": " + e); 5272 } 5273 if (isUserRunningLocked(user, false)) { 5274 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5275 } 5276 } 5277 } 5278 } finally { 5279 Binder.restoreCallingIdentity(callingId); 5280 } 5281 } 5282 5283 @Override 5284 public void addPackageDependency(String packageName) { 5285 synchronized (this) { 5286 int callingPid = Binder.getCallingPid(); 5287 if (callingPid == Process.myPid()) { 5288 // Yeah, um, no. 5289 Slog.w(TAG, "Can't addPackageDependency on system process"); 5290 return; 5291 } 5292 ProcessRecord proc; 5293 synchronized (mPidsSelfLocked) { 5294 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5295 } 5296 if (proc != null) { 5297 if (proc.pkgDeps == null) { 5298 proc.pkgDeps = new ArraySet<String>(1); 5299 } 5300 proc.pkgDeps.add(packageName); 5301 } 5302 } 5303 } 5304 5305 /* 5306 * The pkg name and app id have to be specified. 5307 */ 5308 @Override 5309 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5310 if (pkg == null) { 5311 return; 5312 } 5313 // Make sure the uid is valid. 5314 if (appid < 0) { 5315 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5316 return; 5317 } 5318 int callerUid = Binder.getCallingUid(); 5319 // Only the system server can kill an application 5320 if (callerUid == Process.SYSTEM_UID) { 5321 // Post an aysnc message to kill the application 5322 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5323 msg.arg1 = appid; 5324 msg.arg2 = 0; 5325 Bundle bundle = new Bundle(); 5326 bundle.putString("pkg", pkg); 5327 bundle.putString("reason", reason); 5328 msg.obj = bundle; 5329 mHandler.sendMessage(msg); 5330 } else { 5331 throw new SecurityException(callerUid + " cannot kill pkg: " + 5332 pkg); 5333 } 5334 } 5335 5336 @Override 5337 public void closeSystemDialogs(String reason) { 5338 enforceNotIsolatedCaller("closeSystemDialogs"); 5339 5340 final int pid = Binder.getCallingPid(); 5341 final int uid = Binder.getCallingUid(); 5342 final long origId = Binder.clearCallingIdentity(); 5343 try { 5344 synchronized (this) { 5345 // Only allow this from foreground processes, so that background 5346 // applications can't abuse it to prevent system UI from being shown. 5347 if (uid >= Process.FIRST_APPLICATION_UID) { 5348 ProcessRecord proc; 5349 synchronized (mPidsSelfLocked) { 5350 proc = mPidsSelfLocked.get(pid); 5351 } 5352 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5353 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5354 + " from background process " + proc); 5355 return; 5356 } 5357 } 5358 closeSystemDialogsLocked(reason); 5359 } 5360 } finally { 5361 Binder.restoreCallingIdentity(origId); 5362 } 5363 } 5364 5365 void closeSystemDialogsLocked(String reason) { 5366 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5367 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5368 | Intent.FLAG_RECEIVER_FOREGROUND); 5369 if (reason != null) { 5370 intent.putExtra("reason", reason); 5371 } 5372 mWindowManager.closeSystemDialogs(reason); 5373 5374 mStackSupervisor.closeSystemDialogsLocked(); 5375 5376 broadcastIntentLocked(null, null, intent, null, 5377 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5378 Process.SYSTEM_UID, UserHandle.USER_ALL); 5379 } 5380 5381 @Override 5382 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5383 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5384 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5385 for (int i=pids.length-1; i>=0; i--) { 5386 ProcessRecord proc; 5387 int oomAdj; 5388 synchronized (this) { 5389 synchronized (mPidsSelfLocked) { 5390 proc = mPidsSelfLocked.get(pids[i]); 5391 oomAdj = proc != null ? proc.setAdj : 0; 5392 } 5393 } 5394 infos[i] = new Debug.MemoryInfo(); 5395 Debug.getMemoryInfo(pids[i], infos[i]); 5396 if (proc != null) { 5397 synchronized (this) { 5398 if (proc.thread != null && proc.setAdj == oomAdj) { 5399 // Record this for posterity if the process has been stable. 5400 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5401 infos[i].getTotalUss(), false, proc.pkgList); 5402 } 5403 } 5404 } 5405 } 5406 return infos; 5407 } 5408 5409 @Override 5410 public long[] getProcessPss(int[] pids) { 5411 enforceNotIsolatedCaller("getProcessPss"); 5412 long[] pss = new long[pids.length]; 5413 for (int i=pids.length-1; i>=0; i--) { 5414 ProcessRecord proc; 5415 int oomAdj; 5416 synchronized (this) { 5417 synchronized (mPidsSelfLocked) { 5418 proc = mPidsSelfLocked.get(pids[i]); 5419 oomAdj = proc != null ? proc.setAdj : 0; 5420 } 5421 } 5422 long[] tmpUss = new long[1]; 5423 pss[i] = Debug.getPss(pids[i], tmpUss); 5424 if (proc != null) { 5425 synchronized (this) { 5426 if (proc.thread != null && proc.setAdj == oomAdj) { 5427 // Record this for posterity if the process has been stable. 5428 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5429 } 5430 } 5431 } 5432 } 5433 return pss; 5434 } 5435 5436 @Override 5437 public void killApplicationProcess(String processName, int uid) { 5438 if (processName == null) { 5439 return; 5440 } 5441 5442 int callerUid = Binder.getCallingUid(); 5443 // Only the system server can kill an application 5444 if (callerUid == Process.SYSTEM_UID) { 5445 synchronized (this) { 5446 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5447 if (app != null && app.thread != null) { 5448 try { 5449 app.thread.scheduleSuicide(); 5450 } catch (RemoteException e) { 5451 // If the other end already died, then our work here is done. 5452 } 5453 } else { 5454 Slog.w(TAG, "Process/uid not found attempting kill of " 5455 + processName + " / " + uid); 5456 } 5457 } 5458 } else { 5459 throw new SecurityException(callerUid + " cannot kill app process: " + 5460 processName); 5461 } 5462 } 5463 5464 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5465 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5466 false, true, false, false, UserHandle.getUserId(uid), reason); 5467 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5468 Uri.fromParts("package", packageName, null)); 5469 if (!mProcessesReady) { 5470 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5471 | Intent.FLAG_RECEIVER_FOREGROUND); 5472 } 5473 intent.putExtra(Intent.EXTRA_UID, uid); 5474 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5475 broadcastIntentLocked(null, null, intent, 5476 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5477 false, false, 5478 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5479 } 5480 5481 private void forceStopUserLocked(int userId, String reason) { 5482 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5483 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5484 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5485 | Intent.FLAG_RECEIVER_FOREGROUND); 5486 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5487 broadcastIntentLocked(null, null, intent, 5488 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5489 false, false, 5490 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5491 } 5492 5493 private final boolean killPackageProcessesLocked(String packageName, int appId, 5494 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5495 boolean doit, boolean evenPersistent, String reason) { 5496 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5497 5498 // Remove all processes this package may have touched: all with the 5499 // same UID (except for the system or root user), and all whose name 5500 // matches the package name. 5501 final int NP = mProcessNames.getMap().size(); 5502 for (int ip=0; ip<NP; ip++) { 5503 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5504 final int NA = apps.size(); 5505 for (int ia=0; ia<NA; ia++) { 5506 ProcessRecord app = apps.valueAt(ia); 5507 if (app.persistent && !evenPersistent) { 5508 // we don't kill persistent processes 5509 continue; 5510 } 5511 if (app.removed) { 5512 if (doit) { 5513 procs.add(app); 5514 } 5515 continue; 5516 } 5517 5518 // Skip process if it doesn't meet our oom adj requirement. 5519 if (app.setAdj < minOomAdj) { 5520 continue; 5521 } 5522 5523 // If no package is specified, we call all processes under the 5524 // give user id. 5525 if (packageName == null) { 5526 if (app.userId != userId) { 5527 continue; 5528 } 5529 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5530 continue; 5531 } 5532 // Package has been specified, we want to hit all processes 5533 // that match it. We need to qualify this by the processes 5534 // that are running under the specified app and user ID. 5535 } else { 5536 final boolean isDep = app.pkgDeps != null 5537 && app.pkgDeps.contains(packageName); 5538 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5539 continue; 5540 } 5541 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5542 continue; 5543 } 5544 if (!app.pkgList.containsKey(packageName) && !isDep) { 5545 continue; 5546 } 5547 } 5548 5549 // Process has passed all conditions, kill it! 5550 if (!doit) { 5551 return true; 5552 } 5553 app.removed = true; 5554 procs.add(app); 5555 } 5556 } 5557 5558 int N = procs.size(); 5559 for (int i=0; i<N; i++) { 5560 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5561 } 5562 updateOomAdjLocked(); 5563 return N > 0; 5564 } 5565 5566 private final boolean forceStopPackageLocked(String name, int appId, 5567 boolean callerWillRestart, boolean purgeCache, boolean doit, 5568 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5569 int i; 5570 int N; 5571 5572 if (userId == UserHandle.USER_ALL && name == null) { 5573 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5574 } 5575 5576 if (appId < 0 && name != null) { 5577 try { 5578 appId = UserHandle.getAppId( 5579 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5580 } catch (RemoteException e) { 5581 } 5582 } 5583 5584 if (doit) { 5585 if (name != null) { 5586 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5587 + " user=" + userId + ": " + reason); 5588 } else { 5589 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5590 } 5591 5592 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5593 for (int ip=pmap.size()-1; ip>=0; ip--) { 5594 SparseArray<Long> ba = pmap.valueAt(ip); 5595 for (i=ba.size()-1; i>=0; i--) { 5596 boolean remove = false; 5597 final int entUid = ba.keyAt(i); 5598 if (name != null) { 5599 if (userId == UserHandle.USER_ALL) { 5600 if (UserHandle.getAppId(entUid) == appId) { 5601 remove = true; 5602 } 5603 } else { 5604 if (entUid == UserHandle.getUid(userId, appId)) { 5605 remove = true; 5606 } 5607 } 5608 } else if (UserHandle.getUserId(entUid) == userId) { 5609 remove = true; 5610 } 5611 if (remove) { 5612 ba.removeAt(i); 5613 } 5614 } 5615 if (ba.size() == 0) { 5616 pmap.removeAt(ip); 5617 } 5618 } 5619 } 5620 5621 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5622 -100, callerWillRestart, true, doit, evenPersistent, 5623 name == null ? ("stop user " + userId) : ("stop " + name)); 5624 5625 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5626 if (!doit) { 5627 return true; 5628 } 5629 didSomething = true; 5630 } 5631 5632 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5633 if (!doit) { 5634 return true; 5635 } 5636 didSomething = true; 5637 } 5638 5639 if (name == null) { 5640 // Remove all sticky broadcasts from this user. 5641 mStickyBroadcasts.remove(userId); 5642 } 5643 5644 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5645 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5646 userId, providers)) { 5647 if (!doit) { 5648 return true; 5649 } 5650 didSomething = true; 5651 } 5652 N = providers.size(); 5653 for (i=0; i<N; i++) { 5654 removeDyingProviderLocked(null, providers.get(i), true); 5655 } 5656 5657 // Remove transient permissions granted from/to this package/user 5658 removeUriPermissionsForPackageLocked(name, userId, false); 5659 5660 if (name == null || uninstalling) { 5661 // Remove pending intents. For now we only do this when force 5662 // stopping users, because we have some problems when doing this 5663 // for packages -- app widgets are not currently cleaned up for 5664 // such packages, so they can be left with bad pending intents. 5665 if (mIntentSenderRecords.size() > 0) { 5666 Iterator<WeakReference<PendingIntentRecord>> it 5667 = mIntentSenderRecords.values().iterator(); 5668 while (it.hasNext()) { 5669 WeakReference<PendingIntentRecord> wpir = it.next(); 5670 if (wpir == null) { 5671 it.remove(); 5672 continue; 5673 } 5674 PendingIntentRecord pir = wpir.get(); 5675 if (pir == null) { 5676 it.remove(); 5677 continue; 5678 } 5679 if (name == null) { 5680 // Stopping user, remove all objects for the user. 5681 if (pir.key.userId != userId) { 5682 // Not the same user, skip it. 5683 continue; 5684 } 5685 } else { 5686 if (UserHandle.getAppId(pir.uid) != appId) { 5687 // Different app id, skip it. 5688 continue; 5689 } 5690 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5691 // Different user, skip it. 5692 continue; 5693 } 5694 if (!pir.key.packageName.equals(name)) { 5695 // Different package, skip it. 5696 continue; 5697 } 5698 } 5699 if (!doit) { 5700 return true; 5701 } 5702 didSomething = true; 5703 it.remove(); 5704 pir.canceled = true; 5705 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5706 pir.key.activity.pendingResults.remove(pir.ref); 5707 } 5708 } 5709 } 5710 } 5711 5712 if (doit) { 5713 if (purgeCache && name != null) { 5714 AttributeCache ac = AttributeCache.instance(); 5715 if (ac != null) { 5716 ac.removePackage(name); 5717 } 5718 } 5719 if (mBooted) { 5720 mStackSupervisor.resumeTopActivitiesLocked(); 5721 mStackSupervisor.scheduleIdleLocked(); 5722 } 5723 } 5724 5725 return didSomething; 5726 } 5727 5728 private final boolean removeProcessLocked(ProcessRecord app, 5729 boolean callerWillRestart, boolean allowRestart, String reason) { 5730 final String name = app.processName; 5731 final int uid = app.uid; 5732 if (DEBUG_PROCESSES) Slog.d( 5733 TAG, "Force removing proc " + app.toShortString() + " (" + name 5734 + "/" + uid + ")"); 5735 5736 mProcessNames.remove(name, uid); 5737 mIsolatedProcesses.remove(app.uid); 5738 if (mHeavyWeightProcess == app) { 5739 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5740 mHeavyWeightProcess.userId, 0)); 5741 mHeavyWeightProcess = null; 5742 } 5743 boolean needRestart = false; 5744 if (app.pid > 0 && app.pid != MY_PID) { 5745 int pid = app.pid; 5746 synchronized (mPidsSelfLocked) { 5747 mPidsSelfLocked.remove(pid); 5748 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5749 } 5750 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5751 if (app.isolated) { 5752 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5753 } 5754 app.kill(reason, true); 5755 handleAppDiedLocked(app, true, allowRestart); 5756 removeLruProcessLocked(app); 5757 5758 if (app.persistent && !app.isolated) { 5759 if (!callerWillRestart) { 5760 addAppLocked(app.info, false, null /* ABI override */); 5761 } else { 5762 needRestart = true; 5763 } 5764 } 5765 } else { 5766 mRemovedProcesses.add(app); 5767 } 5768 5769 return needRestart; 5770 } 5771 5772 private final void processStartTimedOutLocked(ProcessRecord app) { 5773 final int pid = app.pid; 5774 boolean gone = false; 5775 synchronized (mPidsSelfLocked) { 5776 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5777 if (knownApp != null && knownApp.thread == null) { 5778 mPidsSelfLocked.remove(pid); 5779 gone = true; 5780 } 5781 } 5782 5783 if (gone) { 5784 Slog.w(TAG, "Process " + app + " failed to attach"); 5785 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5786 pid, app.uid, app.processName); 5787 mProcessNames.remove(app.processName, app.uid); 5788 mIsolatedProcesses.remove(app.uid); 5789 if (mHeavyWeightProcess == app) { 5790 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5791 mHeavyWeightProcess.userId, 0)); 5792 mHeavyWeightProcess = null; 5793 } 5794 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5795 if (app.isolated) { 5796 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5797 } 5798 // Take care of any launching providers waiting for this process. 5799 checkAppInLaunchingProvidersLocked(app, true); 5800 // Take care of any services that are waiting for the process. 5801 mServices.processStartTimedOutLocked(app); 5802 app.kill("start timeout", true); 5803 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5804 Slog.w(TAG, "Unattached app died before backup, skipping"); 5805 try { 5806 IBackupManager bm = IBackupManager.Stub.asInterface( 5807 ServiceManager.getService(Context.BACKUP_SERVICE)); 5808 bm.agentDisconnected(app.info.packageName); 5809 } catch (RemoteException e) { 5810 // Can't happen; the backup manager is local 5811 } 5812 } 5813 if (isPendingBroadcastProcessLocked(pid)) { 5814 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5815 skipPendingBroadcastLocked(pid); 5816 } 5817 } else { 5818 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5819 } 5820 } 5821 5822 private final boolean attachApplicationLocked(IApplicationThread thread, 5823 int pid) { 5824 5825 // Find the application record that is being attached... either via 5826 // the pid if we are running in multiple processes, or just pull the 5827 // next app record if we are emulating process with anonymous threads. 5828 ProcessRecord app; 5829 if (pid != MY_PID && pid >= 0) { 5830 synchronized (mPidsSelfLocked) { 5831 app = mPidsSelfLocked.get(pid); 5832 } 5833 } else { 5834 app = null; 5835 } 5836 5837 if (app == null) { 5838 Slog.w(TAG, "No pending application record for pid " + pid 5839 + " (IApplicationThread " + thread + "); dropping process"); 5840 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5841 if (pid > 0 && pid != MY_PID) { 5842 Process.killProcessQuiet(pid); 5843 //TODO: Process.killProcessGroup(app.info.uid, pid); 5844 } else { 5845 try { 5846 thread.scheduleExit(); 5847 } catch (Exception e) { 5848 // Ignore exceptions. 5849 } 5850 } 5851 return false; 5852 } 5853 5854 // If this application record is still attached to a previous 5855 // process, clean it up now. 5856 if (app.thread != null) { 5857 handleAppDiedLocked(app, true, true); 5858 } 5859 5860 // Tell the process all about itself. 5861 5862 if (localLOGV) Slog.v( 5863 TAG, "Binding process pid " + pid + " to record " + app); 5864 5865 final String processName = app.processName; 5866 try { 5867 AppDeathRecipient adr = new AppDeathRecipient( 5868 app, pid, thread); 5869 thread.asBinder().linkToDeath(adr, 0); 5870 app.deathRecipient = adr; 5871 } catch (RemoteException e) { 5872 app.resetPackageList(mProcessStats); 5873 startProcessLocked(app, "link fail", processName); 5874 return false; 5875 } 5876 5877 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5878 5879 app.makeActive(thread, mProcessStats); 5880 app.curAdj = app.setAdj = -100; 5881 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5882 app.forcingToForeground = null; 5883 updateProcessForegroundLocked(app, false, false); 5884 app.hasShownUi = false; 5885 app.debugging = false; 5886 app.cached = false; 5887 app.killedByAm = false; 5888 5889 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5890 5891 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5892 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5893 5894 if (!normalMode) { 5895 Slog.i(TAG, "Launching preboot mode app: " + app); 5896 } 5897 5898 if (localLOGV) Slog.v( 5899 TAG, "New app record " + app 5900 + " thread=" + thread.asBinder() + " pid=" + pid); 5901 try { 5902 int testMode = IApplicationThread.DEBUG_OFF; 5903 if (mDebugApp != null && mDebugApp.equals(processName)) { 5904 testMode = mWaitForDebugger 5905 ? IApplicationThread.DEBUG_WAIT 5906 : IApplicationThread.DEBUG_ON; 5907 app.debugging = true; 5908 if (mDebugTransient) { 5909 mDebugApp = mOrigDebugApp; 5910 mWaitForDebugger = mOrigWaitForDebugger; 5911 } 5912 } 5913 String profileFile = app.instrumentationProfileFile; 5914 ParcelFileDescriptor profileFd = null; 5915 int samplingInterval = 0; 5916 boolean profileAutoStop = false; 5917 if (mProfileApp != null && mProfileApp.equals(processName)) { 5918 mProfileProc = app; 5919 profileFile = mProfileFile; 5920 profileFd = mProfileFd; 5921 samplingInterval = mSamplingInterval; 5922 profileAutoStop = mAutoStopProfiler; 5923 } 5924 boolean enableOpenGlTrace = false; 5925 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5926 enableOpenGlTrace = true; 5927 mOpenGlTraceApp = null; 5928 } 5929 5930 // If the app is being launched for restore or full backup, set it up specially 5931 boolean isRestrictedBackupMode = false; 5932 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5933 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5934 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5935 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5936 } 5937 5938 ensurePackageDexOpt(app.instrumentationInfo != null 5939 ? app.instrumentationInfo.packageName 5940 : app.info.packageName); 5941 if (app.instrumentationClass != null) { 5942 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5943 } 5944 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5945 + processName + " with config " + mConfiguration); 5946 ApplicationInfo appInfo = app.instrumentationInfo != null 5947 ? app.instrumentationInfo : app.info; 5948 app.compat = compatibilityInfoForPackageLocked(appInfo); 5949 if (profileFd != null) { 5950 profileFd = profileFd.dup(); 5951 } 5952 ProfilerInfo profilerInfo = profileFile == null ? null 5953 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5954 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5955 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5956 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5957 isRestrictedBackupMode || !normalMode, app.persistent, 5958 new Configuration(mConfiguration), app.compat, 5959 getCommonServicesLocked(app.isolated), 5960 mCoreSettingsObserver.getCoreSettingsLocked()); 5961 updateLruProcessLocked(app, false, null); 5962 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5963 } catch (Exception e) { 5964 // todo: Yikes! What should we do? For now we will try to 5965 // start another process, but that could easily get us in 5966 // an infinite loop of restarting processes... 5967 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5968 5969 app.resetPackageList(mProcessStats); 5970 app.unlinkDeathRecipient(); 5971 startProcessLocked(app, "bind fail", processName); 5972 return false; 5973 } 5974 5975 // Remove this record from the list of starting applications. 5976 mPersistentStartingProcesses.remove(app); 5977 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5978 "Attach application locked removing on hold: " + app); 5979 mProcessesOnHold.remove(app); 5980 5981 boolean badApp = false; 5982 boolean didSomething = false; 5983 5984 // See if the top visible activity is waiting to run in this process... 5985 if (normalMode) { 5986 try { 5987 if (mStackSupervisor.attachApplicationLocked(app)) { 5988 didSomething = true; 5989 } 5990 } catch (Exception e) { 5991 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5992 badApp = true; 5993 } 5994 } 5995 5996 // Find any services that should be running in this process... 5997 if (!badApp) { 5998 try { 5999 didSomething |= mServices.attachApplicationLocked(app, processName); 6000 } catch (Exception e) { 6001 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6002 badApp = true; 6003 } 6004 } 6005 6006 // Check if a next-broadcast receiver is in this process... 6007 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6008 try { 6009 didSomething |= sendPendingBroadcastsLocked(app); 6010 } catch (Exception e) { 6011 // If the app died trying to launch the receiver we declare it 'bad' 6012 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6013 badApp = true; 6014 } 6015 } 6016 6017 // Check whether the next backup agent is in this process... 6018 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6019 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6020 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6021 try { 6022 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6023 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6024 mBackupTarget.backupMode); 6025 } catch (Exception e) { 6026 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6027 badApp = true; 6028 } 6029 } 6030 6031 if (badApp) { 6032 app.kill("error during init", true); 6033 handleAppDiedLocked(app, false, true); 6034 return false; 6035 } 6036 6037 if (!didSomething) { 6038 updateOomAdjLocked(); 6039 } 6040 6041 return true; 6042 } 6043 6044 @Override 6045 public final void attachApplication(IApplicationThread thread) { 6046 synchronized (this) { 6047 int callingPid = Binder.getCallingPid(); 6048 final long origId = Binder.clearCallingIdentity(); 6049 attachApplicationLocked(thread, callingPid); 6050 Binder.restoreCallingIdentity(origId); 6051 } 6052 } 6053 6054 @Override 6055 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6056 final long origId = Binder.clearCallingIdentity(); 6057 synchronized (this) { 6058 ActivityStack stack = ActivityRecord.getStackLocked(token); 6059 if (stack != null) { 6060 ActivityRecord r = 6061 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6062 if (stopProfiling) { 6063 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6064 try { 6065 mProfileFd.close(); 6066 } catch (IOException e) { 6067 } 6068 clearProfilerLocked(); 6069 } 6070 } 6071 } 6072 } 6073 Binder.restoreCallingIdentity(origId); 6074 } 6075 6076 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6077 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6078 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6079 } 6080 6081 void enableScreenAfterBoot() { 6082 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6083 SystemClock.uptimeMillis()); 6084 mWindowManager.enableScreenAfterBoot(); 6085 6086 synchronized (this) { 6087 updateEventDispatchingLocked(); 6088 } 6089 } 6090 6091 @Override 6092 public void showBootMessage(final CharSequence msg, final boolean always) { 6093 enforceNotIsolatedCaller("showBootMessage"); 6094 mWindowManager.showBootMessage(msg, always); 6095 } 6096 6097 @Override 6098 public void keyguardWaitingForActivityDrawn() { 6099 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6100 final long token = Binder.clearCallingIdentity(); 6101 try { 6102 synchronized (this) { 6103 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6104 mWindowManager.keyguardWaitingForActivityDrawn(); 6105 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6106 mLockScreenShown = LOCK_SCREEN_LEAVING; 6107 updateSleepIfNeededLocked(); 6108 } 6109 } 6110 } finally { 6111 Binder.restoreCallingIdentity(token); 6112 } 6113 } 6114 6115 final void finishBooting() { 6116 synchronized (this) { 6117 if (!mBootAnimationComplete) { 6118 mCallFinishBooting = true; 6119 return; 6120 } 6121 mCallFinishBooting = false; 6122 } 6123 6124 ArraySet<String> completedIsas = new ArraySet<String>(); 6125 for (String abi : Build.SUPPORTED_ABIS) { 6126 Process.establishZygoteConnectionForAbi(abi); 6127 final String instructionSet = VMRuntime.getInstructionSet(abi); 6128 if (!completedIsas.contains(instructionSet)) { 6129 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6130 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6131 } 6132 completedIsas.add(instructionSet); 6133 } 6134 } 6135 6136 IntentFilter pkgFilter = new IntentFilter(); 6137 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6138 pkgFilter.addDataScheme("package"); 6139 mContext.registerReceiver(new BroadcastReceiver() { 6140 @Override 6141 public void onReceive(Context context, Intent intent) { 6142 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6143 if (pkgs != null) { 6144 for (String pkg : pkgs) { 6145 synchronized (ActivityManagerService.this) { 6146 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6147 0, "finished booting")) { 6148 setResultCode(Activity.RESULT_OK); 6149 return; 6150 } 6151 } 6152 } 6153 } 6154 } 6155 }, pkgFilter); 6156 6157 // Let system services know. 6158 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6159 6160 synchronized (this) { 6161 // Ensure that any processes we had put on hold are now started 6162 // up. 6163 final int NP = mProcessesOnHold.size(); 6164 if (NP > 0) { 6165 ArrayList<ProcessRecord> procs = 6166 new ArrayList<ProcessRecord>(mProcessesOnHold); 6167 for (int ip=0; ip<NP; ip++) { 6168 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6169 + procs.get(ip)); 6170 startProcessLocked(procs.get(ip), "on-hold", null); 6171 } 6172 } 6173 6174 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6175 // Start looking for apps that are abusing wake locks. 6176 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6177 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6178 // Tell anyone interested that we are done booting! 6179 SystemProperties.set("sys.boot_completed", "1"); 6180 6181 // And trigger dev.bootcomplete if we are not showing encryption progress 6182 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6183 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6184 SystemProperties.set("dev.bootcomplete", "1"); 6185 } 6186 for (int i=0; i<mStartedUsers.size(); i++) { 6187 UserStartedState uss = mStartedUsers.valueAt(i); 6188 if (uss.mState == UserStartedState.STATE_BOOTING) { 6189 uss.mState = UserStartedState.STATE_RUNNING; 6190 final int userId = mStartedUsers.keyAt(i); 6191 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6192 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6193 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6194 broadcastIntentLocked(null, null, intent, null, 6195 new IIntentReceiver.Stub() { 6196 @Override 6197 public void performReceive(Intent intent, int resultCode, 6198 String data, Bundle extras, boolean ordered, 6199 boolean sticky, int sendingUser) { 6200 synchronized (ActivityManagerService.this) { 6201 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6202 true, false); 6203 } 6204 } 6205 }, 6206 0, null, null, 6207 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6208 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6209 userId); 6210 } 6211 } 6212 scheduleStartProfilesLocked(); 6213 } 6214 } 6215 } 6216 6217 @Override 6218 public void bootAnimationComplete() { 6219 final boolean callFinishBooting; 6220 synchronized (this) { 6221 callFinishBooting = mCallFinishBooting; 6222 mBootAnimationComplete = true; 6223 } 6224 if (callFinishBooting) { 6225 finishBooting(); 6226 } 6227 } 6228 6229 @Override 6230 public void systemBackupRestored() { 6231 synchronized (this) { 6232 if (mSystemReady) { 6233 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6234 } else { 6235 Slog.w(TAG, "System backup restored before system is ready"); 6236 } 6237 } 6238 } 6239 6240 final void ensureBootCompleted() { 6241 boolean booting; 6242 boolean enableScreen; 6243 synchronized (this) { 6244 booting = mBooting; 6245 mBooting = false; 6246 enableScreen = !mBooted; 6247 mBooted = true; 6248 } 6249 6250 if (booting) { 6251 finishBooting(); 6252 } 6253 6254 if (enableScreen) { 6255 enableScreenAfterBoot(); 6256 } 6257 } 6258 6259 @Override 6260 public final void activityResumed(IBinder token) { 6261 final long origId = Binder.clearCallingIdentity(); 6262 synchronized(this) { 6263 ActivityStack stack = ActivityRecord.getStackLocked(token); 6264 if (stack != null) { 6265 ActivityRecord.activityResumedLocked(token); 6266 } 6267 } 6268 Binder.restoreCallingIdentity(origId); 6269 } 6270 6271 @Override 6272 public final void activityPaused(IBinder token) { 6273 final long origId = Binder.clearCallingIdentity(); 6274 synchronized(this) { 6275 ActivityStack stack = ActivityRecord.getStackLocked(token); 6276 if (stack != null) { 6277 stack.activityPausedLocked(token, false); 6278 } 6279 } 6280 Binder.restoreCallingIdentity(origId); 6281 } 6282 6283 @Override 6284 public final void activityStopped(IBinder token, Bundle icicle, 6285 PersistableBundle persistentState, CharSequence description) { 6286 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6287 6288 // Refuse possible leaked file descriptors 6289 if (icicle != null && icicle.hasFileDescriptors()) { 6290 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6291 } 6292 6293 final long origId = Binder.clearCallingIdentity(); 6294 6295 synchronized (this) { 6296 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6297 if (r != null) { 6298 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6299 } 6300 } 6301 6302 trimApplications(); 6303 6304 Binder.restoreCallingIdentity(origId); 6305 } 6306 6307 @Override 6308 public final void activityDestroyed(IBinder token) { 6309 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6310 synchronized (this) { 6311 ActivityStack stack = ActivityRecord.getStackLocked(token); 6312 if (stack != null) { 6313 stack.activityDestroyedLocked(token); 6314 } 6315 } 6316 } 6317 6318 @Override 6319 public final void backgroundResourcesReleased(IBinder token) { 6320 final long origId = Binder.clearCallingIdentity(); 6321 try { 6322 synchronized (this) { 6323 ActivityStack stack = ActivityRecord.getStackLocked(token); 6324 if (stack != null) { 6325 stack.backgroundResourcesReleased(); 6326 } 6327 } 6328 } finally { 6329 Binder.restoreCallingIdentity(origId); 6330 } 6331 } 6332 6333 @Override 6334 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6335 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6336 } 6337 6338 @Override 6339 public final void notifyEnterAnimationComplete(IBinder token) { 6340 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6341 } 6342 6343 @Override 6344 public String getCallingPackage(IBinder token) { 6345 synchronized (this) { 6346 ActivityRecord r = getCallingRecordLocked(token); 6347 return r != null ? r.info.packageName : null; 6348 } 6349 } 6350 6351 @Override 6352 public ComponentName getCallingActivity(IBinder token) { 6353 synchronized (this) { 6354 ActivityRecord r = getCallingRecordLocked(token); 6355 return r != null ? r.intent.getComponent() : null; 6356 } 6357 } 6358 6359 private ActivityRecord getCallingRecordLocked(IBinder token) { 6360 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6361 if (r == null) { 6362 return null; 6363 } 6364 return r.resultTo; 6365 } 6366 6367 @Override 6368 public ComponentName getActivityClassForToken(IBinder token) { 6369 synchronized(this) { 6370 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6371 if (r == null) { 6372 return null; 6373 } 6374 return r.intent.getComponent(); 6375 } 6376 } 6377 6378 @Override 6379 public String getPackageForToken(IBinder token) { 6380 synchronized(this) { 6381 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6382 if (r == null) { 6383 return null; 6384 } 6385 return r.packageName; 6386 } 6387 } 6388 6389 @Override 6390 public IIntentSender getIntentSender(int type, 6391 String packageName, IBinder token, String resultWho, 6392 int requestCode, Intent[] intents, String[] resolvedTypes, 6393 int flags, Bundle options, int userId) { 6394 enforceNotIsolatedCaller("getIntentSender"); 6395 // Refuse possible leaked file descriptors 6396 if (intents != null) { 6397 if (intents.length < 1) { 6398 throw new IllegalArgumentException("Intents array length must be >= 1"); 6399 } 6400 for (int i=0; i<intents.length; i++) { 6401 Intent intent = intents[i]; 6402 if (intent != null) { 6403 if (intent.hasFileDescriptors()) { 6404 throw new IllegalArgumentException("File descriptors passed in Intent"); 6405 } 6406 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6407 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6408 throw new IllegalArgumentException( 6409 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6410 } 6411 intents[i] = new Intent(intent); 6412 } 6413 } 6414 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6415 throw new IllegalArgumentException( 6416 "Intent array length does not match resolvedTypes length"); 6417 } 6418 } 6419 if (options != null) { 6420 if (options.hasFileDescriptors()) { 6421 throw new IllegalArgumentException("File descriptors passed in options"); 6422 } 6423 } 6424 6425 synchronized(this) { 6426 int callingUid = Binder.getCallingUid(); 6427 int origUserId = userId; 6428 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6429 type == ActivityManager.INTENT_SENDER_BROADCAST, 6430 ALLOW_NON_FULL, "getIntentSender", null); 6431 if (origUserId == UserHandle.USER_CURRENT) { 6432 // We don't want to evaluate this until the pending intent is 6433 // actually executed. However, we do want to always do the 6434 // security checking for it above. 6435 userId = UserHandle.USER_CURRENT; 6436 } 6437 try { 6438 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6439 int uid = AppGlobals.getPackageManager() 6440 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6441 if (!UserHandle.isSameApp(callingUid, uid)) { 6442 String msg = "Permission Denial: getIntentSender() from pid=" 6443 + Binder.getCallingPid() 6444 + ", uid=" + Binder.getCallingUid() 6445 + ", (need uid=" + uid + ")" 6446 + " is not allowed to send as package " + packageName; 6447 Slog.w(TAG, msg); 6448 throw new SecurityException(msg); 6449 } 6450 } 6451 6452 return getIntentSenderLocked(type, packageName, callingUid, userId, 6453 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6454 6455 } catch (RemoteException e) { 6456 throw new SecurityException(e); 6457 } 6458 } 6459 } 6460 6461 IIntentSender getIntentSenderLocked(int type, String packageName, 6462 int callingUid, int userId, IBinder token, String resultWho, 6463 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6464 Bundle options) { 6465 if (DEBUG_MU) 6466 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6467 ActivityRecord activity = null; 6468 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6469 activity = ActivityRecord.isInStackLocked(token); 6470 if (activity == null) { 6471 return null; 6472 } 6473 if (activity.finishing) { 6474 return null; 6475 } 6476 } 6477 6478 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6479 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6480 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6481 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6482 |PendingIntent.FLAG_UPDATE_CURRENT); 6483 6484 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6485 type, packageName, activity, resultWho, 6486 requestCode, intents, resolvedTypes, flags, options, userId); 6487 WeakReference<PendingIntentRecord> ref; 6488 ref = mIntentSenderRecords.get(key); 6489 PendingIntentRecord rec = ref != null ? ref.get() : null; 6490 if (rec != null) { 6491 if (!cancelCurrent) { 6492 if (updateCurrent) { 6493 if (rec.key.requestIntent != null) { 6494 rec.key.requestIntent.replaceExtras(intents != null ? 6495 intents[intents.length - 1] : null); 6496 } 6497 if (intents != null) { 6498 intents[intents.length-1] = rec.key.requestIntent; 6499 rec.key.allIntents = intents; 6500 rec.key.allResolvedTypes = resolvedTypes; 6501 } else { 6502 rec.key.allIntents = null; 6503 rec.key.allResolvedTypes = null; 6504 } 6505 } 6506 return rec; 6507 } 6508 rec.canceled = true; 6509 mIntentSenderRecords.remove(key); 6510 } 6511 if (noCreate) { 6512 return rec; 6513 } 6514 rec = new PendingIntentRecord(this, key, callingUid); 6515 mIntentSenderRecords.put(key, rec.ref); 6516 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6517 if (activity.pendingResults == null) { 6518 activity.pendingResults 6519 = new HashSet<WeakReference<PendingIntentRecord>>(); 6520 } 6521 activity.pendingResults.add(rec.ref); 6522 } 6523 return rec; 6524 } 6525 6526 @Override 6527 public void cancelIntentSender(IIntentSender sender) { 6528 if (!(sender instanceof PendingIntentRecord)) { 6529 return; 6530 } 6531 synchronized(this) { 6532 PendingIntentRecord rec = (PendingIntentRecord)sender; 6533 try { 6534 int uid = AppGlobals.getPackageManager() 6535 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6536 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6537 String msg = "Permission Denial: cancelIntentSender() from pid=" 6538 + Binder.getCallingPid() 6539 + ", uid=" + Binder.getCallingUid() 6540 + " is not allowed to cancel packges " 6541 + rec.key.packageName; 6542 Slog.w(TAG, msg); 6543 throw new SecurityException(msg); 6544 } 6545 } catch (RemoteException e) { 6546 throw new SecurityException(e); 6547 } 6548 cancelIntentSenderLocked(rec, true); 6549 } 6550 } 6551 6552 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6553 rec.canceled = true; 6554 mIntentSenderRecords.remove(rec.key); 6555 if (cleanActivity && rec.key.activity != null) { 6556 rec.key.activity.pendingResults.remove(rec.ref); 6557 } 6558 } 6559 6560 @Override 6561 public String getPackageForIntentSender(IIntentSender pendingResult) { 6562 if (!(pendingResult instanceof PendingIntentRecord)) { 6563 return null; 6564 } 6565 try { 6566 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6567 return res.key.packageName; 6568 } catch (ClassCastException e) { 6569 } 6570 return null; 6571 } 6572 6573 @Override 6574 public int getUidForIntentSender(IIntentSender sender) { 6575 if (sender instanceof PendingIntentRecord) { 6576 try { 6577 PendingIntentRecord res = (PendingIntentRecord)sender; 6578 return res.uid; 6579 } catch (ClassCastException e) { 6580 } 6581 } 6582 return -1; 6583 } 6584 6585 @Override 6586 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6587 if (!(pendingResult instanceof PendingIntentRecord)) { 6588 return false; 6589 } 6590 try { 6591 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6592 if (res.key.allIntents == null) { 6593 return false; 6594 } 6595 for (int i=0; i<res.key.allIntents.length; i++) { 6596 Intent intent = res.key.allIntents[i]; 6597 if (intent.getPackage() != null && intent.getComponent() != null) { 6598 return false; 6599 } 6600 } 6601 return true; 6602 } catch (ClassCastException e) { 6603 } 6604 return false; 6605 } 6606 6607 @Override 6608 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6609 if (!(pendingResult instanceof PendingIntentRecord)) { 6610 return false; 6611 } 6612 try { 6613 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6614 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6615 return true; 6616 } 6617 return false; 6618 } catch (ClassCastException e) { 6619 } 6620 return false; 6621 } 6622 6623 @Override 6624 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6625 if (!(pendingResult instanceof PendingIntentRecord)) { 6626 return null; 6627 } 6628 try { 6629 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6630 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6631 } catch (ClassCastException e) { 6632 } 6633 return null; 6634 } 6635 6636 @Override 6637 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6638 if (!(pendingResult instanceof PendingIntentRecord)) { 6639 return null; 6640 } 6641 try { 6642 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6643 Intent intent = res.key.requestIntent; 6644 if (intent != null) { 6645 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6646 || res.lastTagPrefix.equals(prefix))) { 6647 return res.lastTag; 6648 } 6649 res.lastTagPrefix = prefix; 6650 StringBuilder sb = new StringBuilder(128); 6651 if (prefix != null) { 6652 sb.append(prefix); 6653 } 6654 if (intent.getAction() != null) { 6655 sb.append(intent.getAction()); 6656 } else if (intent.getComponent() != null) { 6657 intent.getComponent().appendShortString(sb); 6658 } else { 6659 sb.append("?"); 6660 } 6661 return res.lastTag = sb.toString(); 6662 } 6663 } catch (ClassCastException e) { 6664 } 6665 return null; 6666 } 6667 6668 @Override 6669 public void setProcessLimit(int max) { 6670 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6671 "setProcessLimit()"); 6672 synchronized (this) { 6673 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6674 mProcessLimitOverride = max; 6675 } 6676 trimApplications(); 6677 } 6678 6679 @Override 6680 public int getProcessLimit() { 6681 synchronized (this) { 6682 return mProcessLimitOverride; 6683 } 6684 } 6685 6686 void foregroundTokenDied(ForegroundToken token) { 6687 synchronized (ActivityManagerService.this) { 6688 synchronized (mPidsSelfLocked) { 6689 ForegroundToken cur 6690 = mForegroundProcesses.get(token.pid); 6691 if (cur != token) { 6692 return; 6693 } 6694 mForegroundProcesses.remove(token.pid); 6695 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6696 if (pr == null) { 6697 return; 6698 } 6699 pr.forcingToForeground = null; 6700 updateProcessForegroundLocked(pr, false, false); 6701 } 6702 updateOomAdjLocked(); 6703 } 6704 } 6705 6706 @Override 6707 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6708 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6709 "setProcessForeground()"); 6710 synchronized(this) { 6711 boolean changed = false; 6712 6713 synchronized (mPidsSelfLocked) { 6714 ProcessRecord pr = mPidsSelfLocked.get(pid); 6715 if (pr == null && isForeground) { 6716 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6717 return; 6718 } 6719 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6720 if (oldToken != null) { 6721 oldToken.token.unlinkToDeath(oldToken, 0); 6722 mForegroundProcesses.remove(pid); 6723 if (pr != null) { 6724 pr.forcingToForeground = null; 6725 } 6726 changed = true; 6727 } 6728 if (isForeground && token != null) { 6729 ForegroundToken newToken = new ForegroundToken() { 6730 @Override 6731 public void binderDied() { 6732 foregroundTokenDied(this); 6733 } 6734 }; 6735 newToken.pid = pid; 6736 newToken.token = token; 6737 try { 6738 token.linkToDeath(newToken, 0); 6739 mForegroundProcesses.put(pid, newToken); 6740 pr.forcingToForeground = token; 6741 changed = true; 6742 } catch (RemoteException e) { 6743 // If the process died while doing this, we will later 6744 // do the cleanup with the process death link. 6745 } 6746 } 6747 } 6748 6749 if (changed) { 6750 updateOomAdjLocked(); 6751 } 6752 } 6753 } 6754 6755 // ========================================================= 6756 // PERMISSIONS 6757 // ========================================================= 6758 6759 static class PermissionController extends IPermissionController.Stub { 6760 ActivityManagerService mActivityManagerService; 6761 PermissionController(ActivityManagerService activityManagerService) { 6762 mActivityManagerService = activityManagerService; 6763 } 6764 6765 @Override 6766 public boolean checkPermission(String permission, int pid, int uid) { 6767 return mActivityManagerService.checkPermission(permission, pid, 6768 uid) == PackageManager.PERMISSION_GRANTED; 6769 } 6770 } 6771 6772 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6773 @Override 6774 public int checkComponentPermission(String permission, int pid, int uid, 6775 int owningUid, boolean exported) { 6776 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6777 owningUid, exported); 6778 } 6779 6780 @Override 6781 public Object getAMSLock() { 6782 return ActivityManagerService.this; 6783 } 6784 } 6785 6786 /** 6787 * This can be called with or without the global lock held. 6788 */ 6789 int checkComponentPermission(String permission, int pid, int uid, 6790 int owningUid, boolean exported) { 6791 if (pid == MY_PID) { 6792 return PackageManager.PERMISSION_GRANTED; 6793 } 6794 return ActivityManager.checkComponentPermission(permission, uid, 6795 owningUid, exported); 6796 } 6797 6798 /** 6799 * As the only public entry point for permissions checking, this method 6800 * can enforce the semantic that requesting a check on a null global 6801 * permission is automatically denied. (Internally a null permission 6802 * string is used when calling {@link #checkComponentPermission} in cases 6803 * when only uid-based security is needed.) 6804 * 6805 * This can be called with or without the global lock held. 6806 */ 6807 @Override 6808 public int checkPermission(String permission, int pid, int uid) { 6809 if (permission == null) { 6810 return PackageManager.PERMISSION_DENIED; 6811 } 6812 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6813 } 6814 6815 @Override 6816 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6817 if (permission == null) { 6818 return PackageManager.PERMISSION_DENIED; 6819 } 6820 6821 // We might be performing an operation on behalf of an indirect binder 6822 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6823 // client identity accordingly before proceeding. 6824 Identity tlsIdentity = sCallerIdentity.get(); 6825 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6826 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6827 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6828 uid = tlsIdentity.uid; 6829 pid = tlsIdentity.pid; 6830 } 6831 6832 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6833 } 6834 6835 /** 6836 * Binder IPC calls go through the public entry point. 6837 * This can be called with or without the global lock held. 6838 */ 6839 int checkCallingPermission(String permission) { 6840 return checkPermission(permission, 6841 Binder.getCallingPid(), 6842 UserHandle.getAppId(Binder.getCallingUid())); 6843 } 6844 6845 /** 6846 * This can be called with or without the global lock held. 6847 */ 6848 void enforceCallingPermission(String permission, String func) { 6849 if (checkCallingPermission(permission) 6850 == PackageManager.PERMISSION_GRANTED) { 6851 return; 6852 } 6853 6854 String msg = "Permission Denial: " + func + " from pid=" 6855 + Binder.getCallingPid() 6856 + ", uid=" + Binder.getCallingUid() 6857 + " requires " + permission; 6858 Slog.w(TAG, msg); 6859 throw new SecurityException(msg); 6860 } 6861 6862 /** 6863 * Determine if UID is holding permissions required to access {@link Uri} in 6864 * the given {@link ProviderInfo}. Final permission checking is always done 6865 * in {@link ContentProvider}. 6866 */ 6867 private final boolean checkHoldingPermissionsLocked( 6868 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6869 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6870 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6871 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6872 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6873 != PERMISSION_GRANTED) { 6874 return false; 6875 } 6876 } 6877 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6878 } 6879 6880 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6881 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6882 if (pi.applicationInfo.uid == uid) { 6883 return true; 6884 } else if (!pi.exported) { 6885 return false; 6886 } 6887 6888 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6889 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6890 try { 6891 // check if target holds top-level <provider> permissions 6892 if (!readMet && pi.readPermission != null && considerUidPermissions 6893 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6894 readMet = true; 6895 } 6896 if (!writeMet && pi.writePermission != null && considerUidPermissions 6897 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6898 writeMet = true; 6899 } 6900 6901 // track if unprotected read/write is allowed; any denied 6902 // <path-permission> below removes this ability 6903 boolean allowDefaultRead = pi.readPermission == null; 6904 boolean allowDefaultWrite = pi.writePermission == null; 6905 6906 // check if target holds any <path-permission> that match uri 6907 final PathPermission[] pps = pi.pathPermissions; 6908 if (pps != null) { 6909 final String path = grantUri.uri.getPath(); 6910 int i = pps.length; 6911 while (i > 0 && (!readMet || !writeMet)) { 6912 i--; 6913 PathPermission pp = pps[i]; 6914 if (pp.match(path)) { 6915 if (!readMet) { 6916 final String pprperm = pp.getReadPermission(); 6917 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6918 + pprperm + " for " + pp.getPath() 6919 + ": match=" + pp.match(path) 6920 + " check=" + pm.checkUidPermission(pprperm, uid)); 6921 if (pprperm != null) { 6922 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6923 == PERMISSION_GRANTED) { 6924 readMet = true; 6925 } else { 6926 allowDefaultRead = false; 6927 } 6928 } 6929 } 6930 if (!writeMet) { 6931 final String ppwperm = pp.getWritePermission(); 6932 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6933 + ppwperm + " for " + pp.getPath() 6934 + ": match=" + pp.match(path) 6935 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6936 if (ppwperm != null) { 6937 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6938 == PERMISSION_GRANTED) { 6939 writeMet = true; 6940 } else { 6941 allowDefaultWrite = false; 6942 } 6943 } 6944 } 6945 } 6946 } 6947 } 6948 6949 // grant unprotected <provider> read/write, if not blocked by 6950 // <path-permission> above 6951 if (allowDefaultRead) readMet = true; 6952 if (allowDefaultWrite) writeMet = true; 6953 6954 } catch (RemoteException e) { 6955 return false; 6956 } 6957 6958 return readMet && writeMet; 6959 } 6960 6961 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6962 ProviderInfo pi = null; 6963 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6964 if (cpr != null) { 6965 pi = cpr.info; 6966 } else { 6967 try { 6968 pi = AppGlobals.getPackageManager().resolveContentProvider( 6969 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6970 } catch (RemoteException ex) { 6971 } 6972 } 6973 return pi; 6974 } 6975 6976 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6977 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6978 if (targetUris != null) { 6979 return targetUris.get(grantUri); 6980 } 6981 return null; 6982 } 6983 6984 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6985 String targetPkg, int targetUid, GrantUri grantUri) { 6986 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6987 if (targetUris == null) { 6988 targetUris = Maps.newArrayMap(); 6989 mGrantedUriPermissions.put(targetUid, targetUris); 6990 } 6991 6992 UriPermission perm = targetUris.get(grantUri); 6993 if (perm == null) { 6994 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6995 targetUris.put(grantUri, perm); 6996 } 6997 6998 return perm; 6999 } 7000 7001 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7002 final int modeFlags) { 7003 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7004 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7005 : UriPermission.STRENGTH_OWNED; 7006 7007 // Root gets to do everything. 7008 if (uid == 0) { 7009 return true; 7010 } 7011 7012 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7013 if (perms == null) return false; 7014 7015 // First look for exact match 7016 final UriPermission exactPerm = perms.get(grantUri); 7017 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7018 return true; 7019 } 7020 7021 // No exact match, look for prefixes 7022 final int N = perms.size(); 7023 for (int i = 0; i < N; i++) { 7024 final UriPermission perm = perms.valueAt(i); 7025 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7026 && perm.getStrength(modeFlags) >= minStrength) { 7027 return true; 7028 } 7029 } 7030 7031 return false; 7032 } 7033 7034 /** 7035 * @param uri This uri must NOT contain an embedded userId. 7036 * @param userId The userId in which the uri is to be resolved. 7037 */ 7038 @Override 7039 public int checkUriPermission(Uri uri, int pid, int uid, 7040 final int modeFlags, int userId, IBinder callerToken) { 7041 enforceNotIsolatedCaller("checkUriPermission"); 7042 7043 // Another redirected-binder-call permissions check as in 7044 // {@link checkPermissionWithToken}. 7045 Identity tlsIdentity = sCallerIdentity.get(); 7046 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7047 uid = tlsIdentity.uid; 7048 pid = tlsIdentity.pid; 7049 } 7050 7051 // Our own process gets to do everything. 7052 if (pid == MY_PID) { 7053 return PackageManager.PERMISSION_GRANTED; 7054 } 7055 synchronized (this) { 7056 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7057 ? PackageManager.PERMISSION_GRANTED 7058 : PackageManager.PERMISSION_DENIED; 7059 } 7060 } 7061 7062 /** 7063 * Check if the targetPkg can be granted permission to access uri by 7064 * the callingUid using the given modeFlags. Throws a security exception 7065 * if callingUid is not allowed to do this. Returns the uid of the target 7066 * if the URI permission grant should be performed; returns -1 if it is not 7067 * needed (for example targetPkg already has permission to access the URI). 7068 * If you already know the uid of the target, you can supply it in 7069 * lastTargetUid else set that to -1. 7070 */ 7071 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7072 final int modeFlags, int lastTargetUid) { 7073 if (!Intent.isAccessUriMode(modeFlags)) { 7074 return -1; 7075 } 7076 7077 if (targetPkg != null) { 7078 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7079 "Checking grant " + targetPkg + " permission to " + grantUri); 7080 } 7081 7082 final IPackageManager pm = AppGlobals.getPackageManager(); 7083 7084 // If this is not a content: uri, we can't do anything with it. 7085 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7087 "Can't grant URI permission for non-content URI: " + grantUri); 7088 return -1; 7089 } 7090 7091 final String authority = grantUri.uri.getAuthority(); 7092 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7093 if (pi == null) { 7094 Slog.w(TAG, "No content provider found for permission check: " + 7095 grantUri.uri.toSafeString()); 7096 return -1; 7097 } 7098 7099 int targetUid = lastTargetUid; 7100 if (targetUid < 0 && targetPkg != null) { 7101 try { 7102 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7103 if (targetUid < 0) { 7104 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7105 "Can't grant URI permission no uid for: " + targetPkg); 7106 return -1; 7107 } 7108 } catch (RemoteException ex) { 7109 return -1; 7110 } 7111 } 7112 7113 if (targetUid >= 0) { 7114 // First... does the target actually need this permission? 7115 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7116 // No need to grant the target this permission. 7117 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7118 "Target " + targetPkg + " already has full permission to " + grantUri); 7119 return -1; 7120 } 7121 } else { 7122 // First... there is no target package, so can anyone access it? 7123 boolean allowed = pi.exported; 7124 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7125 if (pi.readPermission != null) { 7126 allowed = false; 7127 } 7128 } 7129 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7130 if (pi.writePermission != null) { 7131 allowed = false; 7132 } 7133 } 7134 if (allowed) { 7135 return -1; 7136 } 7137 } 7138 7139 /* There is a special cross user grant if: 7140 * - The target is on another user. 7141 * - Apps on the current user can access the uri without any uid permissions. 7142 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7143 * grant uri permissions. 7144 */ 7145 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7146 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7147 modeFlags, false /*without considering the uid permissions*/); 7148 7149 // Second... is the provider allowing granting of URI permissions? 7150 if (!specialCrossUserGrant) { 7151 if (!pi.grantUriPermissions) { 7152 throw new SecurityException("Provider " + pi.packageName 7153 + "/" + pi.name 7154 + " does not allow granting of Uri permissions (uri " 7155 + grantUri + ")"); 7156 } 7157 if (pi.uriPermissionPatterns != null) { 7158 final int N = pi.uriPermissionPatterns.length; 7159 boolean allowed = false; 7160 for (int i=0; i<N; i++) { 7161 if (pi.uriPermissionPatterns[i] != null 7162 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7163 allowed = true; 7164 break; 7165 } 7166 } 7167 if (!allowed) { 7168 throw new SecurityException("Provider " + pi.packageName 7169 + "/" + pi.name 7170 + " does not allow granting of permission to path of Uri " 7171 + grantUri); 7172 } 7173 } 7174 } 7175 7176 // Third... does the caller itself have permission to access 7177 // this uri? 7178 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7179 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7180 // Require they hold a strong enough Uri permission 7181 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7182 throw new SecurityException("Uid " + callingUid 7183 + " does not have permission to uri " + grantUri); 7184 } 7185 } 7186 } 7187 return targetUid; 7188 } 7189 7190 /** 7191 * @param uri This uri must NOT contain an embedded userId. 7192 * @param userId The userId in which the uri is to be resolved. 7193 */ 7194 @Override 7195 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7196 final int modeFlags, int userId) { 7197 enforceNotIsolatedCaller("checkGrantUriPermission"); 7198 synchronized(this) { 7199 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7200 new GrantUri(userId, uri, false), modeFlags, -1); 7201 } 7202 } 7203 7204 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7205 final int modeFlags, UriPermissionOwner owner) { 7206 if (!Intent.isAccessUriMode(modeFlags)) { 7207 return; 7208 } 7209 7210 // So here we are: the caller has the assumed permission 7211 // to the uri, and the target doesn't. Let's now give this to 7212 // the target. 7213 7214 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7215 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7216 7217 final String authority = grantUri.uri.getAuthority(); 7218 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7219 if (pi == null) { 7220 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7221 return; 7222 } 7223 7224 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7225 grantUri.prefix = true; 7226 } 7227 final UriPermission perm = findOrCreateUriPermissionLocked( 7228 pi.packageName, targetPkg, targetUid, grantUri); 7229 perm.grantModes(modeFlags, owner); 7230 } 7231 7232 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7233 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7234 if (targetPkg == null) { 7235 throw new NullPointerException("targetPkg"); 7236 } 7237 int targetUid; 7238 final IPackageManager pm = AppGlobals.getPackageManager(); 7239 try { 7240 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7241 } catch (RemoteException ex) { 7242 return; 7243 } 7244 7245 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7246 targetUid); 7247 if (targetUid < 0) { 7248 return; 7249 } 7250 7251 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7252 owner); 7253 } 7254 7255 static class NeededUriGrants extends ArrayList<GrantUri> { 7256 final String targetPkg; 7257 final int targetUid; 7258 final int flags; 7259 7260 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7261 this.targetPkg = targetPkg; 7262 this.targetUid = targetUid; 7263 this.flags = flags; 7264 } 7265 } 7266 7267 /** 7268 * Like checkGrantUriPermissionLocked, but takes an Intent. 7269 */ 7270 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7271 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7272 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7273 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7274 + " clip=" + (intent != null ? intent.getClipData() : null) 7275 + " from " + intent + "; flags=0x" 7276 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7277 7278 if (targetPkg == null) { 7279 throw new NullPointerException("targetPkg"); 7280 } 7281 7282 if (intent == null) { 7283 return null; 7284 } 7285 Uri data = intent.getData(); 7286 ClipData clip = intent.getClipData(); 7287 if (data == null && clip == null) { 7288 return null; 7289 } 7290 // Default userId for uris in the intent (if they don't specify it themselves) 7291 int contentUserHint = intent.getContentUserHint(); 7292 if (contentUserHint == UserHandle.USER_CURRENT) { 7293 contentUserHint = UserHandle.getUserId(callingUid); 7294 } 7295 final IPackageManager pm = AppGlobals.getPackageManager(); 7296 int targetUid; 7297 if (needed != null) { 7298 targetUid = needed.targetUid; 7299 } else { 7300 try { 7301 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7302 } catch (RemoteException ex) { 7303 return null; 7304 } 7305 if (targetUid < 0) { 7306 if (DEBUG_URI_PERMISSION) { 7307 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7308 + " on user " + targetUserId); 7309 } 7310 return null; 7311 } 7312 } 7313 if (data != null) { 7314 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7315 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7316 targetUid); 7317 if (targetUid > 0) { 7318 if (needed == null) { 7319 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7320 } 7321 needed.add(grantUri); 7322 } 7323 } 7324 if (clip != null) { 7325 for (int i=0; i<clip.getItemCount(); i++) { 7326 Uri uri = clip.getItemAt(i).getUri(); 7327 if (uri != null) { 7328 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7329 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7330 targetUid); 7331 if (targetUid > 0) { 7332 if (needed == null) { 7333 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7334 } 7335 needed.add(grantUri); 7336 } 7337 } else { 7338 Intent clipIntent = clip.getItemAt(i).getIntent(); 7339 if (clipIntent != null) { 7340 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7341 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7342 if (newNeeded != null) { 7343 needed = newNeeded; 7344 } 7345 } 7346 } 7347 } 7348 } 7349 7350 return needed; 7351 } 7352 7353 /** 7354 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7355 */ 7356 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7357 UriPermissionOwner owner) { 7358 if (needed != null) { 7359 for (int i=0; i<needed.size(); i++) { 7360 GrantUri grantUri = needed.get(i); 7361 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7362 grantUri, needed.flags, owner); 7363 } 7364 } 7365 } 7366 7367 void grantUriPermissionFromIntentLocked(int callingUid, 7368 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7369 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7370 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7371 if (needed == null) { 7372 return; 7373 } 7374 7375 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7376 } 7377 7378 /** 7379 * @param uri This uri must NOT contain an embedded userId. 7380 * @param userId The userId in which the uri is to be resolved. 7381 */ 7382 @Override 7383 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7384 final int modeFlags, int userId) { 7385 enforceNotIsolatedCaller("grantUriPermission"); 7386 GrantUri grantUri = new GrantUri(userId, uri, false); 7387 synchronized(this) { 7388 final ProcessRecord r = getRecordForAppLocked(caller); 7389 if (r == null) { 7390 throw new SecurityException("Unable to find app for caller " 7391 + caller 7392 + " when granting permission to uri " + grantUri); 7393 } 7394 if (targetPkg == null) { 7395 throw new IllegalArgumentException("null target"); 7396 } 7397 if (grantUri == null) { 7398 throw new IllegalArgumentException("null uri"); 7399 } 7400 7401 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7402 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7403 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7404 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7405 7406 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7407 UserHandle.getUserId(r.uid)); 7408 } 7409 } 7410 7411 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7412 if (perm.modeFlags == 0) { 7413 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7414 perm.targetUid); 7415 if (perms != null) { 7416 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7417 "Removing " + perm.targetUid + " permission to " + perm.uri); 7418 7419 perms.remove(perm.uri); 7420 if (perms.isEmpty()) { 7421 mGrantedUriPermissions.remove(perm.targetUid); 7422 } 7423 } 7424 } 7425 } 7426 7427 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7428 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7429 7430 final IPackageManager pm = AppGlobals.getPackageManager(); 7431 final String authority = grantUri.uri.getAuthority(); 7432 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7433 if (pi == null) { 7434 Slog.w(TAG, "No content provider found for permission revoke: " 7435 + grantUri.toSafeString()); 7436 return; 7437 } 7438 7439 // Does the caller have this permission on the URI? 7440 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7441 // If they don't have direct access to the URI, then revoke any 7442 // ownerless URI permissions that have been granted to them. 7443 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7444 if (perms != null) { 7445 boolean persistChanged = false; 7446 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7447 final UriPermission perm = it.next(); 7448 if (perm.uri.sourceUserId == grantUri.sourceUserId 7449 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7450 if (DEBUG_URI_PERMISSION) 7451 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7452 " permission to " + perm.uri); 7453 persistChanged |= perm.revokeModes( 7454 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7455 if (perm.modeFlags == 0) { 7456 it.remove(); 7457 } 7458 } 7459 } 7460 if (perms.isEmpty()) { 7461 mGrantedUriPermissions.remove(callingUid); 7462 } 7463 if (persistChanged) { 7464 schedulePersistUriGrants(); 7465 } 7466 } 7467 return; 7468 } 7469 7470 boolean persistChanged = false; 7471 7472 // Go through all of the permissions and remove any that match. 7473 int N = mGrantedUriPermissions.size(); 7474 for (int i = 0; i < N; i++) { 7475 final int targetUid = mGrantedUriPermissions.keyAt(i); 7476 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7477 7478 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7479 final UriPermission perm = it.next(); 7480 if (perm.uri.sourceUserId == grantUri.sourceUserId 7481 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7482 if (DEBUG_URI_PERMISSION) 7483 Slog.v(TAG, 7484 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7485 persistChanged |= perm.revokeModes( 7486 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7487 if (perm.modeFlags == 0) { 7488 it.remove(); 7489 } 7490 } 7491 } 7492 7493 if (perms.isEmpty()) { 7494 mGrantedUriPermissions.remove(targetUid); 7495 N--; 7496 i--; 7497 } 7498 } 7499 7500 if (persistChanged) { 7501 schedulePersistUriGrants(); 7502 } 7503 } 7504 7505 /** 7506 * @param uri This uri must NOT contain an embedded userId. 7507 * @param userId The userId in which the uri is to be resolved. 7508 */ 7509 @Override 7510 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7511 int userId) { 7512 enforceNotIsolatedCaller("revokeUriPermission"); 7513 synchronized(this) { 7514 final ProcessRecord r = getRecordForAppLocked(caller); 7515 if (r == null) { 7516 throw new SecurityException("Unable to find app for caller " 7517 + caller 7518 + " when revoking permission to uri " + uri); 7519 } 7520 if (uri == null) { 7521 Slog.w(TAG, "revokeUriPermission: null uri"); 7522 return; 7523 } 7524 7525 if (!Intent.isAccessUriMode(modeFlags)) { 7526 return; 7527 } 7528 7529 final IPackageManager pm = AppGlobals.getPackageManager(); 7530 final String authority = uri.getAuthority(); 7531 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7532 if (pi == null) { 7533 Slog.w(TAG, "No content provider found for permission revoke: " 7534 + uri.toSafeString()); 7535 return; 7536 } 7537 7538 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7539 } 7540 } 7541 7542 /** 7543 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7544 * given package. 7545 * 7546 * @param packageName Package name to match, or {@code null} to apply to all 7547 * packages. 7548 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7549 * to all users. 7550 * @param persistable If persistable grants should be removed. 7551 */ 7552 private void removeUriPermissionsForPackageLocked( 7553 String packageName, int userHandle, boolean persistable) { 7554 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7555 throw new IllegalArgumentException("Must narrow by either package or user"); 7556 } 7557 7558 boolean persistChanged = false; 7559 7560 int N = mGrantedUriPermissions.size(); 7561 for (int i = 0; i < N; i++) { 7562 final int targetUid = mGrantedUriPermissions.keyAt(i); 7563 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7564 7565 // Only inspect grants matching user 7566 if (userHandle == UserHandle.USER_ALL 7567 || userHandle == UserHandle.getUserId(targetUid)) { 7568 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7569 final UriPermission perm = it.next(); 7570 7571 // Only inspect grants matching package 7572 if (packageName == null || perm.sourcePkg.equals(packageName) 7573 || perm.targetPkg.equals(packageName)) { 7574 persistChanged |= perm.revokeModes(persistable 7575 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7576 7577 // Only remove when no modes remain; any persisted grants 7578 // will keep this alive. 7579 if (perm.modeFlags == 0) { 7580 it.remove(); 7581 } 7582 } 7583 } 7584 7585 if (perms.isEmpty()) { 7586 mGrantedUriPermissions.remove(targetUid); 7587 N--; 7588 i--; 7589 } 7590 } 7591 } 7592 7593 if (persistChanged) { 7594 schedulePersistUriGrants(); 7595 } 7596 } 7597 7598 @Override 7599 public IBinder newUriPermissionOwner(String name) { 7600 enforceNotIsolatedCaller("newUriPermissionOwner"); 7601 synchronized(this) { 7602 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7603 return owner.getExternalTokenLocked(); 7604 } 7605 } 7606 7607 /** 7608 * @param uri This uri must NOT contain an embedded userId. 7609 * @param sourceUserId The userId in which the uri is to be resolved. 7610 * @param targetUserId The userId of the app that receives the grant. 7611 */ 7612 @Override 7613 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7614 final int modeFlags, int sourceUserId, int targetUserId) { 7615 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7616 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7617 synchronized(this) { 7618 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7619 if (owner == null) { 7620 throw new IllegalArgumentException("Unknown owner: " + token); 7621 } 7622 if (fromUid != Binder.getCallingUid()) { 7623 if (Binder.getCallingUid() != Process.myUid()) { 7624 // Only system code can grant URI permissions on behalf 7625 // of other users. 7626 throw new SecurityException("nice try"); 7627 } 7628 } 7629 if (targetPkg == null) { 7630 throw new IllegalArgumentException("null target"); 7631 } 7632 if (uri == null) { 7633 throw new IllegalArgumentException("null uri"); 7634 } 7635 7636 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7637 modeFlags, owner, targetUserId); 7638 } 7639 } 7640 7641 /** 7642 * @param uri This uri must NOT contain an embedded userId. 7643 * @param userId The userId in which the uri is to be resolved. 7644 */ 7645 @Override 7646 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7647 synchronized(this) { 7648 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7649 if (owner == null) { 7650 throw new IllegalArgumentException("Unknown owner: " + token); 7651 } 7652 7653 if (uri == null) { 7654 owner.removeUriPermissionsLocked(mode); 7655 } else { 7656 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7657 } 7658 } 7659 } 7660 7661 private void schedulePersistUriGrants() { 7662 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7663 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7664 10 * DateUtils.SECOND_IN_MILLIS); 7665 } 7666 } 7667 7668 private void writeGrantedUriPermissions() { 7669 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7670 7671 // Snapshot permissions so we can persist without lock 7672 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7673 synchronized (this) { 7674 final int size = mGrantedUriPermissions.size(); 7675 for (int i = 0; i < size; i++) { 7676 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7677 for (UriPermission perm : perms.values()) { 7678 if (perm.persistedModeFlags != 0) { 7679 persist.add(perm.snapshot()); 7680 } 7681 } 7682 } 7683 } 7684 7685 FileOutputStream fos = null; 7686 try { 7687 fos = mGrantFile.startWrite(); 7688 7689 XmlSerializer out = new FastXmlSerializer(); 7690 out.setOutput(fos, "utf-8"); 7691 out.startDocument(null, true); 7692 out.startTag(null, TAG_URI_GRANTS); 7693 for (UriPermission.Snapshot perm : persist) { 7694 out.startTag(null, TAG_URI_GRANT); 7695 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7696 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7697 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7698 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7699 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7700 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7701 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7702 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7703 out.endTag(null, TAG_URI_GRANT); 7704 } 7705 out.endTag(null, TAG_URI_GRANTS); 7706 out.endDocument(); 7707 7708 mGrantFile.finishWrite(fos); 7709 } catch (IOException e) { 7710 if (fos != null) { 7711 mGrantFile.failWrite(fos); 7712 } 7713 } 7714 } 7715 7716 private void readGrantedUriPermissionsLocked() { 7717 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7718 7719 final long now = System.currentTimeMillis(); 7720 7721 FileInputStream fis = null; 7722 try { 7723 fis = mGrantFile.openRead(); 7724 final XmlPullParser in = Xml.newPullParser(); 7725 in.setInput(fis, null); 7726 7727 int type; 7728 while ((type = in.next()) != END_DOCUMENT) { 7729 final String tag = in.getName(); 7730 if (type == START_TAG) { 7731 if (TAG_URI_GRANT.equals(tag)) { 7732 final int sourceUserId; 7733 final int targetUserId; 7734 final int userHandle = readIntAttribute(in, 7735 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7736 if (userHandle != UserHandle.USER_NULL) { 7737 // For backwards compatibility. 7738 sourceUserId = userHandle; 7739 targetUserId = userHandle; 7740 } else { 7741 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7742 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7743 } 7744 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7745 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7746 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7747 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7748 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7749 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7750 7751 // Sanity check that provider still belongs to source package 7752 final ProviderInfo pi = getProviderInfoLocked( 7753 uri.getAuthority(), sourceUserId); 7754 if (pi != null && sourcePkg.equals(pi.packageName)) { 7755 int targetUid = -1; 7756 try { 7757 targetUid = AppGlobals.getPackageManager() 7758 .getPackageUid(targetPkg, targetUserId); 7759 } catch (RemoteException e) { 7760 } 7761 if (targetUid != -1) { 7762 final UriPermission perm = findOrCreateUriPermissionLocked( 7763 sourcePkg, targetPkg, targetUid, 7764 new GrantUri(sourceUserId, uri, prefix)); 7765 perm.initPersistedModes(modeFlags, createdTime); 7766 } 7767 } else { 7768 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7769 + " but instead found " + pi); 7770 } 7771 } 7772 } 7773 } 7774 } catch (FileNotFoundException e) { 7775 // Missing grants is okay 7776 } catch (IOException e) { 7777 Slog.wtf(TAG, "Failed reading Uri grants", e); 7778 } catch (XmlPullParserException e) { 7779 Slog.wtf(TAG, "Failed reading Uri grants", e); 7780 } finally { 7781 IoUtils.closeQuietly(fis); 7782 } 7783 } 7784 7785 /** 7786 * @param uri This uri must NOT contain an embedded userId. 7787 * @param userId The userId in which the uri is to be resolved. 7788 */ 7789 @Override 7790 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7791 enforceNotIsolatedCaller("takePersistableUriPermission"); 7792 7793 Preconditions.checkFlagsArgument(modeFlags, 7794 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7795 7796 synchronized (this) { 7797 final int callingUid = Binder.getCallingUid(); 7798 boolean persistChanged = false; 7799 GrantUri grantUri = new GrantUri(userId, uri, false); 7800 7801 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7802 new GrantUri(userId, uri, false)); 7803 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7804 new GrantUri(userId, uri, true)); 7805 7806 final boolean exactValid = (exactPerm != null) 7807 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7808 final boolean prefixValid = (prefixPerm != null) 7809 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7810 7811 if (!(exactValid || prefixValid)) { 7812 throw new SecurityException("No persistable permission grants found for UID " 7813 + callingUid + " and Uri " + grantUri.toSafeString()); 7814 } 7815 7816 if (exactValid) { 7817 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7818 } 7819 if (prefixValid) { 7820 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7821 } 7822 7823 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7824 7825 if (persistChanged) { 7826 schedulePersistUriGrants(); 7827 } 7828 } 7829 } 7830 7831 /** 7832 * @param uri This uri must NOT contain an embedded userId. 7833 * @param userId The userId in which the uri is to be resolved. 7834 */ 7835 @Override 7836 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7837 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7838 7839 Preconditions.checkFlagsArgument(modeFlags, 7840 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7841 7842 synchronized (this) { 7843 final int callingUid = Binder.getCallingUid(); 7844 boolean persistChanged = false; 7845 7846 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7847 new GrantUri(userId, uri, false)); 7848 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7849 new GrantUri(userId, uri, true)); 7850 if (exactPerm == null && prefixPerm == null) { 7851 throw new SecurityException("No permission grants found for UID " + callingUid 7852 + " and Uri " + uri.toSafeString()); 7853 } 7854 7855 if (exactPerm != null) { 7856 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7857 removeUriPermissionIfNeededLocked(exactPerm); 7858 } 7859 if (prefixPerm != null) { 7860 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7861 removeUriPermissionIfNeededLocked(prefixPerm); 7862 } 7863 7864 if (persistChanged) { 7865 schedulePersistUriGrants(); 7866 } 7867 } 7868 } 7869 7870 /** 7871 * Prune any older {@link UriPermission} for the given UID until outstanding 7872 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7873 * 7874 * @return if any mutations occured that require persisting. 7875 */ 7876 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7877 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7878 if (perms == null) return false; 7879 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7880 7881 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7882 for (UriPermission perm : perms.values()) { 7883 if (perm.persistedModeFlags != 0) { 7884 persisted.add(perm); 7885 } 7886 } 7887 7888 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7889 if (trimCount <= 0) return false; 7890 7891 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7892 for (int i = 0; i < trimCount; i++) { 7893 final UriPermission perm = persisted.get(i); 7894 7895 if (DEBUG_URI_PERMISSION) { 7896 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7897 } 7898 7899 perm.releasePersistableModes(~0); 7900 removeUriPermissionIfNeededLocked(perm); 7901 } 7902 7903 return true; 7904 } 7905 7906 @Override 7907 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7908 String packageName, boolean incoming) { 7909 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7910 Preconditions.checkNotNull(packageName, "packageName"); 7911 7912 final int callingUid = Binder.getCallingUid(); 7913 final IPackageManager pm = AppGlobals.getPackageManager(); 7914 try { 7915 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7916 if (packageUid != callingUid) { 7917 throw new SecurityException( 7918 "Package " + packageName + " does not belong to calling UID " + callingUid); 7919 } 7920 } catch (RemoteException e) { 7921 throw new SecurityException("Failed to verify package name ownership"); 7922 } 7923 7924 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7925 synchronized (this) { 7926 if (incoming) { 7927 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7928 callingUid); 7929 if (perms == null) { 7930 Slog.w(TAG, "No permission grants found for " + packageName); 7931 } else { 7932 for (UriPermission perm : perms.values()) { 7933 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7934 result.add(perm.buildPersistedPublicApiObject()); 7935 } 7936 } 7937 } 7938 } else { 7939 final int size = mGrantedUriPermissions.size(); 7940 for (int i = 0; i < size; i++) { 7941 final ArrayMap<GrantUri, UriPermission> perms = 7942 mGrantedUriPermissions.valueAt(i); 7943 for (UriPermission perm : perms.values()) { 7944 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7945 result.add(perm.buildPersistedPublicApiObject()); 7946 } 7947 } 7948 } 7949 } 7950 } 7951 return new ParceledListSlice<android.content.UriPermission>(result); 7952 } 7953 7954 @Override 7955 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7956 synchronized (this) { 7957 ProcessRecord app = 7958 who != null ? getRecordForAppLocked(who) : null; 7959 if (app == null) return; 7960 7961 Message msg = Message.obtain(); 7962 msg.what = WAIT_FOR_DEBUGGER_MSG; 7963 msg.obj = app; 7964 msg.arg1 = waiting ? 1 : 0; 7965 mHandler.sendMessage(msg); 7966 } 7967 } 7968 7969 @Override 7970 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7971 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7972 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7973 outInfo.availMem = Process.getFreeMemory(); 7974 outInfo.totalMem = Process.getTotalMemory(); 7975 outInfo.threshold = homeAppMem; 7976 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7977 outInfo.hiddenAppThreshold = cachedAppMem; 7978 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7979 ProcessList.SERVICE_ADJ); 7980 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7981 ProcessList.VISIBLE_APP_ADJ); 7982 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7983 ProcessList.FOREGROUND_APP_ADJ); 7984 } 7985 7986 // ========================================================= 7987 // TASK MANAGEMENT 7988 // ========================================================= 7989 7990 @Override 7991 public List<IAppTask> getAppTasks(String callingPackage) { 7992 int callingUid = Binder.getCallingUid(); 7993 long ident = Binder.clearCallingIdentity(); 7994 7995 synchronized(this) { 7996 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7997 try { 7998 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7999 8000 final int N = mRecentTasks.size(); 8001 for (int i = 0; i < N; i++) { 8002 TaskRecord tr = mRecentTasks.get(i); 8003 // Skip tasks that do not match the caller. We don't need to verify 8004 // callingPackage, because we are also limiting to callingUid and know 8005 // that will limit to the correct security sandbox. 8006 if (tr.effectiveUid != callingUid) { 8007 continue; 8008 } 8009 Intent intent = tr.getBaseIntent(); 8010 if (intent == null || 8011 !callingPackage.equals(intent.getComponent().getPackageName())) { 8012 continue; 8013 } 8014 ActivityManager.RecentTaskInfo taskInfo = 8015 createRecentTaskInfoFromTaskRecord(tr); 8016 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8017 list.add(taskImpl); 8018 } 8019 } finally { 8020 Binder.restoreCallingIdentity(ident); 8021 } 8022 return list; 8023 } 8024 } 8025 8026 @Override 8027 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8028 final int callingUid = Binder.getCallingUid(); 8029 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8030 8031 synchronized(this) { 8032 if (localLOGV) Slog.v( 8033 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8034 8035 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8036 callingUid); 8037 8038 // TODO: Improve with MRU list from all ActivityStacks. 8039 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8040 } 8041 8042 return list; 8043 } 8044 8045 /** 8046 * Creates a new RecentTaskInfo from a TaskRecord. 8047 */ 8048 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8049 // Update the task description to reflect any changes in the task stack 8050 tr.updateTaskDescription(); 8051 8052 // Compose the recent task info 8053 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8054 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8055 rti.persistentId = tr.taskId; 8056 rti.baseIntent = new Intent(tr.getBaseIntent()); 8057 rti.origActivity = tr.origActivity; 8058 rti.description = tr.lastDescription; 8059 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8060 rti.userId = tr.userId; 8061 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8062 rti.firstActiveTime = tr.firstActiveTime; 8063 rti.lastActiveTime = tr.lastActiveTime; 8064 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8065 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8066 return rti; 8067 } 8068 8069 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8070 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8071 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8072 if (!allowed) { 8073 if (checkPermission(android.Manifest.permission.GET_TASKS, 8074 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8075 // Temporary compatibility: some existing apps on the system image may 8076 // still be requesting the old permission and not switched to the new 8077 // one; if so, we'll still allow them full access. This means we need 8078 // to see if they are holding the old permission and are a system app. 8079 try { 8080 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8081 allowed = true; 8082 Slog.w(TAG, caller + ": caller " + callingUid 8083 + " is using old GET_TASKS but privileged; allowing"); 8084 } 8085 } catch (RemoteException e) { 8086 } 8087 } 8088 } 8089 if (!allowed) { 8090 Slog.w(TAG, caller + ": caller " + callingUid 8091 + " does not hold GET_TASKS; limiting output"); 8092 } 8093 return allowed; 8094 } 8095 8096 @Override 8097 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8098 final int callingUid = Binder.getCallingUid(); 8099 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8100 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8101 8102 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8103 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8104 synchronized (this) { 8105 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8106 callingUid); 8107 final boolean detailed = checkCallingPermission( 8108 android.Manifest.permission.GET_DETAILED_TASKS) 8109 == PackageManager.PERMISSION_GRANTED; 8110 8111 final int N = mRecentTasks.size(); 8112 ArrayList<ActivityManager.RecentTaskInfo> res 8113 = new ArrayList<ActivityManager.RecentTaskInfo>( 8114 maxNum < N ? maxNum : N); 8115 8116 final Set<Integer> includedUsers; 8117 if (includeProfiles) { 8118 includedUsers = getProfileIdsLocked(userId); 8119 } else { 8120 includedUsers = new HashSet<Integer>(); 8121 } 8122 includedUsers.add(Integer.valueOf(userId)); 8123 8124 for (int i=0; i<N && maxNum > 0; i++) { 8125 TaskRecord tr = mRecentTasks.get(i); 8126 // Only add calling user or related users recent tasks 8127 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8128 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8129 continue; 8130 } 8131 8132 // Return the entry if desired by the caller. We always return 8133 // the first entry, because callers always expect this to be the 8134 // foreground app. We may filter others if the caller has 8135 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8136 // we should exclude the entry. 8137 8138 if (i == 0 8139 || withExcluded 8140 || (tr.intent == null) 8141 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8142 == 0)) { 8143 if (!allowed) { 8144 // If the caller doesn't have the GET_TASKS permission, then only 8145 // allow them to see a small subset of tasks -- their own and home. 8146 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8147 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8148 continue; 8149 } 8150 } 8151 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8152 if (tr.stack != null && tr.stack.isHomeStack()) { 8153 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8154 continue; 8155 } 8156 } 8157 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8158 // Don't include auto remove tasks that are finished or finishing. 8159 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8160 + tr); 8161 continue; 8162 } 8163 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8164 && !tr.isAvailable) { 8165 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8166 continue; 8167 } 8168 8169 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8170 if (!detailed) { 8171 rti.baseIntent.replaceExtras((Bundle)null); 8172 } 8173 8174 res.add(rti); 8175 maxNum--; 8176 } 8177 } 8178 return res; 8179 } 8180 } 8181 8182 private TaskRecord taskForIdLocked(int id) { 8183 final TaskRecord task = recentTaskForIdLocked(id); 8184 if (task != null) { 8185 return task; 8186 } 8187 8188 // Don't give up. Sometimes it just hasn't made it to recents yet. 8189 return mStackSupervisor.anyTaskForIdLocked(id); 8190 } 8191 8192 private TaskRecord recentTaskForIdLocked(int id) { 8193 final int N = mRecentTasks.size(); 8194 for (int i=0; i<N; i++) { 8195 TaskRecord tr = mRecentTasks.get(i); 8196 if (tr.taskId == id) { 8197 return tr; 8198 } 8199 } 8200 return null; 8201 } 8202 8203 @Override 8204 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8205 synchronized (this) { 8206 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8207 "getTaskThumbnail()"); 8208 TaskRecord tr = recentTaskForIdLocked(id); 8209 if (tr != null) { 8210 return tr.getTaskThumbnailLocked(); 8211 } 8212 } 8213 return null; 8214 } 8215 8216 @Override 8217 public int addAppTask(IBinder activityToken, Intent intent, 8218 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8219 final int callingUid = Binder.getCallingUid(); 8220 final long callingIdent = Binder.clearCallingIdentity(); 8221 8222 try { 8223 synchronized (this) { 8224 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8225 if (r == null) { 8226 throw new IllegalArgumentException("Activity does not exist; token=" 8227 + activityToken); 8228 } 8229 ComponentName comp = intent.getComponent(); 8230 if (comp == null) { 8231 throw new IllegalArgumentException("Intent " + intent 8232 + " must specify explicit component"); 8233 } 8234 if (thumbnail.getWidth() != mThumbnailWidth 8235 || thumbnail.getHeight() != mThumbnailHeight) { 8236 throw new IllegalArgumentException("Bad thumbnail size: got " 8237 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8238 + mThumbnailWidth + "x" + mThumbnailHeight); 8239 } 8240 if (intent.getSelector() != null) { 8241 intent.setSelector(null); 8242 } 8243 if (intent.getSourceBounds() != null) { 8244 intent.setSourceBounds(null); 8245 } 8246 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8247 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8248 // The caller has added this as an auto-remove task... that makes no 8249 // sense, so turn off auto-remove. 8250 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8251 } 8252 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8253 // Must be a new task. 8254 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8255 } 8256 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8257 mLastAddedTaskActivity = null; 8258 } 8259 ActivityInfo ainfo = mLastAddedTaskActivity; 8260 if (ainfo == null) { 8261 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8262 comp, 0, UserHandle.getUserId(callingUid)); 8263 if (ainfo.applicationInfo.uid != callingUid) { 8264 throw new SecurityException( 8265 "Can't add task for another application: target uid=" 8266 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8267 } 8268 } 8269 8270 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8271 intent, description); 8272 8273 int trimIdx = trimRecentsForTaskLocked(task, false); 8274 if (trimIdx >= 0) { 8275 // If this would have caused a trim, then we'll abort because that 8276 // means it would be added at the end of the list but then just removed. 8277 return INVALID_TASK_ID; 8278 } 8279 8280 final int N = mRecentTasks.size(); 8281 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8282 final TaskRecord tr = mRecentTasks.remove(N - 1); 8283 tr.removedFromRecents(); 8284 } 8285 8286 task.inRecents = true; 8287 mRecentTasks.add(task); 8288 r.task.stack.addTask(task, false, false); 8289 8290 task.setLastThumbnail(thumbnail); 8291 task.freeLastThumbnail(); 8292 8293 return task.taskId; 8294 } 8295 } finally { 8296 Binder.restoreCallingIdentity(callingIdent); 8297 } 8298 } 8299 8300 @Override 8301 public Point getAppTaskThumbnailSize() { 8302 synchronized (this) { 8303 return new Point(mThumbnailWidth, mThumbnailHeight); 8304 } 8305 } 8306 8307 @Override 8308 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8309 synchronized (this) { 8310 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8311 if (r != null) { 8312 r.setTaskDescription(td); 8313 r.task.updateTaskDescription(); 8314 } 8315 } 8316 } 8317 8318 @Override 8319 public Bitmap getTaskDescriptionIcon(String filename) { 8320 if (!FileUtils.isValidExtFilename(filename) 8321 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8322 throw new IllegalArgumentException("Bad filename: " + filename); 8323 } 8324 return mTaskPersister.getTaskDescriptionIcon(filename); 8325 } 8326 8327 @Override 8328 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8329 throws RemoteException { 8330 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8331 opts.getCustomInPlaceResId() == 0) { 8332 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8333 "with valid animation"); 8334 } 8335 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8336 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8337 opts.getCustomInPlaceResId()); 8338 mWindowManager.executeAppTransition(); 8339 } 8340 8341 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8342 mRecentTasks.remove(tr); 8343 tr.removedFromRecents(); 8344 ComponentName component = tr.getBaseIntent().getComponent(); 8345 if (component == null) { 8346 Slog.w(TAG, "No component for base intent of task: " + tr); 8347 return; 8348 } 8349 8350 if (!killProcess) { 8351 return; 8352 } 8353 8354 // Determine if the process(es) for this task should be killed. 8355 final String pkg = component.getPackageName(); 8356 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8357 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8358 for (int i = 0; i < pmap.size(); i++) { 8359 8360 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8361 for (int j = 0; j < uids.size(); j++) { 8362 ProcessRecord proc = uids.valueAt(j); 8363 if (proc.userId != tr.userId) { 8364 // Don't kill process for a different user. 8365 continue; 8366 } 8367 if (proc == mHomeProcess) { 8368 // Don't kill the home process along with tasks from the same package. 8369 continue; 8370 } 8371 if (!proc.pkgList.containsKey(pkg)) { 8372 // Don't kill process that is not associated with this task. 8373 continue; 8374 } 8375 8376 for (int k = 0; k < proc.activities.size(); k++) { 8377 TaskRecord otherTask = proc.activities.get(k).task; 8378 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8379 // Don't kill process(es) that has an activity in a different task that is 8380 // also in recents. 8381 return; 8382 } 8383 } 8384 8385 // Add process to kill list. 8386 procsToKill.add(proc); 8387 } 8388 } 8389 8390 // Find any running services associated with this app and stop if needed. 8391 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8392 8393 // Kill the running processes. 8394 for (int i = 0; i < procsToKill.size(); i++) { 8395 ProcessRecord pr = procsToKill.get(i); 8396 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8397 pr.kill("remove task", true); 8398 } else { 8399 pr.waitingToKill = "remove task"; 8400 } 8401 } 8402 } 8403 8404 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8405 // Remove all tasks with activities in the specified package from the list of recent tasks 8406 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8407 TaskRecord tr = mRecentTasks.get(i); 8408 if (tr.userId != userId) continue; 8409 8410 ComponentName cn = tr.intent.getComponent(); 8411 if (cn != null && cn.getPackageName().equals(packageName)) { 8412 // If the package name matches, remove the task. 8413 removeTaskByIdLocked(tr.taskId, true); 8414 } 8415 } 8416 } 8417 8418 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8419 final IPackageManager pm = AppGlobals.getPackageManager(); 8420 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8421 8422 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8423 TaskRecord tr = mRecentTasks.get(i); 8424 if (tr.userId != userId) continue; 8425 8426 ComponentName cn = tr.intent.getComponent(); 8427 if (cn != null && cn.getPackageName().equals(packageName)) { 8428 // Skip if component still exists in the package. 8429 if (componentsKnownToExist.contains(cn)) continue; 8430 8431 try { 8432 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8433 if (info != null) { 8434 componentsKnownToExist.add(cn); 8435 } else { 8436 removeTaskByIdLocked(tr.taskId, false); 8437 } 8438 } catch (RemoteException e) { 8439 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8440 } 8441 } 8442 } 8443 } 8444 8445 /** 8446 * Removes the task with the specified task id. 8447 * 8448 * @param taskId Identifier of the task to be removed. 8449 * @param killProcess Kill any process associated with the task if possible. 8450 * @return Returns true if the given task was found and removed. 8451 */ 8452 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8453 TaskRecord tr = taskForIdLocked(taskId); 8454 if (tr != null) { 8455 tr.removeTaskActivitiesLocked(); 8456 cleanUpRemovedTaskLocked(tr, killProcess); 8457 if (tr.isPersistable) { 8458 notifyTaskPersisterLocked(null, true); 8459 } 8460 return true; 8461 } 8462 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8463 return false; 8464 } 8465 8466 @Override 8467 public boolean removeTask(int taskId) { 8468 synchronized (this) { 8469 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8470 "removeTask()"); 8471 long ident = Binder.clearCallingIdentity(); 8472 try { 8473 return removeTaskByIdLocked(taskId, true); 8474 } finally { 8475 Binder.restoreCallingIdentity(ident); 8476 } 8477 } 8478 } 8479 8480 /** 8481 * TODO: Add mController hook 8482 */ 8483 @Override 8484 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8485 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8486 "moveTaskToFront()"); 8487 8488 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8489 synchronized(this) { 8490 moveTaskToFrontLocked(taskId, flags, options); 8491 } 8492 } 8493 8494 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8495 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8496 Binder.getCallingUid(), -1, -1, "Task to front")) { 8497 ActivityOptions.abort(options); 8498 return; 8499 } 8500 final long origId = Binder.clearCallingIdentity(); 8501 try { 8502 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8503 if (task == null) { 8504 Slog.d(TAG, "Could not find task for id: "+ taskId); 8505 return; 8506 } 8507 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8508 mStackSupervisor.showLockTaskToast(); 8509 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8510 return; 8511 } 8512 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8513 if (prev != null && prev.isRecentsActivity()) { 8514 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8515 } 8516 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8517 } finally { 8518 Binder.restoreCallingIdentity(origId); 8519 } 8520 ActivityOptions.abort(options); 8521 } 8522 8523 @Override 8524 public void moveTaskToBack(int taskId) { 8525 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8526 "moveTaskToBack()"); 8527 8528 synchronized(this) { 8529 TaskRecord tr = taskForIdLocked(taskId); 8530 if (tr != null) { 8531 if (tr == mStackSupervisor.mLockTaskModeTask) { 8532 mStackSupervisor.showLockTaskToast(); 8533 return; 8534 } 8535 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8536 ActivityStack stack = tr.stack; 8537 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8538 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8539 Binder.getCallingUid(), -1, -1, "Task to back")) { 8540 return; 8541 } 8542 } 8543 final long origId = Binder.clearCallingIdentity(); 8544 try { 8545 stack.moveTaskToBackLocked(taskId, null); 8546 } finally { 8547 Binder.restoreCallingIdentity(origId); 8548 } 8549 } 8550 } 8551 } 8552 8553 /** 8554 * Moves an activity, and all of the other activities within the same task, to the bottom 8555 * of the history stack. The activity's order within the task is unchanged. 8556 * 8557 * @param token A reference to the activity we wish to move 8558 * @param nonRoot If false then this only works if the activity is the root 8559 * of a task; if true it will work for any activity in a task. 8560 * @return Returns true if the move completed, false if not. 8561 */ 8562 @Override 8563 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8564 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8565 synchronized(this) { 8566 final long origId = Binder.clearCallingIdentity(); 8567 try { 8568 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8569 if (taskId >= 0) { 8570 if ((mStackSupervisor.mLockTaskModeTask != null) 8571 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8572 mStackSupervisor.showLockTaskToast(); 8573 return false; 8574 } 8575 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8576 } 8577 } finally { 8578 Binder.restoreCallingIdentity(origId); 8579 } 8580 } 8581 return false; 8582 } 8583 8584 @Override 8585 public void moveTaskBackwards(int task) { 8586 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8587 "moveTaskBackwards()"); 8588 8589 synchronized(this) { 8590 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8591 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8592 return; 8593 } 8594 final long origId = Binder.clearCallingIdentity(); 8595 moveTaskBackwardsLocked(task); 8596 Binder.restoreCallingIdentity(origId); 8597 } 8598 } 8599 8600 private final void moveTaskBackwardsLocked(int task) { 8601 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8602 } 8603 8604 @Override 8605 public IBinder getHomeActivityToken() throws RemoteException { 8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8607 "getHomeActivityToken()"); 8608 synchronized (this) { 8609 return mStackSupervisor.getHomeActivityToken(); 8610 } 8611 } 8612 8613 @Override 8614 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8615 IActivityContainerCallback callback) throws RemoteException { 8616 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8617 "createActivityContainer()"); 8618 synchronized (this) { 8619 if (parentActivityToken == null) { 8620 throw new IllegalArgumentException("parent token must not be null"); 8621 } 8622 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8623 if (r == null) { 8624 return null; 8625 } 8626 if (callback == null) { 8627 throw new IllegalArgumentException("callback must not be null"); 8628 } 8629 return mStackSupervisor.createActivityContainer(r, callback); 8630 } 8631 } 8632 8633 @Override 8634 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8635 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8636 "deleteActivityContainer()"); 8637 synchronized (this) { 8638 mStackSupervisor.deleteActivityContainer(container); 8639 } 8640 } 8641 8642 @Override 8643 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8644 throws RemoteException { 8645 synchronized (this) { 8646 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8647 if (stack != null) { 8648 return stack.mActivityContainer; 8649 } 8650 return null; 8651 } 8652 } 8653 8654 @Override 8655 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8656 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8657 "moveTaskToStack()"); 8658 if (stackId == HOME_STACK_ID) { 8659 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8660 new RuntimeException("here").fillInStackTrace()); 8661 } 8662 synchronized (this) { 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8666 + stackId + " toTop=" + toTop); 8667 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8668 } finally { 8669 Binder.restoreCallingIdentity(ident); 8670 } 8671 } 8672 } 8673 8674 @Override 8675 public void resizeStack(int stackBoxId, Rect bounds) { 8676 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8677 "resizeStackBox()"); 8678 long ident = Binder.clearCallingIdentity(); 8679 try { 8680 mWindowManager.resizeStack(stackBoxId, bounds); 8681 } finally { 8682 Binder.restoreCallingIdentity(ident); 8683 } 8684 } 8685 8686 @Override 8687 public List<StackInfo> getAllStackInfos() { 8688 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8689 "getAllStackInfos()"); 8690 long ident = Binder.clearCallingIdentity(); 8691 try { 8692 synchronized (this) { 8693 return mStackSupervisor.getAllStackInfosLocked(); 8694 } 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 } 8699 8700 @Override 8701 public StackInfo getStackInfo(int stackId) { 8702 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8703 "getStackInfo()"); 8704 long ident = Binder.clearCallingIdentity(); 8705 try { 8706 synchronized (this) { 8707 return mStackSupervisor.getStackInfoLocked(stackId); 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 8714 @Override 8715 public boolean isInHomeStack(int taskId) { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "getStackInfo()"); 8718 long ident = Binder.clearCallingIdentity(); 8719 try { 8720 synchronized (this) { 8721 TaskRecord tr = taskForIdLocked(taskId); 8722 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8723 } 8724 } finally { 8725 Binder.restoreCallingIdentity(ident); 8726 } 8727 } 8728 8729 @Override 8730 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8731 synchronized(this) { 8732 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8733 } 8734 } 8735 8736 private boolean isLockTaskAuthorized(String pkg) { 8737 final DevicePolicyManager dpm = (DevicePolicyManager) 8738 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8739 try { 8740 int uid = mContext.getPackageManager().getPackageUid(pkg, 8741 Binder.getCallingUserHandle().getIdentifier()); 8742 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8743 } catch (NameNotFoundException e) { 8744 return false; 8745 } 8746 } 8747 8748 void startLockTaskMode(TaskRecord task) { 8749 final String pkg; 8750 synchronized (this) { 8751 pkg = task.intent.getComponent().getPackageName(); 8752 } 8753 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8754 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8755 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8756 StatusBarManagerInternal.class); 8757 if (statusBarManager != null) { 8758 statusBarManager.showScreenPinningRequest(); 8759 } 8760 return; 8761 } 8762 long ident = Binder.clearCallingIdentity(); 8763 try { 8764 synchronized (this) { 8765 // Since we lost lock on task, make sure it is still there. 8766 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8767 if (task != null) { 8768 if (!isSystemInitiated 8769 && ((mStackSupervisor.getFocusedStack() == null) 8770 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8771 throw new IllegalArgumentException("Invalid task, not in foreground"); 8772 } 8773 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8774 } 8775 } 8776 } finally { 8777 Binder.restoreCallingIdentity(ident); 8778 } 8779 } 8780 8781 @Override 8782 public void startLockTaskMode(int taskId) { 8783 final TaskRecord task; 8784 long ident = Binder.clearCallingIdentity(); 8785 try { 8786 synchronized (this) { 8787 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8788 } 8789 } finally { 8790 Binder.restoreCallingIdentity(ident); 8791 } 8792 if (task != null) { 8793 startLockTaskMode(task); 8794 } 8795 } 8796 8797 @Override 8798 public void startLockTaskMode(IBinder token) { 8799 final TaskRecord task; 8800 long ident = Binder.clearCallingIdentity(); 8801 try { 8802 synchronized (this) { 8803 final ActivityRecord r = ActivityRecord.forToken(token); 8804 if (r == null) { 8805 return; 8806 } 8807 task = r.task; 8808 } 8809 } finally { 8810 Binder.restoreCallingIdentity(ident); 8811 } 8812 if (task != null) { 8813 startLockTaskMode(task); 8814 } 8815 } 8816 8817 @Override 8818 public void startLockTaskModeOnCurrent() throws RemoteException { 8819 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8820 "startLockTaskModeOnCurrent"); 8821 long ident = Binder.clearCallingIdentity(); 8822 try { 8823 ActivityRecord r = null; 8824 synchronized (this) { 8825 r = mStackSupervisor.topRunningActivityLocked(); 8826 } 8827 startLockTaskMode(r.task); 8828 } finally { 8829 Binder.restoreCallingIdentity(ident); 8830 } 8831 } 8832 8833 @Override 8834 public void stopLockTaskMode() { 8835 // Verify that the user matches the package of the intent for the TaskRecord 8836 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8837 // and stopLockTaskMode. 8838 final int callingUid = Binder.getCallingUid(); 8839 if (callingUid != Process.SYSTEM_UID) { 8840 try { 8841 String pkg = 8842 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8843 int uid = mContext.getPackageManager().getPackageUid(pkg, 8844 Binder.getCallingUserHandle().getIdentifier()); 8845 if (uid != callingUid) { 8846 throw new SecurityException("Invalid uid, expected " + uid); 8847 } 8848 } catch (NameNotFoundException e) { 8849 Log.d(TAG, "stopLockTaskMode " + e); 8850 return; 8851 } 8852 } 8853 long ident = Binder.clearCallingIdentity(); 8854 try { 8855 Log.d(TAG, "stopLockTaskMode"); 8856 // Stop lock task 8857 synchronized (this) { 8858 mStackSupervisor.setLockTaskModeLocked(null, false); 8859 } 8860 } finally { 8861 Binder.restoreCallingIdentity(ident); 8862 } 8863 } 8864 8865 @Override 8866 public void stopLockTaskModeOnCurrent() throws RemoteException { 8867 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8868 "stopLockTaskModeOnCurrent"); 8869 long ident = Binder.clearCallingIdentity(); 8870 try { 8871 stopLockTaskMode(); 8872 } finally { 8873 Binder.restoreCallingIdentity(ident); 8874 } 8875 } 8876 8877 @Override 8878 public boolean isInLockTaskMode() { 8879 synchronized (this) { 8880 return mStackSupervisor.isInLockTaskMode(); 8881 } 8882 } 8883 8884 // ========================================================= 8885 // CONTENT PROVIDERS 8886 // ========================================================= 8887 8888 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8889 List<ProviderInfo> providers = null; 8890 try { 8891 providers = AppGlobals.getPackageManager(). 8892 queryContentProviders(app.processName, app.uid, 8893 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8894 } catch (RemoteException ex) { 8895 } 8896 if (DEBUG_MU) 8897 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8898 int userId = app.userId; 8899 if (providers != null) { 8900 int N = providers.size(); 8901 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8902 for (int i=0; i<N; i++) { 8903 ProviderInfo cpi = 8904 (ProviderInfo)providers.get(i); 8905 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8906 cpi.name, cpi.flags); 8907 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8908 // This is a singleton provider, but a user besides the 8909 // default user is asking to initialize a process it runs 8910 // in... well, no, it doesn't actually run in this process, 8911 // it runs in the process of the default user. Get rid of it. 8912 providers.remove(i); 8913 N--; 8914 i--; 8915 continue; 8916 } 8917 8918 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8919 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8920 if (cpr == null) { 8921 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8922 mProviderMap.putProviderByClass(comp, cpr); 8923 } 8924 if (DEBUG_MU) 8925 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8926 app.pubProviders.put(cpi.name, cpr); 8927 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8928 // Don't add this if it is a platform component that is marked 8929 // to run in multiple processes, because this is actually 8930 // part of the framework so doesn't make sense to track as a 8931 // separate apk in the process. 8932 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8933 mProcessStats); 8934 } 8935 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8936 } 8937 } 8938 return providers; 8939 } 8940 8941 /** 8942 * Check if {@link ProcessRecord} has a possible chance at accessing the 8943 * given {@link ProviderInfo}. Final permission checking is always done 8944 * in {@link ContentProvider}. 8945 */ 8946 private final String checkContentProviderPermissionLocked( 8947 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8948 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8949 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8950 boolean checkedGrants = false; 8951 if (checkUser) { 8952 // Looking for cross-user grants before enforcing the typical cross-users permissions 8953 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8954 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8955 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8956 return null; 8957 } 8958 checkedGrants = true; 8959 } 8960 userId = handleIncomingUser(callingPid, callingUid, userId, 8961 false, ALLOW_NON_FULL, 8962 "checkContentProviderPermissionLocked " + cpi.authority, null); 8963 if (userId != tmpTargetUserId) { 8964 // When we actually went to determine the final targer user ID, this ended 8965 // up different than our initial check for the authority. This is because 8966 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8967 // SELF. So we need to re-check the grants again. 8968 checkedGrants = false; 8969 } 8970 } 8971 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8972 cpi.applicationInfo.uid, cpi.exported) 8973 == PackageManager.PERMISSION_GRANTED) { 8974 return null; 8975 } 8976 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8977 cpi.applicationInfo.uid, cpi.exported) 8978 == PackageManager.PERMISSION_GRANTED) { 8979 return null; 8980 } 8981 8982 PathPermission[] pps = cpi.pathPermissions; 8983 if (pps != null) { 8984 int i = pps.length; 8985 while (i > 0) { 8986 i--; 8987 PathPermission pp = pps[i]; 8988 String pprperm = pp.getReadPermission(); 8989 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8990 cpi.applicationInfo.uid, cpi.exported) 8991 == PackageManager.PERMISSION_GRANTED) { 8992 return null; 8993 } 8994 String ppwperm = pp.getWritePermission(); 8995 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8996 cpi.applicationInfo.uid, cpi.exported) 8997 == PackageManager.PERMISSION_GRANTED) { 8998 return null; 8999 } 9000 } 9001 } 9002 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9003 return null; 9004 } 9005 9006 String msg; 9007 if (!cpi.exported) { 9008 msg = "Permission Denial: opening provider " + cpi.name 9009 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9010 + ", uid=" + callingUid + ") that is not exported from uid " 9011 + cpi.applicationInfo.uid; 9012 } else { 9013 msg = "Permission Denial: opening provider " + cpi.name 9014 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9015 + ", uid=" + callingUid + ") requires " 9016 + cpi.readPermission + " or " + cpi.writePermission; 9017 } 9018 Slog.w(TAG, msg); 9019 return msg; 9020 } 9021 9022 /** 9023 * Returns if the ContentProvider has granted a uri to callingUid 9024 */ 9025 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9026 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9027 if (perms != null) { 9028 for (int i=perms.size()-1; i>=0; i--) { 9029 GrantUri grantUri = perms.keyAt(i); 9030 if (grantUri.sourceUserId == userId || !checkUser) { 9031 if (matchesProvider(grantUri.uri, cpi)) { 9032 return true; 9033 } 9034 } 9035 } 9036 } 9037 return false; 9038 } 9039 9040 /** 9041 * Returns true if the uri authority is one of the authorities specified in the provider. 9042 */ 9043 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9044 String uriAuth = uri.getAuthority(); 9045 String cpiAuth = cpi.authority; 9046 if (cpiAuth.indexOf(';') == -1) { 9047 return cpiAuth.equals(uriAuth); 9048 } 9049 String[] cpiAuths = cpiAuth.split(";"); 9050 int length = cpiAuths.length; 9051 for (int i = 0; i < length; i++) { 9052 if (cpiAuths[i].equals(uriAuth)) return true; 9053 } 9054 return false; 9055 } 9056 9057 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9058 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9059 if (r != null) { 9060 for (int i=0; i<r.conProviders.size(); i++) { 9061 ContentProviderConnection conn = r.conProviders.get(i); 9062 if (conn.provider == cpr) { 9063 if (DEBUG_PROVIDER) Slog.v(TAG, 9064 "Adding provider requested by " 9065 + r.processName + " from process " 9066 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9067 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9068 if (stable) { 9069 conn.stableCount++; 9070 conn.numStableIncs++; 9071 } else { 9072 conn.unstableCount++; 9073 conn.numUnstableIncs++; 9074 } 9075 return conn; 9076 } 9077 } 9078 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9079 if (stable) { 9080 conn.stableCount = 1; 9081 conn.numStableIncs = 1; 9082 } else { 9083 conn.unstableCount = 1; 9084 conn.numUnstableIncs = 1; 9085 } 9086 cpr.connections.add(conn); 9087 r.conProviders.add(conn); 9088 return conn; 9089 } 9090 cpr.addExternalProcessHandleLocked(externalProcessToken); 9091 return null; 9092 } 9093 9094 boolean decProviderCountLocked(ContentProviderConnection conn, 9095 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9096 if (conn != null) { 9097 cpr = conn.provider; 9098 if (DEBUG_PROVIDER) Slog.v(TAG, 9099 "Removing provider requested by " 9100 + conn.client.processName + " from process " 9101 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9102 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9103 if (stable) { 9104 conn.stableCount--; 9105 } else { 9106 conn.unstableCount--; 9107 } 9108 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9109 cpr.connections.remove(conn); 9110 conn.client.conProviders.remove(conn); 9111 return true; 9112 } 9113 return false; 9114 } 9115 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9116 return false; 9117 } 9118 9119 private void checkTime(long startTime, String where) { 9120 long now = SystemClock.elapsedRealtime(); 9121 if ((now-startTime) > 1000) { 9122 // If we are taking more than a second, log about it. 9123 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9124 } 9125 } 9126 9127 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9128 String name, IBinder token, boolean stable, int userId) { 9129 ContentProviderRecord cpr; 9130 ContentProviderConnection conn = null; 9131 ProviderInfo cpi = null; 9132 9133 synchronized(this) { 9134 long startTime = SystemClock.elapsedRealtime(); 9135 9136 ProcessRecord r = null; 9137 if (caller != null) { 9138 r = getRecordForAppLocked(caller); 9139 if (r == null) { 9140 throw new SecurityException( 9141 "Unable to find app for caller " + caller 9142 + " (pid=" + Binder.getCallingPid() 9143 + ") when getting content provider " + name); 9144 } 9145 } 9146 9147 boolean checkCrossUser = true; 9148 9149 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9150 9151 // First check if this content provider has been published... 9152 cpr = mProviderMap.getProviderByName(name, userId); 9153 // If that didn't work, check if it exists for user 0 and then 9154 // verify that it's a singleton provider before using it. 9155 if (cpr == null && userId != UserHandle.USER_OWNER) { 9156 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9157 if (cpr != null) { 9158 cpi = cpr.info; 9159 if (isSingleton(cpi.processName, cpi.applicationInfo, 9160 cpi.name, cpi.flags) 9161 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9162 userId = UserHandle.USER_OWNER; 9163 checkCrossUser = false; 9164 } else { 9165 cpr = null; 9166 cpi = null; 9167 } 9168 } 9169 } 9170 9171 boolean providerRunning = cpr != null; 9172 if (providerRunning) { 9173 cpi = cpr.info; 9174 String msg; 9175 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9176 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9177 != null) { 9178 throw new SecurityException(msg); 9179 } 9180 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9181 9182 if (r != null && cpr.canRunHere(r)) { 9183 // This provider has been published or is in the process 9184 // of being published... but it is also allowed to run 9185 // in the caller's process, so don't make a connection 9186 // and just let the caller instantiate its own instance. 9187 ContentProviderHolder holder = cpr.newHolder(null); 9188 // don't give caller the provider object, it needs 9189 // to make its own. 9190 holder.provider = null; 9191 return holder; 9192 } 9193 9194 final long origId = Binder.clearCallingIdentity(); 9195 9196 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9197 9198 // In this case the provider instance already exists, so we can 9199 // return it right away. 9200 conn = incProviderCountLocked(r, cpr, token, stable); 9201 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9202 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9203 // If this is a perceptible app accessing the provider, 9204 // make sure to count it as being accessed and thus 9205 // back up on the LRU list. This is good because 9206 // content providers are often expensive to start. 9207 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9208 updateLruProcessLocked(cpr.proc, false, null); 9209 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9210 } 9211 } 9212 9213 if (cpr.proc != null) { 9214 if (false) { 9215 if (cpr.name.flattenToShortString().equals( 9216 "com.android.providers.calendar/.CalendarProvider2")) { 9217 Slog.v(TAG, "****************** KILLING " 9218 + cpr.name.flattenToShortString()); 9219 Process.killProcess(cpr.proc.pid); 9220 } 9221 } 9222 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9223 boolean success = updateOomAdjLocked(cpr.proc); 9224 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9225 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9226 // NOTE: there is still a race here where a signal could be 9227 // pending on the process even though we managed to update its 9228 // adj level. Not sure what to do about this, but at least 9229 // the race is now smaller. 9230 if (!success) { 9231 // Uh oh... it looks like the provider's process 9232 // has been killed on us. We need to wait for a new 9233 // process to be started, and make sure its death 9234 // doesn't kill our process. 9235 Slog.i(TAG, 9236 "Existing provider " + cpr.name.flattenToShortString() 9237 + " is crashing; detaching " + r); 9238 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9239 checkTime(startTime, "getContentProviderImpl: before appDied"); 9240 appDiedLocked(cpr.proc); 9241 checkTime(startTime, "getContentProviderImpl: after appDied"); 9242 if (!lastRef) { 9243 // This wasn't the last ref our process had on 9244 // the provider... we have now been killed, bail. 9245 return null; 9246 } 9247 providerRunning = false; 9248 conn = null; 9249 } 9250 } 9251 9252 Binder.restoreCallingIdentity(origId); 9253 } 9254 9255 boolean singleton; 9256 if (!providerRunning) { 9257 try { 9258 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9259 cpi = AppGlobals.getPackageManager(). 9260 resolveContentProvider(name, 9261 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9262 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9263 } catch (RemoteException ex) { 9264 } 9265 if (cpi == null) { 9266 return null; 9267 } 9268 // If the provider is a singleton AND 9269 // (it's a call within the same user || the provider is a 9270 // privileged app) 9271 // Then allow connecting to the singleton provider 9272 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9273 cpi.name, cpi.flags) 9274 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9275 if (singleton) { 9276 userId = UserHandle.USER_OWNER; 9277 } 9278 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9279 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9280 9281 String msg; 9282 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9283 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9284 != null) { 9285 throw new SecurityException(msg); 9286 } 9287 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9288 9289 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9290 && !cpi.processName.equals("system")) { 9291 // If this content provider does not run in the system 9292 // process, and the system is not yet ready to run other 9293 // processes, then fail fast instead of hanging. 9294 throw new IllegalArgumentException( 9295 "Attempt to launch content provider before system ready"); 9296 } 9297 9298 // Make sure that the user who owns this provider is started. If not, 9299 // we don't want to allow it to run. 9300 if (mStartedUsers.get(userId) == null) { 9301 Slog.w(TAG, "Unable to launch app " 9302 + cpi.applicationInfo.packageName + "/" 9303 + cpi.applicationInfo.uid + " for provider " 9304 + name + ": user " + userId + " is stopped"); 9305 return null; 9306 } 9307 9308 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9309 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9310 cpr = mProviderMap.getProviderByClass(comp, userId); 9311 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9312 final boolean firstClass = cpr == null; 9313 if (firstClass) { 9314 final long ident = Binder.clearCallingIdentity(); 9315 try { 9316 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9317 ApplicationInfo ai = 9318 AppGlobals.getPackageManager(). 9319 getApplicationInfo( 9320 cpi.applicationInfo.packageName, 9321 STOCK_PM_FLAGS, userId); 9322 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9323 if (ai == null) { 9324 Slog.w(TAG, "No package info for content provider " 9325 + cpi.name); 9326 return null; 9327 } 9328 ai = getAppInfoForUser(ai, userId); 9329 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9330 } catch (RemoteException ex) { 9331 // pm is in same process, this will never happen. 9332 } finally { 9333 Binder.restoreCallingIdentity(ident); 9334 } 9335 } 9336 9337 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9338 9339 if (r != null && cpr.canRunHere(r)) { 9340 // If this is a multiprocess provider, then just return its 9341 // info and allow the caller to instantiate it. Only do 9342 // this if the provider is the same user as the caller's 9343 // process, or can run as root (so can be in any process). 9344 return cpr.newHolder(null); 9345 } 9346 9347 if (DEBUG_PROVIDER) { 9348 RuntimeException e = new RuntimeException("here"); 9349 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9350 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9351 } 9352 9353 // This is single process, and our app is now connecting to it. 9354 // See if we are already in the process of launching this 9355 // provider. 9356 final int N = mLaunchingProviders.size(); 9357 int i; 9358 for (i=0; i<N; i++) { 9359 if (mLaunchingProviders.get(i) == cpr) { 9360 break; 9361 } 9362 } 9363 9364 // If the provider is not already being launched, then get it 9365 // started. 9366 if (i >= N) { 9367 final long origId = Binder.clearCallingIdentity(); 9368 9369 try { 9370 // Content provider is now in use, its package can't be stopped. 9371 try { 9372 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9373 AppGlobals.getPackageManager().setPackageStoppedState( 9374 cpr.appInfo.packageName, false, userId); 9375 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9376 } catch (RemoteException e) { 9377 } catch (IllegalArgumentException e) { 9378 Slog.w(TAG, "Failed trying to unstop package " 9379 + cpr.appInfo.packageName + ": " + e); 9380 } 9381 9382 // Use existing process if already started 9383 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9384 ProcessRecord proc = getProcessRecordLocked( 9385 cpi.processName, cpr.appInfo.uid, false); 9386 if (proc != null && proc.thread != null) { 9387 if (DEBUG_PROVIDER) { 9388 Slog.d(TAG, "Installing in existing process " + proc); 9389 } 9390 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9391 proc.pubProviders.put(cpi.name, cpr); 9392 try { 9393 proc.thread.scheduleInstallProvider(cpi); 9394 } catch (RemoteException e) { 9395 } 9396 } else { 9397 checkTime(startTime, "getContentProviderImpl: before start process"); 9398 proc = startProcessLocked(cpi.processName, 9399 cpr.appInfo, false, 0, "content provider", 9400 new ComponentName(cpi.applicationInfo.packageName, 9401 cpi.name), false, false, false); 9402 checkTime(startTime, "getContentProviderImpl: after start process"); 9403 if (proc == null) { 9404 Slog.w(TAG, "Unable to launch app " 9405 + cpi.applicationInfo.packageName + "/" 9406 + cpi.applicationInfo.uid + " for provider " 9407 + name + ": process is bad"); 9408 return null; 9409 } 9410 } 9411 cpr.launchingApp = proc; 9412 mLaunchingProviders.add(cpr); 9413 } finally { 9414 Binder.restoreCallingIdentity(origId); 9415 } 9416 } 9417 9418 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9419 9420 // Make sure the provider is published (the same provider class 9421 // may be published under multiple names). 9422 if (firstClass) { 9423 mProviderMap.putProviderByClass(comp, cpr); 9424 } 9425 9426 mProviderMap.putProviderByName(name, cpr); 9427 conn = incProviderCountLocked(r, cpr, token, stable); 9428 if (conn != null) { 9429 conn.waiting = true; 9430 } 9431 } 9432 checkTime(startTime, "getContentProviderImpl: done!"); 9433 } 9434 9435 // Wait for the provider to be published... 9436 synchronized (cpr) { 9437 while (cpr.provider == null) { 9438 if (cpr.launchingApp == null) { 9439 Slog.w(TAG, "Unable to launch app " 9440 + cpi.applicationInfo.packageName + "/" 9441 + cpi.applicationInfo.uid + " for provider " 9442 + name + ": launching app became null"); 9443 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9444 UserHandle.getUserId(cpi.applicationInfo.uid), 9445 cpi.applicationInfo.packageName, 9446 cpi.applicationInfo.uid, name); 9447 return null; 9448 } 9449 try { 9450 if (DEBUG_MU) { 9451 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9452 + cpr.launchingApp); 9453 } 9454 if (conn != null) { 9455 conn.waiting = true; 9456 } 9457 cpr.wait(); 9458 } catch (InterruptedException ex) { 9459 } finally { 9460 if (conn != null) { 9461 conn.waiting = false; 9462 } 9463 } 9464 } 9465 } 9466 return cpr != null ? cpr.newHolder(conn) : null; 9467 } 9468 9469 @Override 9470 public final ContentProviderHolder getContentProvider( 9471 IApplicationThread caller, String name, int userId, boolean stable) { 9472 enforceNotIsolatedCaller("getContentProvider"); 9473 if (caller == null) { 9474 String msg = "null IApplicationThread when getting content provider " 9475 + name; 9476 Slog.w(TAG, msg); 9477 throw new SecurityException(msg); 9478 } 9479 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9480 // with cross-user grant. 9481 return getContentProviderImpl(caller, name, null, stable, userId); 9482 } 9483 9484 public ContentProviderHolder getContentProviderExternal( 9485 String name, int userId, IBinder token) { 9486 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9487 "Do not have permission in call getContentProviderExternal()"); 9488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9489 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9490 return getContentProviderExternalUnchecked(name, token, userId); 9491 } 9492 9493 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9494 IBinder token, int userId) { 9495 return getContentProviderImpl(null, name, token, true, userId); 9496 } 9497 9498 /** 9499 * Drop a content provider from a ProcessRecord's bookkeeping 9500 */ 9501 public void removeContentProvider(IBinder connection, boolean stable) { 9502 enforceNotIsolatedCaller("removeContentProvider"); 9503 long ident = Binder.clearCallingIdentity(); 9504 try { 9505 synchronized (this) { 9506 ContentProviderConnection conn; 9507 try { 9508 conn = (ContentProviderConnection)connection; 9509 } catch (ClassCastException e) { 9510 String msg ="removeContentProvider: " + connection 9511 + " not a ContentProviderConnection"; 9512 Slog.w(TAG, msg); 9513 throw new IllegalArgumentException(msg); 9514 } 9515 if (conn == null) { 9516 throw new NullPointerException("connection is null"); 9517 } 9518 if (decProviderCountLocked(conn, null, null, stable)) { 9519 updateOomAdjLocked(); 9520 } 9521 } 9522 } finally { 9523 Binder.restoreCallingIdentity(ident); 9524 } 9525 } 9526 9527 public void removeContentProviderExternal(String name, IBinder token) { 9528 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9529 "Do not have permission in call removeContentProviderExternal()"); 9530 int userId = UserHandle.getCallingUserId(); 9531 long ident = Binder.clearCallingIdentity(); 9532 try { 9533 removeContentProviderExternalUnchecked(name, token, userId); 9534 } finally { 9535 Binder.restoreCallingIdentity(ident); 9536 } 9537 } 9538 9539 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9540 synchronized (this) { 9541 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9542 if(cpr == null) { 9543 //remove from mProvidersByClass 9544 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9545 return; 9546 } 9547 9548 //update content provider record entry info 9549 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9550 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9551 if (localCpr.hasExternalProcessHandles()) { 9552 if (localCpr.removeExternalProcessHandleLocked(token)) { 9553 updateOomAdjLocked(); 9554 } else { 9555 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9556 + " with no external reference for token: " 9557 + token + "."); 9558 } 9559 } else { 9560 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9561 + " with no external references."); 9562 } 9563 } 9564 } 9565 9566 public final void publishContentProviders(IApplicationThread caller, 9567 List<ContentProviderHolder> providers) { 9568 if (providers == null) { 9569 return; 9570 } 9571 9572 enforceNotIsolatedCaller("publishContentProviders"); 9573 synchronized (this) { 9574 final ProcessRecord r = getRecordForAppLocked(caller); 9575 if (DEBUG_MU) 9576 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9577 if (r == null) { 9578 throw new SecurityException( 9579 "Unable to find app for caller " + caller 9580 + " (pid=" + Binder.getCallingPid() 9581 + ") when publishing content providers"); 9582 } 9583 9584 final long origId = Binder.clearCallingIdentity(); 9585 9586 final int N = providers.size(); 9587 for (int i=0; i<N; i++) { 9588 ContentProviderHolder src = providers.get(i); 9589 if (src == null || src.info == null || src.provider == null) { 9590 continue; 9591 } 9592 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9593 if (DEBUG_MU) 9594 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9595 if (dst != null) { 9596 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9597 mProviderMap.putProviderByClass(comp, dst); 9598 String names[] = dst.info.authority.split(";"); 9599 for (int j = 0; j < names.length; j++) { 9600 mProviderMap.putProviderByName(names[j], dst); 9601 } 9602 9603 int NL = mLaunchingProviders.size(); 9604 int j; 9605 for (j=0; j<NL; j++) { 9606 if (mLaunchingProviders.get(j) == dst) { 9607 mLaunchingProviders.remove(j); 9608 j--; 9609 NL--; 9610 } 9611 } 9612 synchronized (dst) { 9613 dst.provider = src.provider; 9614 dst.proc = r; 9615 dst.notifyAll(); 9616 } 9617 updateOomAdjLocked(r); 9618 } 9619 } 9620 9621 Binder.restoreCallingIdentity(origId); 9622 } 9623 } 9624 9625 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9626 ContentProviderConnection conn; 9627 try { 9628 conn = (ContentProviderConnection)connection; 9629 } catch (ClassCastException e) { 9630 String msg ="refContentProvider: " + connection 9631 + " not a ContentProviderConnection"; 9632 Slog.w(TAG, msg); 9633 throw new IllegalArgumentException(msg); 9634 } 9635 if (conn == null) { 9636 throw new NullPointerException("connection is null"); 9637 } 9638 9639 synchronized (this) { 9640 if (stable > 0) { 9641 conn.numStableIncs += stable; 9642 } 9643 stable = conn.stableCount + stable; 9644 if (stable < 0) { 9645 throw new IllegalStateException("stableCount < 0: " + stable); 9646 } 9647 9648 if (unstable > 0) { 9649 conn.numUnstableIncs += unstable; 9650 } 9651 unstable = conn.unstableCount + unstable; 9652 if (unstable < 0) { 9653 throw new IllegalStateException("unstableCount < 0: " + unstable); 9654 } 9655 9656 if ((stable+unstable) <= 0) { 9657 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9658 + stable + " unstable=" + unstable); 9659 } 9660 conn.stableCount = stable; 9661 conn.unstableCount = unstable; 9662 return !conn.dead; 9663 } 9664 } 9665 9666 public void unstableProviderDied(IBinder connection) { 9667 ContentProviderConnection conn; 9668 try { 9669 conn = (ContentProviderConnection)connection; 9670 } catch (ClassCastException e) { 9671 String msg ="refContentProvider: " + connection 9672 + " not a ContentProviderConnection"; 9673 Slog.w(TAG, msg); 9674 throw new IllegalArgumentException(msg); 9675 } 9676 if (conn == null) { 9677 throw new NullPointerException("connection is null"); 9678 } 9679 9680 // Safely retrieve the content provider associated with the connection. 9681 IContentProvider provider; 9682 synchronized (this) { 9683 provider = conn.provider.provider; 9684 } 9685 9686 if (provider == null) { 9687 // Um, yeah, we're way ahead of you. 9688 return; 9689 } 9690 9691 // Make sure the caller is being honest with us. 9692 if (provider.asBinder().pingBinder()) { 9693 // Er, no, still looks good to us. 9694 synchronized (this) { 9695 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9696 + " says " + conn + " died, but we don't agree"); 9697 return; 9698 } 9699 } 9700 9701 // Well look at that! It's dead! 9702 synchronized (this) { 9703 if (conn.provider.provider != provider) { 9704 // But something changed... good enough. 9705 return; 9706 } 9707 9708 ProcessRecord proc = conn.provider.proc; 9709 if (proc == null || proc.thread == null) { 9710 // Seems like the process is already cleaned up. 9711 return; 9712 } 9713 9714 // As far as we're concerned, this is just like receiving a 9715 // death notification... just a bit prematurely. 9716 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9717 + ") early provider death"); 9718 final long ident = Binder.clearCallingIdentity(); 9719 try { 9720 appDiedLocked(proc); 9721 } finally { 9722 Binder.restoreCallingIdentity(ident); 9723 } 9724 } 9725 } 9726 9727 @Override 9728 public void appNotRespondingViaProvider(IBinder connection) { 9729 enforceCallingPermission( 9730 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9731 9732 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9733 if (conn == null) { 9734 Slog.w(TAG, "ContentProviderConnection is null"); 9735 return; 9736 } 9737 9738 final ProcessRecord host = conn.provider.proc; 9739 if (host == null) { 9740 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9741 return; 9742 } 9743 9744 final long token = Binder.clearCallingIdentity(); 9745 try { 9746 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9747 } finally { 9748 Binder.restoreCallingIdentity(token); 9749 } 9750 } 9751 9752 public final void installSystemProviders() { 9753 List<ProviderInfo> providers; 9754 synchronized (this) { 9755 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9756 providers = generateApplicationProvidersLocked(app); 9757 if (providers != null) { 9758 for (int i=providers.size()-1; i>=0; i--) { 9759 ProviderInfo pi = (ProviderInfo)providers.get(i); 9760 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9761 Slog.w(TAG, "Not installing system proc provider " + pi.name 9762 + ": not system .apk"); 9763 providers.remove(i); 9764 } 9765 } 9766 } 9767 } 9768 if (providers != null) { 9769 mSystemThread.installSystemProviders(providers); 9770 } 9771 9772 mCoreSettingsObserver = new CoreSettingsObserver(this); 9773 9774 //mUsageStatsService.monitorPackages(); 9775 } 9776 9777 /** 9778 * Allows apps to retrieve the MIME type of a URI. 9779 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9780 * users, then it does not need permission to access the ContentProvider. 9781 * Either, it needs cross-user uri grants. 9782 * 9783 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9784 * 9785 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9786 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9787 */ 9788 public String getProviderMimeType(Uri uri, int userId) { 9789 enforceNotIsolatedCaller("getProviderMimeType"); 9790 final String name = uri.getAuthority(); 9791 int callingUid = Binder.getCallingUid(); 9792 int callingPid = Binder.getCallingPid(); 9793 long ident = 0; 9794 boolean clearedIdentity = false; 9795 userId = unsafeConvertIncomingUser(userId); 9796 if (canClearIdentity(callingPid, callingUid, userId)) { 9797 clearedIdentity = true; 9798 ident = Binder.clearCallingIdentity(); 9799 } 9800 ContentProviderHolder holder = null; 9801 try { 9802 holder = getContentProviderExternalUnchecked(name, null, userId); 9803 if (holder != null) { 9804 return holder.provider.getType(uri); 9805 } 9806 } catch (RemoteException e) { 9807 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9808 return null; 9809 } finally { 9810 // We need to clear the identity to call removeContentProviderExternalUnchecked 9811 if (!clearedIdentity) { 9812 ident = Binder.clearCallingIdentity(); 9813 } 9814 try { 9815 if (holder != null) { 9816 removeContentProviderExternalUnchecked(name, null, userId); 9817 } 9818 } finally { 9819 Binder.restoreCallingIdentity(ident); 9820 } 9821 } 9822 9823 return null; 9824 } 9825 9826 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9827 if (UserHandle.getUserId(callingUid) == userId) { 9828 return true; 9829 } 9830 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9831 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9832 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9833 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9834 return true; 9835 } 9836 return false; 9837 } 9838 9839 // ========================================================= 9840 // GLOBAL MANAGEMENT 9841 // ========================================================= 9842 9843 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9844 boolean isolated, int isolatedUid) { 9845 String proc = customProcess != null ? customProcess : info.processName; 9846 BatteryStatsImpl.Uid.Proc ps = null; 9847 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9848 int uid = info.uid; 9849 if (isolated) { 9850 if (isolatedUid == 0) { 9851 int userId = UserHandle.getUserId(uid); 9852 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9853 while (true) { 9854 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9855 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9856 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9857 } 9858 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9859 mNextIsolatedProcessUid++; 9860 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9861 // No process for this uid, use it. 9862 break; 9863 } 9864 stepsLeft--; 9865 if (stepsLeft <= 0) { 9866 return null; 9867 } 9868 } 9869 } else { 9870 // Special case for startIsolatedProcess (internal only), where 9871 // the uid of the isolated process is specified by the caller. 9872 uid = isolatedUid; 9873 } 9874 } 9875 return new ProcessRecord(stats, info, proc, uid); 9876 } 9877 9878 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9879 String abiOverride) { 9880 ProcessRecord app; 9881 if (!isolated) { 9882 app = getProcessRecordLocked(info.processName, info.uid, true); 9883 } else { 9884 app = null; 9885 } 9886 9887 if (app == null) { 9888 app = newProcessRecordLocked(info, null, isolated, 0); 9889 mProcessNames.put(info.processName, app.uid, app); 9890 if (isolated) { 9891 mIsolatedProcesses.put(app.uid, app); 9892 } 9893 updateLruProcessLocked(app, false, null); 9894 updateOomAdjLocked(); 9895 } 9896 9897 // This package really, really can not be stopped. 9898 try { 9899 AppGlobals.getPackageManager().setPackageStoppedState( 9900 info.packageName, false, UserHandle.getUserId(app.uid)); 9901 } catch (RemoteException e) { 9902 } catch (IllegalArgumentException e) { 9903 Slog.w(TAG, "Failed trying to unstop package " 9904 + info.packageName + ": " + e); 9905 } 9906 9907 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9908 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9909 app.persistent = true; 9910 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9911 } 9912 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9913 mPersistentStartingProcesses.add(app); 9914 startProcessLocked(app, "added application", app.processName, abiOverride, 9915 null /* entryPoint */, null /* entryPointArgs */); 9916 } 9917 9918 return app; 9919 } 9920 9921 public void unhandledBack() { 9922 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9923 "unhandledBack()"); 9924 9925 synchronized(this) { 9926 final long origId = Binder.clearCallingIdentity(); 9927 try { 9928 getFocusedStack().unhandledBackLocked(); 9929 } finally { 9930 Binder.restoreCallingIdentity(origId); 9931 } 9932 } 9933 } 9934 9935 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9936 enforceNotIsolatedCaller("openContentUri"); 9937 final int userId = UserHandle.getCallingUserId(); 9938 String name = uri.getAuthority(); 9939 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9940 ParcelFileDescriptor pfd = null; 9941 if (cph != null) { 9942 // We record the binder invoker's uid in thread-local storage before 9943 // going to the content provider to open the file. Later, in the code 9944 // that handles all permissions checks, we look for this uid and use 9945 // that rather than the Activity Manager's own uid. The effect is that 9946 // we do the check against the caller's permissions even though it looks 9947 // to the content provider like the Activity Manager itself is making 9948 // the request. 9949 Binder token = new Binder(); 9950 sCallerIdentity.set(new Identity( 9951 token, Binder.getCallingPid(), Binder.getCallingUid())); 9952 try { 9953 pfd = cph.provider.openFile(null, uri, "r", null, token); 9954 } catch (FileNotFoundException e) { 9955 // do nothing; pfd will be returned null 9956 } finally { 9957 // Ensure that whatever happens, we clean up the identity state 9958 sCallerIdentity.remove(); 9959 } 9960 9961 // We've got the fd now, so we're done with the provider. 9962 removeContentProviderExternalUnchecked(name, null, userId); 9963 } else { 9964 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9965 } 9966 return pfd; 9967 } 9968 9969 // Actually is sleeping or shutting down or whatever else in the future 9970 // is an inactive state. 9971 public boolean isSleepingOrShuttingDown() { 9972 return isSleeping() || mShuttingDown; 9973 } 9974 9975 public boolean isSleeping() { 9976 return mSleeping; 9977 } 9978 9979 void onWakefulnessChanged(int wakefulness) { 9980 synchronized(this) { 9981 mWakefulness = wakefulness; 9982 updateSleepIfNeededLocked(); 9983 } 9984 } 9985 9986 void finishRunningVoiceLocked() { 9987 if (mRunningVoice) { 9988 mRunningVoice = false; 9989 updateSleepIfNeededLocked(); 9990 } 9991 } 9992 9993 void updateSleepIfNeededLocked() { 9994 if (mSleeping && !shouldSleepLocked()) { 9995 mSleeping = false; 9996 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9997 } else if (!mSleeping && shouldSleepLocked()) { 9998 mSleeping = true; 9999 mStackSupervisor.goingToSleepLocked(); 10000 10001 // Initialize the wake times of all processes. 10002 checkExcessivePowerUsageLocked(false); 10003 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10004 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10005 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10006 } 10007 } 10008 10009 private boolean shouldSleepLocked() { 10010 // Resume applications while running a voice interactor. 10011 if (mRunningVoice) { 10012 return false; 10013 } 10014 10015 switch (mWakefulness) { 10016 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10017 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10018 // If we're interactive but applications are already paused then defer 10019 // resuming them until the lock screen is hidden. 10020 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10021 case PowerManagerInternal.WAKEFULNESS_DOZING: 10022 // If we're dozing then pause applications whenever the lock screen is shown. 10023 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10024 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10025 default: 10026 // If we're asleep then pause applications unconditionally. 10027 return true; 10028 } 10029 } 10030 10031 /** Pokes the task persister. */ 10032 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10033 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10034 // Never persist the home stack. 10035 return; 10036 } 10037 mTaskPersister.wakeup(task, flush); 10038 } 10039 10040 /** Notifies all listeners when the task stack has changed. */ 10041 void notifyTaskStackChangedLocked() { 10042 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10043 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10044 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10045 } 10046 10047 @Override 10048 public boolean shutdown(int timeout) { 10049 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10050 != PackageManager.PERMISSION_GRANTED) { 10051 throw new SecurityException("Requires permission " 10052 + android.Manifest.permission.SHUTDOWN); 10053 } 10054 10055 boolean timedout = false; 10056 10057 synchronized(this) { 10058 mShuttingDown = true; 10059 updateEventDispatchingLocked(); 10060 timedout = mStackSupervisor.shutdownLocked(timeout); 10061 } 10062 10063 mAppOpsService.shutdown(); 10064 if (mUsageStatsService != null) { 10065 mUsageStatsService.prepareShutdown(); 10066 } 10067 mBatteryStatsService.shutdown(); 10068 synchronized (this) { 10069 mProcessStats.shutdownLocked(); 10070 notifyTaskPersisterLocked(null, true); 10071 } 10072 10073 return timedout; 10074 } 10075 10076 public final void activitySlept(IBinder token) { 10077 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10078 10079 final long origId = Binder.clearCallingIdentity(); 10080 10081 synchronized (this) { 10082 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10083 if (r != null) { 10084 mStackSupervisor.activitySleptLocked(r); 10085 } 10086 } 10087 10088 Binder.restoreCallingIdentity(origId); 10089 } 10090 10091 private String lockScreenShownToString() { 10092 switch (mLockScreenShown) { 10093 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10094 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10095 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10096 default: return "Unknown=" + mLockScreenShown; 10097 } 10098 } 10099 10100 void logLockScreen(String msg) { 10101 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10102 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10103 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10104 + " mSleeping=" + mSleeping); 10105 } 10106 10107 void startRunningVoiceLocked() { 10108 if (!mRunningVoice) { 10109 mRunningVoice = true; 10110 updateSleepIfNeededLocked(); 10111 } 10112 } 10113 10114 private void updateEventDispatchingLocked() { 10115 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10116 } 10117 10118 public void setLockScreenShown(boolean shown) { 10119 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10120 != PackageManager.PERMISSION_GRANTED) { 10121 throw new SecurityException("Requires permission " 10122 + android.Manifest.permission.DEVICE_POWER); 10123 } 10124 10125 synchronized(this) { 10126 long ident = Binder.clearCallingIdentity(); 10127 try { 10128 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10129 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10130 updateSleepIfNeededLocked(); 10131 } finally { 10132 Binder.restoreCallingIdentity(ident); 10133 } 10134 } 10135 } 10136 10137 @Override 10138 public void stopAppSwitches() { 10139 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10140 != PackageManager.PERMISSION_GRANTED) { 10141 throw new SecurityException("Requires permission " 10142 + android.Manifest.permission.STOP_APP_SWITCHES); 10143 } 10144 10145 synchronized(this) { 10146 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10147 + APP_SWITCH_DELAY_TIME; 10148 mDidAppSwitch = false; 10149 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10150 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10151 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10152 } 10153 } 10154 10155 public void resumeAppSwitches() { 10156 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10157 != PackageManager.PERMISSION_GRANTED) { 10158 throw new SecurityException("Requires permission " 10159 + android.Manifest.permission.STOP_APP_SWITCHES); 10160 } 10161 10162 synchronized(this) { 10163 // Note that we don't execute any pending app switches... we will 10164 // let those wait until either the timeout, or the next start 10165 // activity request. 10166 mAppSwitchesAllowedTime = 0; 10167 } 10168 } 10169 10170 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10171 int callingPid, int callingUid, String name) { 10172 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10173 return true; 10174 } 10175 10176 int perm = checkComponentPermission( 10177 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10178 sourceUid, -1, true); 10179 if (perm == PackageManager.PERMISSION_GRANTED) { 10180 return true; 10181 } 10182 10183 // If the actual IPC caller is different from the logical source, then 10184 // also see if they are allowed to control app switches. 10185 if (callingUid != -1 && callingUid != sourceUid) { 10186 perm = checkComponentPermission( 10187 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10188 callingUid, -1, true); 10189 if (perm == PackageManager.PERMISSION_GRANTED) { 10190 return true; 10191 } 10192 } 10193 10194 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10195 return false; 10196 } 10197 10198 public void setDebugApp(String packageName, boolean waitForDebugger, 10199 boolean persistent) { 10200 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10201 "setDebugApp()"); 10202 10203 long ident = Binder.clearCallingIdentity(); 10204 try { 10205 // Note that this is not really thread safe if there are multiple 10206 // callers into it at the same time, but that's not a situation we 10207 // care about. 10208 if (persistent) { 10209 final ContentResolver resolver = mContext.getContentResolver(); 10210 Settings.Global.putString( 10211 resolver, Settings.Global.DEBUG_APP, 10212 packageName); 10213 Settings.Global.putInt( 10214 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10215 waitForDebugger ? 1 : 0); 10216 } 10217 10218 synchronized (this) { 10219 if (!persistent) { 10220 mOrigDebugApp = mDebugApp; 10221 mOrigWaitForDebugger = mWaitForDebugger; 10222 } 10223 mDebugApp = packageName; 10224 mWaitForDebugger = waitForDebugger; 10225 mDebugTransient = !persistent; 10226 if (packageName != null) { 10227 forceStopPackageLocked(packageName, -1, false, false, true, true, 10228 false, UserHandle.USER_ALL, "set debug app"); 10229 } 10230 } 10231 } finally { 10232 Binder.restoreCallingIdentity(ident); 10233 } 10234 } 10235 10236 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10237 synchronized (this) { 10238 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10239 if (!isDebuggable) { 10240 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10241 throw new SecurityException("Process not debuggable: " + app.packageName); 10242 } 10243 } 10244 10245 mOpenGlTraceApp = processName; 10246 } 10247 } 10248 10249 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10250 synchronized (this) { 10251 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10252 if (!isDebuggable) { 10253 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10254 throw new SecurityException("Process not debuggable: " + app.packageName); 10255 } 10256 } 10257 mProfileApp = processName; 10258 mProfileFile = profilerInfo.profileFile; 10259 if (mProfileFd != null) { 10260 try { 10261 mProfileFd.close(); 10262 } catch (IOException e) { 10263 } 10264 mProfileFd = null; 10265 } 10266 mProfileFd = profilerInfo.profileFd; 10267 mSamplingInterval = profilerInfo.samplingInterval; 10268 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10269 mProfileType = 0; 10270 } 10271 } 10272 10273 @Override 10274 public void setAlwaysFinish(boolean enabled) { 10275 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10276 "setAlwaysFinish()"); 10277 10278 Settings.Global.putInt( 10279 mContext.getContentResolver(), 10280 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10281 10282 synchronized (this) { 10283 mAlwaysFinishActivities = enabled; 10284 } 10285 } 10286 10287 @Override 10288 public void setActivityController(IActivityController controller) { 10289 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10290 "setActivityController()"); 10291 synchronized (this) { 10292 mController = controller; 10293 Watchdog.getInstance().setActivityController(controller); 10294 } 10295 } 10296 10297 @Override 10298 public void setUserIsMonkey(boolean userIsMonkey) { 10299 synchronized (this) { 10300 synchronized (mPidsSelfLocked) { 10301 final int callingPid = Binder.getCallingPid(); 10302 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10303 if (precessRecord == null) { 10304 throw new SecurityException("Unknown process: " + callingPid); 10305 } 10306 if (precessRecord.instrumentationUiAutomationConnection == null) { 10307 throw new SecurityException("Only an instrumentation process " 10308 + "with a UiAutomation can call setUserIsMonkey"); 10309 } 10310 } 10311 mUserIsMonkey = userIsMonkey; 10312 } 10313 } 10314 10315 @Override 10316 public boolean isUserAMonkey() { 10317 synchronized (this) { 10318 // If there is a controller also implies the user is a monkey. 10319 return (mUserIsMonkey || mController != null); 10320 } 10321 } 10322 10323 public void requestBugReport() { 10324 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10325 SystemProperties.set("ctl.start", "bugreport"); 10326 } 10327 10328 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10329 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10330 } 10331 10332 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10333 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10334 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10335 } 10336 return KEY_DISPATCHING_TIMEOUT; 10337 } 10338 10339 @Override 10340 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10341 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10342 != PackageManager.PERMISSION_GRANTED) { 10343 throw new SecurityException("Requires permission " 10344 + android.Manifest.permission.FILTER_EVENTS); 10345 } 10346 ProcessRecord proc; 10347 long timeout; 10348 synchronized (this) { 10349 synchronized (mPidsSelfLocked) { 10350 proc = mPidsSelfLocked.get(pid); 10351 } 10352 timeout = getInputDispatchingTimeoutLocked(proc); 10353 } 10354 10355 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10356 return -1; 10357 } 10358 10359 return timeout; 10360 } 10361 10362 /** 10363 * Handle input dispatching timeouts. 10364 * Returns whether input dispatching should be aborted or not. 10365 */ 10366 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10367 final ActivityRecord activity, final ActivityRecord parent, 10368 final boolean aboveSystem, String reason) { 10369 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10370 != PackageManager.PERMISSION_GRANTED) { 10371 throw new SecurityException("Requires permission " 10372 + android.Manifest.permission.FILTER_EVENTS); 10373 } 10374 10375 final String annotation; 10376 if (reason == null) { 10377 annotation = "Input dispatching timed out"; 10378 } else { 10379 annotation = "Input dispatching timed out (" + reason + ")"; 10380 } 10381 10382 if (proc != null) { 10383 synchronized (this) { 10384 if (proc.debugging) { 10385 return false; 10386 } 10387 10388 if (mDidDexOpt) { 10389 // Give more time since we were dexopting. 10390 mDidDexOpt = false; 10391 return false; 10392 } 10393 10394 if (proc.instrumentationClass != null) { 10395 Bundle info = new Bundle(); 10396 info.putString("shortMsg", "keyDispatchingTimedOut"); 10397 info.putString("longMsg", annotation); 10398 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10399 return true; 10400 } 10401 } 10402 mHandler.post(new Runnable() { 10403 @Override 10404 public void run() { 10405 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10406 } 10407 }); 10408 } 10409 10410 return true; 10411 } 10412 10413 public Bundle getAssistContextExtras(int requestType) { 10414 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10415 UserHandle.getCallingUserId()); 10416 if (pae == null) { 10417 return null; 10418 } 10419 synchronized (pae) { 10420 while (!pae.haveResult) { 10421 try { 10422 pae.wait(); 10423 } catch (InterruptedException e) { 10424 } 10425 } 10426 if (pae.result != null) { 10427 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10428 } 10429 } 10430 synchronized (this) { 10431 mPendingAssistExtras.remove(pae); 10432 mHandler.removeCallbacks(pae); 10433 } 10434 return pae.extras; 10435 } 10436 10437 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10438 int userHandle) { 10439 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10440 "getAssistContextExtras()"); 10441 PendingAssistExtras pae; 10442 Bundle extras = new Bundle(); 10443 synchronized (this) { 10444 ActivityRecord activity = getFocusedStack().mResumedActivity; 10445 if (activity == null) { 10446 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10447 return null; 10448 } 10449 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10450 if (activity.app == null || activity.app.thread == null) { 10451 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10452 return null; 10453 } 10454 if (activity.app.pid == Binder.getCallingPid()) { 10455 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10456 return null; 10457 } 10458 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10459 try { 10460 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10461 requestType); 10462 mPendingAssistExtras.add(pae); 10463 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10464 } catch (RemoteException e) { 10465 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10466 return null; 10467 } 10468 return pae; 10469 } 10470 } 10471 10472 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10473 PendingAssistExtras pae = (PendingAssistExtras)token; 10474 synchronized (pae) { 10475 pae.result = extras; 10476 pae.haveResult = true; 10477 pae.notifyAll(); 10478 if (pae.intent == null) { 10479 // Caller is just waiting for the result. 10480 return; 10481 } 10482 } 10483 10484 // We are now ready to launch the assist activity. 10485 synchronized (this) { 10486 boolean exists = mPendingAssistExtras.remove(pae); 10487 mHandler.removeCallbacks(pae); 10488 if (!exists) { 10489 // Timed out. 10490 return; 10491 } 10492 } 10493 pae.intent.replaceExtras(extras); 10494 if (pae.hint != null) { 10495 pae.intent.putExtra(pae.hint, true); 10496 } 10497 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10498 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10499 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10500 closeSystemDialogs("assist"); 10501 try { 10502 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10503 } catch (ActivityNotFoundException e) { 10504 Slog.w(TAG, "No activity to handle assist action.", e); 10505 } 10506 } 10507 10508 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10509 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10510 } 10511 10512 public void registerProcessObserver(IProcessObserver observer) { 10513 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10514 "registerProcessObserver()"); 10515 synchronized (this) { 10516 mProcessObservers.register(observer); 10517 } 10518 } 10519 10520 @Override 10521 public void unregisterProcessObserver(IProcessObserver observer) { 10522 synchronized (this) { 10523 mProcessObservers.unregister(observer); 10524 } 10525 } 10526 10527 @Override 10528 public boolean convertFromTranslucent(IBinder token) { 10529 final long origId = Binder.clearCallingIdentity(); 10530 try { 10531 synchronized (this) { 10532 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10533 if (r == null) { 10534 return false; 10535 } 10536 final boolean translucentChanged = r.changeWindowTranslucency(true); 10537 if (translucentChanged) { 10538 r.task.stack.releaseBackgroundResources(); 10539 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10540 } 10541 mWindowManager.setAppFullscreen(token, true); 10542 return translucentChanged; 10543 } 10544 } finally { 10545 Binder.restoreCallingIdentity(origId); 10546 } 10547 } 10548 10549 @Override 10550 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10551 final long origId = Binder.clearCallingIdentity(); 10552 try { 10553 synchronized (this) { 10554 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10555 if (r == null) { 10556 return false; 10557 } 10558 int index = r.task.mActivities.lastIndexOf(r); 10559 if (index > 0) { 10560 ActivityRecord under = r.task.mActivities.get(index - 1); 10561 under.returningOptions = options; 10562 } 10563 final boolean translucentChanged = r.changeWindowTranslucency(false); 10564 if (translucentChanged) { 10565 r.task.stack.convertToTranslucent(r); 10566 } 10567 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10568 mWindowManager.setAppFullscreen(token, false); 10569 return translucentChanged; 10570 } 10571 } finally { 10572 Binder.restoreCallingIdentity(origId); 10573 } 10574 } 10575 10576 @Override 10577 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10578 final long origId = Binder.clearCallingIdentity(); 10579 try { 10580 synchronized (this) { 10581 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10582 if (r != null) { 10583 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10584 } 10585 } 10586 return false; 10587 } finally { 10588 Binder.restoreCallingIdentity(origId); 10589 } 10590 } 10591 10592 @Override 10593 public boolean isBackgroundVisibleBehind(IBinder token) { 10594 final long origId = Binder.clearCallingIdentity(); 10595 try { 10596 synchronized (this) { 10597 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10598 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10599 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10600 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10601 return visible; 10602 } 10603 } finally { 10604 Binder.restoreCallingIdentity(origId); 10605 } 10606 } 10607 10608 @Override 10609 public ActivityOptions getActivityOptions(IBinder token) { 10610 final long origId = Binder.clearCallingIdentity(); 10611 try { 10612 synchronized (this) { 10613 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10614 if (r != null) { 10615 final ActivityOptions activityOptions = r.pendingOptions; 10616 r.pendingOptions = null; 10617 return activityOptions; 10618 } 10619 return null; 10620 } 10621 } finally { 10622 Binder.restoreCallingIdentity(origId); 10623 } 10624 } 10625 10626 @Override 10627 public void setImmersive(IBinder token, boolean immersive) { 10628 synchronized(this) { 10629 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10630 if (r == null) { 10631 throw new IllegalArgumentException(); 10632 } 10633 r.immersive = immersive; 10634 10635 // update associated state if we're frontmost 10636 if (r == mFocusedActivity) { 10637 if (DEBUG_IMMERSIVE) { 10638 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10639 } 10640 applyUpdateLockStateLocked(r); 10641 } 10642 } 10643 } 10644 10645 @Override 10646 public boolean isImmersive(IBinder token) { 10647 synchronized (this) { 10648 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10649 if (r == null) { 10650 throw new IllegalArgumentException(); 10651 } 10652 return r.immersive; 10653 } 10654 } 10655 10656 public boolean isTopActivityImmersive() { 10657 enforceNotIsolatedCaller("startActivity"); 10658 synchronized (this) { 10659 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10660 return (r != null) ? r.immersive : false; 10661 } 10662 } 10663 10664 @Override 10665 public boolean isTopOfTask(IBinder token) { 10666 synchronized (this) { 10667 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10668 if (r == null) { 10669 throw new IllegalArgumentException(); 10670 } 10671 return r.task.getTopActivity() == r; 10672 } 10673 } 10674 10675 public final void enterSafeMode() { 10676 synchronized(this) { 10677 // It only makes sense to do this before the system is ready 10678 // and started launching other packages. 10679 if (!mSystemReady) { 10680 try { 10681 AppGlobals.getPackageManager().enterSafeMode(); 10682 } catch (RemoteException e) { 10683 } 10684 } 10685 10686 mSafeMode = true; 10687 } 10688 } 10689 10690 public final void showSafeModeOverlay() { 10691 View v = LayoutInflater.from(mContext).inflate( 10692 com.android.internal.R.layout.safe_mode, null); 10693 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10694 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10695 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10696 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10697 lp.gravity = Gravity.BOTTOM | Gravity.START; 10698 lp.format = v.getBackground().getOpacity(); 10699 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10700 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10701 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10702 ((WindowManager)mContext.getSystemService( 10703 Context.WINDOW_SERVICE)).addView(v, lp); 10704 } 10705 10706 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10707 if (!(sender instanceof PendingIntentRecord)) { 10708 return; 10709 } 10710 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10711 synchronized (stats) { 10712 if (mBatteryStatsService.isOnBattery()) { 10713 mBatteryStatsService.enforceCallingPermission(); 10714 PendingIntentRecord rec = (PendingIntentRecord)sender; 10715 int MY_UID = Binder.getCallingUid(); 10716 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10717 BatteryStatsImpl.Uid.Pkg pkg = 10718 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10719 sourcePkg != null ? sourcePkg : rec.key.packageName); 10720 pkg.incWakeupsLocked(); 10721 } 10722 } 10723 } 10724 10725 public boolean killPids(int[] pids, String pReason, boolean secure) { 10726 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10727 throw new SecurityException("killPids only available to the system"); 10728 } 10729 String reason = (pReason == null) ? "Unknown" : pReason; 10730 // XXX Note: don't acquire main activity lock here, because the window 10731 // manager calls in with its locks held. 10732 10733 boolean killed = false; 10734 synchronized (mPidsSelfLocked) { 10735 int[] types = new int[pids.length]; 10736 int worstType = 0; 10737 for (int i=0; i<pids.length; i++) { 10738 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10739 if (proc != null) { 10740 int type = proc.setAdj; 10741 types[i] = type; 10742 if (type > worstType) { 10743 worstType = type; 10744 } 10745 } 10746 } 10747 10748 // If the worst oom_adj is somewhere in the cached proc LRU range, 10749 // then constrain it so we will kill all cached procs. 10750 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10751 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10752 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10753 } 10754 10755 // If this is not a secure call, don't let it kill processes that 10756 // are important. 10757 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10758 worstType = ProcessList.SERVICE_ADJ; 10759 } 10760 10761 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10762 for (int i=0; i<pids.length; i++) { 10763 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10764 if (proc == null) { 10765 continue; 10766 } 10767 int adj = proc.setAdj; 10768 if (adj >= worstType && !proc.killedByAm) { 10769 proc.kill(reason, true); 10770 killed = true; 10771 } 10772 } 10773 } 10774 return killed; 10775 } 10776 10777 @Override 10778 public void killUid(int uid, String reason) { 10779 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10780 throw new SecurityException("killUid only available to the system"); 10781 } 10782 synchronized (this) { 10783 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10784 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10785 reason != null ? reason : "kill uid"); 10786 } 10787 } 10788 10789 @Override 10790 public boolean killProcessesBelowForeground(String reason) { 10791 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10792 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10793 } 10794 10795 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10796 } 10797 10798 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10799 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10800 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10801 } 10802 10803 boolean killed = false; 10804 synchronized (mPidsSelfLocked) { 10805 final int size = mPidsSelfLocked.size(); 10806 for (int i = 0; i < size; i++) { 10807 final int pid = mPidsSelfLocked.keyAt(i); 10808 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10809 if (proc == null) continue; 10810 10811 final int adj = proc.setAdj; 10812 if (adj > belowAdj && !proc.killedByAm) { 10813 proc.kill(reason, true); 10814 killed = true; 10815 } 10816 } 10817 } 10818 return killed; 10819 } 10820 10821 @Override 10822 public void hang(final IBinder who, boolean allowRestart) { 10823 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10824 != PackageManager.PERMISSION_GRANTED) { 10825 throw new SecurityException("Requires permission " 10826 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10827 } 10828 10829 final IBinder.DeathRecipient death = new DeathRecipient() { 10830 @Override 10831 public void binderDied() { 10832 synchronized (this) { 10833 notifyAll(); 10834 } 10835 } 10836 }; 10837 10838 try { 10839 who.linkToDeath(death, 0); 10840 } catch (RemoteException e) { 10841 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10842 return; 10843 } 10844 10845 synchronized (this) { 10846 Watchdog.getInstance().setAllowRestart(allowRestart); 10847 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10848 synchronized (death) { 10849 while (who.isBinderAlive()) { 10850 try { 10851 death.wait(); 10852 } catch (InterruptedException e) { 10853 } 10854 } 10855 } 10856 Watchdog.getInstance().setAllowRestart(true); 10857 } 10858 } 10859 10860 @Override 10861 public void restart() { 10862 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10863 != PackageManager.PERMISSION_GRANTED) { 10864 throw new SecurityException("Requires permission " 10865 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10866 } 10867 10868 Log.i(TAG, "Sending shutdown broadcast..."); 10869 10870 BroadcastReceiver br = new BroadcastReceiver() { 10871 @Override public void onReceive(Context context, Intent intent) { 10872 // Now the broadcast is done, finish up the low-level shutdown. 10873 Log.i(TAG, "Shutting down activity manager..."); 10874 shutdown(10000); 10875 Log.i(TAG, "Shutdown complete, restarting!"); 10876 Process.killProcess(Process.myPid()); 10877 System.exit(10); 10878 } 10879 }; 10880 10881 // First send the high-level shut down broadcast. 10882 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10883 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10884 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10885 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10886 mContext.sendOrderedBroadcastAsUser(intent, 10887 UserHandle.ALL, null, br, mHandler, 0, null, null); 10888 */ 10889 br.onReceive(mContext, intent); 10890 } 10891 10892 private long getLowRamTimeSinceIdle(long now) { 10893 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10894 } 10895 10896 @Override 10897 public void performIdleMaintenance() { 10898 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10899 != PackageManager.PERMISSION_GRANTED) { 10900 throw new SecurityException("Requires permission " 10901 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10902 } 10903 10904 synchronized (this) { 10905 final long now = SystemClock.uptimeMillis(); 10906 final long timeSinceLastIdle = now - mLastIdleTime; 10907 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10908 mLastIdleTime = now; 10909 mLowRamTimeSinceLastIdle = 0; 10910 if (mLowRamStartTime != 0) { 10911 mLowRamStartTime = now; 10912 } 10913 10914 StringBuilder sb = new StringBuilder(128); 10915 sb.append("Idle maintenance over "); 10916 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10917 sb.append(" low RAM for "); 10918 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10919 Slog.i(TAG, sb.toString()); 10920 10921 // If at least 1/3 of our time since the last idle period has been spent 10922 // with RAM low, then we want to kill processes. 10923 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10924 10925 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10926 ProcessRecord proc = mLruProcesses.get(i); 10927 if (proc.notCachedSinceIdle) { 10928 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10929 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10930 if (doKilling && proc.initialIdlePss != 0 10931 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10932 sb = new StringBuilder(128); 10933 sb.append("Kill"); 10934 sb.append(proc.processName); 10935 sb.append(" in idle maint: pss="); 10936 sb.append(proc.lastPss); 10937 sb.append(", initialPss="); 10938 sb.append(proc.initialIdlePss); 10939 sb.append(", period="); 10940 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10941 sb.append(", lowRamPeriod="); 10942 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10943 Slog.wtfQuiet(TAG, sb.toString()); 10944 proc.kill("idle maint (pss " + proc.lastPss 10945 + " from " + proc.initialIdlePss + ")", true); 10946 } 10947 } 10948 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10949 proc.notCachedSinceIdle = true; 10950 proc.initialIdlePss = 0; 10951 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10952 isSleeping(), now); 10953 } 10954 } 10955 10956 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10957 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10958 } 10959 } 10960 10961 private void retrieveSettings() { 10962 final ContentResolver resolver = mContext.getContentResolver(); 10963 String debugApp = Settings.Global.getString( 10964 resolver, Settings.Global.DEBUG_APP); 10965 boolean waitForDebugger = Settings.Global.getInt( 10966 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10967 boolean alwaysFinishActivities = Settings.Global.getInt( 10968 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10969 boolean forceRtl = Settings.Global.getInt( 10970 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10971 // Transfer any global setting for forcing RTL layout, into a System Property 10972 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10973 10974 Configuration configuration = new Configuration(); 10975 Settings.System.getConfiguration(resolver, configuration); 10976 if (forceRtl) { 10977 // This will take care of setting the correct layout direction flags 10978 configuration.setLayoutDirection(configuration.locale); 10979 } 10980 10981 synchronized (this) { 10982 mDebugApp = mOrigDebugApp = debugApp; 10983 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10984 mAlwaysFinishActivities = alwaysFinishActivities; 10985 // This happens before any activities are started, so we can 10986 // change mConfiguration in-place. 10987 updateConfigurationLocked(configuration, null, false, true); 10988 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10989 } 10990 } 10991 10992 /** Loads resources after the current configuration has been set. */ 10993 private void loadResourcesOnSystemReady() { 10994 final Resources res = mContext.getResources(); 10995 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10996 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10997 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10998 } 10999 11000 public boolean testIsSystemReady() { 11001 // no need to synchronize(this) just to read & return the value 11002 return mSystemReady; 11003 } 11004 11005 private static File getCalledPreBootReceiversFile() { 11006 File dataDir = Environment.getDataDirectory(); 11007 File systemDir = new File(dataDir, "system"); 11008 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11009 return fname; 11010 } 11011 11012 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11013 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11014 File file = getCalledPreBootReceiversFile(); 11015 FileInputStream fis = null; 11016 try { 11017 fis = new FileInputStream(file); 11018 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11019 int fvers = dis.readInt(); 11020 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11021 String vers = dis.readUTF(); 11022 String codename = dis.readUTF(); 11023 String build = dis.readUTF(); 11024 if (android.os.Build.VERSION.RELEASE.equals(vers) 11025 && android.os.Build.VERSION.CODENAME.equals(codename) 11026 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11027 int num = dis.readInt(); 11028 while (num > 0) { 11029 num--; 11030 String pkg = dis.readUTF(); 11031 String cls = dis.readUTF(); 11032 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11033 } 11034 } 11035 } 11036 } catch (FileNotFoundException e) { 11037 } catch (IOException e) { 11038 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11039 } finally { 11040 if (fis != null) { 11041 try { 11042 fis.close(); 11043 } catch (IOException e) { 11044 } 11045 } 11046 } 11047 return lastDoneReceivers; 11048 } 11049 11050 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11051 File file = getCalledPreBootReceiversFile(); 11052 FileOutputStream fos = null; 11053 DataOutputStream dos = null; 11054 try { 11055 fos = new FileOutputStream(file); 11056 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11057 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11058 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11059 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11060 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11061 dos.writeInt(list.size()); 11062 for (int i=0; i<list.size(); i++) { 11063 dos.writeUTF(list.get(i).getPackageName()); 11064 dos.writeUTF(list.get(i).getClassName()); 11065 } 11066 } catch (IOException e) { 11067 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11068 file.delete(); 11069 } finally { 11070 FileUtils.sync(fos); 11071 if (dos != null) { 11072 try { 11073 dos.close(); 11074 } catch (IOException e) { 11075 // TODO Auto-generated catch block 11076 e.printStackTrace(); 11077 } 11078 } 11079 } 11080 } 11081 11082 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11083 ArrayList<ComponentName> doneReceivers, int userId) { 11084 boolean waitingUpdate = false; 11085 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11086 List<ResolveInfo> ris = null; 11087 try { 11088 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11089 intent, null, 0, userId); 11090 } catch (RemoteException e) { 11091 } 11092 if (ris != null) { 11093 for (int i=ris.size()-1; i>=0; i--) { 11094 if ((ris.get(i).activityInfo.applicationInfo.flags 11095 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11096 ris.remove(i); 11097 } 11098 } 11099 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11100 11101 // For User 0, load the version number. When delivering to a new user, deliver 11102 // to all receivers. 11103 if (userId == UserHandle.USER_OWNER) { 11104 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11105 for (int i=0; i<ris.size(); i++) { 11106 ActivityInfo ai = ris.get(i).activityInfo; 11107 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11108 if (lastDoneReceivers.contains(comp)) { 11109 // We already did the pre boot receiver for this app with the current 11110 // platform version, so don't do it again... 11111 ris.remove(i); 11112 i--; 11113 // ...however, do keep it as one that has been done, so we don't 11114 // forget about it when rewriting the file of last done receivers. 11115 doneReceivers.add(comp); 11116 } 11117 } 11118 } 11119 11120 // If primary user, send broadcast to all available users, else just to userId 11121 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11122 : new int[] { userId }; 11123 for (int i = 0; i < ris.size(); i++) { 11124 ActivityInfo ai = ris.get(i).activityInfo; 11125 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11126 doneReceivers.add(comp); 11127 intent.setComponent(comp); 11128 for (int j=0; j<users.length; j++) { 11129 IIntentReceiver finisher = null; 11130 // On last receiver and user, set up a completion callback 11131 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11132 finisher = new IIntentReceiver.Stub() { 11133 public void performReceive(Intent intent, int resultCode, 11134 String data, Bundle extras, boolean ordered, 11135 boolean sticky, int sendingUser) { 11136 // The raw IIntentReceiver interface is called 11137 // with the AM lock held, so redispatch to 11138 // execute our code without the lock. 11139 mHandler.post(onFinishCallback); 11140 } 11141 }; 11142 } 11143 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11144 + " for user " + users[j]); 11145 broadcastIntentLocked(null, null, intent, null, finisher, 11146 0, null, null, null, AppOpsManager.OP_NONE, 11147 true, false, MY_PID, Process.SYSTEM_UID, 11148 users[j]); 11149 if (finisher != null) { 11150 waitingUpdate = true; 11151 } 11152 } 11153 } 11154 } 11155 11156 return waitingUpdate; 11157 } 11158 11159 public void systemReady(final Runnable goingCallback) { 11160 synchronized(this) { 11161 if (mSystemReady) { 11162 // If we're done calling all the receivers, run the next "boot phase" passed in 11163 // by the SystemServer 11164 if (goingCallback != null) { 11165 goingCallback.run(); 11166 } 11167 return; 11168 } 11169 11170 // Make sure we have the current profile info, since it is needed for 11171 // security checks. 11172 updateCurrentProfileIdsLocked(); 11173 11174 if (mRecentTasks == null) { 11175 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11176 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11177 if (!mRecentTasks.isEmpty()) { 11178 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11179 } 11180 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11181 mTaskPersister.startPersisting(); 11182 } 11183 11184 // Check to see if there are any update receivers to run. 11185 if (!mDidUpdate) { 11186 if (mWaitingUpdate) { 11187 return; 11188 } 11189 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11190 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11191 public void run() { 11192 synchronized (ActivityManagerService.this) { 11193 mDidUpdate = true; 11194 } 11195 writeLastDonePreBootReceivers(doneReceivers); 11196 showBootMessage(mContext.getText( 11197 R.string.android_upgrading_complete), 11198 false); 11199 systemReady(goingCallback); 11200 } 11201 }, doneReceivers, UserHandle.USER_OWNER); 11202 11203 if (mWaitingUpdate) { 11204 return; 11205 } 11206 mDidUpdate = true; 11207 } 11208 11209 mAppOpsService.systemReady(); 11210 mSystemReady = true; 11211 } 11212 11213 ArrayList<ProcessRecord> procsToKill = null; 11214 synchronized(mPidsSelfLocked) { 11215 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11216 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11217 if (!isAllowedWhileBooting(proc.info)){ 11218 if (procsToKill == null) { 11219 procsToKill = new ArrayList<ProcessRecord>(); 11220 } 11221 procsToKill.add(proc); 11222 } 11223 } 11224 } 11225 11226 synchronized(this) { 11227 if (procsToKill != null) { 11228 for (int i=procsToKill.size()-1; i>=0; i--) { 11229 ProcessRecord proc = procsToKill.get(i); 11230 Slog.i(TAG, "Removing system update proc: " + proc); 11231 removeProcessLocked(proc, true, false, "system update done"); 11232 } 11233 } 11234 11235 // Now that we have cleaned up any update processes, we 11236 // are ready to start launching real processes and know that 11237 // we won't trample on them any more. 11238 mProcessesReady = true; 11239 } 11240 11241 Slog.i(TAG, "System now ready"); 11242 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11243 SystemClock.uptimeMillis()); 11244 11245 synchronized(this) { 11246 // Make sure we have no pre-ready processes sitting around. 11247 11248 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11249 ResolveInfo ri = mContext.getPackageManager() 11250 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11251 STOCK_PM_FLAGS); 11252 CharSequence errorMsg = null; 11253 if (ri != null) { 11254 ActivityInfo ai = ri.activityInfo; 11255 ApplicationInfo app = ai.applicationInfo; 11256 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11257 mTopAction = Intent.ACTION_FACTORY_TEST; 11258 mTopData = null; 11259 mTopComponent = new ComponentName(app.packageName, 11260 ai.name); 11261 } else { 11262 errorMsg = mContext.getResources().getText( 11263 com.android.internal.R.string.factorytest_not_system); 11264 } 11265 } else { 11266 errorMsg = mContext.getResources().getText( 11267 com.android.internal.R.string.factorytest_no_action); 11268 } 11269 if (errorMsg != null) { 11270 mTopAction = null; 11271 mTopData = null; 11272 mTopComponent = null; 11273 Message msg = Message.obtain(); 11274 msg.what = SHOW_FACTORY_ERROR_MSG; 11275 msg.getData().putCharSequence("msg", errorMsg); 11276 mHandler.sendMessage(msg); 11277 } 11278 } 11279 } 11280 11281 retrieveSettings(); 11282 loadResourcesOnSystemReady(); 11283 11284 synchronized (this) { 11285 readGrantedUriPermissionsLocked(); 11286 } 11287 11288 if (goingCallback != null) goingCallback.run(); 11289 11290 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11291 Integer.toString(mCurrentUserId), mCurrentUserId); 11292 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11293 Integer.toString(mCurrentUserId), mCurrentUserId); 11294 mSystemServiceManager.startUser(mCurrentUserId); 11295 11296 synchronized (this) { 11297 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11298 try { 11299 List apps = AppGlobals.getPackageManager(). 11300 getPersistentApplications(STOCK_PM_FLAGS); 11301 if (apps != null) { 11302 int N = apps.size(); 11303 int i; 11304 for (i=0; i<N; i++) { 11305 ApplicationInfo info 11306 = (ApplicationInfo)apps.get(i); 11307 if (info != null && 11308 !info.packageName.equals("android")) { 11309 addAppLocked(info, false, null /* ABI override */); 11310 } 11311 } 11312 } 11313 } catch (RemoteException ex) { 11314 // pm is in same process, this will never happen. 11315 } 11316 } 11317 11318 // Start up initial activity. 11319 mBooting = true; 11320 startHomeActivityLocked(mCurrentUserId); 11321 11322 try { 11323 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11324 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11325 + " data partition or your device will be unstable."); 11326 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11327 } 11328 } catch (RemoteException e) { 11329 } 11330 11331 if (!Build.isFingerprintConsistent()) { 11332 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11333 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11334 } 11335 11336 long ident = Binder.clearCallingIdentity(); 11337 try { 11338 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11339 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11340 | Intent.FLAG_RECEIVER_FOREGROUND); 11341 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11342 broadcastIntentLocked(null, null, intent, 11343 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11344 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11345 intent = new Intent(Intent.ACTION_USER_STARTING); 11346 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11347 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11348 broadcastIntentLocked(null, null, intent, 11349 null, new IIntentReceiver.Stub() { 11350 @Override 11351 public void performReceive(Intent intent, int resultCode, String data, 11352 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11353 throws RemoteException { 11354 } 11355 }, 0, null, null, 11356 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11357 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11358 } catch (Throwable t) { 11359 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11360 } finally { 11361 Binder.restoreCallingIdentity(ident); 11362 } 11363 mStackSupervisor.resumeTopActivitiesLocked(); 11364 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11365 } 11366 } 11367 11368 private boolean makeAppCrashingLocked(ProcessRecord app, 11369 String shortMsg, String longMsg, String stackTrace) { 11370 app.crashing = true; 11371 app.crashingReport = generateProcessError(app, 11372 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11373 startAppProblemLocked(app); 11374 app.stopFreezingAllLocked(); 11375 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11376 } 11377 11378 private void makeAppNotRespondingLocked(ProcessRecord app, 11379 String activity, String shortMsg, String longMsg) { 11380 app.notResponding = true; 11381 app.notRespondingReport = generateProcessError(app, 11382 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11383 activity, shortMsg, longMsg, null); 11384 startAppProblemLocked(app); 11385 app.stopFreezingAllLocked(); 11386 } 11387 11388 /** 11389 * Generate a process error record, suitable for attachment to a ProcessRecord. 11390 * 11391 * @param app The ProcessRecord in which the error occurred. 11392 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11393 * ActivityManager.AppErrorStateInfo 11394 * @param activity The activity associated with the crash, if known. 11395 * @param shortMsg Short message describing the crash. 11396 * @param longMsg Long message describing the crash. 11397 * @param stackTrace Full crash stack trace, may be null. 11398 * 11399 * @return Returns a fully-formed AppErrorStateInfo record. 11400 */ 11401 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11402 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11403 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11404 11405 report.condition = condition; 11406 report.processName = app.processName; 11407 report.pid = app.pid; 11408 report.uid = app.info.uid; 11409 report.tag = activity; 11410 report.shortMsg = shortMsg; 11411 report.longMsg = longMsg; 11412 report.stackTrace = stackTrace; 11413 11414 return report; 11415 } 11416 11417 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11418 synchronized (this) { 11419 app.crashing = false; 11420 app.crashingReport = null; 11421 app.notResponding = false; 11422 app.notRespondingReport = null; 11423 if (app.anrDialog == fromDialog) { 11424 app.anrDialog = null; 11425 } 11426 if (app.waitDialog == fromDialog) { 11427 app.waitDialog = null; 11428 } 11429 if (app.pid > 0 && app.pid != MY_PID) { 11430 handleAppCrashLocked(app, null, null, null); 11431 app.kill("user request after error", true); 11432 } 11433 } 11434 } 11435 11436 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11437 String stackTrace) { 11438 long now = SystemClock.uptimeMillis(); 11439 11440 Long crashTime; 11441 if (!app.isolated) { 11442 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11443 } else { 11444 crashTime = null; 11445 } 11446 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11447 // This process loses! 11448 Slog.w(TAG, "Process " + app.info.processName 11449 + " has crashed too many times: killing!"); 11450 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11451 app.userId, app.info.processName, app.uid); 11452 mStackSupervisor.handleAppCrashLocked(app); 11453 if (!app.persistent) { 11454 // We don't want to start this process again until the user 11455 // explicitly does so... but for persistent process, we really 11456 // need to keep it running. If a persistent process is actually 11457 // repeatedly crashing, then badness for everyone. 11458 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11459 app.info.processName); 11460 if (!app.isolated) { 11461 // XXX We don't have a way to mark isolated processes 11462 // as bad, since they don't have a peristent identity. 11463 mBadProcesses.put(app.info.processName, app.uid, 11464 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11465 mProcessCrashTimes.remove(app.info.processName, app.uid); 11466 } 11467 app.bad = true; 11468 app.removed = true; 11469 // Don't let services in this process be restarted and potentially 11470 // annoy the user repeatedly. Unless it is persistent, since those 11471 // processes run critical code. 11472 removeProcessLocked(app, false, false, "crash"); 11473 mStackSupervisor.resumeTopActivitiesLocked(); 11474 return false; 11475 } 11476 mStackSupervisor.resumeTopActivitiesLocked(); 11477 } else { 11478 mStackSupervisor.finishTopRunningActivityLocked(app); 11479 } 11480 11481 // Bump up the crash count of any services currently running in the proc. 11482 for (int i=app.services.size()-1; i>=0; i--) { 11483 // Any services running in the application need to be placed 11484 // back in the pending list. 11485 ServiceRecord sr = app.services.valueAt(i); 11486 sr.crashCount++; 11487 } 11488 11489 // If the crashing process is what we consider to be the "home process" and it has been 11490 // replaced by a third-party app, clear the package preferred activities from packages 11491 // with a home activity running in the process to prevent a repeatedly crashing app 11492 // from blocking the user to manually clear the list. 11493 final ArrayList<ActivityRecord> activities = app.activities; 11494 if (app == mHomeProcess && activities.size() > 0 11495 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11496 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11497 final ActivityRecord r = activities.get(activityNdx); 11498 if (r.isHomeActivity()) { 11499 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11500 try { 11501 ActivityThread.getPackageManager() 11502 .clearPackagePreferredActivities(r.packageName); 11503 } catch (RemoteException c) { 11504 // pm is in same process, this will never happen. 11505 } 11506 } 11507 } 11508 } 11509 11510 if (!app.isolated) { 11511 // XXX Can't keep track of crash times for isolated processes, 11512 // because they don't have a perisistent identity. 11513 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11514 } 11515 11516 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11517 return true; 11518 } 11519 11520 void startAppProblemLocked(ProcessRecord app) { 11521 // If this app is not running under the current user, then we 11522 // can't give it a report button because that would require 11523 // launching the report UI under a different user. 11524 app.errorReportReceiver = null; 11525 11526 for (int userId : mCurrentProfileIds) { 11527 if (app.userId == userId) { 11528 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11529 mContext, app.info.packageName, app.info.flags); 11530 } 11531 } 11532 skipCurrentReceiverLocked(app); 11533 } 11534 11535 void skipCurrentReceiverLocked(ProcessRecord app) { 11536 for (BroadcastQueue queue : mBroadcastQueues) { 11537 queue.skipCurrentReceiverLocked(app); 11538 } 11539 } 11540 11541 /** 11542 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11543 * The application process will exit immediately after this call returns. 11544 * @param app object of the crashing app, null for the system server 11545 * @param crashInfo describing the exception 11546 */ 11547 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11548 ProcessRecord r = findAppProcess(app, "Crash"); 11549 final String processName = app == null ? "system_server" 11550 : (r == null ? "unknown" : r.processName); 11551 11552 handleApplicationCrashInner("crash", r, processName, crashInfo); 11553 } 11554 11555 /* Native crash reporting uses this inner version because it needs to be somewhat 11556 * decoupled from the AM-managed cleanup lifecycle 11557 */ 11558 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11559 ApplicationErrorReport.CrashInfo crashInfo) { 11560 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11561 UserHandle.getUserId(Binder.getCallingUid()), processName, 11562 r == null ? -1 : r.info.flags, 11563 crashInfo.exceptionClassName, 11564 crashInfo.exceptionMessage, 11565 crashInfo.throwFileName, 11566 crashInfo.throwLineNumber); 11567 11568 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11569 11570 crashApplication(r, crashInfo); 11571 } 11572 11573 public void handleApplicationStrictModeViolation( 11574 IBinder app, 11575 int violationMask, 11576 StrictMode.ViolationInfo info) { 11577 ProcessRecord r = findAppProcess(app, "StrictMode"); 11578 if (r == null) { 11579 return; 11580 } 11581 11582 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11583 Integer stackFingerprint = info.hashCode(); 11584 boolean logIt = true; 11585 synchronized (mAlreadyLoggedViolatedStacks) { 11586 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11587 logIt = false; 11588 // TODO: sub-sample into EventLog for these, with 11589 // the info.durationMillis? Then we'd get 11590 // the relative pain numbers, without logging all 11591 // the stack traces repeatedly. We'd want to do 11592 // likewise in the client code, which also does 11593 // dup suppression, before the Binder call. 11594 } else { 11595 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11596 mAlreadyLoggedViolatedStacks.clear(); 11597 } 11598 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11599 } 11600 } 11601 if (logIt) { 11602 logStrictModeViolationToDropBox(r, info); 11603 } 11604 } 11605 11606 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11607 AppErrorResult result = new AppErrorResult(); 11608 synchronized (this) { 11609 final long origId = Binder.clearCallingIdentity(); 11610 11611 Message msg = Message.obtain(); 11612 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11613 HashMap<String, Object> data = new HashMap<String, Object>(); 11614 data.put("result", result); 11615 data.put("app", r); 11616 data.put("violationMask", violationMask); 11617 data.put("info", info); 11618 msg.obj = data; 11619 mHandler.sendMessage(msg); 11620 11621 Binder.restoreCallingIdentity(origId); 11622 } 11623 int res = result.get(); 11624 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11625 } 11626 } 11627 11628 // Depending on the policy in effect, there could be a bunch of 11629 // these in quick succession so we try to batch these together to 11630 // minimize disk writes, number of dropbox entries, and maximize 11631 // compression, by having more fewer, larger records. 11632 private void logStrictModeViolationToDropBox( 11633 ProcessRecord process, 11634 StrictMode.ViolationInfo info) { 11635 if (info == null) { 11636 return; 11637 } 11638 final boolean isSystemApp = process == null || 11639 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11640 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11641 final String processName = process == null ? "unknown" : process.processName; 11642 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11643 final DropBoxManager dbox = (DropBoxManager) 11644 mContext.getSystemService(Context.DROPBOX_SERVICE); 11645 11646 // Exit early if the dropbox isn't configured to accept this report type. 11647 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11648 11649 boolean bufferWasEmpty; 11650 boolean needsFlush; 11651 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11652 synchronized (sb) { 11653 bufferWasEmpty = sb.length() == 0; 11654 appendDropBoxProcessHeaders(process, processName, sb); 11655 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11656 sb.append("System-App: ").append(isSystemApp).append("\n"); 11657 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11658 if (info.violationNumThisLoop != 0) { 11659 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11660 } 11661 if (info.numAnimationsRunning != 0) { 11662 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11663 } 11664 if (info.broadcastIntentAction != null) { 11665 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11666 } 11667 if (info.durationMillis != -1) { 11668 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11669 } 11670 if (info.numInstances != -1) { 11671 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11672 } 11673 if (info.tags != null) { 11674 for (String tag : info.tags) { 11675 sb.append("Span-Tag: ").append(tag).append("\n"); 11676 } 11677 } 11678 sb.append("\n"); 11679 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11680 sb.append(info.crashInfo.stackTrace); 11681 } 11682 sb.append("\n"); 11683 11684 // Only buffer up to ~64k. Various logging bits truncate 11685 // things at 128k. 11686 needsFlush = (sb.length() > 64 * 1024); 11687 } 11688 11689 // Flush immediately if the buffer's grown too large, or this 11690 // is a non-system app. Non-system apps are isolated with a 11691 // different tag & policy and not batched. 11692 // 11693 // Batching is useful during internal testing with 11694 // StrictMode settings turned up high. Without batching, 11695 // thousands of separate files could be created on boot. 11696 if (!isSystemApp || needsFlush) { 11697 new Thread("Error dump: " + dropboxTag) { 11698 @Override 11699 public void run() { 11700 String report; 11701 synchronized (sb) { 11702 report = sb.toString(); 11703 sb.delete(0, sb.length()); 11704 sb.trimToSize(); 11705 } 11706 if (report.length() != 0) { 11707 dbox.addText(dropboxTag, report); 11708 } 11709 } 11710 }.start(); 11711 return; 11712 } 11713 11714 // System app batching: 11715 if (!bufferWasEmpty) { 11716 // An existing dropbox-writing thread is outstanding, so 11717 // we don't need to start it up. The existing thread will 11718 // catch the buffer appends we just did. 11719 return; 11720 } 11721 11722 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11723 // (After this point, we shouldn't access AMS internal data structures.) 11724 new Thread("Error dump: " + dropboxTag) { 11725 @Override 11726 public void run() { 11727 // 5 second sleep to let stacks arrive and be batched together 11728 try { 11729 Thread.sleep(5000); // 5 seconds 11730 } catch (InterruptedException e) {} 11731 11732 String errorReport; 11733 synchronized (mStrictModeBuffer) { 11734 errorReport = mStrictModeBuffer.toString(); 11735 if (errorReport.length() == 0) { 11736 return; 11737 } 11738 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11739 mStrictModeBuffer.trimToSize(); 11740 } 11741 dbox.addText(dropboxTag, errorReport); 11742 } 11743 }.start(); 11744 } 11745 11746 /** 11747 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11748 * @param app object of the crashing app, null for the system server 11749 * @param tag reported by the caller 11750 * @param system whether this wtf is coming from the system 11751 * @param crashInfo describing the context of the error 11752 * @return true if the process should exit immediately (WTF is fatal) 11753 */ 11754 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11755 final ApplicationErrorReport.CrashInfo crashInfo) { 11756 final int callingUid = Binder.getCallingUid(); 11757 final int callingPid = Binder.getCallingPid(); 11758 11759 if (system) { 11760 // If this is coming from the system, we could very well have low-level 11761 // system locks held, so we want to do this all asynchronously. And we 11762 // never want this to become fatal, so there is that too. 11763 mHandler.post(new Runnable() { 11764 @Override public void run() { 11765 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11766 } 11767 }); 11768 return false; 11769 } 11770 11771 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11772 crashInfo); 11773 11774 if (r != null && r.pid != Process.myPid() && 11775 Settings.Global.getInt(mContext.getContentResolver(), 11776 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11777 crashApplication(r, crashInfo); 11778 return true; 11779 } else { 11780 return false; 11781 } 11782 } 11783 11784 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11785 final ApplicationErrorReport.CrashInfo crashInfo) { 11786 final ProcessRecord r = findAppProcess(app, "WTF"); 11787 final String processName = app == null ? "system_server" 11788 : (r == null ? "unknown" : r.processName); 11789 11790 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11791 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11792 11793 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11794 11795 return r; 11796 } 11797 11798 /** 11799 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11800 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11801 */ 11802 private ProcessRecord findAppProcess(IBinder app, String reason) { 11803 if (app == null) { 11804 return null; 11805 } 11806 11807 synchronized (this) { 11808 final int NP = mProcessNames.getMap().size(); 11809 for (int ip=0; ip<NP; ip++) { 11810 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11811 final int NA = apps.size(); 11812 for (int ia=0; ia<NA; ia++) { 11813 ProcessRecord p = apps.valueAt(ia); 11814 if (p.thread != null && p.thread.asBinder() == app) { 11815 return p; 11816 } 11817 } 11818 } 11819 11820 Slog.w(TAG, "Can't find mystery application for " + reason 11821 + " from pid=" + Binder.getCallingPid() 11822 + " uid=" + Binder.getCallingUid() + ": " + app); 11823 return null; 11824 } 11825 } 11826 11827 /** 11828 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11829 * to append various headers to the dropbox log text. 11830 */ 11831 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11832 StringBuilder sb) { 11833 // Watchdog thread ends up invoking this function (with 11834 // a null ProcessRecord) to add the stack file to dropbox. 11835 // Do not acquire a lock on this (am) in such cases, as it 11836 // could cause a potential deadlock, if and when watchdog 11837 // is invoked due to unavailability of lock on am and it 11838 // would prevent watchdog from killing system_server. 11839 if (process == null) { 11840 sb.append("Process: ").append(processName).append("\n"); 11841 return; 11842 } 11843 // Note: ProcessRecord 'process' is guarded by the service 11844 // instance. (notably process.pkgList, which could otherwise change 11845 // concurrently during execution of this method) 11846 synchronized (this) { 11847 sb.append("Process: ").append(processName).append("\n"); 11848 int flags = process.info.flags; 11849 IPackageManager pm = AppGlobals.getPackageManager(); 11850 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11851 for (int ip=0; ip<process.pkgList.size(); ip++) { 11852 String pkg = process.pkgList.keyAt(ip); 11853 sb.append("Package: ").append(pkg); 11854 try { 11855 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11856 if (pi != null) { 11857 sb.append(" v").append(pi.versionCode); 11858 if (pi.versionName != null) { 11859 sb.append(" (").append(pi.versionName).append(")"); 11860 } 11861 } 11862 } catch (RemoteException e) { 11863 Slog.e(TAG, "Error getting package info: " + pkg, e); 11864 } 11865 sb.append("\n"); 11866 } 11867 } 11868 } 11869 11870 private static String processClass(ProcessRecord process) { 11871 if (process == null || process.pid == MY_PID) { 11872 return "system_server"; 11873 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11874 return "system_app"; 11875 } else { 11876 return "data_app"; 11877 } 11878 } 11879 11880 /** 11881 * Write a description of an error (crash, WTF, ANR) to the drop box. 11882 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11883 * @param process which caused the error, null means the system server 11884 * @param activity which triggered the error, null if unknown 11885 * @param parent activity related to the error, null if unknown 11886 * @param subject line related to the error, null if absent 11887 * @param report in long form describing the error, null if absent 11888 * @param logFile to include in the report, null if none 11889 * @param crashInfo giving an application stack trace, null if absent 11890 */ 11891 public void addErrorToDropBox(String eventType, 11892 ProcessRecord process, String processName, ActivityRecord activity, 11893 ActivityRecord parent, String subject, 11894 final String report, final File logFile, 11895 final ApplicationErrorReport.CrashInfo crashInfo) { 11896 // NOTE -- this must never acquire the ActivityManagerService lock, 11897 // otherwise the watchdog may be prevented from resetting the system. 11898 11899 final String dropboxTag = processClass(process) + "_" + eventType; 11900 final DropBoxManager dbox = (DropBoxManager) 11901 mContext.getSystemService(Context.DROPBOX_SERVICE); 11902 11903 // Exit early if the dropbox isn't configured to accept this report type. 11904 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11905 11906 final StringBuilder sb = new StringBuilder(1024); 11907 appendDropBoxProcessHeaders(process, processName, sb); 11908 if (activity != null) { 11909 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11910 } 11911 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11912 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11913 } 11914 if (parent != null && parent != activity) { 11915 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11916 } 11917 if (subject != null) { 11918 sb.append("Subject: ").append(subject).append("\n"); 11919 } 11920 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11921 if (Debug.isDebuggerConnected()) { 11922 sb.append("Debugger: Connected\n"); 11923 } 11924 sb.append("\n"); 11925 11926 // Do the rest in a worker thread to avoid blocking the caller on I/O 11927 // (After this point, we shouldn't access AMS internal data structures.) 11928 Thread worker = new Thread("Error dump: " + dropboxTag) { 11929 @Override 11930 public void run() { 11931 if (report != null) { 11932 sb.append(report); 11933 } 11934 if (logFile != null) { 11935 try { 11936 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11937 "\n\n[[TRUNCATED]]")); 11938 } catch (IOException e) { 11939 Slog.e(TAG, "Error reading " + logFile, e); 11940 } 11941 } 11942 if (crashInfo != null && crashInfo.stackTrace != null) { 11943 sb.append(crashInfo.stackTrace); 11944 } 11945 11946 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11947 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11948 if (lines > 0) { 11949 sb.append("\n"); 11950 11951 // Merge several logcat streams, and take the last N lines 11952 InputStreamReader input = null; 11953 try { 11954 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11955 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11956 "-b", "crash", 11957 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11958 11959 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11960 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11961 input = new InputStreamReader(logcat.getInputStream()); 11962 11963 int num; 11964 char[] buf = new char[8192]; 11965 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11966 } catch (IOException e) { 11967 Slog.e(TAG, "Error running logcat", e); 11968 } finally { 11969 if (input != null) try { input.close(); } catch (IOException e) {} 11970 } 11971 } 11972 11973 dbox.addText(dropboxTag, sb.toString()); 11974 } 11975 }; 11976 11977 if (process == null) { 11978 // If process is null, we are being called from some internal code 11979 // and may be about to die -- run this synchronously. 11980 worker.run(); 11981 } else { 11982 worker.start(); 11983 } 11984 } 11985 11986 /** 11987 * Bring up the "unexpected error" dialog box for a crashing app. 11988 * Deal with edge cases (intercepts from instrumented applications, 11989 * ActivityController, error intent receivers, that sort of thing). 11990 * @param r the application crashing 11991 * @param crashInfo describing the failure 11992 */ 11993 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11994 long timeMillis = System.currentTimeMillis(); 11995 String shortMsg = crashInfo.exceptionClassName; 11996 String longMsg = crashInfo.exceptionMessage; 11997 String stackTrace = crashInfo.stackTrace; 11998 if (shortMsg != null && longMsg != null) { 11999 longMsg = shortMsg + ": " + longMsg; 12000 } else if (shortMsg != null) { 12001 longMsg = shortMsg; 12002 } 12003 12004 AppErrorResult result = new AppErrorResult(); 12005 synchronized (this) { 12006 if (mController != null) { 12007 try { 12008 String name = r != null ? r.processName : null; 12009 int pid = r != null ? r.pid : Binder.getCallingPid(); 12010 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12011 if (!mController.appCrashed(name, pid, 12012 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12013 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12014 && "Native crash".equals(crashInfo.exceptionClassName)) { 12015 Slog.w(TAG, "Skip killing native crashed app " + name 12016 + "(" + pid + ") during testing"); 12017 } else { 12018 Slog.w(TAG, "Force-killing crashed app " + name 12019 + " at watcher's request"); 12020 if (r != null) { 12021 r.kill("crash", true); 12022 } else { 12023 // Huh. 12024 Process.killProcess(pid); 12025 Process.killProcessGroup(uid, pid); 12026 } 12027 } 12028 return; 12029 } 12030 } catch (RemoteException e) { 12031 mController = null; 12032 Watchdog.getInstance().setActivityController(null); 12033 } 12034 } 12035 12036 final long origId = Binder.clearCallingIdentity(); 12037 12038 // If this process is running instrumentation, finish it. 12039 if (r != null && r.instrumentationClass != null) { 12040 Slog.w(TAG, "Error in app " + r.processName 12041 + " running instrumentation " + r.instrumentationClass + ":"); 12042 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12043 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12044 Bundle info = new Bundle(); 12045 info.putString("shortMsg", shortMsg); 12046 info.putString("longMsg", longMsg); 12047 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12048 Binder.restoreCallingIdentity(origId); 12049 return; 12050 } 12051 12052 // Log crash in battery stats. 12053 if (r != null) { 12054 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12055 } 12056 12057 // If we can't identify the process or it's already exceeded its crash quota, 12058 // quit right away without showing a crash dialog. 12059 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12060 Binder.restoreCallingIdentity(origId); 12061 return; 12062 } 12063 12064 Message msg = Message.obtain(); 12065 msg.what = SHOW_ERROR_MSG; 12066 HashMap data = new HashMap(); 12067 data.put("result", result); 12068 data.put("app", r); 12069 msg.obj = data; 12070 mHandler.sendMessage(msg); 12071 12072 Binder.restoreCallingIdentity(origId); 12073 } 12074 12075 int res = result.get(); 12076 12077 Intent appErrorIntent = null; 12078 synchronized (this) { 12079 if (r != null && !r.isolated) { 12080 // XXX Can't keep track of crash time for isolated processes, 12081 // since they don't have a persistent identity. 12082 mProcessCrashTimes.put(r.info.processName, r.uid, 12083 SystemClock.uptimeMillis()); 12084 } 12085 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12086 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12087 } 12088 } 12089 12090 if (appErrorIntent != null) { 12091 try { 12092 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12093 } catch (ActivityNotFoundException e) { 12094 Slog.w(TAG, "bug report receiver dissappeared", e); 12095 } 12096 } 12097 } 12098 12099 Intent createAppErrorIntentLocked(ProcessRecord r, 12100 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12101 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12102 if (report == null) { 12103 return null; 12104 } 12105 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12106 result.setComponent(r.errorReportReceiver); 12107 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12108 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12109 return result; 12110 } 12111 12112 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12113 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12114 if (r.errorReportReceiver == null) { 12115 return null; 12116 } 12117 12118 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12119 return null; 12120 } 12121 12122 ApplicationErrorReport report = new ApplicationErrorReport(); 12123 report.packageName = r.info.packageName; 12124 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12125 report.processName = r.processName; 12126 report.time = timeMillis; 12127 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12128 12129 if (r.crashing || r.forceCrashReport) { 12130 report.type = ApplicationErrorReport.TYPE_CRASH; 12131 report.crashInfo = crashInfo; 12132 } else if (r.notResponding) { 12133 report.type = ApplicationErrorReport.TYPE_ANR; 12134 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12135 12136 report.anrInfo.activity = r.notRespondingReport.tag; 12137 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12138 report.anrInfo.info = r.notRespondingReport.longMsg; 12139 } 12140 12141 return report; 12142 } 12143 12144 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12145 enforceNotIsolatedCaller("getProcessesInErrorState"); 12146 // assume our apps are happy - lazy create the list 12147 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12148 12149 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12150 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12151 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12152 12153 synchronized (this) { 12154 12155 // iterate across all processes 12156 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12157 ProcessRecord app = mLruProcesses.get(i); 12158 if (!allUsers && app.userId != userId) { 12159 continue; 12160 } 12161 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12162 // This one's in trouble, so we'll generate a report for it 12163 // crashes are higher priority (in case there's a crash *and* an anr) 12164 ActivityManager.ProcessErrorStateInfo report = null; 12165 if (app.crashing) { 12166 report = app.crashingReport; 12167 } else if (app.notResponding) { 12168 report = app.notRespondingReport; 12169 } 12170 12171 if (report != null) { 12172 if (errList == null) { 12173 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12174 } 12175 errList.add(report); 12176 } else { 12177 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12178 " crashing = " + app.crashing + 12179 " notResponding = " + app.notResponding); 12180 } 12181 } 12182 } 12183 } 12184 12185 return errList; 12186 } 12187 12188 static int procStateToImportance(int procState, int memAdj, 12189 ActivityManager.RunningAppProcessInfo currApp) { 12190 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12191 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12192 currApp.lru = memAdj; 12193 } else { 12194 currApp.lru = 0; 12195 } 12196 return imp; 12197 } 12198 12199 private void fillInProcMemInfo(ProcessRecord app, 12200 ActivityManager.RunningAppProcessInfo outInfo) { 12201 outInfo.pid = app.pid; 12202 outInfo.uid = app.info.uid; 12203 if (mHeavyWeightProcess == app) { 12204 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12205 } 12206 if (app.persistent) { 12207 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12208 } 12209 if (app.activities.size() > 0) { 12210 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12211 } 12212 outInfo.lastTrimLevel = app.trimMemoryLevel; 12213 int adj = app.curAdj; 12214 int procState = app.curProcState; 12215 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12216 outInfo.importanceReasonCode = app.adjTypeCode; 12217 outInfo.processState = app.curProcState; 12218 } 12219 12220 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12221 enforceNotIsolatedCaller("getRunningAppProcesses"); 12222 // Lazy instantiation of list 12223 List<ActivityManager.RunningAppProcessInfo> runList = null; 12224 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12225 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12226 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12227 synchronized (this) { 12228 // Iterate across all processes 12229 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12230 ProcessRecord app = mLruProcesses.get(i); 12231 if (!allUsers && app.userId != userId) { 12232 continue; 12233 } 12234 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12235 // Generate process state info for running application 12236 ActivityManager.RunningAppProcessInfo currApp = 12237 new ActivityManager.RunningAppProcessInfo(app.processName, 12238 app.pid, app.getPackageList()); 12239 fillInProcMemInfo(app, currApp); 12240 if (app.adjSource instanceof ProcessRecord) { 12241 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12242 currApp.importanceReasonImportance = 12243 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12244 app.adjSourceProcState); 12245 } else if (app.adjSource instanceof ActivityRecord) { 12246 ActivityRecord r = (ActivityRecord)app.adjSource; 12247 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12248 } 12249 if (app.adjTarget instanceof ComponentName) { 12250 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12251 } 12252 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12253 // + " lru=" + currApp.lru); 12254 if (runList == null) { 12255 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12256 } 12257 runList.add(currApp); 12258 } 12259 } 12260 } 12261 return runList; 12262 } 12263 12264 public List<ApplicationInfo> getRunningExternalApplications() { 12265 enforceNotIsolatedCaller("getRunningExternalApplications"); 12266 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12267 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12268 if (runningApps != null && runningApps.size() > 0) { 12269 Set<String> extList = new HashSet<String>(); 12270 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12271 if (app.pkgList != null) { 12272 for (String pkg : app.pkgList) { 12273 extList.add(pkg); 12274 } 12275 } 12276 } 12277 IPackageManager pm = AppGlobals.getPackageManager(); 12278 for (String pkg : extList) { 12279 try { 12280 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12281 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12282 retList.add(info); 12283 } 12284 } catch (RemoteException e) { 12285 } 12286 } 12287 } 12288 return retList; 12289 } 12290 12291 @Override 12292 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12293 enforceNotIsolatedCaller("getMyMemoryState"); 12294 synchronized (this) { 12295 ProcessRecord proc; 12296 synchronized (mPidsSelfLocked) { 12297 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12298 } 12299 fillInProcMemInfo(proc, outInfo); 12300 } 12301 } 12302 12303 @Override 12304 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12305 if (checkCallingPermission(android.Manifest.permission.DUMP) 12306 != PackageManager.PERMISSION_GRANTED) { 12307 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12308 + Binder.getCallingPid() 12309 + ", uid=" + Binder.getCallingUid() 12310 + " without permission " 12311 + android.Manifest.permission.DUMP); 12312 return; 12313 } 12314 12315 boolean dumpAll = false; 12316 boolean dumpClient = false; 12317 String dumpPackage = null; 12318 12319 int opti = 0; 12320 while (opti < args.length) { 12321 String opt = args[opti]; 12322 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12323 break; 12324 } 12325 opti++; 12326 if ("-a".equals(opt)) { 12327 dumpAll = true; 12328 } else if ("-c".equals(opt)) { 12329 dumpClient = true; 12330 } else if ("-h".equals(opt)) { 12331 pw.println("Activity manager dump options:"); 12332 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12333 pw.println(" cmd may be one of:"); 12334 pw.println(" a[ctivities]: activity stack state"); 12335 pw.println(" r[recents]: recent activities state"); 12336 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12337 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12338 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12339 pw.println(" o[om]: out of memory management"); 12340 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12341 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12342 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12343 pw.println(" service [COMP_SPEC]: service client-side state"); 12344 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12345 pw.println(" all: dump all activities"); 12346 pw.println(" top: dump the top activity"); 12347 pw.println(" write: write all pending state to storage"); 12348 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12349 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12350 pw.println(" a partial substring in a component name, a"); 12351 pw.println(" hex object identifier."); 12352 pw.println(" -a: include all available server state."); 12353 pw.println(" -c: include client state."); 12354 return; 12355 } else { 12356 pw.println("Unknown argument: " + opt + "; use -h for help"); 12357 } 12358 } 12359 12360 long origId = Binder.clearCallingIdentity(); 12361 boolean more = false; 12362 // Is the caller requesting to dump a particular piece of data? 12363 if (opti < args.length) { 12364 String cmd = args[opti]; 12365 opti++; 12366 if ("activities".equals(cmd) || "a".equals(cmd)) { 12367 synchronized (this) { 12368 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12369 } 12370 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12371 synchronized (this) { 12372 dumpRecentsLocked(fd, pw, args, opti, true, null); 12373 } 12374 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12375 String[] newArgs; 12376 String name; 12377 if (opti >= args.length) { 12378 name = null; 12379 newArgs = EMPTY_STRING_ARRAY; 12380 } else { 12381 name = args[opti]; 12382 opti++; 12383 newArgs = new String[args.length - opti]; 12384 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12385 args.length - opti); 12386 } 12387 synchronized (this) { 12388 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12389 } 12390 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12391 String[] newArgs; 12392 String name; 12393 if (opti >= args.length) { 12394 name = null; 12395 newArgs = EMPTY_STRING_ARRAY; 12396 } else { 12397 name = args[opti]; 12398 opti++; 12399 newArgs = new String[args.length - opti]; 12400 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12401 args.length - opti); 12402 } 12403 synchronized (this) { 12404 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12405 } 12406 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12407 String[] newArgs; 12408 String name; 12409 if (opti >= args.length) { 12410 name = null; 12411 newArgs = EMPTY_STRING_ARRAY; 12412 } else { 12413 name = args[opti]; 12414 opti++; 12415 newArgs = new String[args.length - opti]; 12416 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12417 args.length - opti); 12418 } 12419 synchronized (this) { 12420 dumpProcessesLocked(fd, pw, args, opti, true, name); 12421 } 12422 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12423 synchronized (this) { 12424 dumpOomLocked(fd, pw, args, opti, true); 12425 } 12426 } else if ("provider".equals(cmd)) { 12427 String[] newArgs; 12428 String name; 12429 if (opti >= args.length) { 12430 name = null; 12431 newArgs = EMPTY_STRING_ARRAY; 12432 } else { 12433 name = args[opti]; 12434 opti++; 12435 newArgs = new String[args.length - opti]; 12436 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12437 } 12438 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12439 pw.println("No providers match: " + name); 12440 pw.println("Use -h for help."); 12441 } 12442 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12443 synchronized (this) { 12444 dumpProvidersLocked(fd, pw, args, opti, true, null); 12445 } 12446 } else if ("service".equals(cmd)) { 12447 String[] newArgs; 12448 String name; 12449 if (opti >= args.length) { 12450 name = null; 12451 newArgs = EMPTY_STRING_ARRAY; 12452 } else { 12453 name = args[opti]; 12454 opti++; 12455 newArgs = new String[args.length - opti]; 12456 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12457 args.length - opti); 12458 } 12459 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12460 pw.println("No services match: " + name); 12461 pw.println("Use -h for help."); 12462 } 12463 } else if ("package".equals(cmd)) { 12464 String[] newArgs; 12465 if (opti >= args.length) { 12466 pw.println("package: no package name specified"); 12467 pw.println("Use -h for help."); 12468 } else { 12469 dumpPackage = args[opti]; 12470 opti++; 12471 newArgs = new String[args.length - opti]; 12472 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12473 args.length - opti); 12474 args = newArgs; 12475 opti = 0; 12476 more = true; 12477 } 12478 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12479 synchronized (this) { 12480 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12481 } 12482 } else if ("write".equals(cmd)) { 12483 mTaskPersister.flush(); 12484 pw.println("All tasks persisted."); 12485 return; 12486 } else { 12487 // Dumping a single activity? 12488 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12489 pw.println("Bad activity command, or no activities match: " + cmd); 12490 pw.println("Use -h for help."); 12491 } 12492 } 12493 if (!more) { 12494 Binder.restoreCallingIdentity(origId); 12495 return; 12496 } 12497 } 12498 12499 // No piece of data specified, dump everything. 12500 synchronized (this) { 12501 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12502 pw.println(); 12503 if (dumpAll) { 12504 pw.println("-------------------------------------------------------------------------------"); 12505 } 12506 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12507 pw.println(); 12508 if (dumpAll) { 12509 pw.println("-------------------------------------------------------------------------------"); 12510 } 12511 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12512 pw.println(); 12513 if (dumpAll) { 12514 pw.println("-------------------------------------------------------------------------------"); 12515 } 12516 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12517 pw.println(); 12518 if (dumpAll) { 12519 pw.println("-------------------------------------------------------------------------------"); 12520 } 12521 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12522 pw.println(); 12523 if (dumpAll) { 12524 pw.println("-------------------------------------------------------------------------------"); 12525 } 12526 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12527 pw.println(); 12528 if (dumpAll) { 12529 pw.println("-------------------------------------------------------------------------------"); 12530 } 12531 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12532 } 12533 Binder.restoreCallingIdentity(origId); 12534 } 12535 12536 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12537 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12538 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12539 12540 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12541 dumpPackage); 12542 boolean needSep = printedAnything; 12543 12544 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12545 dumpPackage, needSep, " mFocusedActivity: "); 12546 if (printed) { 12547 printedAnything = true; 12548 needSep = false; 12549 } 12550 12551 if (dumpPackage == null) { 12552 if (needSep) { 12553 pw.println(); 12554 } 12555 needSep = true; 12556 printedAnything = true; 12557 mStackSupervisor.dump(pw, " "); 12558 } 12559 12560 if (!printedAnything) { 12561 pw.println(" (nothing)"); 12562 } 12563 } 12564 12565 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12566 int opti, boolean dumpAll, String dumpPackage) { 12567 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12568 12569 boolean printedAnything = false; 12570 12571 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12572 boolean printedHeader = false; 12573 12574 final int N = mRecentTasks.size(); 12575 for (int i=0; i<N; i++) { 12576 TaskRecord tr = mRecentTasks.get(i); 12577 if (dumpPackage != null) { 12578 if (tr.realActivity == null || 12579 !dumpPackage.equals(tr.realActivity)) { 12580 continue; 12581 } 12582 } 12583 if (!printedHeader) { 12584 pw.println(" Recent tasks:"); 12585 printedHeader = true; 12586 printedAnything = true; 12587 } 12588 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12589 pw.println(tr); 12590 if (dumpAll) { 12591 mRecentTasks.get(i).dump(pw, " "); 12592 } 12593 } 12594 } 12595 12596 if (!printedAnything) { 12597 pw.println(" (nothing)"); 12598 } 12599 } 12600 12601 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12602 int opti, boolean dumpAll, String dumpPackage) { 12603 boolean needSep = false; 12604 boolean printedAnything = false; 12605 int numPers = 0; 12606 12607 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12608 12609 if (dumpAll) { 12610 final int NP = mProcessNames.getMap().size(); 12611 for (int ip=0; ip<NP; ip++) { 12612 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12613 final int NA = procs.size(); 12614 for (int ia=0; ia<NA; ia++) { 12615 ProcessRecord r = procs.valueAt(ia); 12616 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12617 continue; 12618 } 12619 if (!needSep) { 12620 pw.println(" All known processes:"); 12621 needSep = true; 12622 printedAnything = true; 12623 } 12624 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12625 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12626 pw.print(" "); pw.println(r); 12627 r.dump(pw, " "); 12628 if (r.persistent) { 12629 numPers++; 12630 } 12631 } 12632 } 12633 } 12634 12635 if (mIsolatedProcesses.size() > 0) { 12636 boolean printed = false; 12637 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12638 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12639 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12640 continue; 12641 } 12642 if (!printed) { 12643 if (needSep) { 12644 pw.println(); 12645 } 12646 pw.println(" Isolated process list (sorted by uid):"); 12647 printedAnything = true; 12648 printed = true; 12649 needSep = true; 12650 } 12651 pw.println(String.format("%sIsolated #%2d: %s", 12652 " ", i, r.toString())); 12653 } 12654 } 12655 12656 if (mLruProcesses.size() > 0) { 12657 if (needSep) { 12658 pw.println(); 12659 } 12660 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12661 pw.print(" total, non-act at "); 12662 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12663 pw.print(", non-svc at "); 12664 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12665 pw.println("):"); 12666 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12667 needSep = true; 12668 printedAnything = true; 12669 } 12670 12671 if (dumpAll || dumpPackage != null) { 12672 synchronized (mPidsSelfLocked) { 12673 boolean printed = false; 12674 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12675 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12676 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12677 continue; 12678 } 12679 if (!printed) { 12680 if (needSep) pw.println(); 12681 needSep = true; 12682 pw.println(" PID mappings:"); 12683 printed = true; 12684 printedAnything = true; 12685 } 12686 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12687 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12688 } 12689 } 12690 } 12691 12692 if (mForegroundProcesses.size() > 0) { 12693 synchronized (mPidsSelfLocked) { 12694 boolean printed = false; 12695 for (int i=0; i<mForegroundProcesses.size(); i++) { 12696 ProcessRecord r = mPidsSelfLocked.get( 12697 mForegroundProcesses.valueAt(i).pid); 12698 if (dumpPackage != null && (r == null 12699 || !r.pkgList.containsKey(dumpPackage))) { 12700 continue; 12701 } 12702 if (!printed) { 12703 if (needSep) pw.println(); 12704 needSep = true; 12705 pw.println(" Foreground Processes:"); 12706 printed = true; 12707 printedAnything = true; 12708 } 12709 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12710 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12711 } 12712 } 12713 } 12714 12715 if (mPersistentStartingProcesses.size() > 0) { 12716 if (needSep) pw.println(); 12717 needSep = true; 12718 printedAnything = true; 12719 pw.println(" Persisent processes that are starting:"); 12720 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12721 "Starting Norm", "Restarting PERS", dumpPackage); 12722 } 12723 12724 if (mRemovedProcesses.size() > 0) { 12725 if (needSep) pw.println(); 12726 needSep = true; 12727 printedAnything = true; 12728 pw.println(" Processes that are being removed:"); 12729 dumpProcessList(pw, this, mRemovedProcesses, " ", 12730 "Removed Norm", "Removed PERS", dumpPackage); 12731 } 12732 12733 if (mProcessesOnHold.size() > 0) { 12734 if (needSep) pw.println(); 12735 needSep = true; 12736 printedAnything = true; 12737 pw.println(" Processes that are on old until the system is ready:"); 12738 dumpProcessList(pw, this, mProcessesOnHold, " ", 12739 "OnHold Norm", "OnHold PERS", dumpPackage); 12740 } 12741 12742 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12743 12744 if (mProcessCrashTimes.getMap().size() > 0) { 12745 boolean printed = false; 12746 long now = SystemClock.uptimeMillis(); 12747 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12748 final int NP = pmap.size(); 12749 for (int ip=0; ip<NP; ip++) { 12750 String pname = pmap.keyAt(ip); 12751 SparseArray<Long> uids = pmap.valueAt(ip); 12752 final int N = uids.size(); 12753 for (int i=0; i<N; i++) { 12754 int puid = uids.keyAt(i); 12755 ProcessRecord r = mProcessNames.get(pname, puid); 12756 if (dumpPackage != null && (r == null 12757 || !r.pkgList.containsKey(dumpPackage))) { 12758 continue; 12759 } 12760 if (!printed) { 12761 if (needSep) pw.println(); 12762 needSep = true; 12763 pw.println(" Time since processes crashed:"); 12764 printed = true; 12765 printedAnything = true; 12766 } 12767 pw.print(" Process "); pw.print(pname); 12768 pw.print(" uid "); pw.print(puid); 12769 pw.print(": last crashed "); 12770 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12771 pw.println(" ago"); 12772 } 12773 } 12774 } 12775 12776 if (mBadProcesses.getMap().size() > 0) { 12777 boolean printed = false; 12778 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12779 final int NP = pmap.size(); 12780 for (int ip=0; ip<NP; ip++) { 12781 String pname = pmap.keyAt(ip); 12782 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12783 final int N = uids.size(); 12784 for (int i=0; i<N; i++) { 12785 int puid = uids.keyAt(i); 12786 ProcessRecord r = mProcessNames.get(pname, puid); 12787 if (dumpPackage != null && (r == null 12788 || !r.pkgList.containsKey(dumpPackage))) { 12789 continue; 12790 } 12791 if (!printed) { 12792 if (needSep) pw.println(); 12793 needSep = true; 12794 pw.println(" Bad processes:"); 12795 printedAnything = true; 12796 } 12797 BadProcessInfo info = uids.valueAt(i); 12798 pw.print(" Bad process "); pw.print(pname); 12799 pw.print(" uid "); pw.print(puid); 12800 pw.print(": crashed at time "); pw.println(info.time); 12801 if (info.shortMsg != null) { 12802 pw.print(" Short msg: "); pw.println(info.shortMsg); 12803 } 12804 if (info.longMsg != null) { 12805 pw.print(" Long msg: "); pw.println(info.longMsg); 12806 } 12807 if (info.stack != null) { 12808 pw.println(" Stack:"); 12809 int lastPos = 0; 12810 for (int pos=0; pos<info.stack.length(); pos++) { 12811 if (info.stack.charAt(pos) == '\n') { 12812 pw.print(" "); 12813 pw.write(info.stack, lastPos, pos-lastPos); 12814 pw.println(); 12815 lastPos = pos+1; 12816 } 12817 } 12818 if (lastPos < info.stack.length()) { 12819 pw.print(" "); 12820 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12821 pw.println(); 12822 } 12823 } 12824 } 12825 } 12826 } 12827 12828 if (dumpPackage == null) { 12829 pw.println(); 12830 needSep = false; 12831 pw.println(" mStartedUsers:"); 12832 for (int i=0; i<mStartedUsers.size(); i++) { 12833 UserStartedState uss = mStartedUsers.valueAt(i); 12834 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12835 pw.print(": "); uss.dump("", pw); 12836 } 12837 pw.print(" mStartedUserArray: ["); 12838 for (int i=0; i<mStartedUserArray.length; i++) { 12839 if (i > 0) pw.print(", "); 12840 pw.print(mStartedUserArray[i]); 12841 } 12842 pw.println("]"); 12843 pw.print(" mUserLru: ["); 12844 for (int i=0; i<mUserLru.size(); i++) { 12845 if (i > 0) pw.print(", "); 12846 pw.print(mUserLru.get(i)); 12847 } 12848 pw.println("]"); 12849 if (dumpAll) { 12850 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12851 } 12852 synchronized (mUserProfileGroupIdsSelfLocked) { 12853 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12854 pw.println(" mUserProfileGroupIds:"); 12855 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12856 pw.print(" User #"); 12857 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12858 pw.print(" -> profile #"); 12859 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12860 } 12861 } 12862 } 12863 } 12864 if (mHomeProcess != null && (dumpPackage == null 12865 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12866 if (needSep) { 12867 pw.println(); 12868 needSep = false; 12869 } 12870 pw.println(" mHomeProcess: " + mHomeProcess); 12871 } 12872 if (mPreviousProcess != null && (dumpPackage == null 12873 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12874 if (needSep) { 12875 pw.println(); 12876 needSep = false; 12877 } 12878 pw.println(" mPreviousProcess: " + mPreviousProcess); 12879 } 12880 if (dumpAll) { 12881 StringBuilder sb = new StringBuilder(128); 12882 sb.append(" mPreviousProcessVisibleTime: "); 12883 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12884 pw.println(sb); 12885 } 12886 if (mHeavyWeightProcess != null && (dumpPackage == null 12887 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12888 if (needSep) { 12889 pw.println(); 12890 needSep = false; 12891 } 12892 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12893 } 12894 if (dumpPackage == null) { 12895 pw.println(" mConfiguration: " + mConfiguration); 12896 } 12897 if (dumpAll) { 12898 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12899 if (mCompatModePackages.getPackages().size() > 0) { 12900 boolean printed = false; 12901 for (Map.Entry<String, Integer> entry 12902 : mCompatModePackages.getPackages().entrySet()) { 12903 String pkg = entry.getKey(); 12904 int mode = entry.getValue(); 12905 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12906 continue; 12907 } 12908 if (!printed) { 12909 pw.println(" mScreenCompatPackages:"); 12910 printed = true; 12911 } 12912 pw.print(" "); pw.print(pkg); pw.print(": "); 12913 pw.print(mode); pw.println(); 12914 } 12915 } 12916 } 12917 if (dumpPackage == null) { 12918 pw.println(" mWakefulness=" 12919 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12920 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12921 + lockScreenShownToString()); 12922 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 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); 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); 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 synchronized (mProcessCpuTracker) { 14156 final int N = mProcessCpuTracker.countStats(); 14157 for (int i=0; i<N; i++) { 14158 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14159 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14160 if (mi == null) { 14161 mi = new Debug.MemoryInfo(); 14162 } 14163 if (!brief && !oomOnly) { 14164 Debug.getMemoryInfo(st.pid, mi); 14165 } else { 14166 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14167 mi.nativePrivateDirty = (int)tmpLong[0]; 14168 } 14169 14170 final long myTotalPss = mi.getTotalPss(); 14171 totalPss += myTotalPss; 14172 nativeProcTotalPss += myTotalPss; 14173 14174 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14175 st.name, myTotalPss, st.pid, false); 14176 procMems.add(pssItem); 14177 14178 nativePss += mi.nativePss; 14179 dalvikPss += mi.dalvikPss; 14180 otherPss += mi.otherPss; 14181 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14182 long mem = mi.getOtherPss(j); 14183 miscPss[j] += mem; 14184 otherPss -= mem; 14185 } 14186 oomPss[0] += myTotalPss; 14187 if (oomProcs[0] == null) { 14188 oomProcs[0] = new ArrayList<MemItem>(); 14189 } 14190 oomProcs[0].add(pssItem); 14191 } 14192 } 14193 } 14194 14195 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14196 14197 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14198 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14199 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14200 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14201 String label = Debug.MemoryInfo.getOtherLabel(j); 14202 catMems.add(new MemItem(label, label, miscPss[j], j)); 14203 } 14204 14205 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14206 for (int j=0; j<oomPss.length; j++) { 14207 if (oomPss[j] != 0) { 14208 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14209 : DUMP_MEM_OOM_LABEL[j]; 14210 MemItem item = new MemItem(label, label, oomPss[j], 14211 DUMP_MEM_OOM_ADJ[j]); 14212 item.subitems = oomProcs[j]; 14213 oomMems.add(item); 14214 } 14215 } 14216 14217 if (!brief && !oomOnly && !isCompact) { 14218 pw.println(); 14219 pw.println("Total PSS by process:"); 14220 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14221 pw.println(); 14222 } 14223 if (!isCompact) { 14224 pw.println("Total PSS by OOM adjustment:"); 14225 } 14226 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14227 if (!brief && !oomOnly) { 14228 PrintWriter out = categoryPw != null ? categoryPw : pw; 14229 if (!isCompact) { 14230 out.println(); 14231 out.println("Total PSS by category:"); 14232 } 14233 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14234 } 14235 if (!isCompact) { 14236 pw.println(); 14237 } 14238 MemInfoReader memInfo = new MemInfoReader(); 14239 memInfo.readMemInfo(); 14240 if (nativeProcTotalPss > 0) { 14241 synchronized (this) { 14242 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14243 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14244 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14245 } 14246 } 14247 if (!brief) { 14248 if (!isCompact) { 14249 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14250 pw.print(" kB (status "); 14251 switch (mLastMemoryLevel) { 14252 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14253 pw.println("normal)"); 14254 break; 14255 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14256 pw.println("moderate)"); 14257 break; 14258 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14259 pw.println("low)"); 14260 break; 14261 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14262 pw.println("critical)"); 14263 break; 14264 default: 14265 pw.print(mLastMemoryLevel); 14266 pw.println(")"); 14267 break; 14268 } 14269 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14270 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14271 pw.print(cachedPss); pw.print(" cached pss + "); 14272 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14273 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14274 } else { 14275 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14276 pw.print(cachedPss + memInfo.getCachedSizeKb() 14277 + memInfo.getFreeSizeKb()); pw.print(","); 14278 pw.println(totalPss - cachedPss); 14279 } 14280 } 14281 if (!isCompact) { 14282 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14283 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14284 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14285 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14286 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14287 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14288 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14289 } 14290 if (!brief) { 14291 if (memInfo.getZramTotalSizeKb() != 0) { 14292 if (!isCompact) { 14293 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14294 pw.print(" kB physical used for "); 14295 pw.print(memInfo.getSwapTotalSizeKb() 14296 - memInfo.getSwapFreeSizeKb()); 14297 pw.print(" kB in swap ("); 14298 pw.print(memInfo.getSwapTotalSizeKb()); 14299 pw.println(" kB total swap)"); 14300 } else { 14301 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14302 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14303 pw.println(memInfo.getSwapFreeSizeKb()); 14304 } 14305 } 14306 final long[] ksm = getKsmInfo(); 14307 if (!isCompact) { 14308 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14309 || ksm[KSM_VOLATILE] != 0) { 14310 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14311 pw.print(" kB saved from shared "); 14312 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14313 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14314 pw.print(" kB unshared; "); 14315 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14316 } 14317 pw.print(" Tuning: "); 14318 pw.print(ActivityManager.staticGetMemoryClass()); 14319 pw.print(" (large "); 14320 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14321 pw.print("), oom "); 14322 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14323 pw.print(" kB"); 14324 pw.print(", restore limit "); 14325 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14326 pw.print(" kB"); 14327 if (ActivityManager.isLowRamDeviceStatic()) { 14328 pw.print(" (low-ram)"); 14329 } 14330 if (ActivityManager.isHighEndGfx()) { 14331 pw.print(" (high-end-gfx)"); 14332 } 14333 pw.println(); 14334 } else { 14335 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14336 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14337 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14338 pw.print("tuning,"); 14339 pw.print(ActivityManager.staticGetMemoryClass()); 14340 pw.print(','); 14341 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14342 pw.print(','); 14343 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14344 if (ActivityManager.isLowRamDeviceStatic()) { 14345 pw.print(",low-ram"); 14346 } 14347 if (ActivityManager.isHighEndGfx()) { 14348 pw.print(",high-end-gfx"); 14349 } 14350 pw.println(); 14351 } 14352 } 14353 } 14354 } 14355 14356 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14357 String name) { 14358 sb.append(" "); 14359 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14360 sb.append(' '); 14361 sb.append(ProcessList.makeProcStateString(procState)); 14362 sb.append(' '); 14363 ProcessList.appendRamKb(sb, pss); 14364 sb.append(" kB: "); 14365 sb.append(name); 14366 } 14367 14368 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14369 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14370 sb.append(" ("); 14371 sb.append(mi.pid); 14372 sb.append(") "); 14373 sb.append(mi.adjType); 14374 sb.append('\n'); 14375 if (mi.adjReason != null) { 14376 sb.append(" "); 14377 sb.append(mi.adjReason); 14378 sb.append('\n'); 14379 } 14380 } 14381 14382 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14383 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14384 for (int i=0, N=memInfos.size(); i<N; i++) { 14385 ProcessMemInfo mi = memInfos.get(i); 14386 infoMap.put(mi.pid, mi); 14387 } 14388 updateCpuStatsNow(); 14389 synchronized (mProcessCpuTracker) { 14390 final int N = mProcessCpuTracker.countStats(); 14391 for (int i=0; i<N; i++) { 14392 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14393 if (st.vsize > 0) { 14394 long pss = Debug.getPss(st.pid, null); 14395 if (pss > 0) { 14396 if (infoMap.indexOfKey(st.pid) < 0) { 14397 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14398 ProcessList.NATIVE_ADJ, -1, "native", null); 14399 mi.pss = pss; 14400 memInfos.add(mi); 14401 } 14402 } 14403 } 14404 } 14405 } 14406 14407 long totalPss = 0; 14408 for (int i=0, N=memInfos.size(); i<N; i++) { 14409 ProcessMemInfo mi = memInfos.get(i); 14410 if (mi.pss == 0) { 14411 mi.pss = Debug.getPss(mi.pid, null); 14412 } 14413 totalPss += mi.pss; 14414 } 14415 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14416 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14417 if (lhs.oomAdj != rhs.oomAdj) { 14418 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14419 } 14420 if (lhs.pss != rhs.pss) { 14421 return lhs.pss < rhs.pss ? 1 : -1; 14422 } 14423 return 0; 14424 } 14425 }); 14426 14427 StringBuilder tag = new StringBuilder(128); 14428 StringBuilder stack = new StringBuilder(128); 14429 tag.append("Low on memory -- "); 14430 appendMemBucket(tag, totalPss, "total", false); 14431 appendMemBucket(stack, totalPss, "total", true); 14432 14433 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14434 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14435 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14436 14437 boolean firstLine = true; 14438 int lastOomAdj = Integer.MIN_VALUE; 14439 long extraNativeRam = 0; 14440 long cachedPss = 0; 14441 for (int i=0, N=memInfos.size(); i<N; i++) { 14442 ProcessMemInfo mi = memInfos.get(i); 14443 14444 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14445 cachedPss += mi.pss; 14446 } 14447 14448 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14449 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14450 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14451 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14452 if (lastOomAdj != mi.oomAdj) { 14453 lastOomAdj = mi.oomAdj; 14454 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14455 tag.append(" / "); 14456 } 14457 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14458 if (firstLine) { 14459 stack.append(":"); 14460 firstLine = false; 14461 } 14462 stack.append("\n\t at "); 14463 } else { 14464 stack.append("$"); 14465 } 14466 } else { 14467 tag.append(" "); 14468 stack.append("$"); 14469 } 14470 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14471 appendMemBucket(tag, mi.pss, mi.name, false); 14472 } 14473 appendMemBucket(stack, mi.pss, mi.name, true); 14474 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14475 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14476 stack.append("("); 14477 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14478 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14479 stack.append(DUMP_MEM_OOM_LABEL[k]); 14480 stack.append(":"); 14481 stack.append(DUMP_MEM_OOM_ADJ[k]); 14482 } 14483 } 14484 stack.append(")"); 14485 } 14486 } 14487 14488 appendMemInfo(fullNativeBuilder, mi); 14489 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14490 // The short form only has native processes that are >= 1MB. 14491 if (mi.pss >= 1000) { 14492 appendMemInfo(shortNativeBuilder, mi); 14493 } else { 14494 extraNativeRam += mi.pss; 14495 } 14496 } else { 14497 // Short form has all other details, but if we have collected RAM 14498 // from smaller native processes let's dump a summary of that. 14499 if (extraNativeRam > 0) { 14500 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14501 -1, extraNativeRam, "(Other native)"); 14502 shortNativeBuilder.append('\n'); 14503 extraNativeRam = 0; 14504 } 14505 appendMemInfo(fullJavaBuilder, mi); 14506 } 14507 } 14508 14509 fullJavaBuilder.append(" "); 14510 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14511 fullJavaBuilder.append(" kB: TOTAL\n"); 14512 14513 MemInfoReader memInfo = new MemInfoReader(); 14514 memInfo.readMemInfo(); 14515 final long[] infos = memInfo.getRawInfo(); 14516 14517 StringBuilder memInfoBuilder = new StringBuilder(1024); 14518 Debug.getMemInfo(infos); 14519 memInfoBuilder.append(" MemInfo: "); 14520 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14521 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14522 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14523 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14524 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14525 memInfoBuilder.append(" "); 14526 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14527 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14528 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14529 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14530 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14531 memInfoBuilder.append(" ZRAM: "); 14532 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14533 memInfoBuilder.append(" kB RAM, "); 14534 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14535 memInfoBuilder.append(" kB swap total, "); 14536 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14537 memInfoBuilder.append(" kB swap free\n"); 14538 } 14539 final long[] ksm = getKsmInfo(); 14540 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14541 || ksm[KSM_VOLATILE] != 0) { 14542 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14543 memInfoBuilder.append(" kB saved from shared "); 14544 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14545 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14546 memInfoBuilder.append(" kB unshared; "); 14547 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14548 } 14549 memInfoBuilder.append(" Free RAM: "); 14550 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14551 + memInfo.getFreeSizeKb()); 14552 memInfoBuilder.append(" kB\n"); 14553 memInfoBuilder.append(" Used RAM: "); 14554 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14555 memInfoBuilder.append(" kB\n"); 14556 memInfoBuilder.append(" Lost RAM: "); 14557 memInfoBuilder.append(memInfo.getTotalSizeKb() 14558 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14559 - memInfo.getKernelUsedSizeKb()); 14560 memInfoBuilder.append(" kB\n"); 14561 Slog.i(TAG, "Low on memory:"); 14562 Slog.i(TAG, shortNativeBuilder.toString()); 14563 Slog.i(TAG, fullJavaBuilder.toString()); 14564 Slog.i(TAG, memInfoBuilder.toString()); 14565 14566 StringBuilder dropBuilder = new StringBuilder(1024); 14567 /* 14568 StringWriter oomSw = new StringWriter(); 14569 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14570 StringWriter catSw = new StringWriter(); 14571 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14572 String[] emptyArgs = new String[] { }; 14573 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14574 oomPw.flush(); 14575 String oomString = oomSw.toString(); 14576 */ 14577 dropBuilder.append("Low on memory:"); 14578 dropBuilder.append(stack); 14579 dropBuilder.append('\n'); 14580 dropBuilder.append(fullNativeBuilder); 14581 dropBuilder.append(fullJavaBuilder); 14582 dropBuilder.append('\n'); 14583 dropBuilder.append(memInfoBuilder); 14584 dropBuilder.append('\n'); 14585 /* 14586 dropBuilder.append(oomString); 14587 dropBuilder.append('\n'); 14588 */ 14589 StringWriter catSw = new StringWriter(); 14590 synchronized (ActivityManagerService.this) { 14591 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14592 String[] emptyArgs = new String[] { }; 14593 catPw.println(); 14594 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14595 catPw.println(); 14596 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14597 false, false, null); 14598 catPw.println(); 14599 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14600 catPw.flush(); 14601 } 14602 dropBuilder.append(catSw.toString()); 14603 addErrorToDropBox("lowmem", null, "system_server", null, 14604 null, tag.toString(), dropBuilder.toString(), null, null); 14605 //Slog.i(TAG, "Sent to dropbox:"); 14606 //Slog.i(TAG, dropBuilder.toString()); 14607 synchronized (ActivityManagerService.this) { 14608 long now = SystemClock.uptimeMillis(); 14609 if (mLastMemUsageReportTime < now) { 14610 mLastMemUsageReportTime = now; 14611 } 14612 } 14613 } 14614 14615 /** 14616 * Searches array of arguments for the specified string 14617 * @param args array of argument strings 14618 * @param value value to search for 14619 * @return true if the value is contained in the array 14620 */ 14621 private static boolean scanArgs(String[] args, String value) { 14622 if (args != null) { 14623 for (String arg : args) { 14624 if (value.equals(arg)) { 14625 return true; 14626 } 14627 } 14628 } 14629 return false; 14630 } 14631 14632 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14633 ContentProviderRecord cpr, boolean always) { 14634 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14635 14636 if (!inLaunching || always) { 14637 synchronized (cpr) { 14638 cpr.launchingApp = null; 14639 cpr.notifyAll(); 14640 } 14641 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14642 String names[] = cpr.info.authority.split(";"); 14643 for (int j = 0; j < names.length; j++) { 14644 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14645 } 14646 } 14647 14648 for (int i=0; i<cpr.connections.size(); i++) { 14649 ContentProviderConnection conn = cpr.connections.get(i); 14650 if (conn.waiting) { 14651 // If this connection is waiting for the provider, then we don't 14652 // need to mess with its process unless we are always removing 14653 // or for some reason the provider is not currently launching. 14654 if (inLaunching && !always) { 14655 continue; 14656 } 14657 } 14658 ProcessRecord capp = conn.client; 14659 conn.dead = true; 14660 if (conn.stableCount > 0) { 14661 if (!capp.persistent && capp.thread != null 14662 && capp.pid != 0 14663 && capp.pid != MY_PID) { 14664 capp.kill("depends on provider " 14665 + cpr.name.flattenToShortString() 14666 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14667 } 14668 } else if (capp.thread != null && conn.provider.provider != null) { 14669 try { 14670 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14671 } catch (RemoteException e) { 14672 } 14673 // In the protocol here, we don't expect the client to correctly 14674 // clean up this connection, we'll just remove it. 14675 cpr.connections.remove(i); 14676 conn.client.conProviders.remove(conn); 14677 } 14678 } 14679 14680 if (inLaunching && always) { 14681 mLaunchingProviders.remove(cpr); 14682 } 14683 return inLaunching; 14684 } 14685 14686 /** 14687 * Main code for cleaning up a process when it has gone away. This is 14688 * called both as a result of the process dying, or directly when stopping 14689 * a process when running in single process mode. 14690 * 14691 * @return Returns true if the given process has been restarted, so the 14692 * app that was passed in must remain on the process lists. 14693 */ 14694 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14695 boolean restarting, boolean allowRestart, int index) { 14696 if (index >= 0) { 14697 removeLruProcessLocked(app); 14698 ProcessList.remove(app.pid); 14699 } 14700 14701 mProcessesToGc.remove(app); 14702 mPendingPssProcesses.remove(app); 14703 14704 // Dismiss any open dialogs. 14705 if (app.crashDialog != null && !app.forceCrashReport) { 14706 app.crashDialog.dismiss(); 14707 app.crashDialog = null; 14708 } 14709 if (app.anrDialog != null) { 14710 app.anrDialog.dismiss(); 14711 app.anrDialog = null; 14712 } 14713 if (app.waitDialog != null) { 14714 app.waitDialog.dismiss(); 14715 app.waitDialog = null; 14716 } 14717 14718 app.crashing = false; 14719 app.notResponding = false; 14720 14721 app.resetPackageList(mProcessStats); 14722 app.unlinkDeathRecipient(); 14723 app.makeInactive(mProcessStats); 14724 app.waitingToKill = null; 14725 app.forcingToForeground = null; 14726 updateProcessForegroundLocked(app, false, false); 14727 app.foregroundActivities = false; 14728 app.hasShownUi = false; 14729 app.treatLikeActivity = false; 14730 app.hasAboveClient = false; 14731 app.hasClientActivities = false; 14732 14733 mServices.killServicesLocked(app, allowRestart); 14734 14735 boolean restart = false; 14736 14737 // Remove published content providers. 14738 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14739 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14740 final boolean always = app.bad || !allowRestart; 14741 if (removeDyingProviderLocked(app, cpr, always) || always) { 14742 // We left the provider in the launching list, need to 14743 // restart it. 14744 restart = true; 14745 } 14746 14747 cpr.provider = null; 14748 cpr.proc = null; 14749 } 14750 app.pubProviders.clear(); 14751 14752 // Take care of any launching providers waiting for this process. 14753 if (checkAppInLaunchingProvidersLocked(app, false)) { 14754 restart = true; 14755 } 14756 14757 // Unregister from connected content providers. 14758 if (!app.conProviders.isEmpty()) { 14759 for (int i=0; i<app.conProviders.size(); i++) { 14760 ContentProviderConnection conn = app.conProviders.get(i); 14761 conn.provider.connections.remove(conn); 14762 } 14763 app.conProviders.clear(); 14764 } 14765 14766 // At this point there may be remaining entries in mLaunchingProviders 14767 // where we were the only one waiting, so they are no longer of use. 14768 // Look for these and clean up if found. 14769 // XXX Commented out for now. Trying to figure out a way to reproduce 14770 // the actual situation to identify what is actually going on. 14771 if (false) { 14772 for (int i=0; i<mLaunchingProviders.size(); i++) { 14773 ContentProviderRecord cpr = (ContentProviderRecord) 14774 mLaunchingProviders.get(i); 14775 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14776 synchronized (cpr) { 14777 cpr.launchingApp = null; 14778 cpr.notifyAll(); 14779 } 14780 } 14781 } 14782 } 14783 14784 skipCurrentReceiverLocked(app); 14785 14786 // Unregister any receivers. 14787 for (int i=app.receivers.size()-1; i>=0; i--) { 14788 removeReceiverLocked(app.receivers.valueAt(i)); 14789 } 14790 app.receivers.clear(); 14791 14792 // If the app is undergoing backup, tell the backup manager about it 14793 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14794 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14795 + mBackupTarget.appInfo + " died during backup"); 14796 try { 14797 IBackupManager bm = IBackupManager.Stub.asInterface( 14798 ServiceManager.getService(Context.BACKUP_SERVICE)); 14799 bm.agentDisconnected(app.info.packageName); 14800 } catch (RemoteException e) { 14801 // can't happen; backup manager is local 14802 } 14803 } 14804 14805 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14806 ProcessChangeItem item = mPendingProcessChanges.get(i); 14807 if (item.pid == app.pid) { 14808 mPendingProcessChanges.remove(i); 14809 mAvailProcessChanges.add(item); 14810 } 14811 } 14812 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14813 14814 // If the caller is restarting this app, then leave it in its 14815 // current lists and let the caller take care of it. 14816 if (restarting) { 14817 return false; 14818 } 14819 14820 if (!app.persistent || app.isolated) { 14821 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14822 "Removing non-persistent process during cleanup: " + app); 14823 mProcessNames.remove(app.processName, app.uid); 14824 mIsolatedProcesses.remove(app.uid); 14825 if (mHeavyWeightProcess == app) { 14826 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14827 mHeavyWeightProcess.userId, 0)); 14828 mHeavyWeightProcess = null; 14829 } 14830 } else if (!app.removed) { 14831 // This app is persistent, so we need to keep its record around. 14832 // If it is not already on the pending app list, add it there 14833 // and start a new process for it. 14834 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14835 mPersistentStartingProcesses.add(app); 14836 restart = true; 14837 } 14838 } 14839 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14840 "Clean-up removing on hold: " + app); 14841 mProcessesOnHold.remove(app); 14842 14843 if (app == mHomeProcess) { 14844 mHomeProcess = null; 14845 } 14846 if (app == mPreviousProcess) { 14847 mPreviousProcess = null; 14848 } 14849 14850 if (restart && !app.isolated) { 14851 // We have components that still need to be running in the 14852 // process, so re-launch it. 14853 if (index < 0) { 14854 ProcessList.remove(app.pid); 14855 } 14856 mProcessNames.put(app.processName, app.uid, app); 14857 startProcessLocked(app, "restart", app.processName); 14858 return true; 14859 } else if (app.pid > 0 && app.pid != MY_PID) { 14860 // Goodbye! 14861 boolean removed; 14862 synchronized (mPidsSelfLocked) { 14863 mPidsSelfLocked.remove(app.pid); 14864 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14865 } 14866 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14867 if (app.isolated) { 14868 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14869 } 14870 app.setPid(0); 14871 } 14872 return false; 14873 } 14874 14875 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14876 // Look through the content providers we are waiting to have launched, 14877 // and if any run in this process then either schedule a restart of 14878 // the process or kill the client waiting for it if this process has 14879 // gone bad. 14880 int NL = mLaunchingProviders.size(); 14881 boolean restart = false; 14882 for (int i=0; i<NL; i++) { 14883 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14884 if (cpr.launchingApp == app) { 14885 if (!alwaysBad && !app.bad) { 14886 restart = true; 14887 } else { 14888 removeDyingProviderLocked(app, cpr, true); 14889 // cpr should have been removed from mLaunchingProviders 14890 NL = mLaunchingProviders.size(); 14891 i--; 14892 } 14893 } 14894 } 14895 return restart; 14896 } 14897 14898 // ========================================================= 14899 // SERVICES 14900 // ========================================================= 14901 14902 @Override 14903 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14904 int flags) { 14905 enforceNotIsolatedCaller("getServices"); 14906 synchronized (this) { 14907 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14908 } 14909 } 14910 14911 @Override 14912 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14913 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14914 synchronized (this) { 14915 return mServices.getRunningServiceControlPanelLocked(name); 14916 } 14917 } 14918 14919 @Override 14920 public ComponentName startService(IApplicationThread caller, Intent service, 14921 String resolvedType, int userId) { 14922 enforceNotIsolatedCaller("startService"); 14923 // Refuse possible leaked file descriptors 14924 if (service != null && service.hasFileDescriptors() == true) { 14925 throw new IllegalArgumentException("File descriptors passed in Intent"); 14926 } 14927 14928 if (DEBUG_SERVICE) 14929 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14930 synchronized(this) { 14931 final int callingPid = Binder.getCallingPid(); 14932 final int callingUid = Binder.getCallingUid(); 14933 final long origId = Binder.clearCallingIdentity(); 14934 ComponentName res = mServices.startServiceLocked(caller, service, 14935 resolvedType, callingPid, callingUid, userId); 14936 Binder.restoreCallingIdentity(origId); 14937 return res; 14938 } 14939 } 14940 14941 ComponentName startServiceInPackage(int uid, 14942 Intent service, String resolvedType, int userId) { 14943 synchronized(this) { 14944 if (DEBUG_SERVICE) 14945 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14946 final long origId = Binder.clearCallingIdentity(); 14947 ComponentName res = mServices.startServiceLocked(null, service, 14948 resolvedType, -1, uid, userId); 14949 Binder.restoreCallingIdentity(origId); 14950 return res; 14951 } 14952 } 14953 14954 @Override 14955 public int stopService(IApplicationThread caller, Intent service, 14956 String resolvedType, int userId) { 14957 enforceNotIsolatedCaller("stopService"); 14958 // Refuse possible leaked file descriptors 14959 if (service != null && service.hasFileDescriptors() == true) { 14960 throw new IllegalArgumentException("File descriptors passed in Intent"); 14961 } 14962 14963 synchronized(this) { 14964 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14965 } 14966 } 14967 14968 @Override 14969 public IBinder peekService(Intent service, String resolvedType) { 14970 enforceNotIsolatedCaller("peekService"); 14971 // Refuse possible leaked file descriptors 14972 if (service != null && service.hasFileDescriptors() == true) { 14973 throw new IllegalArgumentException("File descriptors passed in Intent"); 14974 } 14975 synchronized(this) { 14976 return mServices.peekServiceLocked(service, resolvedType); 14977 } 14978 } 14979 14980 @Override 14981 public boolean stopServiceToken(ComponentName className, IBinder token, 14982 int startId) { 14983 synchronized(this) { 14984 return mServices.stopServiceTokenLocked(className, token, startId); 14985 } 14986 } 14987 14988 @Override 14989 public void setServiceForeground(ComponentName className, IBinder token, 14990 int id, Notification notification, boolean removeNotification) { 14991 synchronized(this) { 14992 mServices.setServiceForegroundLocked(className, token, id, notification, 14993 removeNotification); 14994 } 14995 } 14996 14997 @Override 14998 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14999 boolean requireFull, String name, String callerPackage) { 15000 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15001 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15002 } 15003 15004 int unsafeConvertIncomingUser(int userId) { 15005 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15006 ? mCurrentUserId : userId; 15007 } 15008 15009 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15010 int allowMode, String name, String callerPackage) { 15011 final int callingUserId = UserHandle.getUserId(callingUid); 15012 if (callingUserId == userId) { 15013 return userId; 15014 } 15015 15016 // Note that we may be accessing mCurrentUserId outside of a lock... 15017 // shouldn't be a big deal, if this is being called outside 15018 // of a locked context there is intrinsically a race with 15019 // the value the caller will receive and someone else changing it. 15020 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15021 // we will switch to the calling user if access to the current user fails. 15022 int targetUserId = unsafeConvertIncomingUser(userId); 15023 15024 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15025 final boolean allow; 15026 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15027 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15028 // If the caller has this permission, they always pass go. And collect $200. 15029 allow = true; 15030 } else if (allowMode == ALLOW_FULL_ONLY) { 15031 // We require full access, sucks to be you. 15032 allow = false; 15033 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15034 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15035 // If the caller does not have either permission, they are always doomed. 15036 allow = false; 15037 } else if (allowMode == ALLOW_NON_FULL) { 15038 // We are blanket allowing non-full access, you lucky caller! 15039 allow = true; 15040 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15041 // We may or may not allow this depending on whether the two users are 15042 // in the same profile. 15043 synchronized (mUserProfileGroupIdsSelfLocked) { 15044 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15045 UserInfo.NO_PROFILE_GROUP_ID); 15046 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15047 UserInfo.NO_PROFILE_GROUP_ID); 15048 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15049 && callingProfile == targetProfile; 15050 } 15051 } else { 15052 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15053 } 15054 if (!allow) { 15055 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15056 // In this case, they would like to just execute as their 15057 // owner user instead of failing. 15058 targetUserId = callingUserId; 15059 } else { 15060 StringBuilder builder = new StringBuilder(128); 15061 builder.append("Permission Denial: "); 15062 builder.append(name); 15063 if (callerPackage != null) { 15064 builder.append(" from "); 15065 builder.append(callerPackage); 15066 } 15067 builder.append(" asks to run as user "); 15068 builder.append(userId); 15069 builder.append(" but is calling from user "); 15070 builder.append(UserHandle.getUserId(callingUid)); 15071 builder.append("; this requires "); 15072 builder.append(INTERACT_ACROSS_USERS_FULL); 15073 if (allowMode != ALLOW_FULL_ONLY) { 15074 builder.append(" or "); 15075 builder.append(INTERACT_ACROSS_USERS); 15076 } 15077 String msg = builder.toString(); 15078 Slog.w(TAG, msg); 15079 throw new SecurityException(msg); 15080 } 15081 } 15082 } 15083 if (!allowAll && targetUserId < 0) { 15084 throw new IllegalArgumentException( 15085 "Call does not support special user #" + targetUserId); 15086 } 15087 // Check shell permission 15088 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15089 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15090 targetUserId)) { 15091 throw new SecurityException("Shell does not have permission to access user " 15092 + targetUserId + "\n " + Debug.getCallers(3)); 15093 } 15094 } 15095 return targetUserId; 15096 } 15097 15098 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15099 String className, int flags) { 15100 boolean result = false; 15101 // For apps that don't have pre-defined UIDs, check for permission 15102 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15103 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15104 if (ActivityManager.checkUidPermission( 15105 INTERACT_ACROSS_USERS, 15106 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15107 ComponentName comp = new ComponentName(aInfo.packageName, className); 15108 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15109 + " requests FLAG_SINGLE_USER, but app does not hold " 15110 + INTERACT_ACROSS_USERS; 15111 Slog.w(TAG, msg); 15112 throw new SecurityException(msg); 15113 } 15114 // Permission passed 15115 result = true; 15116 } 15117 } else if ("system".equals(componentProcessName)) { 15118 result = true; 15119 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15120 // Phone app and persistent apps are allowed to export singleuser providers. 15121 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15122 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15123 } 15124 if (DEBUG_MU) { 15125 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15126 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15127 } 15128 return result; 15129 } 15130 15131 /** 15132 * Checks to see if the caller is in the same app as the singleton 15133 * component, or the component is in a special app. It allows special apps 15134 * to export singleton components but prevents exporting singleton 15135 * components for regular apps. 15136 */ 15137 boolean isValidSingletonCall(int callingUid, int componentUid) { 15138 int componentAppId = UserHandle.getAppId(componentUid); 15139 return UserHandle.isSameApp(callingUid, componentUid) 15140 || componentAppId == Process.SYSTEM_UID 15141 || componentAppId == Process.PHONE_UID 15142 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15143 == PackageManager.PERMISSION_GRANTED; 15144 } 15145 15146 public int bindService(IApplicationThread caller, IBinder token, 15147 Intent service, String resolvedType, 15148 IServiceConnection connection, int flags, int userId) { 15149 enforceNotIsolatedCaller("bindService"); 15150 15151 // Refuse possible leaked file descriptors 15152 if (service != null && service.hasFileDescriptors() == true) { 15153 throw new IllegalArgumentException("File descriptors passed in Intent"); 15154 } 15155 15156 synchronized(this) { 15157 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15158 connection, flags, userId); 15159 } 15160 } 15161 15162 public boolean unbindService(IServiceConnection connection) { 15163 synchronized (this) { 15164 return mServices.unbindServiceLocked(connection); 15165 } 15166 } 15167 15168 public void publishService(IBinder token, Intent intent, IBinder service) { 15169 // Refuse possible leaked file descriptors 15170 if (intent != null && intent.hasFileDescriptors() == true) { 15171 throw new IllegalArgumentException("File descriptors passed in Intent"); 15172 } 15173 15174 synchronized(this) { 15175 if (!(token instanceof ServiceRecord)) { 15176 throw new IllegalArgumentException("Invalid service token"); 15177 } 15178 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15179 } 15180 } 15181 15182 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15183 // Refuse possible leaked file descriptors 15184 if (intent != null && intent.hasFileDescriptors() == true) { 15185 throw new IllegalArgumentException("File descriptors passed in Intent"); 15186 } 15187 15188 synchronized(this) { 15189 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15190 } 15191 } 15192 15193 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15194 synchronized(this) { 15195 if (!(token instanceof ServiceRecord)) { 15196 throw new IllegalArgumentException("Invalid service token"); 15197 } 15198 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15199 } 15200 } 15201 15202 // ========================================================= 15203 // BACKUP AND RESTORE 15204 // ========================================================= 15205 15206 // Cause the target app to be launched if necessary and its backup agent 15207 // instantiated. The backup agent will invoke backupAgentCreated() on the 15208 // activity manager to announce its creation. 15209 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15210 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15211 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15212 15213 synchronized(this) { 15214 // !!! TODO: currently no check here that we're already bound 15215 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15216 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15217 synchronized (stats) { 15218 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15219 } 15220 15221 // Backup agent is now in use, its package can't be stopped. 15222 try { 15223 AppGlobals.getPackageManager().setPackageStoppedState( 15224 app.packageName, false, UserHandle.getUserId(app.uid)); 15225 } catch (RemoteException e) { 15226 } catch (IllegalArgumentException e) { 15227 Slog.w(TAG, "Failed trying to unstop package " 15228 + app.packageName + ": " + e); 15229 } 15230 15231 BackupRecord r = new BackupRecord(ss, app, backupMode); 15232 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15233 ? new ComponentName(app.packageName, app.backupAgentName) 15234 : new ComponentName("android", "FullBackupAgent"); 15235 // startProcessLocked() returns existing proc's record if it's already running 15236 ProcessRecord proc = startProcessLocked(app.processName, app, 15237 false, 0, "backup", hostingName, false, false, false); 15238 if (proc == null) { 15239 Slog.e(TAG, "Unable to start backup agent process " + r); 15240 return false; 15241 } 15242 15243 r.app = proc; 15244 mBackupTarget = r; 15245 mBackupAppName = app.packageName; 15246 15247 // Try not to kill the process during backup 15248 updateOomAdjLocked(proc); 15249 15250 // If the process is already attached, schedule the creation of the backup agent now. 15251 // If it is not yet live, this will be done when it attaches to the framework. 15252 if (proc.thread != null) { 15253 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15254 try { 15255 proc.thread.scheduleCreateBackupAgent(app, 15256 compatibilityInfoForPackageLocked(app), backupMode); 15257 } catch (RemoteException e) { 15258 // Will time out on the backup manager side 15259 } 15260 } else { 15261 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15262 } 15263 // Invariants: at this point, the target app process exists and the application 15264 // is either already running or in the process of coming up. mBackupTarget and 15265 // mBackupAppName describe the app, so that when it binds back to the AM we 15266 // know that it's scheduled for a backup-agent operation. 15267 } 15268 15269 return true; 15270 } 15271 15272 @Override 15273 public void clearPendingBackup() { 15274 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15275 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15276 15277 synchronized (this) { 15278 mBackupTarget = null; 15279 mBackupAppName = null; 15280 } 15281 } 15282 15283 // A backup agent has just come up 15284 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15285 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15286 + " = " + agent); 15287 15288 synchronized(this) { 15289 if (!agentPackageName.equals(mBackupAppName)) { 15290 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15291 return; 15292 } 15293 } 15294 15295 long oldIdent = Binder.clearCallingIdentity(); 15296 try { 15297 IBackupManager bm = IBackupManager.Stub.asInterface( 15298 ServiceManager.getService(Context.BACKUP_SERVICE)); 15299 bm.agentConnected(agentPackageName, agent); 15300 } catch (RemoteException e) { 15301 // can't happen; the backup manager service is local 15302 } catch (Exception e) { 15303 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15304 e.printStackTrace(); 15305 } finally { 15306 Binder.restoreCallingIdentity(oldIdent); 15307 } 15308 } 15309 15310 // done with this agent 15311 public void unbindBackupAgent(ApplicationInfo appInfo) { 15312 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15313 if (appInfo == null) { 15314 Slog.w(TAG, "unbind backup agent for null app"); 15315 return; 15316 } 15317 15318 synchronized(this) { 15319 try { 15320 if (mBackupAppName == null) { 15321 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15322 return; 15323 } 15324 15325 if (!mBackupAppName.equals(appInfo.packageName)) { 15326 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15327 return; 15328 } 15329 15330 // Not backing this app up any more; reset its OOM adjustment 15331 final ProcessRecord proc = mBackupTarget.app; 15332 updateOomAdjLocked(proc); 15333 15334 // If the app crashed during backup, 'thread' will be null here 15335 if (proc.thread != null) { 15336 try { 15337 proc.thread.scheduleDestroyBackupAgent(appInfo, 15338 compatibilityInfoForPackageLocked(appInfo)); 15339 } catch (Exception e) { 15340 Slog.e(TAG, "Exception when unbinding backup agent:"); 15341 e.printStackTrace(); 15342 } 15343 } 15344 } finally { 15345 mBackupTarget = null; 15346 mBackupAppName = null; 15347 } 15348 } 15349 } 15350 // ========================================================= 15351 // BROADCASTS 15352 // ========================================================= 15353 15354 private final List getStickiesLocked(String action, IntentFilter filter, 15355 List cur, int userId) { 15356 final ContentResolver resolver = mContext.getContentResolver(); 15357 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15358 if (stickies == null) { 15359 return cur; 15360 } 15361 final ArrayList<Intent> list = stickies.get(action); 15362 if (list == null) { 15363 return cur; 15364 } 15365 int N = list.size(); 15366 for (int i=0; i<N; i++) { 15367 Intent intent = list.get(i); 15368 if (filter.match(resolver, intent, true, TAG) >= 0) { 15369 if (cur == null) { 15370 cur = new ArrayList<Intent>(); 15371 } 15372 cur.add(intent); 15373 } 15374 } 15375 return cur; 15376 } 15377 15378 boolean isPendingBroadcastProcessLocked(int pid) { 15379 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15380 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15381 } 15382 15383 void skipPendingBroadcastLocked(int pid) { 15384 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15385 for (BroadcastQueue queue : mBroadcastQueues) { 15386 queue.skipPendingBroadcastLocked(pid); 15387 } 15388 } 15389 15390 // The app just attached; send any pending broadcasts that it should receive 15391 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15392 boolean didSomething = false; 15393 for (BroadcastQueue queue : mBroadcastQueues) { 15394 didSomething |= queue.sendPendingBroadcastsLocked(app); 15395 } 15396 return didSomething; 15397 } 15398 15399 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15400 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15401 enforceNotIsolatedCaller("registerReceiver"); 15402 int callingUid; 15403 int callingPid; 15404 synchronized(this) { 15405 ProcessRecord callerApp = null; 15406 if (caller != null) { 15407 callerApp = getRecordForAppLocked(caller); 15408 if (callerApp == null) { 15409 throw new SecurityException( 15410 "Unable to find app for caller " + caller 15411 + " (pid=" + Binder.getCallingPid() 15412 + ") when registering receiver " + receiver); 15413 } 15414 if (callerApp.info.uid != Process.SYSTEM_UID && 15415 !callerApp.pkgList.containsKey(callerPackage) && 15416 !"android".equals(callerPackage)) { 15417 throw new SecurityException("Given caller package " + callerPackage 15418 + " is not running in process " + callerApp); 15419 } 15420 callingUid = callerApp.info.uid; 15421 callingPid = callerApp.pid; 15422 } else { 15423 callerPackage = null; 15424 callingUid = Binder.getCallingUid(); 15425 callingPid = Binder.getCallingPid(); 15426 } 15427 15428 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15429 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15430 15431 List allSticky = null; 15432 15433 // Look for any matching sticky broadcasts... 15434 Iterator actions = filter.actionsIterator(); 15435 if (actions != null) { 15436 while (actions.hasNext()) { 15437 String action = (String)actions.next(); 15438 allSticky = getStickiesLocked(action, filter, allSticky, 15439 UserHandle.USER_ALL); 15440 allSticky = getStickiesLocked(action, filter, allSticky, 15441 UserHandle.getUserId(callingUid)); 15442 } 15443 } else { 15444 allSticky = getStickiesLocked(null, filter, allSticky, 15445 UserHandle.USER_ALL); 15446 allSticky = getStickiesLocked(null, filter, allSticky, 15447 UserHandle.getUserId(callingUid)); 15448 } 15449 15450 // The first sticky in the list is returned directly back to 15451 // the client. 15452 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15453 15454 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15455 + ": " + sticky); 15456 15457 if (receiver == null) { 15458 return sticky; 15459 } 15460 15461 ReceiverList rl 15462 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15463 if (rl == null) { 15464 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15465 userId, receiver); 15466 if (rl.app != null) { 15467 rl.app.receivers.add(rl); 15468 } else { 15469 try { 15470 receiver.asBinder().linkToDeath(rl, 0); 15471 } catch (RemoteException e) { 15472 return sticky; 15473 } 15474 rl.linkedToDeath = true; 15475 } 15476 mRegisteredReceivers.put(receiver.asBinder(), rl); 15477 } else if (rl.uid != callingUid) { 15478 throw new IllegalArgumentException( 15479 "Receiver requested to register for uid " + callingUid 15480 + " was previously registered for uid " + rl.uid); 15481 } else if (rl.pid != callingPid) { 15482 throw new IllegalArgumentException( 15483 "Receiver requested to register for pid " + callingPid 15484 + " was previously registered for pid " + rl.pid); 15485 } else if (rl.userId != userId) { 15486 throw new IllegalArgumentException( 15487 "Receiver requested to register for user " + userId 15488 + " was previously registered for user " + rl.userId); 15489 } 15490 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15491 permission, callingUid, userId); 15492 rl.add(bf); 15493 if (!bf.debugCheck()) { 15494 Slog.w(TAG, "==> For Dynamic broadast"); 15495 } 15496 mReceiverResolver.addFilter(bf); 15497 15498 // Enqueue broadcasts for all existing stickies that match 15499 // this filter. 15500 if (allSticky != null) { 15501 ArrayList receivers = new ArrayList(); 15502 receivers.add(bf); 15503 15504 int N = allSticky.size(); 15505 for (int i=0; i<N; i++) { 15506 Intent intent = (Intent)allSticky.get(i); 15507 BroadcastQueue queue = broadcastQueueForIntent(intent); 15508 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15509 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15510 null, null, false, true, true, -1); 15511 queue.enqueueParallelBroadcastLocked(r); 15512 queue.scheduleBroadcastsLocked(); 15513 } 15514 } 15515 15516 return sticky; 15517 } 15518 } 15519 15520 public void unregisterReceiver(IIntentReceiver receiver) { 15521 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15522 15523 final long origId = Binder.clearCallingIdentity(); 15524 try { 15525 boolean doTrim = false; 15526 15527 synchronized(this) { 15528 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15529 if (rl != null) { 15530 if (rl.curBroadcast != null) { 15531 BroadcastRecord r = rl.curBroadcast; 15532 final boolean doNext = finishReceiverLocked( 15533 receiver.asBinder(), r.resultCode, r.resultData, 15534 r.resultExtras, r.resultAbort); 15535 if (doNext) { 15536 doTrim = true; 15537 r.queue.processNextBroadcast(false); 15538 } 15539 } 15540 15541 if (rl.app != null) { 15542 rl.app.receivers.remove(rl); 15543 } 15544 removeReceiverLocked(rl); 15545 if (rl.linkedToDeath) { 15546 rl.linkedToDeath = false; 15547 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15548 } 15549 } 15550 } 15551 15552 // If we actually concluded any broadcasts, we might now be able 15553 // to trim the recipients' apps from our working set 15554 if (doTrim) { 15555 trimApplications(); 15556 return; 15557 } 15558 15559 } finally { 15560 Binder.restoreCallingIdentity(origId); 15561 } 15562 } 15563 15564 void removeReceiverLocked(ReceiverList rl) { 15565 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15566 int N = rl.size(); 15567 for (int i=0; i<N; i++) { 15568 mReceiverResolver.removeFilter(rl.get(i)); 15569 } 15570 } 15571 15572 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15573 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15574 ProcessRecord r = mLruProcesses.get(i); 15575 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15576 try { 15577 r.thread.dispatchPackageBroadcast(cmd, packages); 15578 } catch (RemoteException ex) { 15579 } 15580 } 15581 } 15582 } 15583 15584 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15585 int callingUid, int[] users) { 15586 List<ResolveInfo> receivers = null; 15587 try { 15588 HashSet<ComponentName> singleUserReceivers = null; 15589 boolean scannedFirstReceivers = false; 15590 for (int user : users) { 15591 // Skip users that have Shell restrictions 15592 if (callingUid == Process.SHELL_UID 15593 && getUserManagerLocked().hasUserRestriction( 15594 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15595 continue; 15596 } 15597 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15598 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15599 if (user != 0 && newReceivers != null) { 15600 // If this is not the primary user, we need to check for 15601 // any receivers that should be filtered out. 15602 for (int i=0; i<newReceivers.size(); i++) { 15603 ResolveInfo ri = newReceivers.get(i); 15604 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15605 newReceivers.remove(i); 15606 i--; 15607 } 15608 } 15609 } 15610 if (newReceivers != null && newReceivers.size() == 0) { 15611 newReceivers = null; 15612 } 15613 if (receivers == null) { 15614 receivers = newReceivers; 15615 } else if (newReceivers != null) { 15616 // We need to concatenate the additional receivers 15617 // found with what we have do far. This would be easy, 15618 // but we also need to de-dup any receivers that are 15619 // singleUser. 15620 if (!scannedFirstReceivers) { 15621 // Collect any single user receivers we had already retrieved. 15622 scannedFirstReceivers = true; 15623 for (int i=0; i<receivers.size(); i++) { 15624 ResolveInfo ri = receivers.get(i); 15625 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15626 ComponentName cn = new ComponentName( 15627 ri.activityInfo.packageName, ri.activityInfo.name); 15628 if (singleUserReceivers == null) { 15629 singleUserReceivers = new HashSet<ComponentName>(); 15630 } 15631 singleUserReceivers.add(cn); 15632 } 15633 } 15634 } 15635 // Add the new results to the existing results, tracking 15636 // and de-dupping single user receivers. 15637 for (int i=0; i<newReceivers.size(); i++) { 15638 ResolveInfo ri = newReceivers.get(i); 15639 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15640 ComponentName cn = new ComponentName( 15641 ri.activityInfo.packageName, ri.activityInfo.name); 15642 if (singleUserReceivers == null) { 15643 singleUserReceivers = new HashSet<ComponentName>(); 15644 } 15645 if (!singleUserReceivers.contains(cn)) { 15646 singleUserReceivers.add(cn); 15647 receivers.add(ri); 15648 } 15649 } else { 15650 receivers.add(ri); 15651 } 15652 } 15653 } 15654 } 15655 } catch (RemoteException ex) { 15656 // pm is in same process, this will never happen. 15657 } 15658 return receivers; 15659 } 15660 15661 private final int broadcastIntentLocked(ProcessRecord callerApp, 15662 String callerPackage, Intent intent, String resolvedType, 15663 IIntentReceiver resultTo, int resultCode, String resultData, 15664 Bundle map, String requiredPermission, int appOp, 15665 boolean ordered, boolean sticky, int callingPid, int callingUid, 15666 int userId) { 15667 intent = new Intent(intent); 15668 15669 // By default broadcasts do not go to stopped apps. 15670 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15671 15672 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15673 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15674 + " ordered=" + ordered + " userid=" + userId); 15675 if ((resultTo != null) && !ordered) { 15676 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15677 } 15678 15679 userId = handleIncomingUser(callingPid, callingUid, userId, 15680 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15681 15682 // Make sure that the user who is receiving this broadcast is started. 15683 // If not, we will just skip it. 15684 15685 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15686 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15687 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15688 Slog.w(TAG, "Skipping broadcast of " + intent 15689 + ": user " + userId + " is stopped"); 15690 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15691 } 15692 } 15693 15694 /* 15695 * Prevent non-system code (defined here to be non-persistent 15696 * processes) from sending protected broadcasts. 15697 */ 15698 int callingAppId = UserHandle.getAppId(callingUid); 15699 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15700 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15701 || callingAppId == Process.NFC_UID || callingUid == 0) { 15702 // Always okay. 15703 } else if (callerApp == null || !callerApp.persistent) { 15704 try { 15705 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15706 intent.getAction())) { 15707 String msg = "Permission Denial: not allowed to send broadcast " 15708 + intent.getAction() + " from pid=" 15709 + callingPid + ", uid=" + callingUid; 15710 Slog.w(TAG, msg); 15711 throw new SecurityException(msg); 15712 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15713 // Special case for compatibility: we don't want apps to send this, 15714 // but historically it has not been protected and apps may be using it 15715 // to poke their own app widget. So, instead of making it protected, 15716 // just limit it to the caller. 15717 if (callerApp == null) { 15718 String msg = "Permission Denial: not allowed to send broadcast " 15719 + intent.getAction() + " from unknown caller."; 15720 Slog.w(TAG, msg); 15721 throw new SecurityException(msg); 15722 } else if (intent.getComponent() != null) { 15723 // They are good enough to send to an explicit component... verify 15724 // it is being sent to the calling app. 15725 if (!intent.getComponent().getPackageName().equals( 15726 callerApp.info.packageName)) { 15727 String msg = "Permission Denial: not allowed to send broadcast " 15728 + intent.getAction() + " to " 15729 + intent.getComponent().getPackageName() + " from " 15730 + callerApp.info.packageName; 15731 Slog.w(TAG, msg); 15732 throw new SecurityException(msg); 15733 } 15734 } else { 15735 // Limit broadcast to their own package. 15736 intent.setPackage(callerApp.info.packageName); 15737 } 15738 } 15739 } catch (RemoteException e) { 15740 Slog.w(TAG, "Remote exception", e); 15741 return ActivityManager.BROADCAST_SUCCESS; 15742 } 15743 } 15744 15745 final String action = intent.getAction(); 15746 if (action != null) { 15747 switch (action) { 15748 case Intent.ACTION_UID_REMOVED: 15749 case Intent.ACTION_PACKAGE_REMOVED: 15750 case Intent.ACTION_PACKAGE_CHANGED: 15751 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15752 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15753 // Handle special intents: if this broadcast is from the package 15754 // manager about a package being removed, we need to remove all of 15755 // its activities from the history stack. 15756 if (checkComponentPermission( 15757 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15758 callingPid, callingUid, -1, true) 15759 != PackageManager.PERMISSION_GRANTED) { 15760 String msg = "Permission Denial: " + intent.getAction() 15761 + " broadcast from " + callerPackage + " (pid=" + callingPid 15762 + ", uid=" + callingUid + ")" 15763 + " requires " 15764 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15765 Slog.w(TAG, msg); 15766 throw new SecurityException(msg); 15767 } 15768 switch (action) { 15769 case Intent.ACTION_UID_REMOVED: 15770 final Bundle intentExtras = intent.getExtras(); 15771 final int uid = intentExtras != null 15772 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15773 if (uid >= 0) { 15774 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15775 synchronized (bs) { 15776 bs.removeUidStatsLocked(uid); 15777 } 15778 mAppOpsService.uidRemoved(uid); 15779 } 15780 break; 15781 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15782 // If resources are unavailable just force stop all those packages 15783 // and flush the attribute cache as well. 15784 String list[] = 15785 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15786 if (list != null && list.length > 0) { 15787 for (int i = 0; i < list.length; i++) { 15788 forceStopPackageLocked(list[i], -1, false, true, true, 15789 false, false, userId, "storage unmount"); 15790 } 15791 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15792 sendPackageBroadcastLocked( 15793 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15794 userId); 15795 } 15796 break; 15797 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15798 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15799 break; 15800 case Intent.ACTION_PACKAGE_REMOVED: 15801 case Intent.ACTION_PACKAGE_CHANGED: 15802 Uri data = intent.getData(); 15803 String ssp; 15804 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15805 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15806 boolean fullUninstall = removed && 15807 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15808 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15809 forceStopPackageLocked(ssp, UserHandle.getAppId( 15810 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15811 false, true, true, false, fullUninstall, userId, 15812 removed ? "pkg removed" : "pkg changed"); 15813 } 15814 if (removed) { 15815 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15816 new String[] {ssp}, userId); 15817 if (fullUninstall) { 15818 mAppOpsService.packageRemoved( 15819 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15820 15821 // Remove all permissions granted from/to this package 15822 removeUriPermissionsForPackageLocked(ssp, userId, true); 15823 15824 removeTasksByPackageNameLocked(ssp, userId); 15825 } 15826 } else { 15827 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15828 if (userId == UserHandle.USER_OWNER) { 15829 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15830 } 15831 } 15832 } 15833 break; 15834 } 15835 break; 15836 case Intent.ACTION_PACKAGE_ADDED: 15837 // Special case for adding a package: by default turn on compatibility mode. 15838 Uri data = intent.getData(); 15839 String ssp; 15840 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15841 final boolean replacing = 15842 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15843 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15844 15845 if (replacing) { 15846 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15847 } 15848 if (userId == UserHandle.USER_OWNER) { 15849 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15850 } 15851 } 15852 break; 15853 case Intent.ACTION_TIMEZONE_CHANGED: 15854 // If this is the time zone changed action, queue up a message that will reset 15855 // the timezone of all currently running processes. This message will get 15856 // queued up before the broadcast happens. 15857 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15858 break; 15859 case Intent.ACTION_TIME_CHANGED: 15860 // If the user set the time, let all running processes know. 15861 final int is24Hour = 15862 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15863 : 0; 15864 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15865 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15866 synchronized (stats) { 15867 stats.noteCurrentTimeChangedLocked(); 15868 } 15869 break; 15870 case Intent.ACTION_CLEAR_DNS_CACHE: 15871 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15872 break; 15873 case Proxy.PROXY_CHANGE_ACTION: 15874 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15875 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15876 break; 15877 } 15878 } 15879 15880 // Add to the sticky list if requested. 15881 if (sticky) { 15882 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15883 callingPid, callingUid) 15884 != PackageManager.PERMISSION_GRANTED) { 15885 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15886 + callingPid + ", uid=" + callingUid 15887 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15888 Slog.w(TAG, msg); 15889 throw new SecurityException(msg); 15890 } 15891 if (requiredPermission != null) { 15892 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15893 + " and enforce permission " + requiredPermission); 15894 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15895 } 15896 if (intent.getComponent() != null) { 15897 throw new SecurityException( 15898 "Sticky broadcasts can't target a specific component"); 15899 } 15900 // We use userId directly here, since the "all" target is maintained 15901 // as a separate set of sticky broadcasts. 15902 if (userId != UserHandle.USER_ALL) { 15903 // But first, if this is not a broadcast to all users, then 15904 // make sure it doesn't conflict with an existing broadcast to 15905 // all users. 15906 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15907 UserHandle.USER_ALL); 15908 if (stickies != null) { 15909 ArrayList<Intent> list = stickies.get(intent.getAction()); 15910 if (list != null) { 15911 int N = list.size(); 15912 int i; 15913 for (i=0; i<N; i++) { 15914 if (intent.filterEquals(list.get(i))) { 15915 throw new IllegalArgumentException( 15916 "Sticky broadcast " + intent + " for user " 15917 + userId + " conflicts with existing global broadcast"); 15918 } 15919 } 15920 } 15921 } 15922 } 15923 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15924 if (stickies == null) { 15925 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15926 mStickyBroadcasts.put(userId, stickies); 15927 } 15928 ArrayList<Intent> list = stickies.get(intent.getAction()); 15929 if (list == null) { 15930 list = new ArrayList<Intent>(); 15931 stickies.put(intent.getAction(), list); 15932 } 15933 int N = list.size(); 15934 int i; 15935 for (i=0; i<N; i++) { 15936 if (intent.filterEquals(list.get(i))) { 15937 // This sticky already exists, replace it. 15938 list.set(i, new Intent(intent)); 15939 break; 15940 } 15941 } 15942 if (i >= N) { 15943 list.add(new Intent(intent)); 15944 } 15945 } 15946 15947 int[] users; 15948 if (userId == UserHandle.USER_ALL) { 15949 // Caller wants broadcast to go to all started users. 15950 users = mStartedUserArray; 15951 } else { 15952 // Caller wants broadcast to go to one specific user. 15953 users = new int[] {userId}; 15954 } 15955 15956 // Figure out who all will receive this broadcast. 15957 List receivers = null; 15958 List<BroadcastFilter> registeredReceivers = null; 15959 // Need to resolve the intent to interested receivers... 15960 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15961 == 0) { 15962 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15963 } 15964 if (intent.getComponent() == null) { 15965 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15966 // Query one target user at a time, excluding shell-restricted users 15967 UserManagerService ums = getUserManagerLocked(); 15968 for (int i = 0; i < users.length; i++) { 15969 if (ums.hasUserRestriction( 15970 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15971 continue; 15972 } 15973 List<BroadcastFilter> registeredReceiversForUser = 15974 mReceiverResolver.queryIntent(intent, 15975 resolvedType, false, users[i]); 15976 if (registeredReceivers == null) { 15977 registeredReceivers = registeredReceiversForUser; 15978 } else if (registeredReceiversForUser != null) { 15979 registeredReceivers.addAll(registeredReceiversForUser); 15980 } 15981 } 15982 } else { 15983 registeredReceivers = mReceiverResolver.queryIntent(intent, 15984 resolvedType, false, userId); 15985 } 15986 } 15987 15988 final boolean replacePending = 15989 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15990 15991 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15992 + " replacePending=" + replacePending); 15993 15994 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15995 if (!ordered && NR > 0) { 15996 // If we are not serializing this broadcast, then send the 15997 // registered receivers separately so they don't wait for the 15998 // components to be launched. 15999 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16000 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16001 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16002 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16003 ordered, sticky, false, userId); 16004 if (DEBUG_BROADCAST) Slog.v( 16005 TAG, "Enqueueing parallel broadcast " + r); 16006 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16007 if (!replaced) { 16008 queue.enqueueParallelBroadcastLocked(r); 16009 queue.scheduleBroadcastsLocked(); 16010 } 16011 registeredReceivers = null; 16012 NR = 0; 16013 } 16014 16015 // Merge into one list. 16016 int ir = 0; 16017 if (receivers != null) { 16018 // A special case for PACKAGE_ADDED: do not allow the package 16019 // being added to see this broadcast. This prevents them from 16020 // using this as a back door to get run as soon as they are 16021 // installed. Maybe in the future we want to have a special install 16022 // broadcast or such for apps, but we'd like to deliberately make 16023 // this decision. 16024 String skipPackages[] = null; 16025 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16026 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16027 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16028 Uri data = intent.getData(); 16029 if (data != null) { 16030 String pkgName = data.getSchemeSpecificPart(); 16031 if (pkgName != null) { 16032 skipPackages = new String[] { pkgName }; 16033 } 16034 } 16035 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16036 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16037 } 16038 if (skipPackages != null && (skipPackages.length > 0)) { 16039 for (String skipPackage : skipPackages) { 16040 if (skipPackage != null) { 16041 int NT = receivers.size(); 16042 for (int it=0; it<NT; it++) { 16043 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16044 if (curt.activityInfo.packageName.equals(skipPackage)) { 16045 receivers.remove(it); 16046 it--; 16047 NT--; 16048 } 16049 } 16050 } 16051 } 16052 } 16053 16054 int NT = receivers != null ? receivers.size() : 0; 16055 int it = 0; 16056 ResolveInfo curt = null; 16057 BroadcastFilter curr = null; 16058 while (it < NT && ir < NR) { 16059 if (curt == null) { 16060 curt = (ResolveInfo)receivers.get(it); 16061 } 16062 if (curr == null) { 16063 curr = registeredReceivers.get(ir); 16064 } 16065 if (curr.getPriority() >= curt.priority) { 16066 // Insert this broadcast record into the final list. 16067 receivers.add(it, curr); 16068 ir++; 16069 curr = null; 16070 it++; 16071 NT++; 16072 } else { 16073 // Skip to the next ResolveInfo in the final list. 16074 it++; 16075 curt = null; 16076 } 16077 } 16078 } 16079 while (ir < NR) { 16080 if (receivers == null) { 16081 receivers = new ArrayList(); 16082 } 16083 receivers.add(registeredReceivers.get(ir)); 16084 ir++; 16085 } 16086 16087 if ((receivers != null && receivers.size() > 0) 16088 || resultTo != null) { 16089 BroadcastQueue queue = broadcastQueueForIntent(intent); 16090 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16091 callerPackage, callingPid, callingUid, resolvedType, 16092 requiredPermission, appOp, receivers, resultTo, resultCode, 16093 resultData, map, ordered, sticky, false, userId); 16094 if (DEBUG_BROADCAST) Slog.v( 16095 TAG, "Enqueueing ordered broadcast " + r 16096 + ": prev had " + queue.mOrderedBroadcasts.size()); 16097 if (DEBUG_BROADCAST) { 16098 int seq = r.intent.getIntExtra("seq", -1); 16099 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16100 } 16101 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16102 if (!replaced) { 16103 queue.enqueueOrderedBroadcastLocked(r); 16104 queue.scheduleBroadcastsLocked(); 16105 } 16106 } 16107 16108 return ActivityManager.BROADCAST_SUCCESS; 16109 } 16110 16111 final Intent verifyBroadcastLocked(Intent intent) { 16112 // Refuse possible leaked file descriptors 16113 if (intent != null && intent.hasFileDescriptors() == true) { 16114 throw new IllegalArgumentException("File descriptors passed in Intent"); 16115 } 16116 16117 int flags = intent.getFlags(); 16118 16119 if (!mProcessesReady) { 16120 // if the caller really truly claims to know what they're doing, go 16121 // ahead and allow the broadcast without launching any receivers 16122 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16123 intent = new Intent(intent); 16124 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16125 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16126 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16127 + " before boot completion"); 16128 throw new IllegalStateException("Cannot broadcast before boot completed"); 16129 } 16130 } 16131 16132 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16133 throw new IllegalArgumentException( 16134 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16135 } 16136 16137 return intent; 16138 } 16139 16140 public final int broadcastIntent(IApplicationThread caller, 16141 Intent intent, String resolvedType, IIntentReceiver resultTo, 16142 int resultCode, String resultData, Bundle map, 16143 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16144 enforceNotIsolatedCaller("broadcastIntent"); 16145 synchronized(this) { 16146 intent = verifyBroadcastLocked(intent); 16147 16148 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16149 final int callingPid = Binder.getCallingPid(); 16150 final int callingUid = Binder.getCallingUid(); 16151 final long origId = Binder.clearCallingIdentity(); 16152 int res = broadcastIntentLocked(callerApp, 16153 callerApp != null ? callerApp.info.packageName : null, 16154 intent, resolvedType, resultTo, 16155 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16156 callingPid, callingUid, userId); 16157 Binder.restoreCallingIdentity(origId); 16158 return res; 16159 } 16160 } 16161 16162 int broadcastIntentInPackage(String packageName, int uid, 16163 Intent intent, String resolvedType, IIntentReceiver resultTo, 16164 int resultCode, String resultData, Bundle map, 16165 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16166 synchronized(this) { 16167 intent = verifyBroadcastLocked(intent); 16168 16169 final long origId = Binder.clearCallingIdentity(); 16170 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16171 resultTo, resultCode, resultData, map, requiredPermission, 16172 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16173 Binder.restoreCallingIdentity(origId); 16174 return res; 16175 } 16176 } 16177 16178 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16179 // Refuse possible leaked file descriptors 16180 if (intent != null && intent.hasFileDescriptors() == true) { 16181 throw new IllegalArgumentException("File descriptors passed in Intent"); 16182 } 16183 16184 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16185 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16186 16187 synchronized(this) { 16188 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16189 != PackageManager.PERMISSION_GRANTED) { 16190 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16191 + Binder.getCallingPid() 16192 + ", uid=" + Binder.getCallingUid() 16193 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16194 Slog.w(TAG, msg); 16195 throw new SecurityException(msg); 16196 } 16197 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16198 if (stickies != null) { 16199 ArrayList<Intent> list = stickies.get(intent.getAction()); 16200 if (list != null) { 16201 int N = list.size(); 16202 int i; 16203 for (i=0; i<N; i++) { 16204 if (intent.filterEquals(list.get(i))) { 16205 list.remove(i); 16206 break; 16207 } 16208 } 16209 if (list.size() <= 0) { 16210 stickies.remove(intent.getAction()); 16211 } 16212 } 16213 if (stickies.size() <= 0) { 16214 mStickyBroadcasts.remove(userId); 16215 } 16216 } 16217 } 16218 } 16219 16220 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16221 String resultData, Bundle resultExtras, boolean resultAbort) { 16222 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16223 if (r == null) { 16224 Slog.w(TAG, "finishReceiver called but not found on queue"); 16225 return false; 16226 } 16227 16228 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16229 } 16230 16231 void backgroundServicesFinishedLocked(int userId) { 16232 for (BroadcastQueue queue : mBroadcastQueues) { 16233 queue.backgroundServicesFinishedLocked(userId); 16234 } 16235 } 16236 16237 public void finishReceiver(IBinder who, int resultCode, String resultData, 16238 Bundle resultExtras, boolean resultAbort) { 16239 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16240 16241 // Refuse possible leaked file descriptors 16242 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16243 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16244 } 16245 16246 final long origId = Binder.clearCallingIdentity(); 16247 try { 16248 boolean doNext = false; 16249 BroadcastRecord r; 16250 16251 synchronized(this) { 16252 r = broadcastRecordForReceiverLocked(who); 16253 if (r != null) { 16254 doNext = r.queue.finishReceiverLocked(r, resultCode, 16255 resultData, resultExtras, resultAbort, true); 16256 } 16257 } 16258 16259 if (doNext) { 16260 r.queue.processNextBroadcast(false); 16261 } 16262 trimApplications(); 16263 } finally { 16264 Binder.restoreCallingIdentity(origId); 16265 } 16266 } 16267 16268 // ========================================================= 16269 // INSTRUMENTATION 16270 // ========================================================= 16271 16272 public boolean startInstrumentation(ComponentName className, 16273 String profileFile, int flags, Bundle arguments, 16274 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16275 int userId, String abiOverride) { 16276 enforceNotIsolatedCaller("startInstrumentation"); 16277 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16278 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16279 // Refuse possible leaked file descriptors 16280 if (arguments != null && arguments.hasFileDescriptors()) { 16281 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16282 } 16283 16284 synchronized(this) { 16285 InstrumentationInfo ii = null; 16286 ApplicationInfo ai = null; 16287 try { 16288 ii = mContext.getPackageManager().getInstrumentationInfo( 16289 className, STOCK_PM_FLAGS); 16290 ai = AppGlobals.getPackageManager().getApplicationInfo( 16291 ii.targetPackage, STOCK_PM_FLAGS, userId); 16292 } catch (PackageManager.NameNotFoundException e) { 16293 } catch (RemoteException e) { 16294 } 16295 if (ii == null) { 16296 reportStartInstrumentationFailure(watcher, className, 16297 "Unable to find instrumentation info for: " + className); 16298 return false; 16299 } 16300 if (ai == null) { 16301 reportStartInstrumentationFailure(watcher, className, 16302 "Unable to find instrumentation target package: " + ii.targetPackage); 16303 return false; 16304 } 16305 16306 int match = mContext.getPackageManager().checkSignatures( 16307 ii.targetPackage, ii.packageName); 16308 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16309 String msg = "Permission Denial: starting instrumentation " 16310 + className + " from pid=" 16311 + Binder.getCallingPid() 16312 + ", uid=" + Binder.getCallingPid() 16313 + " not allowed because package " + ii.packageName 16314 + " does not have a signature matching the target " 16315 + ii.targetPackage; 16316 reportStartInstrumentationFailure(watcher, className, msg); 16317 throw new SecurityException(msg); 16318 } 16319 16320 final long origId = Binder.clearCallingIdentity(); 16321 // Instrumentation can kill and relaunch even persistent processes 16322 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16323 "start instr"); 16324 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16325 app.instrumentationClass = className; 16326 app.instrumentationInfo = ai; 16327 app.instrumentationProfileFile = profileFile; 16328 app.instrumentationArguments = arguments; 16329 app.instrumentationWatcher = watcher; 16330 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16331 app.instrumentationResultClass = className; 16332 Binder.restoreCallingIdentity(origId); 16333 } 16334 16335 return true; 16336 } 16337 16338 /** 16339 * Report errors that occur while attempting to start Instrumentation. Always writes the 16340 * error to the logs, but if somebody is watching, send the report there too. This enables 16341 * the "am" command to report errors with more information. 16342 * 16343 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16344 * @param cn The component name of the instrumentation. 16345 * @param report The error report. 16346 */ 16347 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16348 ComponentName cn, String report) { 16349 Slog.w(TAG, report); 16350 try { 16351 if (watcher != null) { 16352 Bundle results = new Bundle(); 16353 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16354 results.putString("Error", report); 16355 watcher.instrumentationStatus(cn, -1, results); 16356 } 16357 } catch (RemoteException e) { 16358 Slog.w(TAG, e); 16359 } 16360 } 16361 16362 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16363 if (app.instrumentationWatcher != null) { 16364 try { 16365 // NOTE: IInstrumentationWatcher *must* be oneway here 16366 app.instrumentationWatcher.instrumentationFinished( 16367 app.instrumentationClass, 16368 resultCode, 16369 results); 16370 } catch (RemoteException e) { 16371 } 16372 } 16373 if (app.instrumentationUiAutomationConnection != null) { 16374 try { 16375 app.instrumentationUiAutomationConnection.shutdown(); 16376 } catch (RemoteException re) { 16377 /* ignore */ 16378 } 16379 // Only a UiAutomation can set this flag and now that 16380 // it is finished we make sure it is reset to its default. 16381 mUserIsMonkey = false; 16382 } 16383 app.instrumentationWatcher = null; 16384 app.instrumentationUiAutomationConnection = null; 16385 app.instrumentationClass = null; 16386 app.instrumentationInfo = null; 16387 app.instrumentationProfileFile = null; 16388 app.instrumentationArguments = null; 16389 16390 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16391 "finished inst"); 16392 } 16393 16394 public void finishInstrumentation(IApplicationThread target, 16395 int resultCode, Bundle results) { 16396 int userId = UserHandle.getCallingUserId(); 16397 // Refuse possible leaked file descriptors 16398 if (results != null && results.hasFileDescriptors()) { 16399 throw new IllegalArgumentException("File descriptors passed in Intent"); 16400 } 16401 16402 synchronized(this) { 16403 ProcessRecord app = getRecordForAppLocked(target); 16404 if (app == null) { 16405 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16406 return; 16407 } 16408 final long origId = Binder.clearCallingIdentity(); 16409 finishInstrumentationLocked(app, resultCode, results); 16410 Binder.restoreCallingIdentity(origId); 16411 } 16412 } 16413 16414 // ========================================================= 16415 // CONFIGURATION 16416 // ========================================================= 16417 16418 public ConfigurationInfo getDeviceConfigurationInfo() { 16419 ConfigurationInfo config = new ConfigurationInfo(); 16420 synchronized (this) { 16421 config.reqTouchScreen = mConfiguration.touchscreen; 16422 config.reqKeyboardType = mConfiguration.keyboard; 16423 config.reqNavigation = mConfiguration.navigation; 16424 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16425 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16426 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16427 } 16428 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16429 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16430 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16431 } 16432 config.reqGlEsVersion = GL_ES_VERSION; 16433 } 16434 return config; 16435 } 16436 16437 ActivityStack getFocusedStack() { 16438 return mStackSupervisor.getFocusedStack(); 16439 } 16440 16441 public Configuration getConfiguration() { 16442 Configuration ci; 16443 synchronized(this) { 16444 ci = new Configuration(mConfiguration); 16445 } 16446 return ci; 16447 } 16448 16449 public void updatePersistentConfiguration(Configuration values) { 16450 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16451 "updateConfiguration()"); 16452 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16453 "updateConfiguration()"); 16454 if (values == null) { 16455 throw new NullPointerException("Configuration must not be null"); 16456 } 16457 16458 synchronized(this) { 16459 final long origId = Binder.clearCallingIdentity(); 16460 updateConfigurationLocked(values, null, true, false); 16461 Binder.restoreCallingIdentity(origId); 16462 } 16463 } 16464 16465 public void updateConfiguration(Configuration values) { 16466 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16467 "updateConfiguration()"); 16468 16469 synchronized(this) { 16470 if (values == null && mWindowManager != null) { 16471 // sentinel: fetch the current configuration from the window manager 16472 values = mWindowManager.computeNewConfiguration(); 16473 } 16474 16475 if (mWindowManager != null) { 16476 mProcessList.applyDisplaySize(mWindowManager); 16477 } 16478 16479 final long origId = Binder.clearCallingIdentity(); 16480 if (values != null) { 16481 Settings.System.clearConfiguration(values); 16482 } 16483 updateConfigurationLocked(values, null, false, false); 16484 Binder.restoreCallingIdentity(origId); 16485 } 16486 } 16487 16488 /** 16489 * Do either or both things: (1) change the current configuration, and (2) 16490 * make sure the given activity is running with the (now) current 16491 * configuration. Returns true if the activity has been left running, or 16492 * false if <var>starting</var> is being destroyed to match the new 16493 * configuration. 16494 * @param persistent TODO 16495 */ 16496 boolean updateConfigurationLocked(Configuration values, 16497 ActivityRecord starting, boolean persistent, boolean initLocale) { 16498 int changes = 0; 16499 16500 if (values != null) { 16501 Configuration newConfig = new Configuration(mConfiguration); 16502 changes = newConfig.updateFrom(values); 16503 if (changes != 0) { 16504 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16505 Slog.i(TAG, "Updating configuration to: " + values); 16506 } 16507 16508 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16509 16510 if (values.locale != null && !initLocale) { 16511 saveLocaleLocked(values.locale, 16512 !values.locale.equals(mConfiguration.locale), 16513 values.userSetLocale); 16514 } 16515 16516 mConfigurationSeq++; 16517 if (mConfigurationSeq <= 0) { 16518 mConfigurationSeq = 1; 16519 } 16520 newConfig.seq = mConfigurationSeq; 16521 mConfiguration = newConfig; 16522 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16523 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16524 //mUsageStatsService.noteStartConfig(newConfig); 16525 16526 final Configuration configCopy = new Configuration(mConfiguration); 16527 16528 // TODO: If our config changes, should we auto dismiss any currently 16529 // showing dialogs? 16530 mShowDialogs = shouldShowDialogs(newConfig); 16531 16532 AttributeCache ac = AttributeCache.instance(); 16533 if (ac != null) { 16534 ac.updateConfiguration(configCopy); 16535 } 16536 16537 // Make sure all resources in our process are updated 16538 // right now, so that anyone who is going to retrieve 16539 // resource values after we return will be sure to get 16540 // the new ones. This is especially important during 16541 // boot, where the first config change needs to guarantee 16542 // all resources have that config before following boot 16543 // code is executed. 16544 mSystemThread.applyConfigurationToResources(configCopy); 16545 16546 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16547 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16548 msg.obj = new Configuration(configCopy); 16549 mHandler.sendMessage(msg); 16550 } 16551 16552 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16553 ProcessRecord app = mLruProcesses.get(i); 16554 try { 16555 if (app.thread != null) { 16556 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16557 + app.processName + " new config " + mConfiguration); 16558 app.thread.scheduleConfigurationChanged(configCopy); 16559 } 16560 } catch (Exception e) { 16561 } 16562 } 16563 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16564 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16565 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16566 | Intent.FLAG_RECEIVER_FOREGROUND); 16567 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16568 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16569 Process.SYSTEM_UID, UserHandle.USER_ALL); 16570 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16571 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16572 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16573 broadcastIntentLocked(null, null, intent, 16574 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16575 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16576 } 16577 } 16578 } 16579 16580 boolean kept = true; 16581 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16582 // mainStack is null during startup. 16583 if (mainStack != null) { 16584 if (changes != 0 && starting == null) { 16585 // If the configuration changed, and the caller is not already 16586 // in the process of starting an activity, then find the top 16587 // activity to check if its configuration needs to change. 16588 starting = mainStack.topRunningActivityLocked(null); 16589 } 16590 16591 if (starting != null) { 16592 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16593 // And we need to make sure at this point that all other activities 16594 // are made visible with the correct configuration. 16595 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16596 } 16597 } 16598 16599 if (values != null && mWindowManager != null) { 16600 mWindowManager.setNewConfiguration(mConfiguration); 16601 } 16602 16603 return kept; 16604 } 16605 16606 /** 16607 * Decide based on the configuration whether we should shouw the ANR, 16608 * crash, etc dialogs. The idea is that if there is no affordnace to 16609 * press the on-screen buttons, we shouldn't show the dialog. 16610 * 16611 * A thought: SystemUI might also want to get told about this, the Power 16612 * dialog / global actions also might want different behaviors. 16613 */ 16614 private static final boolean shouldShowDialogs(Configuration config) { 16615 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16616 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16617 } 16618 16619 /** 16620 * Save the locale. You must be inside a synchronized (this) block. 16621 */ 16622 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16623 if(isDiff) { 16624 SystemProperties.set("user.language", l.getLanguage()); 16625 SystemProperties.set("user.region", l.getCountry()); 16626 } 16627 16628 if(isPersist) { 16629 SystemProperties.set("persist.sys.language", l.getLanguage()); 16630 SystemProperties.set("persist.sys.country", l.getCountry()); 16631 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16632 16633 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16634 } 16635 } 16636 16637 @Override 16638 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16639 synchronized (this) { 16640 ActivityRecord srec = ActivityRecord.forToken(token); 16641 if (srec.task != null && srec.task.stack != null) { 16642 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16643 } 16644 } 16645 return false; 16646 } 16647 16648 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16649 Intent resultData) { 16650 16651 synchronized (this) { 16652 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16653 if (stack != null) { 16654 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16655 } 16656 return false; 16657 } 16658 } 16659 16660 public int getLaunchedFromUid(IBinder activityToken) { 16661 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16662 if (srec == null) { 16663 return -1; 16664 } 16665 return srec.launchedFromUid; 16666 } 16667 16668 public String getLaunchedFromPackage(IBinder activityToken) { 16669 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16670 if (srec == null) { 16671 return null; 16672 } 16673 return srec.launchedFromPackage; 16674 } 16675 16676 // ========================================================= 16677 // LIFETIME MANAGEMENT 16678 // ========================================================= 16679 16680 // Returns which broadcast queue the app is the current [or imminent] receiver 16681 // on, or 'null' if the app is not an active broadcast recipient. 16682 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16683 BroadcastRecord r = app.curReceiver; 16684 if (r != null) { 16685 return r.queue; 16686 } 16687 16688 // It's not the current receiver, but it might be starting up to become one 16689 synchronized (this) { 16690 for (BroadcastQueue queue : mBroadcastQueues) { 16691 r = queue.mPendingBroadcast; 16692 if (r != null && r.curApp == app) { 16693 // found it; report which queue it's in 16694 return queue; 16695 } 16696 } 16697 } 16698 16699 return null; 16700 } 16701 16702 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16703 boolean doingAll, long now) { 16704 if (mAdjSeq == app.adjSeq) { 16705 // This adjustment has already been computed. 16706 return app.curRawAdj; 16707 } 16708 16709 if (app.thread == null) { 16710 app.adjSeq = mAdjSeq; 16711 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16712 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16713 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16714 } 16715 16716 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16717 app.adjSource = null; 16718 app.adjTarget = null; 16719 app.empty = false; 16720 app.cached = false; 16721 16722 final int activitiesSize = app.activities.size(); 16723 16724 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16725 // The max adjustment doesn't allow this app to be anything 16726 // below foreground, so it is not worth doing work for it. 16727 app.adjType = "fixed"; 16728 app.adjSeq = mAdjSeq; 16729 app.curRawAdj = app.maxAdj; 16730 app.foregroundActivities = false; 16731 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16732 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16733 // System processes can do UI, and when they do we want to have 16734 // them trim their memory after the user leaves the UI. To 16735 // facilitate this, here we need to determine whether or not it 16736 // is currently showing UI. 16737 app.systemNoUi = true; 16738 if (app == TOP_APP) { 16739 app.systemNoUi = false; 16740 } else if (activitiesSize > 0) { 16741 for (int j = 0; j < activitiesSize; j++) { 16742 final ActivityRecord r = app.activities.get(j); 16743 if (r.visible) { 16744 app.systemNoUi = false; 16745 } 16746 } 16747 } 16748 if (!app.systemNoUi) { 16749 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16750 } 16751 return (app.curAdj=app.maxAdj); 16752 } 16753 16754 app.systemNoUi = false; 16755 16756 // Determine the importance of the process, starting with most 16757 // important to least, and assign an appropriate OOM adjustment. 16758 int adj; 16759 int schedGroup; 16760 int procState; 16761 boolean foregroundActivities = false; 16762 BroadcastQueue queue; 16763 if (app == TOP_APP) { 16764 // The last app on the list is the foreground app. 16765 adj = ProcessList.FOREGROUND_APP_ADJ; 16766 schedGroup = Process.THREAD_GROUP_DEFAULT; 16767 app.adjType = "top-activity"; 16768 foregroundActivities = true; 16769 procState = ActivityManager.PROCESS_STATE_TOP; 16770 } else if (app.instrumentationClass != null) { 16771 // Don't want to kill running instrumentation. 16772 adj = ProcessList.FOREGROUND_APP_ADJ; 16773 schedGroup = Process.THREAD_GROUP_DEFAULT; 16774 app.adjType = "instrumentation"; 16775 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16776 } else if ((queue = isReceivingBroadcast(app)) != null) { 16777 // An app that is currently receiving a broadcast also 16778 // counts as being in the foreground for OOM killer purposes. 16779 // It's placed in a sched group based on the nature of the 16780 // broadcast as reflected by which queue it's active in. 16781 adj = ProcessList.FOREGROUND_APP_ADJ; 16782 schedGroup = (queue == mFgBroadcastQueue) 16783 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16784 app.adjType = "broadcast"; 16785 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16786 } else if (app.executingServices.size() > 0) { 16787 // An app that is currently executing a service callback also 16788 // counts as being in the foreground. 16789 adj = ProcessList.FOREGROUND_APP_ADJ; 16790 schedGroup = app.execServicesFg ? 16791 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16792 app.adjType = "exec-service"; 16793 procState = ActivityManager.PROCESS_STATE_SERVICE; 16794 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16795 } else { 16796 // As far as we know the process is empty. We may change our mind later. 16797 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16798 // At this point we don't actually know the adjustment. Use the cached adj 16799 // value that the caller wants us to. 16800 adj = cachedAdj; 16801 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16802 app.cached = true; 16803 app.empty = true; 16804 app.adjType = "cch-empty"; 16805 } 16806 16807 // Examine all activities if not already foreground. 16808 if (!foregroundActivities && activitiesSize > 0) { 16809 for (int j = 0; j < activitiesSize; j++) { 16810 final ActivityRecord r = app.activities.get(j); 16811 if (r.app != app) { 16812 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16813 + app + "?!?"); 16814 continue; 16815 } 16816 if (r.visible) { 16817 // App has a visible activity; only upgrade adjustment. 16818 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16819 adj = ProcessList.VISIBLE_APP_ADJ; 16820 app.adjType = "visible"; 16821 } 16822 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16823 procState = ActivityManager.PROCESS_STATE_TOP; 16824 } 16825 schedGroup = Process.THREAD_GROUP_DEFAULT; 16826 app.cached = false; 16827 app.empty = false; 16828 foregroundActivities = true; 16829 break; 16830 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16831 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16832 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16833 app.adjType = "pausing"; 16834 } 16835 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16836 procState = ActivityManager.PROCESS_STATE_TOP; 16837 } 16838 schedGroup = Process.THREAD_GROUP_DEFAULT; 16839 app.cached = false; 16840 app.empty = false; 16841 foregroundActivities = true; 16842 } else if (r.state == ActivityState.STOPPING) { 16843 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16844 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16845 app.adjType = "stopping"; 16846 } 16847 // For the process state, we will at this point consider the 16848 // process to be cached. It will be cached either as an activity 16849 // or empty depending on whether the activity is finishing. We do 16850 // this so that we can treat the process as cached for purposes of 16851 // memory trimming (determing current memory level, trim command to 16852 // send to process) since there can be an arbitrary number of stopping 16853 // processes and they should soon all go into the cached state. 16854 if (!r.finishing) { 16855 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16856 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16857 } 16858 } 16859 app.cached = false; 16860 app.empty = false; 16861 foregroundActivities = true; 16862 } else { 16863 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16864 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16865 app.adjType = "cch-act"; 16866 } 16867 } 16868 } 16869 } 16870 16871 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16872 if (app.foregroundServices) { 16873 // The user is aware of this app, so make it visible. 16874 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16875 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16876 app.cached = false; 16877 app.adjType = "fg-service"; 16878 schedGroup = Process.THREAD_GROUP_DEFAULT; 16879 } else if (app.forcingToForeground != null) { 16880 // The user is aware of this app, so make it visible. 16881 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16882 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16883 app.cached = false; 16884 app.adjType = "force-fg"; 16885 app.adjSource = app.forcingToForeground; 16886 schedGroup = Process.THREAD_GROUP_DEFAULT; 16887 } 16888 } 16889 16890 if (app == mHeavyWeightProcess) { 16891 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16892 // We don't want to kill the current heavy-weight process. 16893 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16894 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16895 app.cached = false; 16896 app.adjType = "heavy"; 16897 } 16898 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16899 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16900 } 16901 } 16902 16903 if (app == mHomeProcess) { 16904 if (adj > ProcessList.HOME_APP_ADJ) { 16905 // This process is hosting what we currently consider to be the 16906 // home app, so we don't want to let it go into the background. 16907 adj = ProcessList.HOME_APP_ADJ; 16908 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16909 app.cached = false; 16910 app.adjType = "home"; 16911 } 16912 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16913 procState = ActivityManager.PROCESS_STATE_HOME; 16914 } 16915 } 16916 16917 if (app == mPreviousProcess && app.activities.size() > 0) { 16918 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16919 // This was the previous process that showed UI to the user. 16920 // We want to try to keep it around more aggressively, to give 16921 // a good experience around switching between two apps. 16922 adj = ProcessList.PREVIOUS_APP_ADJ; 16923 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16924 app.cached = false; 16925 app.adjType = "previous"; 16926 } 16927 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16928 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16929 } 16930 } 16931 16932 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16933 + " reason=" + app.adjType); 16934 16935 // By default, we use the computed adjustment. It may be changed if 16936 // there are applications dependent on our services or providers, but 16937 // this gives us a baseline and makes sure we don't get into an 16938 // infinite recursion. 16939 app.adjSeq = mAdjSeq; 16940 app.curRawAdj = adj; 16941 app.hasStartedServices = false; 16942 16943 if (mBackupTarget != null && app == mBackupTarget.app) { 16944 // If possible we want to avoid killing apps while they're being backed up 16945 if (adj > ProcessList.BACKUP_APP_ADJ) { 16946 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16947 adj = ProcessList.BACKUP_APP_ADJ; 16948 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16949 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16950 } 16951 app.adjType = "backup"; 16952 app.cached = false; 16953 } 16954 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16955 procState = ActivityManager.PROCESS_STATE_BACKUP; 16956 } 16957 } 16958 16959 boolean mayBeTop = false; 16960 16961 for (int is = app.services.size()-1; 16962 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16963 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16964 || procState > ActivityManager.PROCESS_STATE_TOP); 16965 is--) { 16966 ServiceRecord s = app.services.valueAt(is); 16967 if (s.startRequested) { 16968 app.hasStartedServices = true; 16969 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16970 procState = ActivityManager.PROCESS_STATE_SERVICE; 16971 } 16972 if (app.hasShownUi && app != mHomeProcess) { 16973 // If this process has shown some UI, let it immediately 16974 // go to the LRU list because it may be pretty heavy with 16975 // UI stuff. We'll tag it with a label just to help 16976 // debug and understand what is going on. 16977 if (adj > ProcessList.SERVICE_ADJ) { 16978 app.adjType = "cch-started-ui-services"; 16979 } 16980 } else { 16981 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16982 // This service has seen some activity within 16983 // recent memory, so we will keep its process ahead 16984 // of the background processes. 16985 if (adj > ProcessList.SERVICE_ADJ) { 16986 adj = ProcessList.SERVICE_ADJ; 16987 app.adjType = "started-services"; 16988 app.cached = false; 16989 } 16990 } 16991 // If we have let the service slide into the background 16992 // state, still have some text describing what it is doing 16993 // even though the service no longer has an impact. 16994 if (adj > ProcessList.SERVICE_ADJ) { 16995 app.adjType = "cch-started-services"; 16996 } 16997 } 16998 } 16999 for (int conni = s.connections.size()-1; 17000 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17001 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17002 || procState > ActivityManager.PROCESS_STATE_TOP); 17003 conni--) { 17004 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17005 for (int i = 0; 17006 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17007 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17008 || procState > ActivityManager.PROCESS_STATE_TOP); 17009 i++) { 17010 // XXX should compute this based on the max of 17011 // all connected clients. 17012 ConnectionRecord cr = clist.get(i); 17013 if (cr.binding.client == app) { 17014 // Binding to ourself is not interesting. 17015 continue; 17016 } 17017 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17018 ProcessRecord client = cr.binding.client; 17019 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17020 TOP_APP, doingAll, now); 17021 int clientProcState = client.curProcState; 17022 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17023 // If the other app is cached for any reason, for purposes here 17024 // we are going to consider it empty. The specific cached state 17025 // doesn't propagate except under certain conditions. 17026 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17027 } 17028 String adjType = null; 17029 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17030 // Not doing bind OOM management, so treat 17031 // this guy more like a started service. 17032 if (app.hasShownUi && app != mHomeProcess) { 17033 // If this process has shown some UI, let it immediately 17034 // go to the LRU list because it may be pretty heavy with 17035 // UI stuff. We'll tag it with a label just to help 17036 // debug and understand what is going on. 17037 if (adj > clientAdj) { 17038 adjType = "cch-bound-ui-services"; 17039 } 17040 app.cached = false; 17041 clientAdj = adj; 17042 clientProcState = procState; 17043 } else { 17044 if (now >= (s.lastActivity 17045 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17046 // This service has not seen activity within 17047 // recent memory, so allow it to drop to the 17048 // LRU list if there is no other reason to keep 17049 // it around. We'll also tag it with a label just 17050 // to help debug and undertand what is going on. 17051 if (adj > clientAdj) { 17052 adjType = "cch-bound-services"; 17053 } 17054 clientAdj = adj; 17055 } 17056 } 17057 } 17058 if (adj > clientAdj) { 17059 // If this process has recently shown UI, and 17060 // the process that is binding to it is less 17061 // important than being visible, then we don't 17062 // care about the binding as much as we care 17063 // about letting this process get into the LRU 17064 // list to be killed and restarted if needed for 17065 // memory. 17066 if (app.hasShownUi && app != mHomeProcess 17067 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17068 adjType = "cch-bound-ui-services"; 17069 } else { 17070 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17071 |Context.BIND_IMPORTANT)) != 0) { 17072 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17073 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17074 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17075 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17076 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17077 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17078 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17079 adj = clientAdj; 17080 } else { 17081 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17082 adj = ProcessList.VISIBLE_APP_ADJ; 17083 } 17084 } 17085 if (!client.cached) { 17086 app.cached = false; 17087 } 17088 adjType = "service"; 17089 } 17090 } 17091 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17092 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17093 schedGroup = Process.THREAD_GROUP_DEFAULT; 17094 } 17095 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17096 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17097 // Special handling of clients who are in the top state. 17098 // We *may* want to consider this process to be in the 17099 // top state as well, but only if there is not another 17100 // reason for it to be running. Being on the top is a 17101 // special state, meaning you are specifically running 17102 // for the current top app. If the process is already 17103 // running in the background for some other reason, it 17104 // is more important to continue considering it to be 17105 // in the background state. 17106 mayBeTop = true; 17107 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17108 } else { 17109 // Special handling for above-top states (persistent 17110 // processes). These should not bring the current process 17111 // into the top state, since they are not on top. Instead 17112 // give them the best state after that. 17113 clientProcState = 17114 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17115 } 17116 } 17117 } else { 17118 if (clientProcState < 17119 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17120 clientProcState = 17121 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17122 } 17123 } 17124 if (procState > clientProcState) { 17125 procState = clientProcState; 17126 } 17127 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17128 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17129 app.pendingUiClean = true; 17130 } 17131 if (adjType != null) { 17132 app.adjType = adjType; 17133 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17134 .REASON_SERVICE_IN_USE; 17135 app.adjSource = cr.binding.client; 17136 app.adjSourceProcState = clientProcState; 17137 app.adjTarget = s.name; 17138 } 17139 } 17140 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17141 app.treatLikeActivity = true; 17142 } 17143 final ActivityRecord a = cr.activity; 17144 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17145 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17146 (a.visible || a.state == ActivityState.RESUMED 17147 || a.state == ActivityState.PAUSING)) { 17148 adj = ProcessList.FOREGROUND_APP_ADJ; 17149 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17150 schedGroup = Process.THREAD_GROUP_DEFAULT; 17151 } 17152 app.cached = false; 17153 app.adjType = "service"; 17154 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17155 .REASON_SERVICE_IN_USE; 17156 app.adjSource = a; 17157 app.adjSourceProcState = procState; 17158 app.adjTarget = s.name; 17159 } 17160 } 17161 } 17162 } 17163 } 17164 17165 for (int provi = app.pubProviders.size()-1; 17166 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17167 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17168 || procState > ActivityManager.PROCESS_STATE_TOP); 17169 provi--) { 17170 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17171 for (int i = cpr.connections.size()-1; 17172 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17173 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17174 || procState > ActivityManager.PROCESS_STATE_TOP); 17175 i--) { 17176 ContentProviderConnection conn = cpr.connections.get(i); 17177 ProcessRecord client = conn.client; 17178 if (client == app) { 17179 // Being our own client is not interesting. 17180 continue; 17181 } 17182 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17183 int clientProcState = client.curProcState; 17184 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17185 // If the other app is cached for any reason, for purposes here 17186 // we are going to consider it empty. 17187 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17188 } 17189 if (adj > clientAdj) { 17190 if (app.hasShownUi && app != mHomeProcess 17191 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17192 app.adjType = "cch-ui-provider"; 17193 } else { 17194 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17195 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17196 app.adjType = "provider"; 17197 } 17198 app.cached &= client.cached; 17199 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17200 .REASON_PROVIDER_IN_USE; 17201 app.adjSource = client; 17202 app.adjSourceProcState = clientProcState; 17203 app.adjTarget = cpr.name; 17204 } 17205 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17206 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17207 // Special handling of clients who are in the top state. 17208 // We *may* want to consider this process to be in the 17209 // top state as well, but only if there is not another 17210 // reason for it to be running. Being on the top is a 17211 // special state, meaning you are specifically running 17212 // for the current top app. If the process is already 17213 // running in the background for some other reason, it 17214 // is more important to continue considering it to be 17215 // in the background state. 17216 mayBeTop = true; 17217 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17218 } else { 17219 // Special handling for above-top states (persistent 17220 // processes). These should not bring the current process 17221 // into the top state, since they are not on top. Instead 17222 // give them the best state after that. 17223 clientProcState = 17224 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17225 } 17226 } 17227 if (procState > clientProcState) { 17228 procState = clientProcState; 17229 } 17230 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17231 schedGroup = Process.THREAD_GROUP_DEFAULT; 17232 } 17233 } 17234 // If the provider has external (non-framework) process 17235 // dependencies, ensure that its adjustment is at least 17236 // FOREGROUND_APP_ADJ. 17237 if (cpr.hasExternalProcessHandles()) { 17238 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17239 adj = ProcessList.FOREGROUND_APP_ADJ; 17240 schedGroup = Process.THREAD_GROUP_DEFAULT; 17241 app.cached = false; 17242 app.adjType = "provider"; 17243 app.adjTarget = cpr.name; 17244 } 17245 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17246 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17247 } 17248 } 17249 } 17250 17251 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17252 // A client of one of our services or providers is in the top state. We 17253 // *may* want to be in the top state, but not if we are already running in 17254 // the background for some other reason. For the decision here, we are going 17255 // to pick out a few specific states that we want to remain in when a client 17256 // is top (states that tend to be longer-term) and otherwise allow it to go 17257 // to the top state. 17258 switch (procState) { 17259 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17260 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17261 case ActivityManager.PROCESS_STATE_SERVICE: 17262 // These all are longer-term states, so pull them up to the top 17263 // of the background states, but not all the way to the top state. 17264 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17265 break; 17266 default: 17267 // Otherwise, top is a better choice, so take it. 17268 procState = ActivityManager.PROCESS_STATE_TOP; 17269 break; 17270 } 17271 } 17272 17273 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17274 if (app.hasClientActivities) { 17275 // This is a cached process, but with client activities. Mark it so. 17276 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17277 app.adjType = "cch-client-act"; 17278 } else if (app.treatLikeActivity) { 17279 // This is a cached process, but somebody wants us to treat it like it has 17280 // an activity, okay! 17281 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17282 app.adjType = "cch-as-act"; 17283 } 17284 } 17285 17286 if (adj == ProcessList.SERVICE_ADJ) { 17287 if (doingAll) { 17288 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17289 mNewNumServiceProcs++; 17290 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17291 if (!app.serviceb) { 17292 // This service isn't far enough down on the LRU list to 17293 // normally be a B service, but if we are low on RAM and it 17294 // is large we want to force it down since we would prefer to 17295 // keep launcher over it. 17296 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17297 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17298 app.serviceHighRam = true; 17299 app.serviceb = true; 17300 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17301 } else { 17302 mNewNumAServiceProcs++; 17303 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17304 } 17305 } else { 17306 app.serviceHighRam = false; 17307 } 17308 } 17309 if (app.serviceb) { 17310 adj = ProcessList.SERVICE_B_ADJ; 17311 } 17312 } 17313 17314 app.curRawAdj = adj; 17315 17316 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17317 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17318 if (adj > app.maxAdj) { 17319 adj = app.maxAdj; 17320 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17321 schedGroup = Process.THREAD_GROUP_DEFAULT; 17322 } 17323 } 17324 17325 // Do final modification to adj. Everything we do between here and applying 17326 // the final setAdj must be done in this function, because we will also use 17327 // it when computing the final cached adj later. Note that we don't need to 17328 // worry about this for max adj above, since max adj will always be used to 17329 // keep it out of the cached vaues. 17330 app.curAdj = app.modifyRawOomAdj(adj); 17331 app.curSchedGroup = schedGroup; 17332 app.curProcState = procState; 17333 app.foregroundActivities = foregroundActivities; 17334 17335 return app.curRawAdj; 17336 } 17337 17338 /** 17339 * Schedule PSS collection of a process. 17340 */ 17341 void requestPssLocked(ProcessRecord proc, int procState) { 17342 if (mPendingPssProcesses.contains(proc)) { 17343 return; 17344 } 17345 if (mPendingPssProcesses.size() == 0) { 17346 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17347 } 17348 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17349 proc.pssProcState = procState; 17350 mPendingPssProcesses.add(proc); 17351 } 17352 17353 /** 17354 * Schedule PSS collection of all processes. 17355 */ 17356 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17357 if (!always) { 17358 if (now < (mLastFullPssTime + 17359 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17360 return; 17361 } 17362 } 17363 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17364 mLastFullPssTime = now; 17365 mFullPssPending = true; 17366 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17367 mPendingPssProcesses.clear(); 17368 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17369 ProcessRecord app = mLruProcesses.get(i); 17370 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17371 app.pssProcState = app.setProcState; 17372 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17373 isSleeping(), now); 17374 mPendingPssProcesses.add(app); 17375 } 17376 } 17377 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17378 } 17379 17380 /** 17381 * Ask a given process to GC right now. 17382 */ 17383 final void performAppGcLocked(ProcessRecord app) { 17384 try { 17385 app.lastRequestedGc = SystemClock.uptimeMillis(); 17386 if (app.thread != null) { 17387 if (app.reportLowMemory) { 17388 app.reportLowMemory = false; 17389 app.thread.scheduleLowMemory(); 17390 } else { 17391 app.thread.processInBackground(); 17392 } 17393 } 17394 } catch (Exception e) { 17395 // whatever. 17396 } 17397 } 17398 17399 /** 17400 * Returns true if things are idle enough to perform GCs. 17401 */ 17402 private final boolean canGcNowLocked() { 17403 boolean processingBroadcasts = false; 17404 for (BroadcastQueue q : mBroadcastQueues) { 17405 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17406 processingBroadcasts = true; 17407 } 17408 } 17409 return !processingBroadcasts 17410 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17411 } 17412 17413 /** 17414 * Perform GCs on all processes that are waiting for it, but only 17415 * if things are idle. 17416 */ 17417 final void performAppGcsLocked() { 17418 final int N = mProcessesToGc.size(); 17419 if (N <= 0) { 17420 return; 17421 } 17422 if (canGcNowLocked()) { 17423 while (mProcessesToGc.size() > 0) { 17424 ProcessRecord proc = mProcessesToGc.remove(0); 17425 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17426 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17427 <= SystemClock.uptimeMillis()) { 17428 // To avoid spamming the system, we will GC processes one 17429 // at a time, waiting a few seconds between each. 17430 performAppGcLocked(proc); 17431 scheduleAppGcsLocked(); 17432 return; 17433 } else { 17434 // It hasn't been long enough since we last GCed this 17435 // process... put it in the list to wait for its time. 17436 addProcessToGcListLocked(proc); 17437 break; 17438 } 17439 } 17440 } 17441 17442 scheduleAppGcsLocked(); 17443 } 17444 } 17445 17446 /** 17447 * If all looks good, perform GCs on all processes waiting for them. 17448 */ 17449 final void performAppGcsIfAppropriateLocked() { 17450 if (canGcNowLocked()) { 17451 performAppGcsLocked(); 17452 return; 17453 } 17454 // Still not idle, wait some more. 17455 scheduleAppGcsLocked(); 17456 } 17457 17458 /** 17459 * Schedule the execution of all pending app GCs. 17460 */ 17461 final void scheduleAppGcsLocked() { 17462 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17463 17464 if (mProcessesToGc.size() > 0) { 17465 // Schedule a GC for the time to the next process. 17466 ProcessRecord proc = mProcessesToGc.get(0); 17467 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17468 17469 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17470 long now = SystemClock.uptimeMillis(); 17471 if (when < (now+GC_TIMEOUT)) { 17472 when = now + GC_TIMEOUT; 17473 } 17474 mHandler.sendMessageAtTime(msg, when); 17475 } 17476 } 17477 17478 /** 17479 * Add a process to the array of processes waiting to be GCed. Keeps the 17480 * list in sorted order by the last GC time. The process can't already be 17481 * on the list. 17482 */ 17483 final void addProcessToGcListLocked(ProcessRecord proc) { 17484 boolean added = false; 17485 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17486 if (mProcessesToGc.get(i).lastRequestedGc < 17487 proc.lastRequestedGc) { 17488 added = true; 17489 mProcessesToGc.add(i+1, proc); 17490 break; 17491 } 17492 } 17493 if (!added) { 17494 mProcessesToGc.add(0, proc); 17495 } 17496 } 17497 17498 /** 17499 * Set up to ask a process to GC itself. This will either do it 17500 * immediately, or put it on the list of processes to gc the next 17501 * time things are idle. 17502 */ 17503 final void scheduleAppGcLocked(ProcessRecord app) { 17504 long now = SystemClock.uptimeMillis(); 17505 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17506 return; 17507 } 17508 if (!mProcessesToGc.contains(app)) { 17509 addProcessToGcListLocked(app); 17510 scheduleAppGcsLocked(); 17511 } 17512 } 17513 17514 final void checkExcessivePowerUsageLocked(boolean doKills) { 17515 updateCpuStatsNow(); 17516 17517 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17518 boolean doWakeKills = doKills; 17519 boolean doCpuKills = doKills; 17520 if (mLastPowerCheckRealtime == 0) { 17521 doWakeKills = false; 17522 } 17523 if (mLastPowerCheckUptime == 0) { 17524 doCpuKills = false; 17525 } 17526 if (stats.isScreenOn()) { 17527 doWakeKills = false; 17528 } 17529 final long curRealtime = SystemClock.elapsedRealtime(); 17530 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17531 final long curUptime = SystemClock.uptimeMillis(); 17532 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17533 mLastPowerCheckRealtime = curRealtime; 17534 mLastPowerCheckUptime = curUptime; 17535 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17536 doWakeKills = false; 17537 } 17538 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17539 doCpuKills = false; 17540 } 17541 int i = mLruProcesses.size(); 17542 while (i > 0) { 17543 i--; 17544 ProcessRecord app = mLruProcesses.get(i); 17545 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17546 long wtime; 17547 synchronized (stats) { 17548 wtime = stats.getProcessWakeTime(app.info.uid, 17549 app.pid, curRealtime); 17550 } 17551 long wtimeUsed = wtime - app.lastWakeTime; 17552 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17553 if (DEBUG_POWER) { 17554 StringBuilder sb = new StringBuilder(128); 17555 sb.append("Wake for "); 17556 app.toShortString(sb); 17557 sb.append(": over "); 17558 TimeUtils.formatDuration(realtimeSince, sb); 17559 sb.append(" used "); 17560 TimeUtils.formatDuration(wtimeUsed, sb); 17561 sb.append(" ("); 17562 sb.append((wtimeUsed*100)/realtimeSince); 17563 sb.append("%)"); 17564 Slog.i(TAG, sb.toString()); 17565 sb.setLength(0); 17566 sb.append("CPU for "); 17567 app.toShortString(sb); 17568 sb.append(": over "); 17569 TimeUtils.formatDuration(uptimeSince, sb); 17570 sb.append(" used "); 17571 TimeUtils.formatDuration(cputimeUsed, sb); 17572 sb.append(" ("); 17573 sb.append((cputimeUsed*100)/uptimeSince); 17574 sb.append("%)"); 17575 Slog.i(TAG, sb.toString()); 17576 } 17577 // If a process has held a wake lock for more 17578 // than 50% of the time during this period, 17579 // that sounds bad. Kill! 17580 if (doWakeKills && realtimeSince > 0 17581 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17582 synchronized (stats) { 17583 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17584 realtimeSince, wtimeUsed); 17585 } 17586 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17587 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17588 } else if (doCpuKills && uptimeSince > 0 17589 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17590 synchronized (stats) { 17591 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17592 uptimeSince, cputimeUsed); 17593 } 17594 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17595 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17596 } else { 17597 app.lastWakeTime = wtime; 17598 app.lastCpuTime = app.curCpuTime; 17599 } 17600 } 17601 } 17602 } 17603 17604 private final boolean applyOomAdjLocked(ProcessRecord app, 17605 ProcessRecord TOP_APP, boolean doingAll, long now) { 17606 boolean success = true; 17607 17608 if (app.curRawAdj != app.setRawAdj) { 17609 app.setRawAdj = app.curRawAdj; 17610 } 17611 17612 int changes = 0; 17613 17614 if (app.curAdj != app.setAdj) { 17615 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17616 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17617 TAG, "Set " + app.pid + " " + app.processName + 17618 " adj " + app.curAdj + ": " + app.adjType); 17619 app.setAdj = app.curAdj; 17620 } 17621 17622 if (app.setSchedGroup != app.curSchedGroup) { 17623 app.setSchedGroup = app.curSchedGroup; 17624 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17625 "Setting process group of " + app.processName 17626 + " to " + app.curSchedGroup); 17627 if (app.waitingToKill != null && 17628 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17629 app.kill(app.waitingToKill, true); 17630 success = false; 17631 } else { 17632 if (true) { 17633 long oldId = Binder.clearCallingIdentity(); 17634 try { 17635 Process.setProcessGroup(app.pid, app.curSchedGroup); 17636 } catch (Exception e) { 17637 Slog.w(TAG, "Failed setting process group of " + app.pid 17638 + " to " + app.curSchedGroup); 17639 e.printStackTrace(); 17640 } finally { 17641 Binder.restoreCallingIdentity(oldId); 17642 } 17643 } else { 17644 if (app.thread != null) { 17645 try { 17646 app.thread.setSchedulingGroup(app.curSchedGroup); 17647 } catch (RemoteException e) { 17648 } 17649 } 17650 } 17651 Process.setSwappiness(app.pid, 17652 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17653 } 17654 } 17655 if (app.repForegroundActivities != app.foregroundActivities) { 17656 app.repForegroundActivities = app.foregroundActivities; 17657 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17658 } 17659 if (app.repProcState != app.curProcState) { 17660 app.repProcState = app.curProcState; 17661 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17662 if (app.thread != null) { 17663 try { 17664 if (false) { 17665 //RuntimeException h = new RuntimeException("here"); 17666 Slog.i(TAG, "Sending new process state " + app.repProcState 17667 + " to " + app /*, h*/); 17668 } 17669 app.thread.setProcessState(app.repProcState); 17670 } catch (RemoteException e) { 17671 } 17672 } 17673 } 17674 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17675 app.setProcState)) { 17676 app.lastStateTime = now; 17677 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17678 isSleeping(), now); 17679 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17680 + ProcessList.makeProcStateString(app.setProcState) + " to " 17681 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17682 + (app.nextPssTime-now) + ": " + app); 17683 } else { 17684 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17685 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17686 requestPssLocked(app, app.setProcState); 17687 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17688 isSleeping(), now); 17689 } else if (false && DEBUG_PSS) { 17690 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17691 } 17692 } 17693 if (app.setProcState != app.curProcState) { 17694 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17695 "Proc state change of " + app.processName 17696 + " to " + app.curProcState); 17697 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17698 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17699 if (setImportant && !curImportant) { 17700 // This app is no longer something we consider important enough to allow to 17701 // use arbitrary amounts of battery power. Note 17702 // its current wake lock time to later know to kill it if 17703 // it is not behaving well. 17704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17705 synchronized (stats) { 17706 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17707 app.pid, SystemClock.elapsedRealtime()); 17708 } 17709 app.lastCpuTime = app.curCpuTime; 17710 17711 } 17712 app.setProcState = app.curProcState; 17713 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17714 app.notCachedSinceIdle = false; 17715 } 17716 if (!doingAll) { 17717 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17718 } else { 17719 app.procStateChanged = true; 17720 } 17721 } 17722 17723 if (changes != 0) { 17724 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17725 int i = mPendingProcessChanges.size()-1; 17726 ProcessChangeItem item = null; 17727 while (i >= 0) { 17728 item = mPendingProcessChanges.get(i); 17729 if (item.pid == app.pid) { 17730 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17731 break; 17732 } 17733 i--; 17734 } 17735 if (i < 0) { 17736 // No existing item in pending changes; need a new one. 17737 final int NA = mAvailProcessChanges.size(); 17738 if (NA > 0) { 17739 item = mAvailProcessChanges.remove(NA-1); 17740 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17741 } else { 17742 item = new ProcessChangeItem(); 17743 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17744 } 17745 item.changes = 0; 17746 item.pid = app.pid; 17747 item.uid = app.info.uid; 17748 if (mPendingProcessChanges.size() == 0) { 17749 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17750 "*** Enqueueing dispatch processes changed!"); 17751 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17752 } 17753 mPendingProcessChanges.add(item); 17754 } 17755 item.changes |= changes; 17756 item.processState = app.repProcState; 17757 item.foregroundActivities = app.repForegroundActivities; 17758 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17759 + Integer.toHexString(System.identityHashCode(item)) 17760 + " " + app.toShortString() + ": changes=" + item.changes 17761 + " procState=" + item.processState 17762 + " foreground=" + item.foregroundActivities 17763 + " type=" + app.adjType + " source=" + app.adjSource 17764 + " target=" + app.adjTarget); 17765 } 17766 17767 return success; 17768 } 17769 17770 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17771 if (proc.thread != null) { 17772 if (proc.baseProcessTracker != null) { 17773 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17774 } 17775 if (proc.repProcState >= 0) { 17776 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17777 proc.repProcState); 17778 } 17779 } 17780 } 17781 17782 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17783 ProcessRecord TOP_APP, boolean doingAll, long now) { 17784 if (app.thread == null) { 17785 return false; 17786 } 17787 17788 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17789 17790 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17791 } 17792 17793 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17794 boolean oomAdj) { 17795 if (isForeground != proc.foregroundServices) { 17796 proc.foregroundServices = isForeground; 17797 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17798 proc.info.uid); 17799 if (isForeground) { 17800 if (curProcs == null) { 17801 curProcs = new ArrayList<ProcessRecord>(); 17802 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17803 } 17804 if (!curProcs.contains(proc)) { 17805 curProcs.add(proc); 17806 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17807 proc.info.packageName, proc.info.uid); 17808 } 17809 } else { 17810 if (curProcs != null) { 17811 if (curProcs.remove(proc)) { 17812 mBatteryStatsService.noteEvent( 17813 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17814 proc.info.packageName, proc.info.uid); 17815 if (curProcs.size() <= 0) { 17816 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17817 } 17818 } 17819 } 17820 } 17821 if (oomAdj) { 17822 updateOomAdjLocked(); 17823 } 17824 } 17825 } 17826 17827 private final ActivityRecord resumedAppLocked() { 17828 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17829 String pkg; 17830 int uid; 17831 if (act != null) { 17832 pkg = act.packageName; 17833 uid = act.info.applicationInfo.uid; 17834 } else { 17835 pkg = null; 17836 uid = -1; 17837 } 17838 // Has the UID or resumed package name changed? 17839 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17840 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17841 if (mCurResumedPackage != null) { 17842 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17843 mCurResumedPackage, mCurResumedUid); 17844 } 17845 mCurResumedPackage = pkg; 17846 mCurResumedUid = uid; 17847 if (mCurResumedPackage != null) { 17848 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17849 mCurResumedPackage, mCurResumedUid); 17850 } 17851 } 17852 return act; 17853 } 17854 17855 final boolean updateOomAdjLocked(ProcessRecord app) { 17856 final ActivityRecord TOP_ACT = resumedAppLocked(); 17857 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17858 final boolean wasCached = app.cached; 17859 17860 mAdjSeq++; 17861 17862 // This is the desired cached adjusment we want to tell it to use. 17863 // If our app is currently cached, we know it, and that is it. Otherwise, 17864 // we don't know it yet, and it needs to now be cached we will then 17865 // need to do a complete oom adj. 17866 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17867 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17868 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17869 SystemClock.uptimeMillis()); 17870 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17871 // Changed to/from cached state, so apps after it in the LRU 17872 // list may also be changed. 17873 updateOomAdjLocked(); 17874 } 17875 return success; 17876 } 17877 17878 final void updateOomAdjLocked() { 17879 final ActivityRecord TOP_ACT = resumedAppLocked(); 17880 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17881 final long now = SystemClock.uptimeMillis(); 17882 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17883 final int N = mLruProcesses.size(); 17884 17885 if (false) { 17886 RuntimeException e = new RuntimeException(); 17887 e.fillInStackTrace(); 17888 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17889 } 17890 17891 mAdjSeq++; 17892 mNewNumServiceProcs = 0; 17893 mNewNumAServiceProcs = 0; 17894 17895 final int emptyProcessLimit; 17896 final int cachedProcessLimit; 17897 if (mProcessLimit <= 0) { 17898 emptyProcessLimit = cachedProcessLimit = 0; 17899 } else if (mProcessLimit == 1) { 17900 emptyProcessLimit = 1; 17901 cachedProcessLimit = 0; 17902 } else { 17903 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17904 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17905 } 17906 17907 // Let's determine how many processes we have running vs. 17908 // how many slots we have for background processes; we may want 17909 // to put multiple processes in a slot of there are enough of 17910 // them. 17911 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17912 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17913 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17914 if (numEmptyProcs > cachedProcessLimit) { 17915 // If there are more empty processes than our limit on cached 17916 // processes, then use the cached process limit for the factor. 17917 // This ensures that the really old empty processes get pushed 17918 // down to the bottom, so if we are running low on memory we will 17919 // have a better chance at keeping around more cached processes 17920 // instead of a gazillion empty processes. 17921 numEmptyProcs = cachedProcessLimit; 17922 } 17923 int emptyFactor = numEmptyProcs/numSlots; 17924 if (emptyFactor < 1) emptyFactor = 1; 17925 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17926 if (cachedFactor < 1) cachedFactor = 1; 17927 int stepCached = 0; 17928 int stepEmpty = 0; 17929 int numCached = 0; 17930 int numEmpty = 0; 17931 int numTrimming = 0; 17932 17933 mNumNonCachedProcs = 0; 17934 mNumCachedHiddenProcs = 0; 17935 17936 // First update the OOM adjustment for each of the 17937 // application processes based on their current state. 17938 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17939 int nextCachedAdj = curCachedAdj+1; 17940 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17941 int nextEmptyAdj = curEmptyAdj+2; 17942 for (int i=N-1; i>=0; i--) { 17943 ProcessRecord app = mLruProcesses.get(i); 17944 if (!app.killedByAm && app.thread != null) { 17945 app.procStateChanged = false; 17946 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17947 17948 // If we haven't yet assigned the final cached adj 17949 // to the process, do that now. 17950 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17951 switch (app.curProcState) { 17952 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17953 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17954 // This process is a cached process holding activities... 17955 // assign it the next cached value for that type, and then 17956 // step that cached level. 17957 app.curRawAdj = curCachedAdj; 17958 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17959 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17960 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17961 + ")"); 17962 if (curCachedAdj != nextCachedAdj) { 17963 stepCached++; 17964 if (stepCached >= cachedFactor) { 17965 stepCached = 0; 17966 curCachedAdj = nextCachedAdj; 17967 nextCachedAdj += 2; 17968 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17969 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17970 } 17971 } 17972 } 17973 break; 17974 default: 17975 // For everything else, assign next empty cached process 17976 // level and bump that up. Note that this means that 17977 // long-running services that have dropped down to the 17978 // cached level will be treated as empty (since their process 17979 // state is still as a service), which is what we want. 17980 app.curRawAdj = curEmptyAdj; 17981 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17982 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17983 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17984 + ")"); 17985 if (curEmptyAdj != nextEmptyAdj) { 17986 stepEmpty++; 17987 if (stepEmpty >= emptyFactor) { 17988 stepEmpty = 0; 17989 curEmptyAdj = nextEmptyAdj; 17990 nextEmptyAdj += 2; 17991 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17992 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17993 } 17994 } 17995 } 17996 break; 17997 } 17998 } 17999 18000 applyOomAdjLocked(app, TOP_APP, true, now); 18001 18002 // Count the number of process types. 18003 switch (app.curProcState) { 18004 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18005 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18006 mNumCachedHiddenProcs++; 18007 numCached++; 18008 if (numCached > cachedProcessLimit) { 18009 app.kill("cached #" + numCached, true); 18010 } 18011 break; 18012 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18013 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18014 && app.lastActivityTime < oldTime) { 18015 app.kill("empty for " 18016 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18017 / 1000) + "s", true); 18018 } else { 18019 numEmpty++; 18020 if (numEmpty > emptyProcessLimit) { 18021 app.kill("empty #" + numEmpty, true); 18022 } 18023 } 18024 break; 18025 default: 18026 mNumNonCachedProcs++; 18027 break; 18028 } 18029 18030 if (app.isolated && app.services.size() <= 0) { 18031 // If this is an isolated process, and there are no 18032 // services running in it, then the process is no longer 18033 // needed. We agressively kill these because we can by 18034 // definition not re-use the same process again, and it is 18035 // good to avoid having whatever code was running in them 18036 // left sitting around after no longer needed. 18037 app.kill("isolated not needed", true); 18038 } 18039 18040 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18041 && !app.killedByAm) { 18042 numTrimming++; 18043 } 18044 } 18045 } 18046 18047 mNumServiceProcs = mNewNumServiceProcs; 18048 18049 // Now determine the memory trimming level of background processes. 18050 // Unfortunately we need to start at the back of the list to do this 18051 // properly. We only do this if the number of background apps we 18052 // are managing to keep around is less than half the maximum we desire; 18053 // if we are keeping a good number around, we'll let them use whatever 18054 // memory they want. 18055 final int numCachedAndEmpty = numCached + numEmpty; 18056 int memFactor; 18057 if (numCached <= ProcessList.TRIM_CACHED_APPS 18058 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18059 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18060 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18061 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18062 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18063 } else { 18064 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18065 } 18066 } else { 18067 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18068 } 18069 // We always allow the memory level to go up (better). We only allow it to go 18070 // down if we are in a state where that is allowed, *and* the total number of processes 18071 // has gone down since last time. 18072 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18073 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18074 + " last=" + mLastNumProcesses); 18075 if (memFactor > mLastMemoryLevel) { 18076 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18077 memFactor = mLastMemoryLevel; 18078 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18079 } 18080 } 18081 mLastMemoryLevel = memFactor; 18082 mLastNumProcesses = mLruProcesses.size(); 18083 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18084 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18085 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18086 if (mLowRamStartTime == 0) { 18087 mLowRamStartTime = now; 18088 } 18089 int step = 0; 18090 int fgTrimLevel; 18091 switch (memFactor) { 18092 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18093 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18094 break; 18095 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18096 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18097 break; 18098 default: 18099 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18100 break; 18101 } 18102 int factor = numTrimming/3; 18103 int minFactor = 2; 18104 if (mHomeProcess != null) minFactor++; 18105 if (mPreviousProcess != null) minFactor++; 18106 if (factor < minFactor) factor = minFactor; 18107 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18108 for (int i=N-1; i>=0; i--) { 18109 ProcessRecord app = mLruProcesses.get(i); 18110 if (allChanged || app.procStateChanged) { 18111 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18112 app.procStateChanged = false; 18113 } 18114 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18115 && !app.killedByAm) { 18116 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18117 try { 18118 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18119 "Trimming memory of " + app.processName 18120 + " to " + curLevel); 18121 app.thread.scheduleTrimMemory(curLevel); 18122 } catch (RemoteException e) { 18123 } 18124 if (false) { 18125 // For now we won't do this; our memory trimming seems 18126 // to be good enough at this point that destroying 18127 // activities causes more harm than good. 18128 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18129 && app != mHomeProcess && app != mPreviousProcess) { 18130 // Need to do this on its own message because the stack may not 18131 // be in a consistent state at this point. 18132 // For these apps we will also finish their activities 18133 // to help them free memory. 18134 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18135 } 18136 } 18137 } 18138 app.trimMemoryLevel = curLevel; 18139 step++; 18140 if (step >= factor) { 18141 step = 0; 18142 switch (curLevel) { 18143 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18144 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18145 break; 18146 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18147 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18148 break; 18149 } 18150 } 18151 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18152 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18153 && app.thread != null) { 18154 try { 18155 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18156 "Trimming memory of heavy-weight " + app.processName 18157 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18158 app.thread.scheduleTrimMemory( 18159 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18160 } catch (RemoteException e) { 18161 } 18162 } 18163 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18164 } else { 18165 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18166 || app.systemNoUi) && app.pendingUiClean) { 18167 // If this application is now in the background and it 18168 // had done UI, then give it the special trim level to 18169 // have it free UI resources. 18170 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18171 if (app.trimMemoryLevel < level && app.thread != null) { 18172 try { 18173 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18174 "Trimming memory of bg-ui " + app.processName 18175 + " to " + level); 18176 app.thread.scheduleTrimMemory(level); 18177 } catch (RemoteException e) { 18178 } 18179 } 18180 app.pendingUiClean = false; 18181 } 18182 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18183 try { 18184 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18185 "Trimming memory of fg " + app.processName 18186 + " to " + fgTrimLevel); 18187 app.thread.scheduleTrimMemory(fgTrimLevel); 18188 } catch (RemoteException e) { 18189 } 18190 } 18191 app.trimMemoryLevel = fgTrimLevel; 18192 } 18193 } 18194 } else { 18195 if (mLowRamStartTime != 0) { 18196 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18197 mLowRamStartTime = 0; 18198 } 18199 for (int i=N-1; i>=0; i--) { 18200 ProcessRecord app = mLruProcesses.get(i); 18201 if (allChanged || app.procStateChanged) { 18202 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18203 app.procStateChanged = false; 18204 } 18205 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18206 || app.systemNoUi) && app.pendingUiClean) { 18207 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18208 && app.thread != null) { 18209 try { 18210 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18211 "Trimming memory of ui hidden " + app.processName 18212 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18213 app.thread.scheduleTrimMemory( 18214 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18215 } catch (RemoteException e) { 18216 } 18217 } 18218 app.pendingUiClean = false; 18219 } 18220 app.trimMemoryLevel = 0; 18221 } 18222 } 18223 18224 if (mAlwaysFinishActivities) { 18225 // Need to do this on its own message because the stack may not 18226 // be in a consistent state at this point. 18227 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18228 } 18229 18230 if (allChanged) { 18231 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18232 } 18233 18234 if (mProcessStats.shouldWriteNowLocked(now)) { 18235 mHandler.post(new Runnable() { 18236 @Override public void run() { 18237 synchronized (ActivityManagerService.this) { 18238 mProcessStats.writeStateAsyncLocked(); 18239 } 18240 } 18241 }); 18242 } 18243 18244 if (DEBUG_OOM_ADJ) { 18245 if (false) { 18246 RuntimeException here = new RuntimeException("here"); 18247 here.fillInStackTrace(); 18248 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18249 } else { 18250 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18251 } 18252 } 18253 } 18254 18255 final void trimApplications() { 18256 synchronized (this) { 18257 int i; 18258 18259 // First remove any unused application processes whose package 18260 // has been removed. 18261 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18262 final ProcessRecord app = mRemovedProcesses.get(i); 18263 if (app.activities.size() == 0 18264 && app.curReceiver == null && app.services.size() == 0) { 18265 Slog.i( 18266 TAG, "Exiting empty application process " 18267 + app.processName + " (" 18268 + (app.thread != null ? app.thread.asBinder() : null) 18269 + ")\n"); 18270 if (app.pid > 0 && app.pid != MY_PID) { 18271 app.kill("empty", false); 18272 } else { 18273 try { 18274 app.thread.scheduleExit(); 18275 } catch (Exception e) { 18276 // Ignore exceptions. 18277 } 18278 } 18279 cleanUpApplicationRecordLocked(app, false, true, -1); 18280 mRemovedProcesses.remove(i); 18281 18282 if (app.persistent) { 18283 addAppLocked(app.info, false, null /* ABI override */); 18284 } 18285 } 18286 } 18287 18288 // Now update the oom adj for all processes. 18289 updateOomAdjLocked(); 18290 } 18291 } 18292 18293 /** This method sends the specified signal to each of the persistent apps */ 18294 public void signalPersistentProcesses(int sig) throws RemoteException { 18295 if (sig != Process.SIGNAL_USR1) { 18296 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18297 } 18298 18299 synchronized (this) { 18300 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18301 != PackageManager.PERMISSION_GRANTED) { 18302 throw new SecurityException("Requires permission " 18303 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18304 } 18305 18306 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18307 ProcessRecord r = mLruProcesses.get(i); 18308 if (r.thread != null && r.persistent) { 18309 Process.sendSignal(r.pid, sig); 18310 } 18311 } 18312 } 18313 } 18314 18315 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18316 if (proc == null || proc == mProfileProc) { 18317 proc = mProfileProc; 18318 profileType = mProfileType; 18319 clearProfilerLocked(); 18320 } 18321 if (proc == null) { 18322 return; 18323 } 18324 try { 18325 proc.thread.profilerControl(false, null, profileType); 18326 } catch (RemoteException e) { 18327 throw new IllegalStateException("Process disappeared"); 18328 } 18329 } 18330 18331 private void clearProfilerLocked() { 18332 if (mProfileFd != null) { 18333 try { 18334 mProfileFd.close(); 18335 } catch (IOException e) { 18336 } 18337 } 18338 mProfileApp = null; 18339 mProfileProc = null; 18340 mProfileFile = null; 18341 mProfileType = 0; 18342 mAutoStopProfiler = false; 18343 mSamplingInterval = 0; 18344 } 18345 18346 public boolean profileControl(String process, int userId, boolean start, 18347 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18348 18349 try { 18350 synchronized (this) { 18351 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18352 // its own permission. 18353 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18354 != PackageManager.PERMISSION_GRANTED) { 18355 throw new SecurityException("Requires permission " 18356 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18357 } 18358 18359 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18360 throw new IllegalArgumentException("null profile info or fd"); 18361 } 18362 18363 ProcessRecord proc = null; 18364 if (process != null) { 18365 proc = findProcessLocked(process, userId, "profileControl"); 18366 } 18367 18368 if (start && (proc == null || proc.thread == null)) { 18369 throw new IllegalArgumentException("Unknown process: " + process); 18370 } 18371 18372 if (start) { 18373 stopProfilerLocked(null, 0); 18374 setProfileApp(proc.info, proc.processName, profilerInfo); 18375 mProfileProc = proc; 18376 mProfileType = profileType; 18377 ParcelFileDescriptor fd = profilerInfo.profileFd; 18378 try { 18379 fd = fd.dup(); 18380 } catch (IOException e) { 18381 fd = null; 18382 } 18383 profilerInfo.profileFd = fd; 18384 proc.thread.profilerControl(start, profilerInfo, profileType); 18385 fd = null; 18386 mProfileFd = null; 18387 } else { 18388 stopProfilerLocked(proc, profileType); 18389 if (profilerInfo != null && profilerInfo.profileFd != null) { 18390 try { 18391 profilerInfo.profileFd.close(); 18392 } catch (IOException e) { 18393 } 18394 } 18395 } 18396 18397 return true; 18398 } 18399 } catch (RemoteException e) { 18400 throw new IllegalStateException("Process disappeared"); 18401 } finally { 18402 if (profilerInfo != null && profilerInfo.profileFd != null) { 18403 try { 18404 profilerInfo.profileFd.close(); 18405 } catch (IOException e) { 18406 } 18407 } 18408 } 18409 } 18410 18411 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18412 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18413 userId, true, ALLOW_FULL_ONLY, callName, null); 18414 ProcessRecord proc = null; 18415 try { 18416 int pid = Integer.parseInt(process); 18417 synchronized (mPidsSelfLocked) { 18418 proc = mPidsSelfLocked.get(pid); 18419 } 18420 } catch (NumberFormatException e) { 18421 } 18422 18423 if (proc == null) { 18424 ArrayMap<String, SparseArray<ProcessRecord>> all 18425 = mProcessNames.getMap(); 18426 SparseArray<ProcessRecord> procs = all.get(process); 18427 if (procs != null && procs.size() > 0) { 18428 proc = procs.valueAt(0); 18429 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18430 for (int i=1; i<procs.size(); i++) { 18431 ProcessRecord thisProc = procs.valueAt(i); 18432 if (thisProc.userId == userId) { 18433 proc = thisProc; 18434 break; 18435 } 18436 } 18437 } 18438 } 18439 } 18440 18441 return proc; 18442 } 18443 18444 public boolean dumpHeap(String process, int userId, boolean managed, 18445 String path, ParcelFileDescriptor fd) throws RemoteException { 18446 18447 try { 18448 synchronized (this) { 18449 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18450 // its own permission (same as profileControl). 18451 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18452 != PackageManager.PERMISSION_GRANTED) { 18453 throw new SecurityException("Requires permission " 18454 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18455 } 18456 18457 if (fd == null) { 18458 throw new IllegalArgumentException("null fd"); 18459 } 18460 18461 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18462 if (proc == null || proc.thread == null) { 18463 throw new IllegalArgumentException("Unknown process: " + process); 18464 } 18465 18466 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18467 if (!isDebuggable) { 18468 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18469 throw new SecurityException("Process not debuggable: " + proc); 18470 } 18471 } 18472 18473 proc.thread.dumpHeap(managed, path, fd); 18474 fd = null; 18475 return true; 18476 } 18477 } catch (RemoteException e) { 18478 throw new IllegalStateException("Process disappeared"); 18479 } finally { 18480 if (fd != null) { 18481 try { 18482 fd.close(); 18483 } catch (IOException e) { 18484 } 18485 } 18486 } 18487 } 18488 18489 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18490 public void monitor() { 18491 synchronized (this) { } 18492 } 18493 18494 void onCoreSettingsChange(Bundle settings) { 18495 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18496 ProcessRecord processRecord = mLruProcesses.get(i); 18497 try { 18498 if (processRecord.thread != null) { 18499 processRecord.thread.setCoreSettings(settings); 18500 } 18501 } catch (RemoteException re) { 18502 /* ignore */ 18503 } 18504 } 18505 } 18506 18507 // Multi-user methods 18508 18509 /** 18510 * Start user, if its not already running, but don't bring it to foreground. 18511 */ 18512 @Override 18513 public boolean startUserInBackground(final int userId) { 18514 return startUser(userId, /* foreground */ false); 18515 } 18516 18517 /** 18518 * Start user, if its not already running, and bring it to foreground. 18519 */ 18520 boolean startUserInForeground(final int userId, Dialog dlg) { 18521 boolean result = startUser(userId, /* foreground */ true); 18522 dlg.dismiss(); 18523 return result; 18524 } 18525 18526 /** 18527 * Refreshes the list of users related to the current user when either a 18528 * user switch happens or when a new related user is started in the 18529 * background. 18530 */ 18531 private void updateCurrentProfileIdsLocked() { 18532 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18533 mCurrentUserId, false /* enabledOnly */); 18534 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18535 for (int i = 0; i < currentProfileIds.length; i++) { 18536 currentProfileIds[i] = profiles.get(i).id; 18537 } 18538 mCurrentProfileIds = currentProfileIds; 18539 18540 synchronized (mUserProfileGroupIdsSelfLocked) { 18541 mUserProfileGroupIdsSelfLocked.clear(); 18542 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18543 for (int i = 0; i < users.size(); i++) { 18544 UserInfo user = users.get(i); 18545 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18546 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18547 } 18548 } 18549 } 18550 } 18551 18552 private Set getProfileIdsLocked(int userId) { 18553 Set userIds = new HashSet<Integer>(); 18554 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18555 userId, false /* enabledOnly */); 18556 for (UserInfo user : profiles) { 18557 userIds.add(Integer.valueOf(user.id)); 18558 } 18559 return userIds; 18560 } 18561 18562 @Override 18563 public boolean switchUser(final int userId) { 18564 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18565 String userName; 18566 synchronized (this) { 18567 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18568 if (userInfo == null) { 18569 Slog.w(TAG, "No user info for user #" + userId); 18570 return false; 18571 } 18572 if (userInfo.isManagedProfile()) { 18573 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18574 return false; 18575 } 18576 userName = userInfo.name; 18577 mTargetUserId = userId; 18578 } 18579 mHandler.removeMessages(START_USER_SWITCH_MSG); 18580 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18581 return true; 18582 } 18583 18584 private void showUserSwitchDialog(int userId, String userName) { 18585 // The dialog will show and then initiate the user switch by calling startUserInForeground 18586 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18587 true /* above system */); 18588 d.show(); 18589 } 18590 18591 private boolean startUser(final int userId, final boolean foreground) { 18592 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18593 != PackageManager.PERMISSION_GRANTED) { 18594 String msg = "Permission Denial: switchUser() from pid=" 18595 + Binder.getCallingPid() 18596 + ", uid=" + Binder.getCallingUid() 18597 + " requires " + INTERACT_ACROSS_USERS_FULL; 18598 Slog.w(TAG, msg); 18599 throw new SecurityException(msg); 18600 } 18601 18602 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18603 18604 final long ident = Binder.clearCallingIdentity(); 18605 try { 18606 synchronized (this) { 18607 final int oldUserId = mCurrentUserId; 18608 if (oldUserId == userId) { 18609 return true; 18610 } 18611 18612 mStackSupervisor.setLockTaskModeLocked(null, false); 18613 18614 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18615 if (userInfo == null) { 18616 Slog.w(TAG, "No user info for user #" + userId); 18617 return false; 18618 } 18619 if (foreground && userInfo.isManagedProfile()) { 18620 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18621 return false; 18622 } 18623 18624 if (foreground) { 18625 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18626 R.anim.screen_user_enter); 18627 } 18628 18629 boolean needStart = false; 18630 18631 // If the user we are switching to is not currently started, then 18632 // we need to start it now. 18633 if (mStartedUsers.get(userId) == null) { 18634 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18635 updateStartedUserArrayLocked(); 18636 needStart = true; 18637 } 18638 18639 final Integer userIdInt = Integer.valueOf(userId); 18640 mUserLru.remove(userIdInt); 18641 mUserLru.add(userIdInt); 18642 18643 if (foreground) { 18644 mCurrentUserId = userId; 18645 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18646 updateCurrentProfileIdsLocked(); 18647 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18648 // Once the internal notion of the active user has switched, we lock the device 18649 // with the option to show the user switcher on the keyguard. 18650 mWindowManager.lockNow(null); 18651 } else { 18652 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18653 updateCurrentProfileIdsLocked(); 18654 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18655 mUserLru.remove(currentUserIdInt); 18656 mUserLru.add(currentUserIdInt); 18657 } 18658 18659 final UserStartedState uss = mStartedUsers.get(userId); 18660 18661 // Make sure user is in the started state. If it is currently 18662 // stopping, we need to knock that off. 18663 if (uss.mState == UserStartedState.STATE_STOPPING) { 18664 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18665 // so we can just fairly silently bring the user back from 18666 // the almost-dead. 18667 uss.mState = UserStartedState.STATE_RUNNING; 18668 updateStartedUserArrayLocked(); 18669 needStart = true; 18670 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18671 // This means ACTION_SHUTDOWN has been sent, so we will 18672 // need to treat this as a new boot of the user. 18673 uss.mState = UserStartedState.STATE_BOOTING; 18674 updateStartedUserArrayLocked(); 18675 needStart = true; 18676 } 18677 18678 if (uss.mState == UserStartedState.STATE_BOOTING) { 18679 // Booting up a new user, need to tell system services about it. 18680 // Note that this is on the same handler as scheduling of broadcasts, 18681 // which is important because it needs to go first. 18682 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18683 } 18684 18685 if (foreground) { 18686 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18687 oldUserId)); 18688 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18689 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18690 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18691 oldUserId, userId, uss)); 18692 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18693 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18694 } 18695 18696 if (needStart) { 18697 // Send USER_STARTED broadcast 18698 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18699 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18700 | Intent.FLAG_RECEIVER_FOREGROUND); 18701 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18702 broadcastIntentLocked(null, null, intent, 18703 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18704 false, false, MY_PID, Process.SYSTEM_UID, userId); 18705 } 18706 18707 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18708 if (userId != UserHandle.USER_OWNER) { 18709 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18710 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18711 broadcastIntentLocked(null, null, intent, null, 18712 new IIntentReceiver.Stub() { 18713 public void performReceive(Intent intent, int resultCode, 18714 String data, Bundle extras, boolean ordered, 18715 boolean sticky, int sendingUser) { 18716 onUserInitialized(uss, foreground, oldUserId, userId); 18717 } 18718 }, 0, null, null, null, AppOpsManager.OP_NONE, 18719 true, false, MY_PID, Process.SYSTEM_UID, 18720 userId); 18721 uss.initializing = true; 18722 } else { 18723 getUserManagerLocked().makeInitialized(userInfo.id); 18724 } 18725 } 18726 18727 if (foreground) { 18728 if (!uss.initializing) { 18729 moveUserToForeground(uss, oldUserId, userId); 18730 } 18731 } else { 18732 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18733 } 18734 18735 if (needStart) { 18736 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18737 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18738 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18739 broadcastIntentLocked(null, null, intent, 18740 null, new IIntentReceiver.Stub() { 18741 @Override 18742 public void performReceive(Intent intent, int resultCode, String data, 18743 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18744 throws RemoteException { 18745 } 18746 }, 0, null, null, 18747 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18748 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18749 } 18750 } 18751 } finally { 18752 Binder.restoreCallingIdentity(ident); 18753 } 18754 18755 return true; 18756 } 18757 18758 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18759 long ident = Binder.clearCallingIdentity(); 18760 try { 18761 Intent intent; 18762 if (oldUserId >= 0) { 18763 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18764 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18765 int count = profiles.size(); 18766 for (int i = 0; i < count; i++) { 18767 int profileUserId = profiles.get(i).id; 18768 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18769 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18770 | Intent.FLAG_RECEIVER_FOREGROUND); 18771 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18772 broadcastIntentLocked(null, null, intent, 18773 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18774 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18775 } 18776 } 18777 if (newUserId >= 0) { 18778 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18779 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18780 int count = profiles.size(); 18781 for (int i = 0; i < count; i++) { 18782 int profileUserId = profiles.get(i).id; 18783 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18784 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18785 | Intent.FLAG_RECEIVER_FOREGROUND); 18786 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18787 broadcastIntentLocked(null, null, intent, 18788 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18789 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18790 } 18791 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18792 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18793 | Intent.FLAG_RECEIVER_FOREGROUND); 18794 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18795 broadcastIntentLocked(null, null, intent, 18796 null, null, 0, null, null, 18797 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18798 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18799 } 18800 } finally { 18801 Binder.restoreCallingIdentity(ident); 18802 } 18803 } 18804 18805 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18806 final int newUserId) { 18807 final int N = mUserSwitchObservers.beginBroadcast(); 18808 if (N > 0) { 18809 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18810 int mCount = 0; 18811 @Override 18812 public void sendResult(Bundle data) throws RemoteException { 18813 synchronized (ActivityManagerService.this) { 18814 if (mCurUserSwitchCallback == this) { 18815 mCount++; 18816 if (mCount == N) { 18817 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18818 } 18819 } 18820 } 18821 } 18822 }; 18823 synchronized (this) { 18824 uss.switching = true; 18825 mCurUserSwitchCallback = callback; 18826 } 18827 for (int i=0; i<N; i++) { 18828 try { 18829 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18830 newUserId, callback); 18831 } catch (RemoteException e) { 18832 } 18833 } 18834 } else { 18835 synchronized (this) { 18836 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18837 } 18838 } 18839 mUserSwitchObservers.finishBroadcast(); 18840 } 18841 18842 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18843 synchronized (this) { 18844 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18845 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18846 } 18847 } 18848 18849 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18850 mCurUserSwitchCallback = null; 18851 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18852 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18853 oldUserId, newUserId, uss)); 18854 } 18855 18856 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18857 synchronized (this) { 18858 if (foreground) { 18859 moveUserToForeground(uss, oldUserId, newUserId); 18860 } 18861 } 18862 18863 completeSwitchAndInitalize(uss, newUserId, true, false); 18864 } 18865 18866 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18867 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18868 if (homeInFront) { 18869 startHomeActivityLocked(newUserId); 18870 } else { 18871 mStackSupervisor.resumeTopActivitiesLocked(); 18872 } 18873 EventLogTags.writeAmSwitchUser(newUserId); 18874 getUserManagerLocked().userForeground(newUserId); 18875 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18876 } 18877 18878 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18879 completeSwitchAndInitalize(uss, newUserId, false, true); 18880 } 18881 18882 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18883 boolean clearInitializing, boolean clearSwitching) { 18884 boolean unfrozen = false; 18885 synchronized (this) { 18886 if (clearInitializing) { 18887 uss.initializing = false; 18888 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18889 } 18890 if (clearSwitching) { 18891 uss.switching = false; 18892 } 18893 if (!uss.switching && !uss.initializing) { 18894 mWindowManager.stopFreezingScreen(); 18895 unfrozen = true; 18896 } 18897 } 18898 if (unfrozen) { 18899 final int N = mUserSwitchObservers.beginBroadcast(); 18900 for (int i=0; i<N; i++) { 18901 try { 18902 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18903 } catch (RemoteException e) { 18904 } 18905 } 18906 mUserSwitchObservers.finishBroadcast(); 18907 } 18908 } 18909 18910 void scheduleStartProfilesLocked() { 18911 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18912 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18913 DateUtils.SECOND_IN_MILLIS); 18914 } 18915 } 18916 18917 void startProfilesLocked() { 18918 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18919 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18920 mCurrentUserId, false /* enabledOnly */); 18921 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18922 for (UserInfo user : profiles) { 18923 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18924 && user.id != mCurrentUserId) { 18925 toStart.add(user); 18926 } 18927 } 18928 final int n = toStart.size(); 18929 int i = 0; 18930 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18931 startUserInBackground(toStart.get(i).id); 18932 } 18933 if (i < n) { 18934 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18935 } 18936 } 18937 18938 void finishUserBoot(UserStartedState uss) { 18939 synchronized (this) { 18940 if (uss.mState == UserStartedState.STATE_BOOTING 18941 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18942 uss.mState = UserStartedState.STATE_RUNNING; 18943 final int userId = uss.mHandle.getIdentifier(); 18944 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18945 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18946 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18947 broadcastIntentLocked(null, null, intent, 18948 null, null, 0, null, null, 18949 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18950 true, false, MY_PID, Process.SYSTEM_UID, userId); 18951 } 18952 } 18953 } 18954 18955 void finishUserSwitch(UserStartedState uss) { 18956 synchronized (this) { 18957 finishUserBoot(uss); 18958 18959 startProfilesLocked(); 18960 18961 int num = mUserLru.size(); 18962 int i = 0; 18963 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18964 Integer oldUserId = mUserLru.get(i); 18965 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18966 if (oldUss == null) { 18967 // Shouldn't happen, but be sane if it does. 18968 mUserLru.remove(i); 18969 num--; 18970 continue; 18971 } 18972 if (oldUss.mState == UserStartedState.STATE_STOPPING 18973 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18974 // This user is already stopping, doesn't count. 18975 num--; 18976 i++; 18977 continue; 18978 } 18979 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18980 // Owner and current can't be stopped, but count as running. 18981 i++; 18982 continue; 18983 } 18984 // This is a user to be stopped. 18985 stopUserLocked(oldUserId, null); 18986 num--; 18987 i++; 18988 } 18989 } 18990 } 18991 18992 @Override 18993 public int stopUser(final int userId, final IStopUserCallback callback) { 18994 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18995 != PackageManager.PERMISSION_GRANTED) { 18996 String msg = "Permission Denial: switchUser() from pid=" 18997 + Binder.getCallingPid() 18998 + ", uid=" + Binder.getCallingUid() 18999 + " requires " + INTERACT_ACROSS_USERS_FULL; 19000 Slog.w(TAG, msg); 19001 throw new SecurityException(msg); 19002 } 19003 if (userId <= 0) { 19004 throw new IllegalArgumentException("Can't stop primary user " + userId); 19005 } 19006 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19007 synchronized (this) { 19008 return stopUserLocked(userId, callback); 19009 } 19010 } 19011 19012 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19013 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19014 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19015 return ActivityManager.USER_OP_IS_CURRENT; 19016 } 19017 19018 final UserStartedState uss = mStartedUsers.get(userId); 19019 if (uss == null) { 19020 // User is not started, nothing to do... but we do need to 19021 // callback if requested. 19022 if (callback != null) { 19023 mHandler.post(new Runnable() { 19024 @Override 19025 public void run() { 19026 try { 19027 callback.userStopped(userId); 19028 } catch (RemoteException e) { 19029 } 19030 } 19031 }); 19032 } 19033 return ActivityManager.USER_OP_SUCCESS; 19034 } 19035 19036 if (callback != null) { 19037 uss.mStopCallbacks.add(callback); 19038 } 19039 19040 if (uss.mState != UserStartedState.STATE_STOPPING 19041 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19042 uss.mState = UserStartedState.STATE_STOPPING; 19043 updateStartedUserArrayLocked(); 19044 19045 long ident = Binder.clearCallingIdentity(); 19046 try { 19047 // We are going to broadcast ACTION_USER_STOPPING and then 19048 // once that is done send a final ACTION_SHUTDOWN and then 19049 // stop the user. 19050 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19051 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19052 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19053 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19054 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19055 // This is the result receiver for the final shutdown broadcast. 19056 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19057 @Override 19058 public void performReceive(Intent intent, int resultCode, String data, 19059 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19060 finishUserStop(uss); 19061 } 19062 }; 19063 // This is the result receiver for the initial stopping broadcast. 19064 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19065 @Override 19066 public void performReceive(Intent intent, int resultCode, String data, 19067 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19068 // On to the next. 19069 synchronized (ActivityManagerService.this) { 19070 if (uss.mState != UserStartedState.STATE_STOPPING) { 19071 // Whoops, we are being started back up. Abort, abort! 19072 return; 19073 } 19074 uss.mState = UserStartedState.STATE_SHUTDOWN; 19075 } 19076 mBatteryStatsService.noteEvent( 19077 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19078 Integer.toString(userId), userId); 19079 mSystemServiceManager.stopUser(userId); 19080 broadcastIntentLocked(null, null, shutdownIntent, 19081 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19082 true, false, MY_PID, Process.SYSTEM_UID, userId); 19083 } 19084 }; 19085 // Kick things off. 19086 broadcastIntentLocked(null, null, stoppingIntent, 19087 null, stoppingReceiver, 0, null, null, 19088 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19089 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19090 } finally { 19091 Binder.restoreCallingIdentity(ident); 19092 } 19093 } 19094 19095 return ActivityManager.USER_OP_SUCCESS; 19096 } 19097 19098 void finishUserStop(UserStartedState uss) { 19099 final int userId = uss.mHandle.getIdentifier(); 19100 boolean stopped; 19101 ArrayList<IStopUserCallback> callbacks; 19102 synchronized (this) { 19103 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19104 if (mStartedUsers.get(userId) != uss) { 19105 stopped = false; 19106 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19107 stopped = false; 19108 } else { 19109 stopped = true; 19110 // User can no longer run. 19111 mStartedUsers.remove(userId); 19112 mUserLru.remove(Integer.valueOf(userId)); 19113 updateStartedUserArrayLocked(); 19114 19115 // Clean up all state and processes associated with the user. 19116 // Kill all the processes for the user. 19117 forceStopUserLocked(userId, "finish user"); 19118 } 19119 19120 // Explicitly remove the old information in mRecentTasks. 19121 removeRecentTasksForUserLocked(userId); 19122 } 19123 19124 for (int i=0; i<callbacks.size(); i++) { 19125 try { 19126 if (stopped) callbacks.get(i).userStopped(userId); 19127 else callbacks.get(i).userStopAborted(userId); 19128 } catch (RemoteException e) { 19129 } 19130 } 19131 19132 if (stopped) { 19133 mSystemServiceManager.cleanupUser(userId); 19134 synchronized (this) { 19135 mStackSupervisor.removeUserLocked(userId); 19136 } 19137 } 19138 } 19139 19140 @Override 19141 public UserInfo getCurrentUser() { 19142 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19143 != PackageManager.PERMISSION_GRANTED) && ( 19144 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19145 != PackageManager.PERMISSION_GRANTED)) { 19146 String msg = "Permission Denial: getCurrentUser() from pid=" 19147 + Binder.getCallingPid() 19148 + ", uid=" + Binder.getCallingUid() 19149 + " requires " + INTERACT_ACROSS_USERS; 19150 Slog.w(TAG, msg); 19151 throw new SecurityException(msg); 19152 } 19153 synchronized (this) { 19154 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19155 return getUserManagerLocked().getUserInfo(userId); 19156 } 19157 } 19158 19159 int getCurrentUserIdLocked() { 19160 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19161 } 19162 19163 @Override 19164 public boolean isUserRunning(int userId, boolean orStopped) { 19165 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19166 != PackageManager.PERMISSION_GRANTED) { 19167 String msg = "Permission Denial: isUserRunning() from pid=" 19168 + Binder.getCallingPid() 19169 + ", uid=" + Binder.getCallingUid() 19170 + " requires " + INTERACT_ACROSS_USERS; 19171 Slog.w(TAG, msg); 19172 throw new SecurityException(msg); 19173 } 19174 synchronized (this) { 19175 return isUserRunningLocked(userId, orStopped); 19176 } 19177 } 19178 19179 boolean isUserRunningLocked(int userId, boolean orStopped) { 19180 UserStartedState state = mStartedUsers.get(userId); 19181 if (state == null) { 19182 return false; 19183 } 19184 if (orStopped) { 19185 return true; 19186 } 19187 return state.mState != UserStartedState.STATE_STOPPING 19188 && state.mState != UserStartedState.STATE_SHUTDOWN; 19189 } 19190 19191 @Override 19192 public int[] getRunningUserIds() { 19193 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19194 != PackageManager.PERMISSION_GRANTED) { 19195 String msg = "Permission Denial: isUserRunning() from pid=" 19196 + Binder.getCallingPid() 19197 + ", uid=" + Binder.getCallingUid() 19198 + " requires " + INTERACT_ACROSS_USERS; 19199 Slog.w(TAG, msg); 19200 throw new SecurityException(msg); 19201 } 19202 synchronized (this) { 19203 return mStartedUserArray; 19204 } 19205 } 19206 19207 private void updateStartedUserArrayLocked() { 19208 int num = 0; 19209 for (int i=0; i<mStartedUsers.size(); i++) { 19210 UserStartedState uss = mStartedUsers.valueAt(i); 19211 // This list does not include stopping users. 19212 if (uss.mState != UserStartedState.STATE_STOPPING 19213 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19214 num++; 19215 } 19216 } 19217 mStartedUserArray = new int[num]; 19218 num = 0; 19219 for (int i=0; i<mStartedUsers.size(); i++) { 19220 UserStartedState uss = mStartedUsers.valueAt(i); 19221 if (uss.mState != UserStartedState.STATE_STOPPING 19222 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19223 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19224 num++; 19225 } 19226 } 19227 } 19228 19229 @Override 19230 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19231 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19232 != PackageManager.PERMISSION_GRANTED) { 19233 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19234 + Binder.getCallingPid() 19235 + ", uid=" + Binder.getCallingUid() 19236 + " requires " + INTERACT_ACROSS_USERS_FULL; 19237 Slog.w(TAG, msg); 19238 throw new SecurityException(msg); 19239 } 19240 19241 mUserSwitchObservers.register(observer); 19242 } 19243 19244 @Override 19245 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19246 mUserSwitchObservers.unregister(observer); 19247 } 19248 19249 private boolean userExists(int userId) { 19250 if (userId == 0) { 19251 return true; 19252 } 19253 UserManagerService ums = getUserManagerLocked(); 19254 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19255 } 19256 19257 int[] getUsersLocked() { 19258 UserManagerService ums = getUserManagerLocked(); 19259 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19260 } 19261 19262 UserManagerService getUserManagerLocked() { 19263 if (mUserManager == null) { 19264 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19265 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19266 } 19267 return mUserManager; 19268 } 19269 19270 private int applyUserId(int uid, int userId) { 19271 return UserHandle.getUid(userId, uid); 19272 } 19273 19274 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19275 if (info == null) return null; 19276 ApplicationInfo newInfo = new ApplicationInfo(info); 19277 newInfo.uid = applyUserId(info.uid, userId); 19278 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19279 + info.packageName; 19280 return newInfo; 19281 } 19282 19283 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19284 if (aInfo == null 19285 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19286 return aInfo; 19287 } 19288 19289 ActivityInfo info = new ActivityInfo(aInfo); 19290 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19291 return info; 19292 } 19293 19294 private final class LocalService extends ActivityManagerInternal { 19295 @Override 19296 public void onWakefulnessChanged(int wakefulness) { 19297 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19298 } 19299 19300 @Override 19301 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19302 String processName, String abiOverride, int uid, Runnable crashHandler) { 19303 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19304 processName, abiOverride, uid, crashHandler); 19305 } 19306 } 19307 19308 /** 19309 * An implementation of IAppTask, that allows an app to manage its own tasks via 19310 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19311 * only the process that calls getAppTasks() can call the AppTask methods. 19312 */ 19313 class AppTaskImpl extends IAppTask.Stub { 19314 private int mTaskId; 19315 private int mCallingUid; 19316 19317 public AppTaskImpl(int taskId, int callingUid) { 19318 mTaskId = taskId; 19319 mCallingUid = callingUid; 19320 } 19321 19322 private void checkCaller() { 19323 if (mCallingUid != Binder.getCallingUid()) { 19324 throw new SecurityException("Caller " + mCallingUid 19325 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19326 } 19327 } 19328 19329 @Override 19330 public void finishAndRemoveTask() { 19331 checkCaller(); 19332 19333 synchronized (ActivityManagerService.this) { 19334 long origId = Binder.clearCallingIdentity(); 19335 try { 19336 if (!removeTaskByIdLocked(mTaskId, false)) { 19337 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19338 } 19339 } finally { 19340 Binder.restoreCallingIdentity(origId); 19341 } 19342 } 19343 } 19344 19345 @Override 19346 public ActivityManager.RecentTaskInfo getTaskInfo() { 19347 checkCaller(); 19348 19349 synchronized (ActivityManagerService.this) { 19350 long origId = Binder.clearCallingIdentity(); 19351 try { 19352 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19353 if (tr == null) { 19354 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19355 } 19356 return createRecentTaskInfoFromTaskRecord(tr); 19357 } finally { 19358 Binder.restoreCallingIdentity(origId); 19359 } 19360 } 19361 } 19362 19363 @Override 19364 public void moveToFront() { 19365 checkCaller(); 19366 19367 final TaskRecord tr; 19368 synchronized (ActivityManagerService.this) { 19369 tr = recentTaskForIdLocked(mTaskId); 19370 if (tr == null) { 19371 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19372 } 19373 if (tr.getRootActivity() != null) { 19374 moveTaskToFrontLocked(tr.taskId, 0, null); 19375 return; 19376 } 19377 } 19378 19379 startActivityFromRecentsInner(tr.taskId, null); 19380 } 19381 19382 @Override 19383 public int startActivity(IBinder whoThread, String callingPackage, 19384 Intent intent, String resolvedType, Bundle options) { 19385 checkCaller(); 19386 19387 int callingUser = UserHandle.getCallingUserId(); 19388 TaskRecord tr; 19389 IApplicationThread appThread; 19390 synchronized (ActivityManagerService.this) { 19391 tr = recentTaskForIdLocked(mTaskId); 19392 if (tr == null) { 19393 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19394 } 19395 appThread = ApplicationThreadNative.asInterface(whoThread); 19396 if (appThread == null) { 19397 throw new IllegalArgumentException("Bad app thread " + appThread); 19398 } 19399 } 19400 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19401 resolvedType, null, null, null, null, 0, 0, null, null, 19402 null, options, callingUser, null, tr); 19403 } 19404 19405 @Override 19406 public void setExcludeFromRecents(boolean exclude) { 19407 checkCaller(); 19408 19409 synchronized (ActivityManagerService.this) { 19410 long origId = Binder.clearCallingIdentity(); 19411 try { 19412 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19413 if (tr == null) { 19414 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19415 } 19416 Intent intent = tr.getBaseIntent(); 19417 if (exclude) { 19418 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19419 } else { 19420 intent.setFlags(intent.getFlags() 19421 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19422 } 19423 } finally { 19424 Binder.restoreCallingIdentity(origId); 19425 } 19426 } 19427 } 19428 } 19429} 19430