ActivityManagerService.java revision ae6cc8af2674909924fb18cb73763a110bee63dd
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35import android.Manifest; 36import android.app.AppOpsManager; 37import android.app.ApplicationThreadNative; 38import android.app.IActivityContainer; 39import android.app.IActivityContainerCallback; 40import android.app.IAppTask; 41import android.app.ITaskStackListener; 42import android.app.ProfilerInfo; 43import android.app.admin.DevicePolicyManager; 44import android.app.usage.UsageEvents; 45import android.app.usage.UsageStatsManagerInternal; 46import android.appwidget.AppWidgetManager; 47import android.content.res.Resources; 48import android.graphics.Bitmap; 49import android.graphics.Point; 50import android.graphics.Rect; 51import android.os.BatteryStats; 52import android.os.PersistableBundle; 53import android.os.storage.IMountService; 54import android.os.storage.StorageManager; 55import android.service.voice.IVoiceInteractionSession; 56import android.util.ArrayMap; 57import android.util.ArraySet; 58import android.util.SparseIntArray; 59 60import com.android.internal.R; 61import com.android.internal.annotations.GuardedBy; 62import com.android.internal.app.IAppOpsService; 63import com.android.internal.app.IVoiceInteractor; 64import com.android.internal.app.ProcessMap; 65import com.android.internal.app.ProcessStats; 66import com.android.internal.os.BackgroundThread; 67import com.android.internal.os.BatteryStatsImpl; 68import com.android.internal.os.ProcessCpuTracker; 69import com.android.internal.os.TransferPipe; 70import com.android.internal.os.Zygote; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.MemInfoReader; 74import com.android.internal.util.Preconditions; 75import com.android.server.AppOpsService; 76import com.android.server.AttributeCache; 77import com.android.server.IntentResolver; 78import com.android.server.LocalServices; 79import com.android.server.ServiceThread; 80import com.android.server.SystemService; 81import com.android.server.SystemServiceManager; 82import com.android.server.Watchdog; 83import com.android.server.am.ActivityStack.ActivityState; 84import com.android.server.firewall.IntentFirewall; 85import com.android.server.pm.Installer; 86import com.android.server.pm.UserManagerService; 87import com.android.server.statusbar.StatusBarManagerInternal; 88import com.android.server.wm.AppTransition; 89import com.android.server.wm.WindowManagerService; 90import com.google.android.collect.Lists; 91import com.google.android.collect.Maps; 92 93import libcore.io.IoUtils; 94 95import org.xmlpull.v1.XmlPullParser; 96import org.xmlpull.v1.XmlPullParserException; 97import org.xmlpull.v1.XmlSerializer; 98 99import android.app.Activity; 100import android.app.ActivityManager; 101import android.app.ActivityManager.RunningTaskInfo; 102import android.app.ActivityManager.StackInfo; 103import android.app.ActivityManagerInternal; 104import android.app.ActivityManagerNative; 105import android.app.ActivityOptions; 106import android.app.ActivityThread; 107import android.app.AlertDialog; 108import android.app.AppGlobals; 109import android.app.ApplicationErrorReport; 110import android.app.Dialog; 111import android.app.IActivityController; 112import android.app.IApplicationThread; 113import android.app.IInstrumentationWatcher; 114import android.app.INotificationManager; 115import android.app.IProcessObserver; 116import android.app.IServiceConnection; 117import android.app.IStopUserCallback; 118import android.app.IUiAutomationConnection; 119import android.app.IUserSwitchObserver; 120import android.app.Instrumentation; 121import android.app.Notification; 122import android.app.NotificationManager; 123import android.app.PendingIntent; 124import android.app.backup.IBackupManager; 125import android.content.ActivityNotFoundException; 126import android.content.BroadcastReceiver; 127import android.content.ClipData; 128import android.content.ComponentCallbacks2; 129import android.content.ComponentName; 130import android.content.ContentProvider; 131import android.content.ContentResolver; 132import android.content.Context; 133import android.content.DialogInterface; 134import android.content.IContentProvider; 135import android.content.IIntentReceiver; 136import android.content.IIntentSender; 137import android.content.Intent; 138import android.content.IntentFilter; 139import android.content.IntentSender; 140import android.content.pm.ActivityInfo; 141import android.content.pm.ApplicationInfo; 142import android.content.pm.ConfigurationInfo; 143import android.content.pm.IPackageDataObserver; 144import android.content.pm.IPackageManager; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.PackageInfo; 147import android.content.pm.PackageManager; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.UserInfo; 150import android.content.pm.PackageManager.NameNotFoundException; 151import android.content.pm.PathPermission; 152import android.content.pm.ProviderInfo; 153import android.content.pm.ResolveInfo; 154import android.content.pm.ServiceInfo; 155import android.content.res.CompatibilityInfo; 156import android.content.res.Configuration; 157import android.net.Proxy; 158import android.net.ProxyInfo; 159import android.net.Uri; 160import android.os.Binder; 161import android.os.Build; 162import android.os.Bundle; 163import android.os.Debug; 164import android.os.DropBoxManager; 165import android.os.Environment; 166import android.os.FactoryTest; 167import android.os.FileObserver; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.IPermissionController; 172import android.os.IRemoteCallback; 173import android.os.IUserManager; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.PowerManagerInternal; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.SELinux; 183import android.os.ServiceManager; 184import android.os.StrictMode; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.UpdateLock; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.provider.Settings; 191import android.text.format.DateUtils; 192import android.text.format.Time; 193import android.util.AtomicFile; 194import android.util.EventLog; 195import android.util.Log; 196import android.util.Pair; 197import android.util.PrintWriterPrinter; 198import android.util.Slog; 199import android.util.SparseArray; 200import android.util.TimeUtils; 201import android.util.Xml; 202import android.view.Gravity; 203import android.view.LayoutInflater; 204import android.view.View; 205import android.view.WindowManager; 206 207import dalvik.system.VMRuntime; 208 209import java.io.BufferedInputStream; 210import java.io.BufferedOutputStream; 211import java.io.DataInputStream; 212import java.io.DataOutputStream; 213import java.io.File; 214import java.io.FileDescriptor; 215import java.io.FileInputStream; 216import java.io.FileNotFoundException; 217import java.io.FileOutputStream; 218import java.io.IOException; 219import java.io.InputStreamReader; 220import java.io.PrintWriter; 221import java.io.StringWriter; 222import java.lang.ref.WeakReference; 223import java.util.ArrayList; 224import java.util.Arrays; 225import java.util.Collections; 226import java.util.Comparator; 227import java.util.HashMap; 228import java.util.HashSet; 229import java.util.Iterator; 230import java.util.List; 231import java.util.Locale; 232import java.util.Map; 233import java.util.Set; 234import java.util.concurrent.atomic.AtomicBoolean; 235import java.util.concurrent.atomic.AtomicLong; 236 237public final class ActivityManagerService extends ActivityManagerNative 238 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 239 240 private static final String USER_DATA_DIR = "/data/user/"; 241 // File that stores last updated system version and called preboot receivers 242 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 243 244 static final String TAG = "ActivityManager"; 245 static final String TAG_MU = "ActivityManagerServiceMU"; 246 static final boolean DEBUG = false; 247 static final boolean localLOGV = DEBUG; 248 static final boolean DEBUG_BACKUP = localLOGV || false; 249 static final boolean DEBUG_BROADCAST = localLOGV || false; 250 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_CLEANUP = localLOGV || false; 253 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 254 static final boolean DEBUG_FOCUS = false; 255 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 256 static final boolean DEBUG_MU = localLOGV || false; 257 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 258 static final boolean DEBUG_LRU = localLOGV || false; 259 static final boolean DEBUG_PAUSE = localLOGV || false; 260 static final boolean DEBUG_POWER = localLOGV || false; 261 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 262 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 263 static final boolean DEBUG_PROCESSES = localLOGV || false; 264 static final boolean DEBUG_PROVIDER = localLOGV || false; 265 static final boolean DEBUG_RESULTS = localLOGV || false; 266 static final boolean DEBUG_SERVICE = localLOGV || false; 267 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 268 static final boolean DEBUG_STACK = localLOGV || false; 269 static final boolean DEBUG_SWITCH = localLOGV || false; 270 static final boolean DEBUG_TASKS = localLOGV || false; 271 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 272 static final boolean DEBUG_TRANSITION = localLOGV || false; 273 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 274 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 275 static final boolean DEBUG_VISBILITY = localLOGV || false; 276 static final boolean DEBUG_PSS = localLOGV || false; 277 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 278 static final boolean DEBUG_RECENTS = localLOGV || false; 279 static final boolean VALIDATE_TOKENS = false; 280 static final boolean SHOW_ACTIVITY_START_TIME = true; 281 282 // Control over CPU and battery monitoring. 283 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 284 static final boolean MONITOR_CPU_USAGE = true; 285 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 286 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 287 static final boolean MONITOR_THREAD_CPU_USAGE = false; 288 289 // The flags that are set for all calls we make to the package manager. 290 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 291 292 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 293 294 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 295 296 // Maximum number recent bitmaps to keep in memory. 297 static final int MAX_RECENT_BITMAPS = 3; 298 299 // Amount of time after a call to stopAppSwitches() during which we will 300 // prevent further untrusted switches from happening. 301 static final long APP_SWITCH_DELAY_TIME = 5*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real. 305 static final int PROC_START_TIMEOUT = 10*1000; 306 307 // How long we wait for a launched process to attach to the activity manager 308 // before we decide it's never going to come up for real, when the process was 309 // started with a wrapper for instrumentation (such as Valgrind) because it 310 // could take much longer than usual. 311 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 312 313 // How long to wait after going idle before forcing apps to GC. 314 static final int GC_TIMEOUT = 5*1000; 315 316 // The minimum amount of time between successive GC requests for a process. 317 static final int GC_MIN_INTERVAL = 60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process. 320 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 321 322 // The minimum amount of time between successive PSS requests for a process 323 // when the request is due to the memory state being lowered. 324 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 325 326 // The rate at which we check for apps using excessive power -- 15 mins. 327 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on wake locks to start killing things. 331 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // The minimum sample duration we will allow before deciding we have 334 // enough data on CPU usage to start killing things. 335 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 336 337 // How long we allow a receiver to run before giving up on it. 338 static final int BROADCAST_FG_TIMEOUT = 10*1000; 339 static final int BROADCAST_BG_TIMEOUT = 60*1000; 340 341 // How long we wait until we timeout on key dispatching. 342 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 343 344 // How long we wait until we timeout on key dispatching during instrumentation. 345 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 346 347 // Amount of time we wait for observers to handle a user switch before 348 // giving up on them and unfreezing the screen. 349 static final int USER_SWITCH_TIMEOUT = 2*1000; 350 351 // Maximum number of users we allow to be running at a time. 352 static final int MAX_RUNNING_USERS = 3; 353 354 // How long to wait in getAssistContextExtras for the activity and foreground services 355 // to respond with the result. 356 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 357 358 // Maximum number of persisted Uri grants a package is allowed 359 static final int MAX_PERSISTED_URI_GRANTS = 128; 360 361 static final int MY_PID = Process.myPid(); 362 363 static final String[] EMPTY_STRING_ARRAY = new String[0]; 364 365 // How many bytes to write into the dropbox log before truncating 366 static final int DROPBOX_MAX_SIZE = 256 * 1024; 367 368 // Access modes for handleIncomingUser. 369 static final int ALLOW_NON_FULL = 0; 370 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 371 static final int ALLOW_FULL_ONLY = 2; 372 373 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 374 375 // Delay in notifying task stack change listeners (in millis) 376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 377 378 /** All system services */ 379 SystemServiceManager mSystemServiceManager; 380 381 private Installer mInstaller; 382 383 /** Run all ActivityStacks through this */ 384 ActivityStackSupervisor mStackSupervisor; 385 386 /** Task stack change listeners. */ 387 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 388 new RemoteCallbackList<ITaskStackListener>(); 389 390 public IntentFirewall mIntentFirewall; 391 392 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 393 // default actuion automatically. Important for devices without direct input 394 // devices. 395 private boolean mShowDialogs = true; 396 397 BroadcastQueue mFgBroadcastQueue; 398 BroadcastQueue mBgBroadcastQueue; 399 // Convenient for easy iteration over the queues. Foreground is first 400 // so that dispatch of foreground broadcasts gets precedence. 401 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 402 403 BroadcastQueue broadcastQueueForIntent(Intent intent) { 404 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 405 if (DEBUG_BACKGROUND_BROADCAST) { 406 Slog.i(TAG, "Broadcast intent " + intent + " on " 407 + (isFg ? "foreground" : "background") 408 + " queue"); 409 } 410 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 411 } 412 413 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 414 for (BroadcastQueue queue : mBroadcastQueues) { 415 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 416 if (r != null) { 417 return r; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Activity we have told the window manager to have key focus. 425 */ 426 ActivityRecord mFocusedActivity = null; 427 428 /** 429 * List of intents that were used to start the most recent tasks. 430 */ 431 ArrayList<TaskRecord> mRecentTasks; 432 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 433 434 /** 435 * For addAppTask: cached of the last activity component that was added. 436 */ 437 ComponentName mLastAddedTaskComponent; 438 439 /** 440 * For addAppTask: cached of the last activity uid that was added. 441 */ 442 int mLastAddedTaskUid; 443 444 /** 445 * For addAppTask: cached of the last ActivityInfo that was added. 446 */ 447 ActivityInfo mLastAddedTaskActivity; 448 449 public class PendingAssistExtras extends Binder implements Runnable { 450 public final ActivityRecord activity; 451 public final Bundle extras; 452 public final Intent intent; 453 public final String hint; 454 public final int userHandle; 455 public boolean haveResult = false; 456 public Bundle result = null; 457 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 458 String _hint, int _userHandle) { 459 activity = _activity; 460 extras = _extras; 461 intent = _intent; 462 hint = _hint; 463 userHandle = _userHandle; 464 } 465 @Override 466 public void run() { 467 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 468 synchronized (this) { 469 haveResult = true; 470 notifyAll(); 471 } 472 } 473 } 474 475 final ArrayList<PendingAssistExtras> mPendingAssistExtras 476 = new ArrayList<PendingAssistExtras>(); 477 478 /** 479 * Process management. 480 */ 481 final ProcessList mProcessList = new ProcessList(); 482 483 /** 484 * All of the applications we currently have running organized by name. 485 * The keys are strings of the application package name (as 486 * returned by the package manager), and the keys are ApplicationRecord 487 * objects. 488 */ 489 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 490 491 /** 492 * Tracking long-term execution of processes to look for abuse and other 493 * bad app behavior. 494 */ 495 final ProcessStatsService mProcessStats; 496 497 /** 498 * The currently running isolated processes. 499 */ 500 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 501 502 /** 503 * Counter for assigning isolated process uids, to avoid frequently reusing the 504 * same ones. 505 */ 506 int mNextIsolatedProcessUid = 0; 507 508 /** 509 * The currently running heavy-weight process, if any. 510 */ 511 ProcessRecord mHeavyWeightProcess = null; 512 513 /** 514 * The last time that various processes have crashed. 515 */ 516 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 517 518 /** 519 * Information about a process that is currently marked as bad. 520 */ 521 static final class BadProcessInfo { 522 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 523 this.time = time; 524 this.shortMsg = shortMsg; 525 this.longMsg = longMsg; 526 this.stack = stack; 527 } 528 529 final long time; 530 final String shortMsg; 531 final String longMsg; 532 final String stack; 533 } 534 535 /** 536 * Set of applications that we consider to be bad, and will reject 537 * incoming broadcasts from (which the user has no control over). 538 * Processes are added to this set when they have crashed twice within 539 * a minimum amount of time; they are removed from it when they are 540 * later restarted (hopefully due to some user action). The value is the 541 * time it was added to the list. 542 */ 543 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 544 545 /** 546 * All of the processes we currently have running organized by pid. 547 * The keys are the pid running the application. 548 * 549 * <p>NOTE: This object is protected by its own lock, NOT the global 550 * activity manager lock! 551 */ 552 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 553 554 /** 555 * All of the processes that have been forced to be foreground. The key 556 * is the pid of the caller who requested it (we hold a death 557 * link on it). 558 */ 559 abstract class ForegroundToken implements IBinder.DeathRecipient { 560 int pid; 561 IBinder token; 562 } 563 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 564 565 /** 566 * List of records for processes that someone had tried to start before the 567 * system was ready. We don't start them at that point, but ensure they 568 * are started by the time booting is complete. 569 */ 570 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of persistent applications that are in the process 574 * of being started. 575 */ 576 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes that are being forcibly torn down. 580 */ 581 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * List of running applications, sorted by recent usage. 585 * The first entry in the list is the least recently used. 586 */ 587 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Where in mLruProcesses that the processes hosting activities start. 591 */ 592 int mLruProcessActivityStart = 0; 593 594 /** 595 * Where in mLruProcesses that the processes hosting services start. 596 * This is after (lower index) than mLruProcessesActivityStart. 597 */ 598 int mLruProcessServiceStart = 0; 599 600 /** 601 * List of processes that should gc as soon as things are idle. 602 */ 603 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 604 605 /** 606 * Processes we want to collect PSS data from. 607 */ 608 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 609 610 /** 611 * Last time we requested PSS data of all processes. 612 */ 613 long mLastFullPssTime = SystemClock.uptimeMillis(); 614 615 /** 616 * If set, the next time we collect PSS data we should do a full collection 617 * with data from native processes and the kernel. 618 */ 619 boolean mFullPssPending = false; 620 621 /** 622 * This is the process holding what we currently consider to be 623 * the "home" activity. 624 */ 625 ProcessRecord mHomeProcess; 626 627 /** 628 * This is the process holding the activity the user last visited that 629 * is in a different process from the one they are currently in. 630 */ 631 ProcessRecord mPreviousProcess; 632 633 /** 634 * The time at which the previous process was last visible. 635 */ 636 long mPreviousProcessVisibleTime; 637 638 /** 639 * Which uses have been started, so are allowed to run code. 640 */ 641 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 642 643 /** 644 * LRU list of history of current users. Most recently current is at the end. 645 */ 646 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 647 648 /** 649 * Constant array of the users that are currently started. 650 */ 651 int[] mStartedUserArray = new int[] { 0 }; 652 653 /** 654 * Registered observers of the user switching mechanics. 655 */ 656 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 657 = new RemoteCallbackList<IUserSwitchObserver>(); 658 659 /** 660 * Currently active user switch. 661 */ 662 Object mCurUserSwitchCallback; 663 664 /** 665 * Packages that the user has asked to have run in screen size 666 * compatibility mode instead of filling the screen. 667 */ 668 final CompatModePackages mCompatModePackages; 669 670 /** 671 * Set of IntentSenderRecord objects that are currently active. 672 */ 673 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 674 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 675 676 /** 677 * Fingerprints (hashCode()) of stack traces that we've 678 * already logged DropBox entries for. Guarded by itself. If 679 * something (rogue user app) forces this over 680 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 681 */ 682 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 683 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 684 685 /** 686 * Strict Mode background batched logging state. 687 * 688 * The string buffer is guarded by itself, and its lock is also 689 * used to determine if another batched write is already 690 * in-flight. 691 */ 692 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 693 694 /** 695 * Keeps track of all IIntentReceivers that have been registered for 696 * broadcasts. Hash keys are the receiver IBinder, hash value is 697 * a ReceiverList. 698 */ 699 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 700 new HashMap<IBinder, ReceiverList>(); 701 702 /** 703 * Resolver for broadcast intents to registered receivers. 704 * Holds BroadcastFilter (subclass of IntentFilter). 705 */ 706 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 707 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 708 @Override 709 protected boolean allowFilterResult( 710 BroadcastFilter filter, List<BroadcastFilter> dest) { 711 IBinder target = filter.receiverList.receiver.asBinder(); 712 for (int i=dest.size()-1; i>=0; i--) { 713 if (dest.get(i).receiverList.receiver.asBinder() == target) { 714 return false; 715 } 716 } 717 return true; 718 } 719 720 @Override 721 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 722 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 723 || userId == filter.owningUserId) { 724 return super.newResult(filter, match, userId); 725 } 726 return null; 727 } 728 729 @Override 730 protected BroadcastFilter[] newArray(int size) { 731 return new BroadcastFilter[size]; 732 } 733 734 @Override 735 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 736 return packageName.equals(filter.packageName); 737 } 738 }; 739 740 /** 741 * State of all active sticky broadcasts per user. Keys are the action of the 742 * sticky Intent, values are an ArrayList of all broadcasted intents with 743 * that action (which should usually be one). The SparseArray is keyed 744 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 745 * for stickies that are sent to all users. 746 */ 747 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 748 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 749 750 final ActiveServices mServices; 751 752 /** 753 * Backup/restore process management 754 */ 755 String mBackupAppName = null; 756 BackupRecord mBackupTarget = null; 757 758 final ProviderMap mProviderMap; 759 760 /** 761 * List of content providers who have clients waiting for them. The 762 * application is currently being launched and the provider will be 763 * removed from this list once it is published. 764 */ 765 final ArrayList<ContentProviderRecord> mLaunchingProviders 766 = new ArrayList<ContentProviderRecord>(); 767 768 /** 769 * File storing persisted {@link #mGrantedUriPermissions}. 770 */ 771 private final AtomicFile mGrantFile; 772 773 /** XML constants used in {@link #mGrantFile} */ 774 private static final String TAG_URI_GRANTS = "uri-grants"; 775 private static final String TAG_URI_GRANT = "uri-grant"; 776 private static final String ATTR_USER_HANDLE = "userHandle"; 777 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 778 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 779 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 780 private static final String ATTR_TARGET_PKG = "targetPkg"; 781 private static final String ATTR_URI = "uri"; 782 private static final String ATTR_MODE_FLAGS = "modeFlags"; 783 private static final String ATTR_CREATED_TIME = "createdTime"; 784 private static final String ATTR_PREFIX = "prefix"; 785 786 /** 787 * Global set of specific {@link Uri} permissions that have been granted. 788 * This optimized lookup structure maps from {@link UriPermission#targetUid} 789 * to {@link UriPermission#uri} to {@link UriPermission}. 790 */ 791 @GuardedBy("this") 792 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 793 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 794 795 public static class GrantUri { 796 public final int sourceUserId; 797 public final Uri uri; 798 public boolean prefix; 799 800 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 801 this.sourceUserId = sourceUserId; 802 this.uri = uri; 803 this.prefix = prefix; 804 } 805 806 @Override 807 public int hashCode() { 808 int hashCode = 1; 809 hashCode = 31 * hashCode + sourceUserId; 810 hashCode = 31 * hashCode + uri.hashCode(); 811 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 812 return hashCode; 813 } 814 815 @Override 816 public boolean equals(Object o) { 817 if (o instanceof GrantUri) { 818 GrantUri other = (GrantUri) o; 819 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 820 && prefix == other.prefix; 821 } 822 return false; 823 } 824 825 @Override 826 public String toString() { 827 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 828 if (prefix) result += " [prefix]"; 829 return result; 830 } 831 832 public String toSafeString() { 833 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 834 if (prefix) result += " [prefix]"; 835 return result; 836 } 837 838 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 839 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 840 ContentProvider.getUriWithoutUserId(uri), false); 841 } 842 } 843 844 CoreSettingsObserver mCoreSettingsObserver; 845 846 /** 847 * Thread-local storage used to carry caller permissions over through 848 * indirect content-provider access. 849 */ 850 private class Identity { 851 public final IBinder token; 852 public final int pid; 853 public final int uid; 854 855 Identity(IBinder _token, int _pid, int _uid) { 856 token = _token; 857 pid = _pid; 858 uid = _uid; 859 } 860 } 861 862 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 863 864 /** 865 * All information we have collected about the runtime performance of 866 * any user id that can impact battery performance. 867 */ 868 final BatteryStatsService mBatteryStatsService; 869 870 /** 871 * Information about component usage 872 */ 873 UsageStatsManagerInternal mUsageStatsService; 874 875 /** 876 * Information about and control over application operations 877 */ 878 final AppOpsService mAppOpsService; 879 880 /** 881 * Save recent tasks information across reboots. 882 */ 883 final TaskPersister mTaskPersister; 884 885 /** 886 * Current configuration information. HistoryRecord objects are given 887 * a reference to this object to indicate which configuration they are 888 * currently running in, so this object must be kept immutable. 889 */ 890 Configuration mConfiguration = new Configuration(); 891 892 /** 893 * Current sequencing integer of the configuration, for skipping old 894 * configurations. 895 */ 896 int mConfigurationSeq = 0; 897 898 /** 899 * Hardware-reported OpenGLES version. 900 */ 901 final int GL_ES_VERSION; 902 903 /** 904 * List of initialization arguments to pass to all processes when binding applications to them. 905 * For example, references to the commonly used services. 906 */ 907 HashMap<String, IBinder> mAppBindArgs; 908 909 /** 910 * Temporary to avoid allocations. Protected by main lock. 911 */ 912 final StringBuilder mStringBuilder = new StringBuilder(256); 913 914 /** 915 * Used to control how we initialize the service. 916 */ 917 ComponentName mTopComponent; 918 String mTopAction = Intent.ACTION_MAIN; 919 String mTopData; 920 boolean mProcessesReady = false; 921 boolean mSystemReady = false; 922 boolean mBooting = false; 923 boolean mCallFinishBooting = false; 924 boolean mBootAnimationComplete = false; 925 boolean mWaitingUpdate = false; 926 boolean mDidUpdate = false; 927 boolean mOnBattery = false; 928 boolean mLaunchWarningShown = false; 929 930 Context mContext; 931 932 int mFactoryTest; 933 934 boolean mCheckedForSetup; 935 936 /** 937 * The time at which we will allow normal application switches again, 938 * after a call to {@link #stopAppSwitches()}. 939 */ 940 long mAppSwitchesAllowedTime; 941 942 /** 943 * This is set to true after the first switch after mAppSwitchesAllowedTime 944 * is set; any switches after that will clear the time. 945 */ 946 boolean mDidAppSwitch; 947 948 /** 949 * Last time (in realtime) at which we checked for power usage. 950 */ 951 long mLastPowerCheckRealtime; 952 953 /** 954 * Last time (in uptime) at which we checked for power usage. 955 */ 956 long mLastPowerCheckUptime; 957 958 /** 959 * Set while we are wanting to sleep, to prevent any 960 * activities from being started/resumed. 961 */ 962 private boolean mSleeping = false; 963 964 /** 965 * Set while we are running a voice interaction. This overrides 966 * sleeping while it is active. 967 */ 968 private boolean mRunningVoice = false; 969 970 /** 971 * State of external calls telling us if the device is awake or asleep. 972 */ 973 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 974 975 static final int LOCK_SCREEN_HIDDEN = 0; 976 static final int LOCK_SCREEN_LEAVING = 1; 977 static final int LOCK_SCREEN_SHOWN = 2; 978 /** 979 * State of external call telling us if the lock screen is shown. 980 */ 981 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 982 983 /** 984 * Set if we are shutting down the system, similar to sleeping. 985 */ 986 boolean mShuttingDown = false; 987 988 /** 989 * Current sequence id for oom_adj computation traversal. 990 */ 991 int mAdjSeq = 0; 992 993 /** 994 * Current sequence id for process LRU updating. 995 */ 996 int mLruSeq = 0; 997 998 /** 999 * Keep track of the non-cached/empty process we last found, to help 1000 * determine how to distribute cached/empty processes next time. 1001 */ 1002 int mNumNonCachedProcs = 0; 1003 1004 /** 1005 * Keep track of the number of cached hidden procs, to balance oom adj 1006 * distribution between those and empty procs. 1007 */ 1008 int mNumCachedHiddenProcs = 0; 1009 1010 /** 1011 * Keep track of the number of service processes we last found, to 1012 * determine on the next iteration which should be B services. 1013 */ 1014 int mNumServiceProcs = 0; 1015 int mNewNumAServiceProcs = 0; 1016 int mNewNumServiceProcs = 0; 1017 1018 /** 1019 * Allow the current computed overall memory level of the system to go down? 1020 * This is set to false when we are killing processes for reasons other than 1021 * memory management, so that the now smaller process list will not be taken as 1022 * an indication that memory is tighter. 1023 */ 1024 boolean mAllowLowerMemLevel = false; 1025 1026 /** 1027 * The last computed memory level, for holding when we are in a state that 1028 * processes are going away for other reasons. 1029 */ 1030 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1031 1032 /** 1033 * The last total number of process we have, to determine if changes actually look 1034 * like a shrinking number of process due to lower RAM. 1035 */ 1036 int mLastNumProcesses; 1037 1038 /** 1039 * The uptime of the last time we performed idle maintenance. 1040 */ 1041 long mLastIdleTime = SystemClock.uptimeMillis(); 1042 1043 /** 1044 * Total time spent with RAM that has been added in the past since the last idle time. 1045 */ 1046 long mLowRamTimeSinceLastIdle = 0; 1047 1048 /** 1049 * If RAM is currently low, when that horrible situation started. 1050 */ 1051 long mLowRamStartTime = 0; 1052 1053 /** 1054 * For reporting to battery stats the current top application. 1055 */ 1056 private String mCurResumedPackage = null; 1057 private int mCurResumedUid = -1; 1058 1059 /** 1060 * For reporting to battery stats the apps currently running foreground 1061 * service. The ProcessMap is package/uid tuples; each of these contain 1062 * an array of the currently foreground processes. 1063 */ 1064 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1065 = new ProcessMap<ArrayList<ProcessRecord>>(); 1066 1067 /** 1068 * This is set if we had to do a delayed dexopt of an app before launching 1069 * it, to increase the ANR timeouts in that case. 1070 */ 1071 boolean mDidDexOpt; 1072 1073 /** 1074 * Set if the systemServer made a call to enterSafeMode. 1075 */ 1076 boolean mSafeMode; 1077 1078 /** 1079 * If true, we are running under a test environment so will sample PSS from processes 1080 * much more rapidly to try to collect better data when the tests are rapidly 1081 * running through apps. 1082 */ 1083 boolean mTestPssMode = false; 1084 1085 String mDebugApp = null; 1086 boolean mWaitForDebugger = false; 1087 boolean mDebugTransient = false; 1088 String mOrigDebugApp = null; 1089 boolean mOrigWaitForDebugger = false; 1090 boolean mAlwaysFinishActivities = false; 1091 IActivityController mController = null; 1092 String mProfileApp = null; 1093 ProcessRecord mProfileProc = null; 1094 String mProfileFile; 1095 ParcelFileDescriptor mProfileFd; 1096 int mSamplingInterval = 0; 1097 boolean mAutoStopProfiler = false; 1098 int mProfileType = 0; 1099 String mOpenGlTraceApp = null; 1100 1101 final long[] mTmpLong = new long[1]; 1102 1103 static class ProcessChangeItem { 1104 static final int CHANGE_ACTIVITIES = 1<<0; 1105 static final int CHANGE_PROCESS_STATE = 1<<1; 1106 int changes; 1107 int uid; 1108 int pid; 1109 int processState; 1110 boolean foregroundActivities; 1111 } 1112 1113 final RemoteCallbackList<IProcessObserver> mProcessObservers 1114 = new RemoteCallbackList<IProcessObserver>(); 1115 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1116 1117 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1118 = new ArrayList<ProcessChangeItem>(); 1119 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1120 = new ArrayList<ProcessChangeItem>(); 1121 1122 /** 1123 * Runtime CPU use collection thread. This object's lock is used to 1124 * perform synchronization with the thread (notifying it to run). 1125 */ 1126 final Thread mProcessCpuThread; 1127 1128 /** 1129 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1130 * Must acquire this object's lock when accessing it. 1131 * NOTE: this lock will be held while doing long operations (trawling 1132 * through all processes in /proc), so it should never be acquired by 1133 * any critical paths such as when holding the main activity manager lock. 1134 */ 1135 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1136 MONITOR_THREAD_CPU_USAGE); 1137 final AtomicLong mLastCpuTime = new AtomicLong(0); 1138 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1139 1140 long mLastWriteTime = 0; 1141 1142 /** 1143 * Used to retain an update lock when the foreground activity is in 1144 * immersive mode. 1145 */ 1146 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1147 1148 /** 1149 * Set to true after the system has finished booting. 1150 */ 1151 boolean mBooted = false; 1152 1153 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1154 int mProcessLimitOverride = -1; 1155 1156 WindowManagerService mWindowManager; 1157 1158 final ActivityThread mSystemThread; 1159 1160 // Holds the current foreground user's id 1161 int mCurrentUserId = 0; 1162 // Holds the target user's id during a user switch 1163 int mTargetUserId = UserHandle.USER_NULL; 1164 // If there are multiple profiles for the current user, their ids are here 1165 // Currently only the primary user can have managed profiles 1166 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1167 1168 /** 1169 * Mapping from each known user ID to the profile group ID it is associated with. 1170 */ 1171 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1172 1173 private UserManagerService mUserManager; 1174 1175 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1176 final ProcessRecord mApp; 1177 final int mPid; 1178 final IApplicationThread mAppThread; 1179 1180 AppDeathRecipient(ProcessRecord app, int pid, 1181 IApplicationThread thread) { 1182 if (localLOGV) Slog.v( 1183 TAG, "New death recipient " + this 1184 + " for thread " + thread.asBinder()); 1185 mApp = app; 1186 mPid = pid; 1187 mAppThread = thread; 1188 } 1189 1190 @Override 1191 public void binderDied() { 1192 if (localLOGV) Slog.v( 1193 TAG, "Death received in " + this 1194 + " for thread " + mAppThread.asBinder()); 1195 synchronized(ActivityManagerService.this) { 1196 appDiedLocked(mApp, mPid, mAppThread); 1197 } 1198 } 1199 } 1200 1201 static final int SHOW_ERROR_MSG = 1; 1202 static final int SHOW_NOT_RESPONDING_MSG = 2; 1203 static final int SHOW_FACTORY_ERROR_MSG = 3; 1204 static final int UPDATE_CONFIGURATION_MSG = 4; 1205 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1206 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1207 static final int SERVICE_TIMEOUT_MSG = 12; 1208 static final int UPDATE_TIME_ZONE = 13; 1209 static final int SHOW_UID_ERROR_MSG = 14; 1210 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1211 static final int PROC_START_TIMEOUT_MSG = 20; 1212 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1213 static final int KILL_APPLICATION_MSG = 22; 1214 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1215 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1216 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1217 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1218 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1219 static final int CLEAR_DNS_CACHE_MSG = 28; 1220 static final int UPDATE_HTTP_PROXY_MSG = 29; 1221 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1222 static final int DISPATCH_PROCESSES_CHANGED = 31; 1223 static final int DISPATCH_PROCESS_DIED = 32; 1224 static final int REPORT_MEM_USAGE_MSG = 33; 1225 static final int REPORT_USER_SWITCH_MSG = 34; 1226 static final int CONTINUE_USER_SWITCH_MSG = 35; 1227 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1228 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1229 static final int PERSIST_URI_GRANTS_MSG = 38; 1230 static final int REQUEST_ALL_PSS_MSG = 39; 1231 static final int START_PROFILES_MSG = 40; 1232 static final int UPDATE_TIME = 41; 1233 static final int SYSTEM_USER_START_MSG = 42; 1234 static final int SYSTEM_USER_CURRENT_MSG = 43; 1235 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1236 static final int FINISH_BOOTING_MSG = 45; 1237 static final int START_USER_SWITCH_MSG = 46; 1238 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1239 static final int DISMISS_DIALOG_MSG = 48; 1240 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1241 1242 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1243 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1244 static final int FIRST_COMPAT_MODE_MSG = 300; 1245 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1246 1247 CompatModeDialog mCompatModeDialog; 1248 long mLastMemUsageReportTime = 0; 1249 1250 /** 1251 * Flag whether the current user is a "monkey", i.e. whether 1252 * the UI is driven by a UI automation tool. 1253 */ 1254 private boolean mUserIsMonkey; 1255 1256 /** Flag whether the device has a Recents UI */ 1257 boolean mHasRecents; 1258 1259 /** The dimensions of the thumbnails in the Recents UI. */ 1260 int mThumbnailWidth; 1261 int mThumbnailHeight; 1262 1263 final ServiceThread mHandlerThread; 1264 final MainHandler mHandler; 1265 1266 final class MainHandler extends Handler { 1267 public MainHandler(Looper looper) { 1268 super(looper, null, true); 1269 } 1270 1271 @Override 1272 public void handleMessage(Message msg) { 1273 switch (msg.what) { 1274 case SHOW_ERROR_MSG: { 1275 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1276 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1277 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1278 synchronized (ActivityManagerService.this) { 1279 ProcessRecord proc = (ProcessRecord)data.get("app"); 1280 AppErrorResult res = (AppErrorResult) data.get("result"); 1281 if (proc != null && proc.crashDialog != null) { 1282 Slog.e(TAG, "App already has crash dialog: " + proc); 1283 if (res != null) { 1284 res.set(0); 1285 } 1286 return; 1287 } 1288 boolean isBackground = (UserHandle.getAppId(proc.uid) 1289 >= Process.FIRST_APPLICATION_UID 1290 && proc.pid != MY_PID); 1291 for (int userId : mCurrentProfileIds) { 1292 isBackground &= (proc.userId != userId); 1293 } 1294 if (isBackground && !showBackground) { 1295 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1296 if (res != null) { 1297 res.set(0); 1298 } 1299 return; 1300 } 1301 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1302 Dialog d = new AppErrorDialog(mContext, 1303 ActivityManagerService.this, res, proc); 1304 d.show(); 1305 proc.crashDialog = d; 1306 } else { 1307 // The device is asleep, so just pretend that the user 1308 // saw a crash dialog and hit "force quit". 1309 if (res != null) { 1310 res.set(0); 1311 } 1312 } 1313 } 1314 1315 ensureBootCompleted(); 1316 } break; 1317 case SHOW_NOT_RESPONDING_MSG: { 1318 synchronized (ActivityManagerService.this) { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 ProcessRecord proc = (ProcessRecord)data.get("app"); 1321 if (proc != null && proc.anrDialog != null) { 1322 Slog.e(TAG, "App already has anr dialog: " + proc); 1323 return; 1324 } 1325 1326 Intent intent = new Intent("android.intent.action.ANR"); 1327 if (!mProcessesReady) { 1328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1329 | Intent.FLAG_RECEIVER_FOREGROUND); 1330 } 1331 broadcastIntentLocked(null, null, intent, 1332 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1333 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1334 1335 if (mShowDialogs) { 1336 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1337 mContext, proc, (ActivityRecord)data.get("activity"), 1338 msg.arg1 != 0); 1339 d.show(); 1340 proc.anrDialog = d; 1341 } else { 1342 // Just kill the app if there is no dialog to be shown. 1343 killAppAtUsersRequest(proc, null); 1344 } 1345 } 1346 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1350 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1351 synchronized (ActivityManagerService.this) { 1352 ProcessRecord proc = (ProcessRecord) data.get("app"); 1353 if (proc == null) { 1354 Slog.e(TAG, "App not found when showing strict mode dialog."); 1355 break; 1356 } 1357 if (proc.crashDialog != null) { 1358 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1359 return; 1360 } 1361 AppErrorResult res = (AppErrorResult) data.get("result"); 1362 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1363 Dialog d = new StrictModeViolationDialog(mContext, 1364 ActivityManagerService.this, res, proc); 1365 d.show(); 1366 proc.crashDialog = d; 1367 } else { 1368 // The device is asleep, so just pretend that the user 1369 // saw a crash dialog and hit "force quit". 1370 res.set(0); 1371 } 1372 } 1373 ensureBootCompleted(); 1374 } break; 1375 case SHOW_FACTORY_ERROR_MSG: { 1376 Dialog d = new FactoryErrorDialog( 1377 mContext, msg.getData().getCharSequence("msg")); 1378 d.show(); 1379 ensureBootCompleted(); 1380 } break; 1381 case UPDATE_CONFIGURATION_MSG: { 1382 final ContentResolver resolver = mContext.getContentResolver(); 1383 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1384 } break; 1385 case GC_BACKGROUND_PROCESSES_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 performAppGcsIfAppropriateLocked(); 1388 } 1389 } break; 1390 case WAIT_FOR_DEBUGGER_MSG: { 1391 synchronized (ActivityManagerService.this) { 1392 ProcessRecord app = (ProcessRecord)msg.obj; 1393 if (msg.arg1 != 0) { 1394 if (!app.waitedForDebugger) { 1395 Dialog d = new AppWaitingForDebuggerDialog( 1396 ActivityManagerService.this, 1397 mContext, app); 1398 app.waitDialog = d; 1399 app.waitedForDebugger = true; 1400 d.show(); 1401 } 1402 } else { 1403 if (app.waitDialog != null) { 1404 app.waitDialog.dismiss(); 1405 app.waitDialog = null; 1406 } 1407 } 1408 } 1409 } break; 1410 case SERVICE_TIMEOUT_MSG: { 1411 if (mDidDexOpt) { 1412 mDidDexOpt = false; 1413 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1414 nmsg.obj = msg.obj; 1415 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1416 return; 1417 } 1418 mServices.serviceTimeout((ProcessRecord)msg.obj); 1419 } break; 1420 case UPDATE_TIME_ZONE: { 1421 synchronized (ActivityManagerService.this) { 1422 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1423 ProcessRecord r = mLruProcesses.get(i); 1424 if (r.thread != null) { 1425 try { 1426 r.thread.updateTimeZone(); 1427 } catch (RemoteException ex) { 1428 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1429 } 1430 } 1431 } 1432 } 1433 } break; 1434 case CLEAR_DNS_CACHE_MSG: { 1435 synchronized (ActivityManagerService.this) { 1436 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1437 ProcessRecord r = mLruProcesses.get(i); 1438 if (r.thread != null) { 1439 try { 1440 r.thread.clearDnsCache(); 1441 } catch (RemoteException ex) { 1442 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1443 } 1444 } 1445 } 1446 } 1447 } break; 1448 case UPDATE_HTTP_PROXY_MSG: { 1449 ProxyInfo proxy = (ProxyInfo)msg.obj; 1450 String host = ""; 1451 String port = ""; 1452 String exclList = ""; 1453 Uri pacFileUrl = Uri.EMPTY; 1454 if (proxy != null) { 1455 host = proxy.getHost(); 1456 port = Integer.toString(proxy.getPort()); 1457 exclList = proxy.getExclusionListAsString(); 1458 pacFileUrl = proxy.getPacFileUrl(); 1459 } 1460 synchronized (ActivityManagerService.this) { 1461 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1462 ProcessRecord r = mLruProcesses.get(i); 1463 if (r.thread != null) { 1464 try { 1465 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1466 } catch (RemoteException ex) { 1467 Slog.w(TAG, "Failed to update http proxy for: " + 1468 r.info.processName); 1469 } 1470 } 1471 } 1472 } 1473 } break; 1474 case SHOW_UID_ERROR_MSG: { 1475 if (mShowDialogs) { 1476 AlertDialog d = new BaseErrorDialog(mContext); 1477 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1478 d.setCancelable(false); 1479 d.setTitle(mContext.getText(R.string.android_system_label)); 1480 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1481 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1482 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1483 d.show(); 1484 } 1485 } break; 1486 case SHOW_FINGERPRINT_ERROR_MSG: { 1487 if (mShowDialogs) { 1488 AlertDialog d = new BaseErrorDialog(mContext); 1489 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1490 d.setCancelable(false); 1491 d.setTitle(mContext.getText(R.string.android_system_label)); 1492 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1493 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1494 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1495 d.show(); 1496 } 1497 } break; 1498 case PROC_START_TIMEOUT_MSG: { 1499 if (mDidDexOpt) { 1500 mDidDexOpt = false; 1501 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1502 nmsg.obj = msg.obj; 1503 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1504 return; 1505 } 1506 ProcessRecord app = (ProcessRecord)msg.obj; 1507 synchronized (ActivityManagerService.this) { 1508 processStartTimedOutLocked(app); 1509 } 1510 } break; 1511 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1512 synchronized (ActivityManagerService.this) { 1513 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1514 } 1515 } break; 1516 case KILL_APPLICATION_MSG: { 1517 synchronized (ActivityManagerService.this) { 1518 int appid = msg.arg1; 1519 boolean restart = (msg.arg2 == 1); 1520 Bundle bundle = (Bundle)msg.obj; 1521 String pkg = bundle.getString("pkg"); 1522 String reason = bundle.getString("reason"); 1523 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1524 false, UserHandle.USER_ALL, reason); 1525 } 1526 } break; 1527 case FINALIZE_PENDING_INTENT_MSG: { 1528 ((PendingIntentRecord)msg.obj).completeFinalize(); 1529 } break; 1530 case POST_HEAVY_NOTIFICATION_MSG: { 1531 INotificationManager inm = NotificationManager.getService(); 1532 if (inm == null) { 1533 return; 1534 } 1535 1536 ActivityRecord root = (ActivityRecord)msg.obj; 1537 ProcessRecord process = root.app; 1538 if (process == null) { 1539 return; 1540 } 1541 1542 try { 1543 Context context = mContext.createPackageContext(process.info.packageName, 0); 1544 String text = mContext.getString(R.string.heavy_weight_notification, 1545 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1546 Notification notification = new Notification(); 1547 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1548 notification.when = 0; 1549 notification.flags = Notification.FLAG_ONGOING_EVENT; 1550 notification.tickerText = text; 1551 notification.defaults = 0; // please be quiet 1552 notification.sound = null; 1553 notification.vibrate = null; 1554 notification.color = mContext.getResources().getColor( 1555 com.android.internal.R.color.system_notification_accent_color); 1556 notification.setLatestEventInfo(context, text, 1557 mContext.getText(R.string.heavy_weight_notification_detail), 1558 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1559 PendingIntent.FLAG_CANCEL_CURRENT, null, 1560 new UserHandle(root.userId))); 1561 1562 try { 1563 int[] outId = new int[1]; 1564 inm.enqueueNotificationWithTag("android", "android", null, 1565 R.string.heavy_weight_notification, 1566 notification, outId, root.userId); 1567 } catch (RuntimeException e) { 1568 Slog.w(ActivityManagerService.TAG, 1569 "Error showing notification for heavy-weight app", e); 1570 } catch (RemoteException e) { 1571 } 1572 } catch (NameNotFoundException e) { 1573 Slog.w(TAG, "Unable to create context for heavy notification", e); 1574 } 1575 } break; 1576 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1577 INotificationManager inm = NotificationManager.getService(); 1578 if (inm == null) { 1579 return; 1580 } 1581 try { 1582 inm.cancelNotificationWithTag("android", null, 1583 R.string.heavy_weight_notification, msg.arg1); 1584 } catch (RuntimeException e) { 1585 Slog.w(ActivityManagerService.TAG, 1586 "Error canceling notification for service", e); 1587 } catch (RemoteException e) { 1588 } 1589 } break; 1590 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1591 synchronized (ActivityManagerService.this) { 1592 checkExcessivePowerUsageLocked(true); 1593 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1594 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1595 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1596 } 1597 } break; 1598 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1599 synchronized (ActivityManagerService.this) { 1600 ActivityRecord ar = (ActivityRecord)msg.obj; 1601 if (mCompatModeDialog != null) { 1602 if (mCompatModeDialog.mAppInfo.packageName.equals( 1603 ar.info.applicationInfo.packageName)) { 1604 return; 1605 } 1606 mCompatModeDialog.dismiss(); 1607 mCompatModeDialog = null; 1608 } 1609 if (ar != null && false) { 1610 if (mCompatModePackages.getPackageAskCompatModeLocked( 1611 ar.packageName)) { 1612 int mode = mCompatModePackages.computeCompatModeLocked( 1613 ar.info.applicationInfo); 1614 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1615 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1616 mCompatModeDialog = new CompatModeDialog( 1617 ActivityManagerService.this, mContext, 1618 ar.info.applicationInfo); 1619 mCompatModeDialog.show(); 1620 } 1621 } 1622 } 1623 } 1624 break; 1625 } 1626 case DISPATCH_PROCESSES_CHANGED: { 1627 dispatchProcessesChanged(); 1628 break; 1629 } 1630 case DISPATCH_PROCESS_DIED: { 1631 final int pid = msg.arg1; 1632 final int uid = msg.arg2; 1633 dispatchProcessDied(pid, uid); 1634 break; 1635 } 1636 case REPORT_MEM_USAGE_MSG: { 1637 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1638 Thread thread = new Thread() { 1639 @Override public void run() { 1640 reportMemUsage(memInfos); 1641 } 1642 }; 1643 thread.start(); 1644 break; 1645 } 1646 case START_USER_SWITCH_MSG: { 1647 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1648 break; 1649 } 1650 case REPORT_USER_SWITCH_MSG: { 1651 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1652 break; 1653 } 1654 case CONTINUE_USER_SWITCH_MSG: { 1655 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1656 break; 1657 } 1658 case USER_SWITCH_TIMEOUT_MSG: { 1659 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1660 break; 1661 } 1662 case IMMERSIVE_MODE_LOCK_MSG: { 1663 final boolean nextState = (msg.arg1 != 0); 1664 if (mUpdateLock.isHeld() != nextState) { 1665 if (DEBUG_IMMERSIVE) { 1666 final ActivityRecord r = (ActivityRecord) msg.obj; 1667 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1668 } 1669 if (nextState) { 1670 mUpdateLock.acquire(); 1671 } else { 1672 mUpdateLock.release(); 1673 } 1674 } 1675 break; 1676 } 1677 case PERSIST_URI_GRANTS_MSG: { 1678 writeGrantedUriPermissions(); 1679 break; 1680 } 1681 case REQUEST_ALL_PSS_MSG: { 1682 synchronized (ActivityManagerService.this) { 1683 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1684 } 1685 break; 1686 } 1687 case START_PROFILES_MSG: { 1688 synchronized (ActivityManagerService.this) { 1689 startProfilesLocked(); 1690 } 1691 break; 1692 } 1693 case UPDATE_TIME: { 1694 synchronized (ActivityManagerService.this) { 1695 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1696 ProcessRecord r = mLruProcesses.get(i); 1697 if (r.thread != null) { 1698 try { 1699 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1700 } catch (RemoteException ex) { 1701 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1702 } 1703 } 1704 } 1705 } 1706 break; 1707 } 1708 case SYSTEM_USER_START_MSG: { 1709 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1710 Integer.toString(msg.arg1), msg.arg1); 1711 mSystemServiceManager.startUser(msg.arg1); 1712 break; 1713 } 1714 case SYSTEM_USER_CURRENT_MSG: { 1715 mBatteryStatsService.noteEvent( 1716 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1717 Integer.toString(msg.arg2), msg.arg2); 1718 mBatteryStatsService.noteEvent( 1719 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1720 Integer.toString(msg.arg1), msg.arg1); 1721 mSystemServiceManager.switchUser(msg.arg1); 1722 break; 1723 } 1724 case ENTER_ANIMATION_COMPLETE_MSG: { 1725 synchronized (ActivityManagerService.this) { 1726 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1727 if (r != null && r.app != null && r.app.thread != null) { 1728 try { 1729 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1730 } catch (RemoteException e) { 1731 } 1732 } 1733 } 1734 break; 1735 } 1736 case FINISH_BOOTING_MSG: { 1737 if (msg.arg1 != 0) { 1738 finishBooting(); 1739 } 1740 if (msg.arg2 != 0) { 1741 enableScreenAfterBoot(); 1742 } 1743 break; 1744 } 1745 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1746 try { 1747 Locale l = (Locale) msg.obj; 1748 IBinder service = ServiceManager.getService("mount"); 1749 IMountService mountService = IMountService.Stub.asInterface(service); 1750 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1751 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1752 } catch (RemoteException e) { 1753 Log.e(TAG, "Error storing locale for decryption UI", e); 1754 } 1755 break; 1756 } 1757 case DISMISS_DIALOG_MSG: { 1758 final Dialog d = (Dialog) msg.obj; 1759 d.dismiss(); 1760 break; 1761 } 1762 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1763 synchronized (ActivityManagerService.this) { 1764 int i = mTaskStackListeners.beginBroadcast(); 1765 while (i > 0) { 1766 i--; 1767 try { 1768 // Make a one-way callback to the listener 1769 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1770 } catch (RemoteException e){ 1771 // Handled by the RemoteCallbackList 1772 } 1773 } 1774 mTaskStackListeners.finishBroadcast(); 1775 } 1776 break; 1777 } 1778 } 1779 } 1780 }; 1781 1782 static final int COLLECT_PSS_BG_MSG = 1; 1783 1784 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1785 @Override 1786 public void handleMessage(Message msg) { 1787 switch (msg.what) { 1788 case COLLECT_PSS_BG_MSG: { 1789 long start = SystemClock.uptimeMillis(); 1790 MemInfoReader memInfo = null; 1791 synchronized (ActivityManagerService.this) { 1792 if (mFullPssPending) { 1793 mFullPssPending = false; 1794 memInfo = new MemInfoReader(); 1795 } 1796 } 1797 if (memInfo != null) { 1798 updateCpuStatsNow(); 1799 long nativeTotalPss = 0; 1800 synchronized (mProcessCpuTracker) { 1801 final int N = mProcessCpuTracker.countStats(); 1802 for (int j=0; j<N; j++) { 1803 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1804 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1805 // This is definitely an application process; skip it. 1806 continue; 1807 } 1808 synchronized (mPidsSelfLocked) { 1809 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1810 // This is one of our own processes; skip it. 1811 continue; 1812 } 1813 } 1814 nativeTotalPss += Debug.getPss(st.pid, null, null); 1815 } 1816 } 1817 memInfo.readMemInfo(); 1818 synchronized (ActivityManagerService.this) { 1819 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1820 + (SystemClock.uptimeMillis()-start) + "ms"); 1821 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1822 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1823 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1824 } 1825 } 1826 1827 int num = 0; 1828 long[] tmp = new long[1]; 1829 do { 1830 ProcessRecord proc; 1831 int procState; 1832 int pid; 1833 long lastPssTime; 1834 synchronized (ActivityManagerService.this) { 1835 if (mPendingPssProcesses.size() <= 0) { 1836 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1837 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1838 mPendingPssProcesses.clear(); 1839 return; 1840 } 1841 proc = mPendingPssProcesses.remove(0); 1842 procState = proc.pssProcState; 1843 lastPssTime = proc.lastPssTime; 1844 if (proc.thread != null && procState == proc.setProcState 1845 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1846 < SystemClock.uptimeMillis()) { 1847 pid = proc.pid; 1848 } else { 1849 proc = null; 1850 pid = 0; 1851 } 1852 } 1853 if (proc != null) { 1854 long pss = Debug.getPss(pid, tmp, null); 1855 synchronized (ActivityManagerService.this) { 1856 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1857 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1858 num++; 1859 recordPssSample(proc, procState, pss, tmp[0], 1860 SystemClock.uptimeMillis()); 1861 } 1862 } 1863 } 1864 } while (true); 1865 } 1866 } 1867 } 1868 }; 1869 1870 public void setSystemProcess() { 1871 try { 1872 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1873 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1874 ServiceManager.addService("meminfo", new MemBinder(this)); 1875 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1876 ServiceManager.addService("dbinfo", new DbBinder(this)); 1877 if (MONITOR_CPU_USAGE) { 1878 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1879 } 1880 ServiceManager.addService("permission", new PermissionController(this)); 1881 1882 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1883 "android", STOCK_PM_FLAGS); 1884 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1885 1886 synchronized (this) { 1887 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1888 app.persistent = true; 1889 app.pid = MY_PID; 1890 app.maxAdj = ProcessList.SYSTEM_ADJ; 1891 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1892 mProcessNames.put(app.processName, app.uid, app); 1893 synchronized (mPidsSelfLocked) { 1894 mPidsSelfLocked.put(app.pid, app); 1895 } 1896 updateLruProcessLocked(app, false, null); 1897 updateOomAdjLocked(); 1898 } 1899 } catch (PackageManager.NameNotFoundException e) { 1900 throw new RuntimeException( 1901 "Unable to find android system package", e); 1902 } 1903 } 1904 1905 public void setWindowManager(WindowManagerService wm) { 1906 mWindowManager = wm; 1907 mStackSupervisor.setWindowManager(wm); 1908 } 1909 1910 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1911 mUsageStatsService = usageStatsManager; 1912 } 1913 1914 public void startObservingNativeCrashes() { 1915 final NativeCrashListener ncl = new NativeCrashListener(this); 1916 ncl.start(); 1917 } 1918 1919 public IAppOpsService getAppOpsService() { 1920 return mAppOpsService; 1921 } 1922 1923 static class MemBinder extends Binder { 1924 ActivityManagerService mActivityManagerService; 1925 MemBinder(ActivityManagerService activityManagerService) { 1926 mActivityManagerService = activityManagerService; 1927 } 1928 1929 @Override 1930 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1931 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1932 != PackageManager.PERMISSION_GRANTED) { 1933 pw.println("Permission Denial: can't dump meminfo from from pid=" 1934 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1935 + " without permission " + android.Manifest.permission.DUMP); 1936 return; 1937 } 1938 1939 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1940 } 1941 } 1942 1943 static class GraphicsBinder extends Binder { 1944 ActivityManagerService mActivityManagerService; 1945 GraphicsBinder(ActivityManagerService activityManagerService) { 1946 mActivityManagerService = activityManagerService; 1947 } 1948 1949 @Override 1950 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1951 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1952 != PackageManager.PERMISSION_GRANTED) { 1953 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1954 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1955 + " without permission " + android.Manifest.permission.DUMP); 1956 return; 1957 } 1958 1959 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1960 } 1961 } 1962 1963 static class DbBinder extends Binder { 1964 ActivityManagerService mActivityManagerService; 1965 DbBinder(ActivityManagerService activityManagerService) { 1966 mActivityManagerService = activityManagerService; 1967 } 1968 1969 @Override 1970 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1971 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1972 != PackageManager.PERMISSION_GRANTED) { 1973 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1974 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1975 + " without permission " + android.Manifest.permission.DUMP); 1976 return; 1977 } 1978 1979 mActivityManagerService.dumpDbInfo(fd, pw, args); 1980 } 1981 } 1982 1983 static class CpuBinder extends Binder { 1984 ActivityManagerService mActivityManagerService; 1985 CpuBinder(ActivityManagerService activityManagerService) { 1986 mActivityManagerService = activityManagerService; 1987 } 1988 1989 @Override 1990 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1991 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1992 != PackageManager.PERMISSION_GRANTED) { 1993 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1994 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1995 + " without permission " + android.Manifest.permission.DUMP); 1996 return; 1997 } 1998 1999 synchronized (mActivityManagerService.mProcessCpuTracker) { 2000 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2001 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2002 SystemClock.uptimeMillis())); 2003 } 2004 } 2005 } 2006 2007 public static final class Lifecycle extends SystemService { 2008 private final ActivityManagerService mService; 2009 2010 public Lifecycle(Context context) { 2011 super(context); 2012 mService = new ActivityManagerService(context); 2013 } 2014 2015 @Override 2016 public void onStart() { 2017 mService.start(); 2018 } 2019 2020 public ActivityManagerService getService() { 2021 return mService; 2022 } 2023 } 2024 2025 // Note: This method is invoked on the main thread but may need to attach various 2026 // handlers to other threads. So take care to be explicit about the looper. 2027 public ActivityManagerService(Context systemContext) { 2028 mContext = systemContext; 2029 mFactoryTest = FactoryTest.getMode(); 2030 mSystemThread = ActivityThread.currentActivityThread(); 2031 2032 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2033 2034 mHandlerThread = new ServiceThread(TAG, 2035 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2036 mHandlerThread.start(); 2037 mHandler = new MainHandler(mHandlerThread.getLooper()); 2038 2039 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2040 "foreground", BROADCAST_FG_TIMEOUT, false); 2041 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2042 "background", BROADCAST_BG_TIMEOUT, true); 2043 mBroadcastQueues[0] = mFgBroadcastQueue; 2044 mBroadcastQueues[1] = mBgBroadcastQueue; 2045 2046 mServices = new ActiveServices(this); 2047 mProviderMap = new ProviderMap(this); 2048 2049 // TODO: Move creation of battery stats service outside of activity manager service. 2050 File dataDir = Environment.getDataDirectory(); 2051 File systemDir = new File(dataDir, "system"); 2052 systemDir.mkdirs(); 2053 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2054 mBatteryStatsService.getActiveStatistics().readLocked(); 2055 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2056 mOnBattery = DEBUG_POWER ? true 2057 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2058 mBatteryStatsService.getActiveStatistics().setCallback(this); 2059 2060 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2061 2062 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2063 2064 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2065 2066 // User 0 is the first and only user that runs at boot. 2067 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2068 mUserLru.add(Integer.valueOf(0)); 2069 updateStartedUserArrayLocked(); 2070 2071 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2072 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2073 2074 mConfiguration.setToDefaults(); 2075 mConfiguration.setLocale(Locale.getDefault()); 2076 2077 mConfigurationSeq = mConfiguration.seq = 1; 2078 mProcessCpuTracker.init(); 2079 2080 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2081 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2082 mStackSupervisor = new ActivityStackSupervisor(this); 2083 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2084 2085 mProcessCpuThread = new Thread("CpuTracker") { 2086 @Override 2087 public void run() { 2088 while (true) { 2089 try { 2090 try { 2091 synchronized(this) { 2092 final long now = SystemClock.uptimeMillis(); 2093 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2094 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2095 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2096 // + ", write delay=" + nextWriteDelay); 2097 if (nextWriteDelay < nextCpuDelay) { 2098 nextCpuDelay = nextWriteDelay; 2099 } 2100 if (nextCpuDelay > 0) { 2101 mProcessCpuMutexFree.set(true); 2102 this.wait(nextCpuDelay); 2103 } 2104 } 2105 } catch (InterruptedException e) { 2106 } 2107 updateCpuStatsNow(); 2108 } catch (Exception e) { 2109 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2110 } 2111 } 2112 } 2113 }; 2114 2115 Watchdog.getInstance().addMonitor(this); 2116 Watchdog.getInstance().addThread(mHandler); 2117 } 2118 2119 public void setSystemServiceManager(SystemServiceManager mgr) { 2120 mSystemServiceManager = mgr; 2121 } 2122 2123 public void setInstaller(Installer installer) { 2124 mInstaller = installer; 2125 } 2126 2127 private void start() { 2128 Process.removeAllProcessGroups(); 2129 mProcessCpuThread.start(); 2130 2131 mBatteryStatsService.publish(mContext); 2132 mAppOpsService.publish(mContext); 2133 Slog.d("AppOps", "AppOpsService published"); 2134 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2135 } 2136 2137 public void initPowerManagement() { 2138 mStackSupervisor.initPowerManagement(); 2139 mBatteryStatsService.initPowerManagement(); 2140 } 2141 2142 @Override 2143 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2144 throws RemoteException { 2145 if (code == SYSPROPS_TRANSACTION) { 2146 // We need to tell all apps about the system property change. 2147 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2148 synchronized(this) { 2149 final int NP = mProcessNames.getMap().size(); 2150 for (int ip=0; ip<NP; ip++) { 2151 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2152 final int NA = apps.size(); 2153 for (int ia=0; ia<NA; ia++) { 2154 ProcessRecord app = apps.valueAt(ia); 2155 if (app.thread != null) { 2156 procs.add(app.thread.asBinder()); 2157 } 2158 } 2159 } 2160 } 2161 2162 int N = procs.size(); 2163 for (int i=0; i<N; i++) { 2164 Parcel data2 = Parcel.obtain(); 2165 try { 2166 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2167 } catch (RemoteException e) { 2168 } 2169 data2.recycle(); 2170 } 2171 } 2172 try { 2173 return super.onTransact(code, data, reply, flags); 2174 } catch (RuntimeException e) { 2175 // The activity manager only throws security exceptions, so let's 2176 // log all others. 2177 if (!(e instanceof SecurityException)) { 2178 Slog.wtf(TAG, "Activity Manager Crash", e); 2179 } 2180 throw e; 2181 } 2182 } 2183 2184 void updateCpuStats() { 2185 final long now = SystemClock.uptimeMillis(); 2186 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2187 return; 2188 } 2189 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2190 synchronized (mProcessCpuThread) { 2191 mProcessCpuThread.notify(); 2192 } 2193 } 2194 } 2195 2196 void updateCpuStatsNow() { 2197 synchronized (mProcessCpuTracker) { 2198 mProcessCpuMutexFree.set(false); 2199 final long now = SystemClock.uptimeMillis(); 2200 boolean haveNewCpuStats = false; 2201 2202 if (MONITOR_CPU_USAGE && 2203 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2204 mLastCpuTime.set(now); 2205 haveNewCpuStats = true; 2206 mProcessCpuTracker.update(); 2207 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2208 //Slog.i(TAG, "Total CPU usage: " 2209 // + mProcessCpu.getTotalCpuPercent() + "%"); 2210 2211 // Slog the cpu usage if the property is set. 2212 if ("true".equals(SystemProperties.get("events.cpu"))) { 2213 int user = mProcessCpuTracker.getLastUserTime(); 2214 int system = mProcessCpuTracker.getLastSystemTime(); 2215 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2216 int irq = mProcessCpuTracker.getLastIrqTime(); 2217 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2218 int idle = mProcessCpuTracker.getLastIdleTime(); 2219 2220 int total = user + system + iowait + irq + softIrq + idle; 2221 if (total == 0) total = 1; 2222 2223 EventLog.writeEvent(EventLogTags.CPU, 2224 ((user+system+iowait+irq+softIrq) * 100) / total, 2225 (user * 100) / total, 2226 (system * 100) / total, 2227 (iowait * 100) / total, 2228 (irq * 100) / total, 2229 (softIrq * 100) / total); 2230 } 2231 } 2232 2233 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2234 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2235 synchronized(bstats) { 2236 synchronized(mPidsSelfLocked) { 2237 if (haveNewCpuStats) { 2238 if (mOnBattery) { 2239 int perc = bstats.startAddingCpuLocked(); 2240 int totalUTime = 0; 2241 int totalSTime = 0; 2242 final int N = mProcessCpuTracker.countStats(); 2243 for (int i=0; i<N; i++) { 2244 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2245 if (!st.working) { 2246 continue; 2247 } 2248 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2249 int otherUTime = (st.rel_utime*perc)/100; 2250 int otherSTime = (st.rel_stime*perc)/100; 2251 totalUTime += otherUTime; 2252 totalSTime += otherSTime; 2253 if (pr != null) { 2254 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2255 if (ps == null || !ps.isActive()) { 2256 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2257 pr.info.uid, pr.processName); 2258 } 2259 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2260 st.rel_stime-otherSTime); 2261 ps.addSpeedStepTimes(cpuSpeedTimes); 2262 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2263 } else { 2264 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2265 if (ps == null || !ps.isActive()) { 2266 st.batteryStats = ps = bstats.getProcessStatsLocked( 2267 bstats.mapUid(st.uid), st.name); 2268 } 2269 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2270 st.rel_stime-otherSTime); 2271 ps.addSpeedStepTimes(cpuSpeedTimes); 2272 } 2273 } 2274 bstats.finishAddingCpuLocked(perc, totalUTime, 2275 totalSTime, cpuSpeedTimes); 2276 } 2277 } 2278 } 2279 2280 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2281 mLastWriteTime = now; 2282 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2283 } 2284 } 2285 } 2286 } 2287 2288 @Override 2289 public void batteryNeedsCpuUpdate() { 2290 updateCpuStatsNow(); 2291 } 2292 2293 @Override 2294 public void batteryPowerChanged(boolean onBattery) { 2295 // When plugging in, update the CPU stats first before changing 2296 // the plug state. 2297 updateCpuStatsNow(); 2298 synchronized (this) { 2299 synchronized(mPidsSelfLocked) { 2300 mOnBattery = DEBUG_POWER ? true : onBattery; 2301 } 2302 } 2303 } 2304 2305 /** 2306 * Initialize the application bind args. These are passed to each 2307 * process when the bindApplication() IPC is sent to the process. They're 2308 * lazily setup to make sure the services are running when they're asked for. 2309 */ 2310 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2311 if (mAppBindArgs == null) { 2312 mAppBindArgs = new HashMap<>(); 2313 2314 // Isolated processes won't get this optimization, so that we don't 2315 // violate the rules about which services they have access to. 2316 if (!isolated) { 2317 // Setup the application init args 2318 mAppBindArgs.put("package", ServiceManager.getService("package")); 2319 mAppBindArgs.put("window", ServiceManager.getService("window")); 2320 mAppBindArgs.put(Context.ALARM_SERVICE, 2321 ServiceManager.getService(Context.ALARM_SERVICE)); 2322 } 2323 } 2324 return mAppBindArgs; 2325 } 2326 2327 final void setFocusedActivityLocked(ActivityRecord r) { 2328 if (mFocusedActivity != r) { 2329 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2330 mFocusedActivity = r; 2331 if (r.task != null && r.task.voiceInteractor != null) { 2332 startRunningVoiceLocked(); 2333 } else { 2334 finishRunningVoiceLocked(); 2335 } 2336 mStackSupervisor.setFocusedStack(r); 2337 if (r != null) { 2338 mWindowManager.setFocusedApp(r.appToken, true); 2339 } 2340 applyUpdateLockStateLocked(r); 2341 } 2342 } 2343 2344 final void clearFocusedActivity(ActivityRecord r) { 2345 if (mFocusedActivity == r) { 2346 mFocusedActivity = null; 2347 } 2348 } 2349 2350 @Override 2351 public void setFocusedStack(int stackId) { 2352 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2353 synchronized (ActivityManagerService.this) { 2354 ActivityStack stack = mStackSupervisor.getStack(stackId); 2355 if (stack != null) { 2356 ActivityRecord r = stack.topRunningActivityLocked(null); 2357 if (r != null) { 2358 setFocusedActivityLocked(r); 2359 } 2360 } 2361 } 2362 } 2363 2364 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2365 @Override 2366 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2367 synchronized (ActivityManagerService.this) { 2368 if (listener != null) { 2369 mTaskStackListeners.register(listener); 2370 } 2371 } 2372 } 2373 2374 @Override 2375 public void notifyActivityDrawn(IBinder token) { 2376 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2377 synchronized (this) { 2378 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2379 if (r != null) { 2380 r.task.stack.notifyActivityDrawnLocked(r); 2381 } 2382 } 2383 } 2384 2385 final void applyUpdateLockStateLocked(ActivityRecord r) { 2386 // Modifications to the UpdateLock state are done on our handler, outside 2387 // the activity manager's locks. The new state is determined based on the 2388 // state *now* of the relevant activity record. The object is passed to 2389 // the handler solely for logging detail, not to be consulted/modified. 2390 final boolean nextState = r != null && r.immersive; 2391 mHandler.sendMessage( 2392 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2393 } 2394 2395 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2396 Message msg = Message.obtain(); 2397 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2398 msg.obj = r.task.askedCompatMode ? null : r; 2399 mHandler.sendMessage(msg); 2400 } 2401 2402 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2403 String what, Object obj, ProcessRecord srcApp) { 2404 app.lastActivityTime = now; 2405 2406 if (app.activities.size() > 0) { 2407 // Don't want to touch dependent processes that are hosting activities. 2408 return index; 2409 } 2410 2411 int lrui = mLruProcesses.lastIndexOf(app); 2412 if (lrui < 0) { 2413 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2414 + what + " " + obj + " from " + srcApp); 2415 return index; 2416 } 2417 2418 if (lrui >= index) { 2419 // Don't want to cause this to move dependent processes *back* in the 2420 // list as if they were less frequently used. 2421 return index; 2422 } 2423 2424 if (lrui >= mLruProcessActivityStart) { 2425 // Don't want to touch dependent processes that are hosting activities. 2426 return index; 2427 } 2428 2429 mLruProcesses.remove(lrui); 2430 if (index > 0) { 2431 index--; 2432 } 2433 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2434 + " in LRU list: " + app); 2435 mLruProcesses.add(index, app); 2436 return index; 2437 } 2438 2439 final void removeLruProcessLocked(ProcessRecord app) { 2440 int lrui = mLruProcesses.lastIndexOf(app); 2441 if (lrui >= 0) { 2442 if (!app.killed) { 2443 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2444 Process.killProcessQuiet(app.pid); 2445 Process.killProcessGroup(app.info.uid, app.pid); 2446 } 2447 if (lrui <= mLruProcessActivityStart) { 2448 mLruProcessActivityStart--; 2449 } 2450 if (lrui <= mLruProcessServiceStart) { 2451 mLruProcessServiceStart--; 2452 } 2453 mLruProcesses.remove(lrui); 2454 } 2455 } 2456 2457 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2458 ProcessRecord client) { 2459 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2460 || app.treatLikeActivity; 2461 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2462 if (!activityChange && hasActivity) { 2463 // The process has activities, so we are only allowing activity-based adjustments 2464 // to move it. It should be kept in the front of the list with other 2465 // processes that have activities, and we don't want those to change their 2466 // order except due to activity operations. 2467 return; 2468 } 2469 2470 mLruSeq++; 2471 final long now = SystemClock.uptimeMillis(); 2472 app.lastActivityTime = now; 2473 2474 // First a quick reject: if the app is already at the position we will 2475 // put it, then there is nothing to do. 2476 if (hasActivity) { 2477 final int N = mLruProcesses.size(); 2478 if (N > 0 && mLruProcesses.get(N-1) == app) { 2479 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2480 return; 2481 } 2482 } else { 2483 if (mLruProcessServiceStart > 0 2484 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2485 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2486 return; 2487 } 2488 } 2489 2490 int lrui = mLruProcesses.lastIndexOf(app); 2491 2492 if (app.persistent && lrui >= 0) { 2493 // We don't care about the position of persistent processes, as long as 2494 // they are in the list. 2495 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2496 return; 2497 } 2498 2499 /* In progress: compute new position first, so we can avoid doing work 2500 if the process is not actually going to move. Not yet working. 2501 int addIndex; 2502 int nextIndex; 2503 boolean inActivity = false, inService = false; 2504 if (hasActivity) { 2505 // Process has activities, put it at the very tipsy-top. 2506 addIndex = mLruProcesses.size(); 2507 nextIndex = mLruProcessServiceStart; 2508 inActivity = true; 2509 } else if (hasService) { 2510 // Process has services, put it at the top of the service list. 2511 addIndex = mLruProcessActivityStart; 2512 nextIndex = mLruProcessServiceStart; 2513 inActivity = true; 2514 inService = true; 2515 } else { 2516 // Process not otherwise of interest, it goes to the top of the non-service area. 2517 addIndex = mLruProcessServiceStart; 2518 if (client != null) { 2519 int clientIndex = mLruProcesses.lastIndexOf(client); 2520 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2521 + app); 2522 if (clientIndex >= 0 && addIndex > clientIndex) { 2523 addIndex = clientIndex; 2524 } 2525 } 2526 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2527 } 2528 2529 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2530 + mLruProcessActivityStart + "): " + app); 2531 */ 2532 2533 if (lrui >= 0) { 2534 if (lrui < mLruProcessActivityStart) { 2535 mLruProcessActivityStart--; 2536 } 2537 if (lrui < mLruProcessServiceStart) { 2538 mLruProcessServiceStart--; 2539 } 2540 /* 2541 if (addIndex > lrui) { 2542 addIndex--; 2543 } 2544 if (nextIndex > lrui) { 2545 nextIndex--; 2546 } 2547 */ 2548 mLruProcesses.remove(lrui); 2549 } 2550 2551 /* 2552 mLruProcesses.add(addIndex, app); 2553 if (inActivity) { 2554 mLruProcessActivityStart++; 2555 } 2556 if (inService) { 2557 mLruProcessActivityStart++; 2558 } 2559 */ 2560 2561 int nextIndex; 2562 if (hasActivity) { 2563 final int N = mLruProcesses.size(); 2564 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2565 // Process doesn't have activities, but has clients with 2566 // activities... move it up, but one below the top (the top 2567 // should always have a real activity). 2568 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2569 mLruProcesses.add(N-1, app); 2570 // To keep it from spamming the LRU list (by making a bunch of clients), 2571 // we will push down any other entries owned by the app. 2572 final int uid = app.info.uid; 2573 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2574 ProcessRecord subProc = mLruProcesses.get(i); 2575 if (subProc.info.uid == uid) { 2576 // We want to push this one down the list. If the process after 2577 // it is for the same uid, however, don't do so, because we don't 2578 // want them internally to be re-ordered. 2579 if (mLruProcesses.get(i-1).info.uid != uid) { 2580 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2581 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2582 ProcessRecord tmp = mLruProcesses.get(i); 2583 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2584 mLruProcesses.set(i-1, tmp); 2585 i--; 2586 } 2587 } else { 2588 // A gap, we can stop here. 2589 break; 2590 } 2591 } 2592 } else { 2593 // Process has activities, put it at the very tipsy-top. 2594 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2595 mLruProcesses.add(app); 2596 } 2597 nextIndex = mLruProcessServiceStart; 2598 } else if (hasService) { 2599 // Process has services, put it at the top of the service list. 2600 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2601 mLruProcesses.add(mLruProcessActivityStart, app); 2602 nextIndex = mLruProcessServiceStart; 2603 mLruProcessActivityStart++; 2604 } else { 2605 // Process not otherwise of interest, it goes to the top of the non-service area. 2606 int index = mLruProcessServiceStart; 2607 if (client != null) { 2608 // If there is a client, don't allow the process to be moved up higher 2609 // in the list than that client. 2610 int clientIndex = mLruProcesses.lastIndexOf(client); 2611 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2612 + " when updating " + app); 2613 if (clientIndex <= lrui) { 2614 // Don't allow the client index restriction to push it down farther in the 2615 // list than it already is. 2616 clientIndex = lrui; 2617 } 2618 if (clientIndex >= 0 && index > clientIndex) { 2619 index = clientIndex; 2620 } 2621 } 2622 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2623 mLruProcesses.add(index, app); 2624 nextIndex = index-1; 2625 mLruProcessActivityStart++; 2626 mLruProcessServiceStart++; 2627 } 2628 2629 // If the app is currently using a content provider or service, 2630 // bump those processes as well. 2631 for (int j=app.connections.size()-1; j>=0; j--) { 2632 ConnectionRecord cr = app.connections.valueAt(j); 2633 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2634 && cr.binding.service.app != null 2635 && cr.binding.service.app.lruSeq != mLruSeq 2636 && !cr.binding.service.app.persistent) { 2637 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2638 "service connection", cr, app); 2639 } 2640 } 2641 for (int j=app.conProviders.size()-1; j>=0; j--) { 2642 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2643 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2644 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2645 "provider reference", cpr, app); 2646 } 2647 } 2648 } 2649 2650 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2651 if (uid == Process.SYSTEM_UID) { 2652 // The system gets to run in any process. If there are multiple 2653 // processes with the same uid, just pick the first (this 2654 // should never happen). 2655 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2656 if (procs == null) return null; 2657 final int N = procs.size(); 2658 for (int i = 0; i < N; i++) { 2659 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2660 } 2661 } 2662 ProcessRecord proc = mProcessNames.get(processName, uid); 2663 if (false && proc != null && !keepIfLarge 2664 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2665 && proc.lastCachedPss >= 4000) { 2666 // Turn this condition on to cause killing to happen regularly, for testing. 2667 if (proc.baseProcessTracker != null) { 2668 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2669 } 2670 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2671 } else if (proc != null && !keepIfLarge 2672 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2673 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2674 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2675 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2676 if (proc.baseProcessTracker != null) { 2677 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2678 } 2679 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2680 } 2681 } 2682 return proc; 2683 } 2684 2685 void ensurePackageDexOpt(String packageName) { 2686 IPackageManager pm = AppGlobals.getPackageManager(); 2687 try { 2688 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2689 mDidDexOpt = true; 2690 } 2691 } catch (RemoteException e) { 2692 } 2693 } 2694 2695 boolean isNextTransitionForward() { 2696 int transit = mWindowManager.getPendingAppTransition(); 2697 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2698 || transit == AppTransition.TRANSIT_TASK_OPEN 2699 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2700 } 2701 2702 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2703 String processName, String abiOverride, int uid, Runnable crashHandler) { 2704 synchronized(this) { 2705 ApplicationInfo info = new ApplicationInfo(); 2706 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2707 // For isolated processes, the former contains the parent's uid and the latter the 2708 // actual uid of the isolated process. 2709 // In the special case introduced by this method (which is, starting an isolated 2710 // process directly from the SystemServer without an actual parent app process) the 2711 // closest thing to a parent's uid is SYSTEM_UID. 2712 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2713 // the |isolated| logic in the ProcessRecord constructor. 2714 info.uid = Process.SYSTEM_UID; 2715 info.processName = processName; 2716 info.className = entryPoint; 2717 info.packageName = "android"; 2718 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2719 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2720 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2721 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2722 crashHandler); 2723 return proc != null ? proc.pid : 0; 2724 } 2725 } 2726 2727 final ProcessRecord startProcessLocked(String processName, 2728 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2729 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2730 boolean isolated, boolean keepIfLarge) { 2731 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2732 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2733 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2734 null /* crashHandler */); 2735 } 2736 2737 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2738 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2739 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2740 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2741 long startTime = SystemClock.elapsedRealtime(); 2742 ProcessRecord app; 2743 if (!isolated) { 2744 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2745 checkTime(startTime, "startProcess: after getProcessRecord"); 2746 } else { 2747 // If this is an isolated process, it can't re-use an existing process. 2748 app = null; 2749 } 2750 // We don't have to do anything more if: 2751 // (1) There is an existing application record; and 2752 // (2) The caller doesn't think it is dead, OR there is no thread 2753 // object attached to it so we know it couldn't have crashed; and 2754 // (3) There is a pid assigned to it, so it is either starting or 2755 // already running. 2756 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2757 + " app=" + app + " knownToBeDead=" + knownToBeDead 2758 + " thread=" + (app != null ? app.thread : null) 2759 + " pid=" + (app != null ? app.pid : -1)); 2760 if (app != null && app.pid > 0) { 2761 if (!knownToBeDead || app.thread == null) { 2762 // We already have the app running, or are waiting for it to 2763 // come up (we have a pid but not yet its thread), so keep it. 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2765 // If this is a new package in the process, add the package to the list 2766 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2767 checkTime(startTime, "startProcess: done, added package to proc"); 2768 return app; 2769 } 2770 2771 // An application record is attached to a previous process, 2772 // clean it up now. 2773 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2774 checkTime(startTime, "startProcess: bad proc running, killing"); 2775 Process.killProcessGroup(app.info.uid, app.pid); 2776 handleAppDiedLocked(app, true, true); 2777 checkTime(startTime, "startProcess: done killing old proc"); 2778 } 2779 2780 String hostingNameStr = hostingName != null 2781 ? hostingName.flattenToShortString() : null; 2782 2783 if (!isolated) { 2784 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2785 // If we are in the background, then check to see if this process 2786 // is bad. If so, we will just silently fail. 2787 if (mBadProcesses.get(info.processName, info.uid) != null) { 2788 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2789 + "/" + info.processName); 2790 return null; 2791 } 2792 } else { 2793 // When the user is explicitly starting a process, then clear its 2794 // crash count so that we won't make it bad until they see at 2795 // least one crash dialog again, and make the process good again 2796 // if it had been bad. 2797 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2798 + "/" + info.processName); 2799 mProcessCrashTimes.remove(info.processName, info.uid); 2800 if (mBadProcesses.get(info.processName, info.uid) != null) { 2801 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2802 UserHandle.getUserId(info.uid), info.uid, 2803 info.processName); 2804 mBadProcesses.remove(info.processName, info.uid); 2805 if (app != null) { 2806 app.bad = false; 2807 } 2808 } 2809 } 2810 } 2811 2812 if (app == null) { 2813 checkTime(startTime, "startProcess: creating new process record"); 2814 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2815 if (app == null) { 2816 Slog.w(TAG, "Failed making new process record for " 2817 + processName + "/" + info.uid + " isolated=" + isolated); 2818 return null; 2819 } 2820 app.crashHandler = crashHandler; 2821 mProcessNames.put(processName, app.uid, app); 2822 if (isolated) { 2823 mIsolatedProcesses.put(app.uid, app); 2824 } 2825 checkTime(startTime, "startProcess: done creating new process record"); 2826 } else { 2827 // If this is a new package in the process, add the package to the list 2828 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2829 checkTime(startTime, "startProcess: added package to existing proc"); 2830 } 2831 2832 // If the system is not ready yet, then hold off on starting this 2833 // process until it is. 2834 if (!mProcessesReady 2835 && !isAllowedWhileBooting(info) 2836 && !allowWhileBooting) { 2837 if (!mProcessesOnHold.contains(app)) { 2838 mProcessesOnHold.add(app); 2839 } 2840 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2841 checkTime(startTime, "startProcess: returning with proc on hold"); 2842 return app; 2843 } 2844 2845 checkTime(startTime, "startProcess: stepping in to startProcess"); 2846 startProcessLocked( 2847 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2848 checkTime(startTime, "startProcess: done starting proc!"); 2849 return (app.pid != 0) ? app : null; 2850 } 2851 2852 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2853 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2854 } 2855 2856 private final void startProcessLocked(ProcessRecord app, 2857 String hostingType, String hostingNameStr) { 2858 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2859 null /* entryPoint */, null /* entryPointArgs */); 2860 } 2861 2862 private final void startProcessLocked(ProcessRecord app, String hostingType, 2863 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2864 long startTime = SystemClock.elapsedRealtime(); 2865 if (app.pid > 0 && app.pid != MY_PID) { 2866 checkTime(startTime, "startProcess: removing from pids map"); 2867 synchronized (mPidsSelfLocked) { 2868 mPidsSelfLocked.remove(app.pid); 2869 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2870 } 2871 checkTime(startTime, "startProcess: done removing from pids map"); 2872 app.setPid(0); 2873 } 2874 2875 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2876 "startProcessLocked removing on hold: " + app); 2877 mProcessesOnHold.remove(app); 2878 2879 checkTime(startTime, "startProcess: starting to update cpu stats"); 2880 updateCpuStats(); 2881 checkTime(startTime, "startProcess: done updating cpu stats"); 2882 2883 try { 2884 int uid = app.uid; 2885 2886 int[] gids = null; 2887 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2888 if (!app.isolated) { 2889 int[] permGids = null; 2890 try { 2891 checkTime(startTime, "startProcess: getting gids from package manager"); 2892 final PackageManager pm = mContext.getPackageManager(); 2893 permGids = pm.getPackageGids(app.info.packageName); 2894 2895 if (Environment.isExternalStorageEmulated()) { 2896 checkTime(startTime, "startProcess: checking external storage perm"); 2897 if (pm.checkPermission( 2898 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2899 app.info.packageName) == PERMISSION_GRANTED) { 2900 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2901 } else { 2902 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2903 } 2904 } 2905 } catch (PackageManager.NameNotFoundException e) { 2906 Slog.w(TAG, "Unable to retrieve gids", e); 2907 } 2908 2909 /* 2910 * Add shared application and profile GIDs so applications can share some 2911 * resources like shared libraries and access user-wide resources 2912 */ 2913 if (permGids == null) { 2914 gids = new int[2]; 2915 } else { 2916 gids = new int[permGids.length + 2]; 2917 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2918 } 2919 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2920 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2921 } 2922 checkTime(startTime, "startProcess: building args"); 2923 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2924 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2925 && mTopComponent != null 2926 && app.processName.equals(mTopComponent.getPackageName())) { 2927 uid = 0; 2928 } 2929 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2930 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2931 uid = 0; 2932 } 2933 } 2934 int debugFlags = 0; 2935 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2936 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2937 // Also turn on CheckJNI for debuggable apps. It's quite 2938 // awkward to turn on otherwise. 2939 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2940 } 2941 // Run the app in safe mode if its manifest requests so or the 2942 // system is booted in safe mode. 2943 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2944 mSafeMode == true) { 2945 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2946 } 2947 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2948 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2949 } 2950 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2951 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2952 } 2953 if ("1".equals(SystemProperties.get("debug.assert"))) { 2954 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2955 } 2956 2957 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2958 if (requiredAbi == null) { 2959 requiredAbi = Build.SUPPORTED_ABIS[0]; 2960 } 2961 2962 String instructionSet = null; 2963 if (app.info.primaryCpuAbi != null) { 2964 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2965 } 2966 2967 // Start the process. It will either succeed and return a result containing 2968 // the PID of the new process, or else throw a RuntimeException. 2969 boolean isActivityProcess = (entryPoint == null); 2970 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2971 checkTime(startTime, "startProcess: asking zygote to start proc"); 2972 Process.ProcessStartResult startResult = Process.start(entryPoint, 2973 app.processName, uid, uid, gids, debugFlags, mountExternal, 2974 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2975 app.info.dataDir, entryPointArgs); 2976 checkTime(startTime, "startProcess: returned from zygote!"); 2977 2978 if (app.isolated) { 2979 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2980 } 2981 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2982 checkTime(startTime, "startProcess: done updating battery stats"); 2983 2984 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2985 UserHandle.getUserId(uid), startResult.pid, uid, 2986 app.processName, hostingType, 2987 hostingNameStr != null ? hostingNameStr : ""); 2988 2989 if (app.persistent) { 2990 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2991 } 2992 2993 checkTime(startTime, "startProcess: building log message"); 2994 StringBuilder buf = mStringBuilder; 2995 buf.setLength(0); 2996 buf.append("Start proc "); 2997 buf.append(app.processName); 2998 if (!isActivityProcess) { 2999 buf.append(" ["); 3000 buf.append(entryPoint); 3001 buf.append("]"); 3002 } 3003 buf.append(" for "); 3004 buf.append(hostingType); 3005 if (hostingNameStr != null) { 3006 buf.append(" "); 3007 buf.append(hostingNameStr); 3008 } 3009 buf.append(": pid="); 3010 buf.append(startResult.pid); 3011 buf.append(" uid="); 3012 buf.append(uid); 3013 buf.append(" gids={"); 3014 if (gids != null) { 3015 for (int gi=0; gi<gids.length; gi++) { 3016 if (gi != 0) buf.append(", "); 3017 buf.append(gids[gi]); 3018 3019 } 3020 } 3021 buf.append("}"); 3022 if (requiredAbi != null) { 3023 buf.append(" abi="); 3024 buf.append(requiredAbi); 3025 } 3026 Slog.i(TAG, buf.toString()); 3027 app.setPid(startResult.pid); 3028 app.usingWrapper = startResult.usingWrapper; 3029 app.removed = false; 3030 app.killed = false; 3031 app.killedByAm = false; 3032 checkTime(startTime, "startProcess: starting to update pids map"); 3033 synchronized (mPidsSelfLocked) { 3034 this.mPidsSelfLocked.put(startResult.pid, app); 3035 if (isActivityProcess) { 3036 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3037 msg.obj = app; 3038 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3039 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3040 } 3041 } 3042 checkTime(startTime, "startProcess: done updating pids map"); 3043 } catch (RuntimeException e) { 3044 // XXX do better error recovery. 3045 app.setPid(0); 3046 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3047 if (app.isolated) { 3048 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3049 } 3050 Slog.e(TAG, "Failure starting process " + app.processName, e); 3051 } 3052 } 3053 3054 void updateUsageStats(ActivityRecord component, boolean resumed) { 3055 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3056 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3057 if (resumed) { 3058 if (mUsageStatsService != null) { 3059 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3060 UsageEvents.Event.MOVE_TO_FOREGROUND); 3061 } 3062 synchronized (stats) { 3063 stats.noteActivityResumedLocked(component.app.uid); 3064 } 3065 } else { 3066 if (mUsageStatsService != null) { 3067 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3068 UsageEvents.Event.MOVE_TO_BACKGROUND); 3069 } 3070 synchronized (stats) { 3071 stats.noteActivityPausedLocked(component.app.uid); 3072 } 3073 } 3074 } 3075 3076 Intent getHomeIntent() { 3077 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3078 intent.setComponent(mTopComponent); 3079 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3080 intent.addCategory(Intent.CATEGORY_HOME); 3081 } 3082 return intent; 3083 } 3084 3085 boolean startHomeActivityLocked(int userId) { 3086 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3087 && mTopAction == null) { 3088 // We are running in factory test mode, but unable to find 3089 // the factory test app, so just sit around displaying the 3090 // error message and don't try to start anything. 3091 return false; 3092 } 3093 Intent intent = getHomeIntent(); 3094 ActivityInfo aInfo = 3095 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3096 if (aInfo != null) { 3097 intent.setComponent(new ComponentName( 3098 aInfo.applicationInfo.packageName, aInfo.name)); 3099 // Don't do this if the home app is currently being 3100 // instrumented. 3101 aInfo = new ActivityInfo(aInfo); 3102 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3103 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3104 aInfo.applicationInfo.uid, true); 3105 if (app == null || app.instrumentationClass == null) { 3106 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3107 mStackSupervisor.startHomeActivity(intent, aInfo); 3108 } 3109 } 3110 3111 return true; 3112 } 3113 3114 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3115 ActivityInfo ai = null; 3116 ComponentName comp = intent.getComponent(); 3117 try { 3118 if (comp != null) { 3119 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3120 } else { 3121 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3122 intent, 3123 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3124 flags, userId); 3125 3126 if (info != null) { 3127 ai = info.activityInfo; 3128 } 3129 } 3130 } catch (RemoteException e) { 3131 // ignore 3132 } 3133 3134 return ai; 3135 } 3136 3137 /** 3138 * Starts the "new version setup screen" if appropriate. 3139 */ 3140 void startSetupActivityLocked() { 3141 // Only do this once per boot. 3142 if (mCheckedForSetup) { 3143 return; 3144 } 3145 3146 // We will show this screen if the current one is a different 3147 // version than the last one shown, and we are not running in 3148 // low-level factory test mode. 3149 final ContentResolver resolver = mContext.getContentResolver(); 3150 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3151 Settings.Global.getInt(resolver, 3152 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3153 mCheckedForSetup = true; 3154 3155 // See if we should be showing the platform update setup UI. 3156 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3157 List<ResolveInfo> ris = mContext.getPackageManager() 3158 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3159 3160 // We don't allow third party apps to replace this. 3161 ResolveInfo ri = null; 3162 for (int i=0; ris != null && i<ris.size(); i++) { 3163 if ((ris.get(i).activityInfo.applicationInfo.flags 3164 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3165 ri = ris.get(i); 3166 break; 3167 } 3168 } 3169 3170 if (ri != null) { 3171 String vers = ri.activityInfo.metaData != null 3172 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3173 : null; 3174 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3175 vers = ri.activityInfo.applicationInfo.metaData.getString( 3176 Intent.METADATA_SETUP_VERSION); 3177 } 3178 String lastVers = Settings.Secure.getString( 3179 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3180 if (vers != null && !vers.equals(lastVers)) { 3181 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3182 intent.setComponent(new ComponentName( 3183 ri.activityInfo.packageName, ri.activityInfo.name)); 3184 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3185 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3186 null); 3187 } 3188 } 3189 } 3190 } 3191 3192 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3193 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3194 } 3195 3196 void enforceNotIsolatedCaller(String caller) { 3197 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3198 throw new SecurityException("Isolated process not allowed to call " + caller); 3199 } 3200 } 3201 3202 void enforceShellRestriction(String restriction, int userHandle) { 3203 if (Binder.getCallingUid() == Process.SHELL_UID) { 3204 if (userHandle < 0 3205 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3206 throw new SecurityException("Shell does not have permission to access user " 3207 + userHandle); 3208 } 3209 } 3210 } 3211 3212 @Override 3213 public int getFrontActivityScreenCompatMode() { 3214 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3215 synchronized (this) { 3216 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3217 } 3218 } 3219 3220 @Override 3221 public void setFrontActivityScreenCompatMode(int mode) { 3222 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3223 "setFrontActivityScreenCompatMode"); 3224 synchronized (this) { 3225 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3226 } 3227 } 3228 3229 @Override 3230 public int getPackageScreenCompatMode(String packageName) { 3231 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3232 synchronized (this) { 3233 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3234 } 3235 } 3236 3237 @Override 3238 public void setPackageScreenCompatMode(String packageName, int mode) { 3239 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3240 "setPackageScreenCompatMode"); 3241 synchronized (this) { 3242 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3243 } 3244 } 3245 3246 @Override 3247 public boolean getPackageAskScreenCompat(String packageName) { 3248 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3249 synchronized (this) { 3250 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3251 } 3252 } 3253 3254 @Override 3255 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3256 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3257 "setPackageAskScreenCompat"); 3258 synchronized (this) { 3259 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3260 } 3261 } 3262 3263 private void dispatchProcessesChanged() { 3264 int N; 3265 synchronized (this) { 3266 N = mPendingProcessChanges.size(); 3267 if (mActiveProcessChanges.length < N) { 3268 mActiveProcessChanges = new ProcessChangeItem[N]; 3269 } 3270 mPendingProcessChanges.toArray(mActiveProcessChanges); 3271 mAvailProcessChanges.addAll(mPendingProcessChanges); 3272 mPendingProcessChanges.clear(); 3273 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3274 } 3275 3276 int i = mProcessObservers.beginBroadcast(); 3277 while (i > 0) { 3278 i--; 3279 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3280 if (observer != null) { 3281 try { 3282 for (int j=0; j<N; j++) { 3283 ProcessChangeItem item = mActiveProcessChanges[j]; 3284 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3286 + item.pid + " uid=" + item.uid + ": " 3287 + item.foregroundActivities); 3288 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3289 item.foregroundActivities); 3290 } 3291 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3292 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3293 + item.pid + " uid=" + item.uid + ": " + item.processState); 3294 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3295 } 3296 } 3297 } catch (RemoteException e) { 3298 } 3299 } 3300 } 3301 mProcessObservers.finishBroadcast(); 3302 } 3303 3304 private void dispatchProcessDied(int pid, int uid) { 3305 int i = mProcessObservers.beginBroadcast(); 3306 while (i > 0) { 3307 i--; 3308 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3309 if (observer != null) { 3310 try { 3311 observer.onProcessDied(pid, uid); 3312 } catch (RemoteException e) { 3313 } 3314 } 3315 } 3316 mProcessObservers.finishBroadcast(); 3317 } 3318 3319 @Override 3320 public final int startActivity(IApplicationThread caller, String callingPackage, 3321 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3322 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3323 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3324 resultWho, requestCode, startFlags, profilerInfo, options, 3325 UserHandle.getCallingUserId()); 3326 } 3327 3328 @Override 3329 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3330 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3331 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3332 enforceNotIsolatedCaller("startActivity"); 3333 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3334 false, ALLOW_FULL_ONLY, "startActivity", null); 3335 // TODO: Switch to user app stacks here. 3336 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3337 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3338 profilerInfo, null, null, options, userId, null, null); 3339 } 3340 3341 @Override 3342 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3343 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3344 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3345 3346 // This is very dangerous -- it allows you to perform a start activity (including 3347 // permission grants) as any app that may launch one of your own activities. So 3348 // we will only allow this to be done from activities that are part of the core framework, 3349 // and then only when they are running as the system. 3350 final ActivityRecord sourceRecord; 3351 final int targetUid; 3352 final String targetPackage; 3353 synchronized (this) { 3354 if (resultTo == null) { 3355 throw new SecurityException("Must be called from an activity"); 3356 } 3357 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3358 if (sourceRecord == null) { 3359 throw new SecurityException("Called with bad activity token: " + resultTo); 3360 } 3361 if (!sourceRecord.info.packageName.equals("android")) { 3362 throw new SecurityException( 3363 "Must be called from an activity that is declared in the android package"); 3364 } 3365 if (sourceRecord.app == null) { 3366 throw new SecurityException("Called without a process attached to activity"); 3367 } 3368 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3369 // This is still okay, as long as this activity is running under the 3370 // uid of the original calling activity. 3371 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3372 throw new SecurityException( 3373 "Calling activity in uid " + sourceRecord.app.uid 3374 + " must be system uid or original calling uid " 3375 + sourceRecord.launchedFromUid); 3376 } 3377 } 3378 targetUid = sourceRecord.launchedFromUid; 3379 targetPackage = sourceRecord.launchedFromPackage; 3380 } 3381 3382 if (userId == UserHandle.USER_NULL) { 3383 userId = UserHandle.getUserId(sourceRecord.app.uid); 3384 } 3385 3386 // TODO: Switch to user app stacks here. 3387 try { 3388 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3389 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3390 null, null, options, userId, null, null); 3391 return ret; 3392 } catch (SecurityException e) { 3393 // XXX need to figure out how to propagate to original app. 3394 // A SecurityException here is generally actually a fault of the original 3395 // calling activity (such as a fairly granting permissions), so propagate it 3396 // back to them. 3397 /* 3398 StringBuilder msg = new StringBuilder(); 3399 msg.append("While launching"); 3400 msg.append(intent.toString()); 3401 msg.append(": "); 3402 msg.append(e.getMessage()); 3403 */ 3404 throw e; 3405 } 3406 } 3407 3408 @Override 3409 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3410 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3411 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3412 enforceNotIsolatedCaller("startActivityAndWait"); 3413 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3414 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3415 WaitResult res = new WaitResult(); 3416 // TODO: Switch to user app stacks here. 3417 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3418 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3419 options, userId, null, null); 3420 return res; 3421 } 3422 3423 @Override 3424 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3425 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3426 int startFlags, Configuration config, Bundle options, int userId) { 3427 enforceNotIsolatedCaller("startActivityWithConfig"); 3428 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3429 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3430 // TODO: Switch to user app stacks here. 3431 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3432 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3433 null, null, config, options, userId, null, null); 3434 return ret; 3435 } 3436 3437 @Override 3438 public int startActivityIntentSender(IApplicationThread caller, 3439 IntentSender intent, Intent fillInIntent, String resolvedType, 3440 IBinder resultTo, String resultWho, int requestCode, 3441 int flagsMask, int flagsValues, Bundle options) { 3442 enforceNotIsolatedCaller("startActivityIntentSender"); 3443 // Refuse possible leaked file descriptors 3444 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3445 throw new IllegalArgumentException("File descriptors passed in Intent"); 3446 } 3447 3448 IIntentSender sender = intent.getTarget(); 3449 if (!(sender instanceof PendingIntentRecord)) { 3450 throw new IllegalArgumentException("Bad PendingIntent object"); 3451 } 3452 3453 PendingIntentRecord pir = (PendingIntentRecord)sender; 3454 3455 synchronized (this) { 3456 // If this is coming from the currently resumed activity, it is 3457 // effectively saying that app switches are allowed at this point. 3458 final ActivityStack stack = getFocusedStack(); 3459 if (stack.mResumedActivity != null && 3460 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3461 mAppSwitchesAllowedTime = 0; 3462 } 3463 } 3464 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3465 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3466 return ret; 3467 } 3468 3469 @Override 3470 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3471 Intent intent, String resolvedType, IVoiceInteractionSession session, 3472 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3473 Bundle options, int userId) { 3474 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3475 != PackageManager.PERMISSION_GRANTED) { 3476 String msg = "Permission Denial: startVoiceActivity() from pid=" 3477 + Binder.getCallingPid() 3478 + ", uid=" + Binder.getCallingUid() 3479 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3480 Slog.w(TAG, msg); 3481 throw new SecurityException(msg); 3482 } 3483 if (session == null || interactor == null) { 3484 throw new NullPointerException("null session or interactor"); 3485 } 3486 userId = handleIncomingUser(callingPid, callingUid, userId, 3487 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3488 // TODO: Switch to user app stacks here. 3489 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3490 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3491 null, options, userId, null, null); 3492 } 3493 3494 @Override 3495 public boolean startNextMatchingActivity(IBinder callingActivity, 3496 Intent intent, Bundle options) { 3497 // Refuse possible leaked file descriptors 3498 if (intent != null && intent.hasFileDescriptors() == true) { 3499 throw new IllegalArgumentException("File descriptors passed in Intent"); 3500 } 3501 3502 synchronized (this) { 3503 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3504 if (r == null) { 3505 ActivityOptions.abort(options); 3506 return false; 3507 } 3508 if (r.app == null || r.app.thread == null) { 3509 // The caller is not running... d'oh! 3510 ActivityOptions.abort(options); 3511 return false; 3512 } 3513 intent = new Intent(intent); 3514 // The caller is not allowed to change the data. 3515 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3516 // And we are resetting to find the next component... 3517 intent.setComponent(null); 3518 3519 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3520 3521 ActivityInfo aInfo = null; 3522 try { 3523 List<ResolveInfo> resolves = 3524 AppGlobals.getPackageManager().queryIntentActivities( 3525 intent, r.resolvedType, 3526 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3527 UserHandle.getCallingUserId()); 3528 3529 // Look for the original activity in the list... 3530 final int N = resolves != null ? resolves.size() : 0; 3531 for (int i=0; i<N; i++) { 3532 ResolveInfo rInfo = resolves.get(i); 3533 if (rInfo.activityInfo.packageName.equals(r.packageName) 3534 && rInfo.activityInfo.name.equals(r.info.name)) { 3535 // We found the current one... the next matching is 3536 // after it. 3537 i++; 3538 if (i<N) { 3539 aInfo = resolves.get(i).activityInfo; 3540 } 3541 if (debug) { 3542 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3543 + "/" + r.info.name); 3544 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3545 + "/" + aInfo.name); 3546 } 3547 break; 3548 } 3549 } 3550 } catch (RemoteException e) { 3551 } 3552 3553 if (aInfo == null) { 3554 // Nobody who is next! 3555 ActivityOptions.abort(options); 3556 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3557 return false; 3558 } 3559 3560 intent.setComponent(new ComponentName( 3561 aInfo.applicationInfo.packageName, aInfo.name)); 3562 intent.setFlags(intent.getFlags()&~( 3563 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3564 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3565 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3566 Intent.FLAG_ACTIVITY_NEW_TASK)); 3567 3568 // Okay now we need to start the new activity, replacing the 3569 // currently running activity. This is a little tricky because 3570 // we want to start the new one as if the current one is finished, 3571 // but not finish the current one first so that there is no flicker. 3572 // And thus... 3573 final boolean wasFinishing = r.finishing; 3574 r.finishing = true; 3575 3576 // Propagate reply information over to the new activity. 3577 final ActivityRecord resultTo = r.resultTo; 3578 final String resultWho = r.resultWho; 3579 final int requestCode = r.requestCode; 3580 r.resultTo = null; 3581 if (resultTo != null) { 3582 resultTo.removeResultsLocked(r, resultWho, requestCode); 3583 } 3584 3585 final long origId = Binder.clearCallingIdentity(); 3586 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3587 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3588 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3589 -1, r.launchedFromUid, 0, options, false, null, null, null); 3590 Binder.restoreCallingIdentity(origId); 3591 3592 r.finishing = wasFinishing; 3593 if (res != ActivityManager.START_SUCCESS) { 3594 return false; 3595 } 3596 return true; 3597 } 3598 } 3599 3600 @Override 3601 public final int startActivityFromRecents(int taskId, Bundle options) { 3602 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3603 String msg = "Permission Denial: startActivityFromRecents called without " + 3604 START_TASKS_FROM_RECENTS; 3605 Slog.w(TAG, msg); 3606 throw new SecurityException(msg); 3607 } 3608 return startActivityFromRecentsInner(taskId, options); 3609 } 3610 3611 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3612 final TaskRecord task; 3613 final int callingUid; 3614 final String callingPackage; 3615 final Intent intent; 3616 final int userId; 3617 synchronized (this) { 3618 task = recentTaskForIdLocked(taskId); 3619 if (task == null) { 3620 throw new IllegalArgumentException("Task " + taskId + " not found."); 3621 } 3622 callingUid = task.mCallingUid; 3623 callingPackage = task.mCallingPackage; 3624 intent = task.intent; 3625 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3626 userId = task.userId; 3627 } 3628 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3629 options, userId, null, task); 3630 } 3631 3632 final int startActivityInPackage(int uid, String callingPackage, 3633 Intent intent, String resolvedType, IBinder resultTo, 3634 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3635 IActivityContainer container, TaskRecord inTask) { 3636 3637 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3638 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3639 3640 // TODO: Switch to user app stacks here. 3641 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3642 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3643 null, null, null, options, userId, container, inTask); 3644 return ret; 3645 } 3646 3647 @Override 3648 public final int startActivities(IApplicationThread caller, String callingPackage, 3649 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3650 int userId) { 3651 enforceNotIsolatedCaller("startActivities"); 3652 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3653 false, ALLOW_FULL_ONLY, "startActivity", null); 3654 // TODO: Switch to user app stacks here. 3655 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3656 resolvedTypes, resultTo, options, userId); 3657 return ret; 3658 } 3659 3660 final int startActivitiesInPackage(int uid, String callingPackage, 3661 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3662 Bundle options, int userId) { 3663 3664 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3665 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3666 // TODO: Switch to user app stacks here. 3667 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3668 resultTo, options, userId); 3669 return ret; 3670 } 3671 3672 //explicitly remove thd old information in mRecentTasks when removing existing user. 3673 private void removeRecentTasksForUserLocked(int userId) { 3674 if(userId <= 0) { 3675 Slog.i(TAG, "Can't remove recent task on user " + userId); 3676 return; 3677 } 3678 3679 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3680 TaskRecord tr = mRecentTasks.get(i); 3681 if (tr.userId == userId) { 3682 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3683 + " when finishing user" + userId); 3684 mRecentTasks.remove(i); 3685 tr.removedFromRecents(); 3686 } 3687 } 3688 3689 // Remove tasks from persistent storage. 3690 notifyTaskPersisterLocked(null, true); 3691 } 3692 3693 // Sort by taskId 3694 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3695 @Override 3696 public int compare(TaskRecord lhs, TaskRecord rhs) { 3697 return rhs.taskId - lhs.taskId; 3698 } 3699 }; 3700 3701 // Extract the affiliates of the chain containing mRecentTasks[start]. 3702 private int processNextAffiliateChainLocked(int start) { 3703 final TaskRecord startTask = mRecentTasks.get(start); 3704 final int affiliateId = startTask.mAffiliatedTaskId; 3705 3706 // Quick identification of isolated tasks. I.e. those not launched behind. 3707 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3708 startTask.mNextAffiliate == null) { 3709 // There is still a slim chance that there are other tasks that point to this task 3710 // and that the chain is so messed up that this task no longer points to them but 3711 // the gain of this optimization outweighs the risk. 3712 startTask.inRecents = true; 3713 return start + 1; 3714 } 3715 3716 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3717 mTmpRecents.clear(); 3718 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3719 final TaskRecord task = mRecentTasks.get(i); 3720 if (task.mAffiliatedTaskId == affiliateId) { 3721 mRecentTasks.remove(i); 3722 mTmpRecents.add(task); 3723 } 3724 } 3725 3726 // Sort them all by taskId. That is the order they were create in and that order will 3727 // always be correct. 3728 Collections.sort(mTmpRecents, mTaskRecordComparator); 3729 3730 // Go through and fix up the linked list. 3731 // The first one is the end of the chain and has no next. 3732 final TaskRecord first = mTmpRecents.get(0); 3733 first.inRecents = true; 3734 if (first.mNextAffiliate != null) { 3735 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3736 first.setNextAffiliate(null); 3737 notifyTaskPersisterLocked(first, false); 3738 } 3739 // Everything in the middle is doubly linked from next to prev. 3740 final int tmpSize = mTmpRecents.size(); 3741 for (int i = 0; i < tmpSize - 1; ++i) { 3742 final TaskRecord next = mTmpRecents.get(i); 3743 final TaskRecord prev = mTmpRecents.get(i + 1); 3744 if (next.mPrevAffiliate != prev) { 3745 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3746 " setting prev=" + prev); 3747 next.setPrevAffiliate(prev); 3748 notifyTaskPersisterLocked(next, false); 3749 } 3750 if (prev.mNextAffiliate != next) { 3751 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3752 " setting next=" + next); 3753 prev.setNextAffiliate(next); 3754 notifyTaskPersisterLocked(prev, false); 3755 } 3756 prev.inRecents = true; 3757 } 3758 // The last one is the beginning of the list and has no prev. 3759 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3760 if (last.mPrevAffiliate != null) { 3761 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3762 last.setPrevAffiliate(null); 3763 notifyTaskPersisterLocked(last, false); 3764 } 3765 3766 // Insert the group back into mRecentTasks at start. 3767 mRecentTasks.addAll(start, mTmpRecents); 3768 3769 // Let the caller know where we left off. 3770 return start + tmpSize; 3771 } 3772 3773 /** 3774 * Update the recent tasks lists: make sure tasks should still be here (their 3775 * applications / activities still exist), update their availability, fixup ordering 3776 * of affiliations. 3777 */ 3778 void cleanupRecentTasksLocked(int userId) { 3779 if (mRecentTasks == null) { 3780 // Happens when called from the packagemanager broadcast before boot. 3781 return; 3782 } 3783 3784 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3785 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3786 final IPackageManager pm = AppGlobals.getPackageManager(); 3787 final ActivityInfo dummyAct = new ActivityInfo(); 3788 final ApplicationInfo dummyApp = new ApplicationInfo(); 3789 3790 int N = mRecentTasks.size(); 3791 3792 int[] users = userId == UserHandle.USER_ALL 3793 ? getUsersLocked() : new int[] { userId }; 3794 for (int user : users) { 3795 for (int i = 0; i < N; i++) { 3796 TaskRecord task = mRecentTasks.get(i); 3797 if (task.userId != user) { 3798 // Only look at tasks for the user ID of interest. 3799 continue; 3800 } 3801 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3802 // This situation is broken, and we should just get rid of it now. 3803 mRecentTasks.remove(i); 3804 task.removedFromRecents(); 3805 i--; 3806 N--; 3807 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3808 continue; 3809 } 3810 // Check whether this activity is currently available. 3811 if (task.realActivity != null) { 3812 ActivityInfo ai = availActCache.get(task.realActivity); 3813 if (ai == null) { 3814 try { 3815 ai = pm.getActivityInfo(task.realActivity, 3816 PackageManager.GET_UNINSTALLED_PACKAGES 3817 | PackageManager.GET_DISABLED_COMPONENTS, user); 3818 } catch (RemoteException e) { 3819 // Will never happen. 3820 continue; 3821 } 3822 if (ai == null) { 3823 ai = dummyAct; 3824 } 3825 availActCache.put(task.realActivity, ai); 3826 } 3827 if (ai == dummyAct) { 3828 // This could be either because the activity no longer exists, or the 3829 // app is temporarily gone. For the former we want to remove the recents 3830 // entry; for the latter we want to mark it as unavailable. 3831 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3832 if (app == null) { 3833 try { 3834 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3835 PackageManager.GET_UNINSTALLED_PACKAGES 3836 | PackageManager.GET_DISABLED_COMPONENTS, user); 3837 } catch (RemoteException e) { 3838 // Will never happen. 3839 continue; 3840 } 3841 if (app == null) { 3842 app = dummyApp; 3843 } 3844 availAppCache.put(task.realActivity.getPackageName(), app); 3845 } 3846 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3847 // Doesn't exist any more! Good-bye. 3848 mRecentTasks.remove(i); 3849 task.removedFromRecents(); 3850 i--; 3851 N--; 3852 Slog.w(TAG, "Removing no longer valid recent: " + task); 3853 continue; 3854 } else { 3855 // Otherwise just not available for now. 3856 if (task.isAvailable) { 3857 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3858 + task); 3859 } 3860 task.isAvailable = false; 3861 } 3862 } else { 3863 if (!ai.enabled || !ai.applicationInfo.enabled 3864 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3865 if (task.isAvailable) { 3866 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3867 + task + " (enabled=" + ai.enabled + "/" 3868 + ai.applicationInfo.enabled + " flags=" 3869 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3870 } 3871 task.isAvailable = false; 3872 } else { 3873 if (!task.isAvailable) { 3874 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3875 + task); 3876 } 3877 task.isAvailable = true; 3878 } 3879 } 3880 } 3881 } 3882 } 3883 3884 // Verify the affiliate chain for each task. 3885 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3886 } 3887 3888 mTmpRecents.clear(); 3889 // mRecentTasks is now in sorted, affiliated order. 3890 } 3891 3892 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3893 int N = mRecentTasks.size(); 3894 TaskRecord top = task; 3895 int topIndex = taskIndex; 3896 while (top.mNextAffiliate != null && topIndex > 0) { 3897 top = top.mNextAffiliate; 3898 topIndex--; 3899 } 3900 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3901 + topIndex + " from intial " + taskIndex); 3902 // Find the end of the chain, doing a sanity check along the way. 3903 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3904 int endIndex = topIndex; 3905 TaskRecord prev = top; 3906 while (endIndex < N) { 3907 TaskRecord cur = mRecentTasks.get(endIndex); 3908 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3909 + endIndex + " " + cur); 3910 if (cur == top) { 3911 // Verify start of the chain. 3912 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3913 Slog.wtf(TAG, "Bad chain @" + endIndex 3914 + ": first task has next affiliate: " + prev); 3915 sane = false; 3916 break; 3917 } 3918 } else { 3919 // Verify middle of the chain's next points back to the one before. 3920 if (cur.mNextAffiliate != prev 3921 || cur.mNextAffiliateTaskId != prev.taskId) { 3922 Slog.wtf(TAG, "Bad chain @" + endIndex 3923 + ": middle task " + cur + " @" + endIndex 3924 + " has bad next affiliate " 3925 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3926 + ", expected " + prev); 3927 sane = false; 3928 break; 3929 } 3930 } 3931 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3932 // Chain ends here. 3933 if (cur.mPrevAffiliate != null) { 3934 Slog.wtf(TAG, "Bad chain @" + endIndex 3935 + ": last task " + cur + " has previous affiliate " 3936 + cur.mPrevAffiliate); 3937 sane = false; 3938 } 3939 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3940 break; 3941 } else { 3942 // Verify middle of the chain's prev points to a valid item. 3943 if (cur.mPrevAffiliate == null) { 3944 Slog.wtf(TAG, "Bad chain @" + endIndex 3945 + ": task " + cur + " has previous affiliate " 3946 + cur.mPrevAffiliate + " but should be id " 3947 + cur.mPrevAffiliate); 3948 sane = false; 3949 break; 3950 } 3951 } 3952 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3953 Slog.wtf(TAG, "Bad chain @" + endIndex 3954 + ": task " + cur + " has affiliated id " 3955 + cur.mAffiliatedTaskId + " but should be " 3956 + task.mAffiliatedTaskId); 3957 sane = false; 3958 break; 3959 } 3960 prev = cur; 3961 endIndex++; 3962 if (endIndex >= N) { 3963 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3964 + ": last task " + prev); 3965 sane = false; 3966 break; 3967 } 3968 } 3969 if (sane) { 3970 if (endIndex < taskIndex) { 3971 Slog.wtf(TAG, "Bad chain @" + endIndex 3972 + ": did not extend to task " + task + " @" + taskIndex); 3973 sane = false; 3974 } 3975 } 3976 if (sane) { 3977 // All looks good, we can just move all of the affiliated tasks 3978 // to the top. 3979 for (int i=topIndex; i<=endIndex; i++) { 3980 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3981 + " from " + i + " to " + (i-topIndex)); 3982 TaskRecord cur = mRecentTasks.remove(i); 3983 mRecentTasks.add(i-topIndex, cur); 3984 } 3985 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3986 + " to " + endIndex); 3987 return true; 3988 } 3989 3990 // Whoops, couldn't do it. 3991 return false; 3992 } 3993 3994 final void addRecentTaskLocked(TaskRecord task) { 3995 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3996 || task.mNextAffiliateTaskId != INVALID_TASK_ID 3997 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 3998 3999 int N = mRecentTasks.size(); 4000 // Quick case: check if the top-most recent task is the same. 4001 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4002 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4003 return; 4004 } 4005 // Another quick case: check if this is part of a set of affiliated 4006 // tasks that are at the top. 4007 if (isAffiliated && N > 0 && task.inRecents 4008 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4009 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4010 + " at top when adding " + task); 4011 return; 4012 } 4013 // Another quick case: never add voice sessions. 4014 if (task.voiceSession != null) { 4015 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4016 return; 4017 } 4018 4019 boolean needAffiliationFix = false; 4020 4021 // Slightly less quick case: the task is already in recents, so all we need 4022 // to do is move it. 4023 if (task.inRecents) { 4024 int taskIndex = mRecentTasks.indexOf(task); 4025 if (taskIndex >= 0) { 4026 if (!isAffiliated) { 4027 // Simple case: this is not an affiliated task, so we just move it to the front. 4028 mRecentTasks.remove(taskIndex); 4029 mRecentTasks.add(0, task); 4030 notifyTaskPersisterLocked(task, false); 4031 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4032 + " from " + taskIndex); 4033 return; 4034 } else { 4035 // More complicated: need to keep all affiliated tasks together. 4036 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4037 // All went well. 4038 return; 4039 } 4040 4041 // Uh oh... something bad in the affiliation chain, try to rebuild 4042 // everything and then go through our general path of adding a new task. 4043 needAffiliationFix = true; 4044 } 4045 } else { 4046 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4047 needAffiliationFix = true; 4048 } 4049 } 4050 4051 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4052 trimRecentsForTaskLocked(task, true); 4053 4054 N = mRecentTasks.size(); 4055 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4056 final TaskRecord tr = mRecentTasks.remove(N - 1); 4057 tr.removedFromRecents(); 4058 N--; 4059 } 4060 task.inRecents = true; 4061 if (!isAffiliated || needAffiliationFix) { 4062 // If this is a simple non-affiliated task, or we had some failure trying to 4063 // handle it as part of an affilated task, then just place it at the top. 4064 mRecentTasks.add(0, task); 4065 } else if (isAffiliated) { 4066 // If this is a new affiliated task, then move all of the affiliated tasks 4067 // to the front and insert this new one. 4068 TaskRecord other = task.mNextAffiliate; 4069 if (other == null) { 4070 other = task.mPrevAffiliate; 4071 } 4072 if (other != null) { 4073 int otherIndex = mRecentTasks.indexOf(other); 4074 if (otherIndex >= 0) { 4075 // Insert new task at appropriate location. 4076 int taskIndex; 4077 if (other == task.mNextAffiliate) { 4078 // We found the index of our next affiliation, which is who is 4079 // before us in the list, so add after that point. 4080 taskIndex = otherIndex+1; 4081 } else { 4082 // We found the index of our previous affiliation, which is who is 4083 // after us in the list, so add at their position. 4084 taskIndex = otherIndex; 4085 } 4086 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4087 + taskIndex + ": " + task); 4088 mRecentTasks.add(taskIndex, task); 4089 4090 // Now move everything to the front. 4091 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4092 // All went well. 4093 return; 4094 } 4095 4096 // Uh oh... something bad in the affiliation chain, try to rebuild 4097 // everything and then go through our general path of adding a new task. 4098 needAffiliationFix = true; 4099 } else { 4100 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4101 + other); 4102 needAffiliationFix = true; 4103 } 4104 } else { 4105 if (DEBUG_RECENTS) Slog.d(TAG, 4106 "addRecent: adding affiliated task without next/prev:" + task); 4107 needAffiliationFix = true; 4108 } 4109 } 4110 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4111 4112 if (needAffiliationFix) { 4113 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4114 cleanupRecentTasksLocked(task.userId); 4115 } 4116 } 4117 4118 /** 4119 * If needed, remove oldest existing entries in recents that are for the same kind 4120 * of task as the given one. 4121 */ 4122 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4123 int N = mRecentTasks.size(); 4124 final Intent intent = task.intent; 4125 final boolean document = intent != null && intent.isDocument(); 4126 4127 int maxRecents = task.maxRecents - 1; 4128 for (int i=0; i<N; i++) { 4129 final TaskRecord tr = mRecentTasks.get(i); 4130 if (task != tr) { 4131 if (task.userId != tr.userId) { 4132 continue; 4133 } 4134 if (i > MAX_RECENT_BITMAPS) { 4135 tr.freeLastThumbnail(); 4136 } 4137 final Intent trIntent = tr.intent; 4138 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4139 (intent == null || !intent.filterEquals(trIntent))) { 4140 continue; 4141 } 4142 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4143 if (document && trIsDocument) { 4144 // These are the same document activity (not necessarily the same doc). 4145 if (maxRecents > 0) { 4146 --maxRecents; 4147 continue; 4148 } 4149 // Hit the maximum number of documents for this task. Fall through 4150 // and remove this document from recents. 4151 } else if (document || trIsDocument) { 4152 // Only one of these is a document. Not the droid we're looking for. 4153 continue; 4154 } 4155 } 4156 4157 if (!doTrim) { 4158 // If the caller is not actually asking for a trim, just tell them we reached 4159 // a point where the trim would happen. 4160 return i; 4161 } 4162 4163 // Either task and tr are the same or, their affinities match or their intents match 4164 // and neither of them is a document, or they are documents using the same activity 4165 // and their maxRecents has been reached. 4166 tr.disposeThumbnail(); 4167 mRecentTasks.remove(i); 4168 if (task != tr) { 4169 tr.removedFromRecents(); 4170 } 4171 i--; 4172 N--; 4173 if (task.intent == null) { 4174 // If the new recent task we are adding is not fully 4175 // specified, then replace it with the existing recent task. 4176 task = tr; 4177 } 4178 notifyTaskPersisterLocked(tr, false); 4179 } 4180 4181 return -1; 4182 } 4183 4184 @Override 4185 public void reportActivityFullyDrawn(IBinder token) { 4186 synchronized (this) { 4187 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4188 if (r == null) { 4189 return; 4190 } 4191 r.reportFullyDrawnLocked(); 4192 } 4193 } 4194 4195 @Override 4196 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4197 synchronized (this) { 4198 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4199 if (r == null) { 4200 return; 4201 } 4202 final long origId = Binder.clearCallingIdentity(); 4203 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4204 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4205 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4206 if (config != null) { 4207 r.frozenBeforeDestroy = true; 4208 if (!updateConfigurationLocked(config, r, false, false)) { 4209 mStackSupervisor.resumeTopActivitiesLocked(); 4210 } 4211 } 4212 Binder.restoreCallingIdentity(origId); 4213 } 4214 } 4215 4216 @Override 4217 public int getRequestedOrientation(IBinder token) { 4218 synchronized (this) { 4219 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4220 if (r == null) { 4221 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4222 } 4223 return mWindowManager.getAppOrientation(r.appToken); 4224 } 4225 } 4226 4227 /** 4228 * This is the internal entry point for handling Activity.finish(). 4229 * 4230 * @param token The Binder token referencing the Activity we want to finish. 4231 * @param resultCode Result code, if any, from this Activity. 4232 * @param resultData Result data (Intent), if any, from this Activity. 4233 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4234 * the root Activity in the task. 4235 * 4236 * @return Returns true if the activity successfully finished, or false if it is still running. 4237 */ 4238 @Override 4239 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4240 boolean finishTask) { 4241 // Refuse possible leaked file descriptors 4242 if (resultData != null && resultData.hasFileDescriptors() == true) { 4243 throw new IllegalArgumentException("File descriptors passed in Intent"); 4244 } 4245 4246 synchronized(this) { 4247 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4248 if (r == null) { 4249 return true; 4250 } 4251 // Keep track of the root activity of the task before we finish it 4252 TaskRecord tr = r.task; 4253 ActivityRecord rootR = tr.getRootActivity(); 4254 if (rootR == null) { 4255 Slog.w(TAG, "Finishing task with all activities already finished"); 4256 } 4257 // Do not allow task to finish in Lock Task mode. 4258 if (tr == mStackSupervisor.mLockTaskModeTask) { 4259 if (rootR == r) { 4260 Slog.i(TAG, "Not finishing task in lock task mode"); 4261 mStackSupervisor.showLockTaskToast(); 4262 return false; 4263 } 4264 } 4265 if (mController != null) { 4266 // Find the first activity that is not finishing. 4267 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4268 if (next != null) { 4269 // ask watcher if this is allowed 4270 boolean resumeOK = true; 4271 try { 4272 resumeOK = mController.activityResuming(next.packageName); 4273 } catch (RemoteException e) { 4274 mController = null; 4275 Watchdog.getInstance().setActivityController(null); 4276 } 4277 4278 if (!resumeOK) { 4279 Slog.i(TAG, "Not finishing activity because controller resumed"); 4280 return false; 4281 } 4282 } 4283 } 4284 final long origId = Binder.clearCallingIdentity(); 4285 try { 4286 boolean res; 4287 if (finishTask && r == rootR) { 4288 // If requested, remove the task that is associated to this activity only if it 4289 // was the root activity in the task. The result code and data is ignored 4290 // because we don't support returning them across task boundaries. 4291 res = removeTaskByIdLocked(tr.taskId, false); 4292 if (!res) { 4293 Slog.i(TAG, "Removing task failed to finish activity"); 4294 } 4295 } else { 4296 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4297 resultData, "app-request", true); 4298 if (!res) { 4299 Slog.i(TAG, "Failed to finish by app-request"); 4300 } 4301 } 4302 return res; 4303 } finally { 4304 Binder.restoreCallingIdentity(origId); 4305 } 4306 } 4307 } 4308 4309 @Override 4310 public final void finishHeavyWeightApp() { 4311 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4312 != PackageManager.PERMISSION_GRANTED) { 4313 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4314 + Binder.getCallingPid() 4315 + ", uid=" + Binder.getCallingUid() 4316 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4317 Slog.w(TAG, msg); 4318 throw new SecurityException(msg); 4319 } 4320 4321 synchronized(this) { 4322 if (mHeavyWeightProcess == null) { 4323 return; 4324 } 4325 4326 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4327 mHeavyWeightProcess.activities); 4328 for (int i=0; i<activities.size(); i++) { 4329 ActivityRecord r = activities.get(i); 4330 if (!r.finishing) { 4331 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4332 null, "finish-heavy", true); 4333 } 4334 } 4335 4336 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4337 mHeavyWeightProcess.userId, 0)); 4338 mHeavyWeightProcess = null; 4339 } 4340 } 4341 4342 @Override 4343 public void crashApplication(int uid, int initialPid, String packageName, 4344 String message) { 4345 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4346 != PackageManager.PERMISSION_GRANTED) { 4347 String msg = "Permission Denial: crashApplication() from pid=" 4348 + Binder.getCallingPid() 4349 + ", uid=" + Binder.getCallingUid() 4350 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4351 Slog.w(TAG, msg); 4352 throw new SecurityException(msg); 4353 } 4354 4355 synchronized(this) { 4356 ProcessRecord proc = null; 4357 4358 // Figure out which process to kill. We don't trust that initialPid 4359 // still has any relation to current pids, so must scan through the 4360 // list. 4361 synchronized (mPidsSelfLocked) { 4362 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4363 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4364 if (p.uid != uid) { 4365 continue; 4366 } 4367 if (p.pid == initialPid) { 4368 proc = p; 4369 break; 4370 } 4371 if (p.pkgList.containsKey(packageName)) { 4372 proc = p; 4373 } 4374 } 4375 } 4376 4377 if (proc == null) { 4378 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4379 + " initialPid=" + initialPid 4380 + " packageName=" + packageName); 4381 return; 4382 } 4383 4384 if (proc.thread != null) { 4385 if (proc.pid == Process.myPid()) { 4386 Log.w(TAG, "crashApplication: trying to crash self!"); 4387 return; 4388 } 4389 long ident = Binder.clearCallingIdentity(); 4390 try { 4391 proc.thread.scheduleCrash(message); 4392 } catch (RemoteException e) { 4393 } 4394 Binder.restoreCallingIdentity(ident); 4395 } 4396 } 4397 } 4398 4399 @Override 4400 public final void finishSubActivity(IBinder token, String resultWho, 4401 int requestCode) { 4402 synchronized(this) { 4403 final long origId = Binder.clearCallingIdentity(); 4404 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4405 if (r != null) { 4406 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4407 } 4408 Binder.restoreCallingIdentity(origId); 4409 } 4410 } 4411 4412 @Override 4413 public boolean finishActivityAffinity(IBinder token) { 4414 synchronized(this) { 4415 final long origId = Binder.clearCallingIdentity(); 4416 try { 4417 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4418 4419 ActivityRecord rootR = r.task.getRootActivity(); 4420 // Do not allow task to finish in Lock Task mode. 4421 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4422 if (rootR == r) { 4423 mStackSupervisor.showLockTaskToast(); 4424 return false; 4425 } 4426 } 4427 boolean res = false; 4428 if (r != null) { 4429 res = r.task.stack.finishActivityAffinityLocked(r); 4430 } 4431 return res; 4432 } finally { 4433 Binder.restoreCallingIdentity(origId); 4434 } 4435 } 4436 } 4437 4438 @Override 4439 public void finishVoiceTask(IVoiceInteractionSession session) { 4440 synchronized(this) { 4441 final long origId = Binder.clearCallingIdentity(); 4442 try { 4443 mStackSupervisor.finishVoiceTask(session); 4444 } finally { 4445 Binder.restoreCallingIdentity(origId); 4446 } 4447 } 4448 4449 } 4450 4451 @Override 4452 public boolean releaseActivityInstance(IBinder token) { 4453 synchronized(this) { 4454 final long origId = Binder.clearCallingIdentity(); 4455 try { 4456 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4457 if (r.task == null || r.task.stack == null) { 4458 return false; 4459 } 4460 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4461 } finally { 4462 Binder.restoreCallingIdentity(origId); 4463 } 4464 } 4465 } 4466 4467 @Override 4468 public void releaseSomeActivities(IApplicationThread appInt) { 4469 synchronized(this) { 4470 final long origId = Binder.clearCallingIdentity(); 4471 try { 4472 ProcessRecord app = getRecordForAppLocked(appInt); 4473 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4474 } finally { 4475 Binder.restoreCallingIdentity(origId); 4476 } 4477 } 4478 } 4479 4480 @Override 4481 public boolean willActivityBeVisible(IBinder token) { 4482 synchronized(this) { 4483 ActivityStack stack = ActivityRecord.getStackLocked(token); 4484 if (stack != null) { 4485 return stack.willActivityBeVisibleLocked(token); 4486 } 4487 return false; 4488 } 4489 } 4490 4491 @Override 4492 public void overridePendingTransition(IBinder token, String packageName, 4493 int enterAnim, int exitAnim) { 4494 synchronized(this) { 4495 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4496 if (self == null) { 4497 return; 4498 } 4499 4500 final long origId = Binder.clearCallingIdentity(); 4501 4502 if (self.state == ActivityState.RESUMED 4503 || self.state == ActivityState.PAUSING) { 4504 mWindowManager.overridePendingAppTransition(packageName, 4505 enterAnim, exitAnim, null); 4506 } 4507 4508 Binder.restoreCallingIdentity(origId); 4509 } 4510 } 4511 4512 /** 4513 * Main function for removing an existing process from the activity manager 4514 * as a result of that process going away. Clears out all connections 4515 * to the process. 4516 */ 4517 private final void handleAppDiedLocked(ProcessRecord app, 4518 boolean restarting, boolean allowRestart) { 4519 int pid = app.pid; 4520 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4521 if (!kept && !restarting) { 4522 removeLruProcessLocked(app); 4523 if (pid > 0) { 4524 ProcessList.remove(pid); 4525 } 4526 } 4527 4528 if (mProfileProc == app) { 4529 clearProfilerLocked(); 4530 } 4531 4532 // Remove this application's activities from active lists. 4533 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4534 4535 app.activities.clear(); 4536 4537 if (app.instrumentationClass != null) { 4538 Slog.w(TAG, "Crash of app " + app.processName 4539 + " running instrumentation " + app.instrumentationClass); 4540 Bundle info = new Bundle(); 4541 info.putString("shortMsg", "Process crashed."); 4542 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4543 } 4544 4545 if (!restarting) { 4546 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4547 // If there was nothing to resume, and we are not already 4548 // restarting this process, but there is a visible activity that 4549 // is hosted by the process... then make sure all visible 4550 // activities are running, taking care of restarting this 4551 // process. 4552 if (hasVisibleActivities) { 4553 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4554 } 4555 } 4556 } 4557 } 4558 4559 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4560 IBinder threadBinder = thread.asBinder(); 4561 // Find the application record. 4562 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4563 ProcessRecord rec = mLruProcesses.get(i); 4564 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4565 return i; 4566 } 4567 } 4568 return -1; 4569 } 4570 4571 final ProcessRecord getRecordForAppLocked( 4572 IApplicationThread thread) { 4573 if (thread == null) { 4574 return null; 4575 } 4576 4577 int appIndex = getLRURecordIndexForAppLocked(thread); 4578 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4579 } 4580 4581 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4582 // If there are no longer any background processes running, 4583 // and the app that died was not running instrumentation, 4584 // then tell everyone we are now low on memory. 4585 boolean haveBg = false; 4586 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4587 ProcessRecord rec = mLruProcesses.get(i); 4588 if (rec.thread != null 4589 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4590 haveBg = true; 4591 break; 4592 } 4593 } 4594 4595 if (!haveBg) { 4596 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4597 if (doReport) { 4598 long now = SystemClock.uptimeMillis(); 4599 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4600 doReport = false; 4601 } else { 4602 mLastMemUsageReportTime = now; 4603 } 4604 } 4605 final ArrayList<ProcessMemInfo> memInfos 4606 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4607 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4608 long now = SystemClock.uptimeMillis(); 4609 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4610 ProcessRecord rec = mLruProcesses.get(i); 4611 if (rec == dyingProc || rec.thread == null) { 4612 continue; 4613 } 4614 if (doReport) { 4615 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4616 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4617 } 4618 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4619 // The low memory report is overriding any current 4620 // state for a GC request. Make sure to do 4621 // heavy/important/visible/foreground processes first. 4622 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4623 rec.lastRequestedGc = 0; 4624 } else { 4625 rec.lastRequestedGc = rec.lastLowMemory; 4626 } 4627 rec.reportLowMemory = true; 4628 rec.lastLowMemory = now; 4629 mProcessesToGc.remove(rec); 4630 addProcessToGcListLocked(rec); 4631 } 4632 } 4633 if (doReport) { 4634 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4635 mHandler.sendMessage(msg); 4636 } 4637 scheduleAppGcsLocked(); 4638 } 4639 } 4640 4641 final void appDiedLocked(ProcessRecord app) { 4642 appDiedLocked(app, app.pid, app.thread); 4643 } 4644 4645 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4646 // First check if this ProcessRecord is actually active for the pid. 4647 synchronized (mPidsSelfLocked) { 4648 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4649 if (curProc != app) { 4650 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4651 return; 4652 } 4653 } 4654 4655 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4656 synchronized (stats) { 4657 stats.noteProcessDiedLocked(app.info.uid, pid); 4658 } 4659 4660 Process.killProcessQuiet(pid); 4661 Process.killProcessGroup(app.info.uid, pid); 4662 app.killed = true; 4663 4664 // Clean up already done if the process has been re-started. 4665 if (app.pid == pid && app.thread != null && 4666 app.thread.asBinder() == thread.asBinder()) { 4667 boolean doLowMem = app.instrumentationClass == null; 4668 boolean doOomAdj = doLowMem; 4669 if (!app.killedByAm) { 4670 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4671 + ") has died"); 4672 mAllowLowerMemLevel = true; 4673 } else { 4674 // Note that we always want to do oom adj to update our state with the 4675 // new number of procs. 4676 mAllowLowerMemLevel = false; 4677 doLowMem = false; 4678 } 4679 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4680 if (DEBUG_CLEANUP) Slog.v( 4681 TAG, "Dying app: " + app + ", pid: " + pid 4682 + ", thread: " + thread.asBinder()); 4683 handleAppDiedLocked(app, false, true); 4684 4685 if (doOomAdj) { 4686 updateOomAdjLocked(); 4687 } 4688 if (doLowMem) { 4689 doLowMemReportIfNeededLocked(app); 4690 } 4691 } else if (app.pid != pid) { 4692 // A new process has already been started. 4693 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4694 + ") has died and restarted (pid " + app.pid + ")."); 4695 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4696 } else if (DEBUG_PROCESSES) { 4697 Slog.d(TAG, "Received spurious death notification for thread " 4698 + thread.asBinder()); 4699 } 4700 } 4701 4702 /** 4703 * If a stack trace dump file is configured, dump process stack traces. 4704 * @param clearTraces causes the dump file to be erased prior to the new 4705 * traces being written, if true; when false, the new traces will be 4706 * appended to any existing file content. 4707 * @param firstPids of dalvik VM processes to dump stack traces for first 4708 * @param lastPids of dalvik VM processes to dump stack traces for last 4709 * @param nativeProcs optional list of native process names to dump stack crawls 4710 * @return file containing stack traces, or null if no dump file is configured 4711 */ 4712 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4713 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4714 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4715 if (tracesPath == null || tracesPath.length() == 0) { 4716 return null; 4717 } 4718 4719 File tracesFile = new File(tracesPath); 4720 try { 4721 File tracesDir = tracesFile.getParentFile(); 4722 if (!tracesDir.exists()) { 4723 tracesDir.mkdirs(); 4724 if (!SELinux.restorecon(tracesDir)) { 4725 return null; 4726 } 4727 } 4728 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4729 4730 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4731 tracesFile.createNewFile(); 4732 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4733 } catch (IOException e) { 4734 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4735 return null; 4736 } 4737 4738 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4739 return tracesFile; 4740 } 4741 4742 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4743 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4744 // Use a FileObserver to detect when traces finish writing. 4745 // The order of traces is considered important to maintain for legibility. 4746 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4747 @Override 4748 public synchronized void onEvent(int event, String path) { notify(); } 4749 }; 4750 4751 try { 4752 observer.startWatching(); 4753 4754 // First collect all of the stacks of the most important pids. 4755 if (firstPids != null) { 4756 try { 4757 int num = firstPids.size(); 4758 for (int i = 0; i < num; i++) { 4759 synchronized (observer) { 4760 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4761 observer.wait(200); // Wait for write-close, give up after 200msec 4762 } 4763 } 4764 } catch (InterruptedException e) { 4765 Slog.wtf(TAG, e); 4766 } 4767 } 4768 4769 // Next collect the stacks of the native pids 4770 if (nativeProcs != null) { 4771 int[] pids = Process.getPidsForCommands(nativeProcs); 4772 if (pids != null) { 4773 for (int pid : pids) { 4774 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4775 } 4776 } 4777 } 4778 4779 // Lastly, measure CPU usage. 4780 if (processCpuTracker != null) { 4781 processCpuTracker.init(); 4782 System.gc(); 4783 processCpuTracker.update(); 4784 try { 4785 synchronized (processCpuTracker) { 4786 processCpuTracker.wait(500); // measure over 1/2 second. 4787 } 4788 } catch (InterruptedException e) { 4789 } 4790 processCpuTracker.update(); 4791 4792 // We'll take the stack crawls of just the top apps using CPU. 4793 final int N = processCpuTracker.countWorkingStats(); 4794 int numProcs = 0; 4795 for (int i=0; i<N && numProcs<5; i++) { 4796 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4797 if (lastPids.indexOfKey(stats.pid) >= 0) { 4798 numProcs++; 4799 try { 4800 synchronized (observer) { 4801 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4802 observer.wait(200); // Wait for write-close, give up after 200msec 4803 } 4804 } catch (InterruptedException e) { 4805 Slog.wtf(TAG, e); 4806 } 4807 4808 } 4809 } 4810 } 4811 } finally { 4812 observer.stopWatching(); 4813 } 4814 } 4815 4816 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4817 if (true || IS_USER_BUILD) { 4818 return; 4819 } 4820 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4821 if (tracesPath == null || tracesPath.length() == 0) { 4822 return; 4823 } 4824 4825 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4826 StrictMode.allowThreadDiskWrites(); 4827 try { 4828 final File tracesFile = new File(tracesPath); 4829 final File tracesDir = tracesFile.getParentFile(); 4830 final File tracesTmp = new File(tracesDir, "__tmp__"); 4831 try { 4832 if (!tracesDir.exists()) { 4833 tracesDir.mkdirs(); 4834 if (!SELinux.restorecon(tracesDir.getPath())) { 4835 return; 4836 } 4837 } 4838 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4839 4840 if (tracesFile.exists()) { 4841 tracesTmp.delete(); 4842 tracesFile.renameTo(tracesTmp); 4843 } 4844 StringBuilder sb = new StringBuilder(); 4845 Time tobj = new Time(); 4846 tobj.set(System.currentTimeMillis()); 4847 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4848 sb.append(": "); 4849 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4850 sb.append(" since "); 4851 sb.append(msg); 4852 FileOutputStream fos = new FileOutputStream(tracesFile); 4853 fos.write(sb.toString().getBytes()); 4854 if (app == null) { 4855 fos.write("\n*** No application process!".getBytes()); 4856 } 4857 fos.close(); 4858 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4859 } catch (IOException e) { 4860 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4861 return; 4862 } 4863 4864 if (app != null) { 4865 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4866 firstPids.add(app.pid); 4867 dumpStackTraces(tracesPath, firstPids, null, null, null); 4868 } 4869 4870 File lastTracesFile = null; 4871 File curTracesFile = null; 4872 for (int i=9; i>=0; i--) { 4873 String name = String.format(Locale.US, "slow%02d.txt", i); 4874 curTracesFile = new File(tracesDir, name); 4875 if (curTracesFile.exists()) { 4876 if (lastTracesFile != null) { 4877 curTracesFile.renameTo(lastTracesFile); 4878 } else { 4879 curTracesFile.delete(); 4880 } 4881 } 4882 lastTracesFile = curTracesFile; 4883 } 4884 tracesFile.renameTo(curTracesFile); 4885 if (tracesTmp.exists()) { 4886 tracesTmp.renameTo(tracesFile); 4887 } 4888 } finally { 4889 StrictMode.setThreadPolicy(oldPolicy); 4890 } 4891 } 4892 4893 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4894 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4895 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4896 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4897 4898 if (mController != null) { 4899 try { 4900 // 0 == continue, -1 = kill process immediately 4901 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4902 if (res < 0 && app.pid != MY_PID) { 4903 app.kill("anr", true); 4904 } 4905 } catch (RemoteException e) { 4906 mController = null; 4907 Watchdog.getInstance().setActivityController(null); 4908 } 4909 } 4910 4911 long anrTime = SystemClock.uptimeMillis(); 4912 if (MONITOR_CPU_USAGE) { 4913 updateCpuStatsNow(); 4914 } 4915 4916 synchronized (this) { 4917 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4918 if (mShuttingDown) { 4919 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4920 return; 4921 } else if (app.notResponding) { 4922 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4923 return; 4924 } else if (app.crashing) { 4925 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4926 return; 4927 } 4928 4929 // In case we come through here for the same app before completing 4930 // this one, mark as anring now so we will bail out. 4931 app.notResponding = true; 4932 4933 // Log the ANR to the event log. 4934 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4935 app.processName, app.info.flags, annotation); 4936 4937 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4938 firstPids.add(app.pid); 4939 4940 int parentPid = app.pid; 4941 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4942 if (parentPid != app.pid) firstPids.add(parentPid); 4943 4944 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4945 4946 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4947 ProcessRecord r = mLruProcesses.get(i); 4948 if (r != null && r.thread != null) { 4949 int pid = r.pid; 4950 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4951 if (r.persistent) { 4952 firstPids.add(pid); 4953 } else { 4954 lastPids.put(pid, Boolean.TRUE); 4955 } 4956 } 4957 } 4958 } 4959 } 4960 4961 // Log the ANR to the main log. 4962 StringBuilder info = new StringBuilder(); 4963 info.setLength(0); 4964 info.append("ANR in ").append(app.processName); 4965 if (activity != null && activity.shortComponentName != null) { 4966 info.append(" (").append(activity.shortComponentName).append(")"); 4967 } 4968 info.append("\n"); 4969 info.append("PID: ").append(app.pid).append("\n"); 4970 if (annotation != null) { 4971 info.append("Reason: ").append(annotation).append("\n"); 4972 } 4973 if (parent != null && parent != activity) { 4974 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4975 } 4976 4977 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4978 4979 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4980 NATIVE_STACKS_OF_INTEREST); 4981 4982 String cpuInfo = null; 4983 if (MONITOR_CPU_USAGE) { 4984 updateCpuStatsNow(); 4985 synchronized (mProcessCpuTracker) { 4986 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4987 } 4988 info.append(processCpuTracker.printCurrentLoad()); 4989 info.append(cpuInfo); 4990 } 4991 4992 info.append(processCpuTracker.printCurrentState(anrTime)); 4993 4994 Slog.e(TAG, info.toString()); 4995 if (tracesFile == null) { 4996 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4997 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4998 } 4999 5000 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5001 cpuInfo, tracesFile, null); 5002 5003 if (mController != null) { 5004 try { 5005 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5006 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5007 if (res != 0) { 5008 if (res < 0 && app.pid != MY_PID) { 5009 app.kill("anr", true); 5010 } else { 5011 synchronized (this) { 5012 mServices.scheduleServiceTimeoutLocked(app); 5013 } 5014 } 5015 return; 5016 } 5017 } catch (RemoteException e) { 5018 mController = null; 5019 Watchdog.getInstance().setActivityController(null); 5020 } 5021 } 5022 5023 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5024 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5025 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5026 5027 synchronized (this) { 5028 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5029 5030 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5031 app.kill("bg anr", true); 5032 return; 5033 } 5034 5035 // Set the app's notResponding state, and look up the errorReportReceiver 5036 makeAppNotRespondingLocked(app, 5037 activity != null ? activity.shortComponentName : null, 5038 annotation != null ? "ANR " + annotation : "ANR", 5039 info.toString()); 5040 5041 // Bring up the infamous App Not Responding dialog 5042 Message msg = Message.obtain(); 5043 HashMap<String, Object> map = new HashMap<String, Object>(); 5044 msg.what = SHOW_NOT_RESPONDING_MSG; 5045 msg.obj = map; 5046 msg.arg1 = aboveSystem ? 1 : 0; 5047 map.put("app", app); 5048 if (activity != null) { 5049 map.put("activity", activity); 5050 } 5051 5052 mHandler.sendMessage(msg); 5053 } 5054 } 5055 5056 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5057 if (!mLaunchWarningShown) { 5058 mLaunchWarningShown = true; 5059 mHandler.post(new Runnable() { 5060 @Override 5061 public void run() { 5062 synchronized (ActivityManagerService.this) { 5063 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5064 d.show(); 5065 mHandler.postDelayed(new Runnable() { 5066 @Override 5067 public void run() { 5068 synchronized (ActivityManagerService.this) { 5069 d.dismiss(); 5070 mLaunchWarningShown = false; 5071 } 5072 } 5073 }, 4000); 5074 } 5075 } 5076 }); 5077 } 5078 } 5079 5080 @Override 5081 public boolean clearApplicationUserData(final String packageName, 5082 final IPackageDataObserver observer, int userId) { 5083 enforceNotIsolatedCaller("clearApplicationUserData"); 5084 int uid = Binder.getCallingUid(); 5085 int pid = Binder.getCallingPid(); 5086 userId = handleIncomingUser(pid, uid, 5087 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5088 long callingId = Binder.clearCallingIdentity(); 5089 try { 5090 IPackageManager pm = AppGlobals.getPackageManager(); 5091 int pkgUid = -1; 5092 synchronized(this) { 5093 try { 5094 pkgUid = pm.getPackageUid(packageName, userId); 5095 } catch (RemoteException e) { 5096 } 5097 if (pkgUid == -1) { 5098 Slog.w(TAG, "Invalid packageName: " + packageName); 5099 if (observer != null) { 5100 try { 5101 observer.onRemoveCompleted(packageName, false); 5102 } catch (RemoteException e) { 5103 Slog.i(TAG, "Observer no longer exists."); 5104 } 5105 } 5106 return false; 5107 } 5108 if (uid == pkgUid || checkComponentPermission( 5109 android.Manifest.permission.CLEAR_APP_USER_DATA, 5110 pid, uid, -1, true) 5111 == PackageManager.PERMISSION_GRANTED) { 5112 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5113 } else { 5114 throw new SecurityException("PID " + pid + " does not have permission " 5115 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5116 + " of package " + packageName); 5117 } 5118 5119 // Remove all tasks match the cleared application package and user 5120 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5121 final TaskRecord tr = mRecentTasks.get(i); 5122 final String taskPackageName = 5123 tr.getBaseIntent().getComponent().getPackageName(); 5124 if (tr.userId != userId) continue; 5125 if (!taskPackageName.equals(packageName)) continue; 5126 removeTaskByIdLocked(tr.taskId, false); 5127 } 5128 } 5129 5130 try { 5131 // Clear application user data 5132 pm.clearApplicationUserData(packageName, observer, userId); 5133 5134 synchronized(this) { 5135 // Remove all permissions granted from/to this package 5136 removeUriPermissionsForPackageLocked(packageName, userId, true); 5137 } 5138 5139 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5140 Uri.fromParts("package", packageName, null)); 5141 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5142 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5143 null, null, 0, null, null, null, false, false, userId); 5144 } catch (RemoteException e) { 5145 } 5146 } finally { 5147 Binder.restoreCallingIdentity(callingId); 5148 } 5149 return true; 5150 } 5151 5152 @Override 5153 public void killBackgroundProcesses(final String packageName, int userId) { 5154 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5155 != PackageManager.PERMISSION_GRANTED && 5156 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5157 != PackageManager.PERMISSION_GRANTED) { 5158 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5159 + Binder.getCallingPid() 5160 + ", uid=" + Binder.getCallingUid() 5161 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5162 Slog.w(TAG, msg); 5163 throw new SecurityException(msg); 5164 } 5165 5166 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5167 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5168 long callingId = Binder.clearCallingIdentity(); 5169 try { 5170 IPackageManager pm = AppGlobals.getPackageManager(); 5171 synchronized(this) { 5172 int appId = -1; 5173 try { 5174 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5175 } catch (RemoteException e) { 5176 } 5177 if (appId == -1) { 5178 Slog.w(TAG, "Invalid packageName: " + packageName); 5179 return; 5180 } 5181 killPackageProcessesLocked(packageName, appId, userId, 5182 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5183 } 5184 } finally { 5185 Binder.restoreCallingIdentity(callingId); 5186 } 5187 } 5188 5189 @Override 5190 public void killAllBackgroundProcesses() { 5191 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5192 != PackageManager.PERMISSION_GRANTED) { 5193 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5194 + Binder.getCallingPid() 5195 + ", uid=" + Binder.getCallingUid() 5196 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5197 Slog.w(TAG, msg); 5198 throw new SecurityException(msg); 5199 } 5200 5201 long callingId = Binder.clearCallingIdentity(); 5202 try { 5203 synchronized(this) { 5204 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5205 final int NP = mProcessNames.getMap().size(); 5206 for (int ip=0; ip<NP; ip++) { 5207 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5208 final int NA = apps.size(); 5209 for (int ia=0; ia<NA; ia++) { 5210 ProcessRecord app = apps.valueAt(ia); 5211 if (app.persistent) { 5212 // we don't kill persistent processes 5213 continue; 5214 } 5215 if (app.removed) { 5216 procs.add(app); 5217 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5218 app.removed = true; 5219 procs.add(app); 5220 } 5221 } 5222 } 5223 5224 int N = procs.size(); 5225 for (int i=0; i<N; i++) { 5226 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5227 } 5228 mAllowLowerMemLevel = true; 5229 updateOomAdjLocked(); 5230 doLowMemReportIfNeededLocked(null); 5231 } 5232 } finally { 5233 Binder.restoreCallingIdentity(callingId); 5234 } 5235 } 5236 5237 @Override 5238 public void forceStopPackage(final String packageName, int userId) { 5239 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5240 != PackageManager.PERMISSION_GRANTED) { 5241 String msg = "Permission Denial: forceStopPackage() from pid=" 5242 + Binder.getCallingPid() 5243 + ", uid=" + Binder.getCallingUid() 5244 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5245 Slog.w(TAG, msg); 5246 throw new SecurityException(msg); 5247 } 5248 final int callingPid = Binder.getCallingPid(); 5249 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5250 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5251 long callingId = Binder.clearCallingIdentity(); 5252 try { 5253 IPackageManager pm = AppGlobals.getPackageManager(); 5254 synchronized(this) { 5255 int[] users = userId == UserHandle.USER_ALL 5256 ? getUsersLocked() : new int[] { userId }; 5257 for (int user : users) { 5258 int pkgUid = -1; 5259 try { 5260 pkgUid = pm.getPackageUid(packageName, user); 5261 } catch (RemoteException e) { 5262 } 5263 if (pkgUid == -1) { 5264 Slog.w(TAG, "Invalid packageName: " + packageName); 5265 continue; 5266 } 5267 try { 5268 pm.setPackageStoppedState(packageName, true, user); 5269 } catch (RemoteException e) { 5270 } catch (IllegalArgumentException e) { 5271 Slog.w(TAG, "Failed trying to unstop package " 5272 + packageName + ": " + e); 5273 } 5274 if (isUserRunningLocked(user, false)) { 5275 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5276 } 5277 } 5278 } 5279 } finally { 5280 Binder.restoreCallingIdentity(callingId); 5281 } 5282 } 5283 5284 @Override 5285 public void addPackageDependency(String packageName) { 5286 synchronized (this) { 5287 int callingPid = Binder.getCallingPid(); 5288 if (callingPid == Process.myPid()) { 5289 // Yeah, um, no. 5290 Slog.w(TAG, "Can't addPackageDependency on system process"); 5291 return; 5292 } 5293 ProcessRecord proc; 5294 synchronized (mPidsSelfLocked) { 5295 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5296 } 5297 if (proc != null) { 5298 if (proc.pkgDeps == null) { 5299 proc.pkgDeps = new ArraySet<String>(1); 5300 } 5301 proc.pkgDeps.add(packageName); 5302 } 5303 } 5304 } 5305 5306 /* 5307 * The pkg name and app id have to be specified. 5308 */ 5309 @Override 5310 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5311 if (pkg == null) { 5312 return; 5313 } 5314 // Make sure the uid is valid. 5315 if (appid < 0) { 5316 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5317 return; 5318 } 5319 int callerUid = Binder.getCallingUid(); 5320 // Only the system server can kill an application 5321 if (callerUid == Process.SYSTEM_UID) { 5322 // Post an aysnc message to kill the application 5323 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5324 msg.arg1 = appid; 5325 msg.arg2 = 0; 5326 Bundle bundle = new Bundle(); 5327 bundle.putString("pkg", pkg); 5328 bundle.putString("reason", reason); 5329 msg.obj = bundle; 5330 mHandler.sendMessage(msg); 5331 } else { 5332 throw new SecurityException(callerUid + " cannot kill pkg: " + 5333 pkg); 5334 } 5335 } 5336 5337 @Override 5338 public void closeSystemDialogs(String reason) { 5339 enforceNotIsolatedCaller("closeSystemDialogs"); 5340 5341 final int pid = Binder.getCallingPid(); 5342 final int uid = Binder.getCallingUid(); 5343 final long origId = Binder.clearCallingIdentity(); 5344 try { 5345 synchronized (this) { 5346 // Only allow this from foreground processes, so that background 5347 // applications can't abuse it to prevent system UI from being shown. 5348 if (uid >= Process.FIRST_APPLICATION_UID) { 5349 ProcessRecord proc; 5350 synchronized (mPidsSelfLocked) { 5351 proc = mPidsSelfLocked.get(pid); 5352 } 5353 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5354 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5355 + " from background process " + proc); 5356 return; 5357 } 5358 } 5359 closeSystemDialogsLocked(reason); 5360 } 5361 } finally { 5362 Binder.restoreCallingIdentity(origId); 5363 } 5364 } 5365 5366 void closeSystemDialogsLocked(String reason) { 5367 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5369 | Intent.FLAG_RECEIVER_FOREGROUND); 5370 if (reason != null) { 5371 intent.putExtra("reason", reason); 5372 } 5373 mWindowManager.closeSystemDialogs(reason); 5374 5375 mStackSupervisor.closeSystemDialogsLocked(); 5376 5377 broadcastIntentLocked(null, null, intent, null, 5378 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5379 Process.SYSTEM_UID, UserHandle.USER_ALL); 5380 } 5381 5382 @Override 5383 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5384 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5385 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5386 for (int i=pids.length-1; i>=0; i--) { 5387 ProcessRecord proc; 5388 int oomAdj; 5389 synchronized (this) { 5390 synchronized (mPidsSelfLocked) { 5391 proc = mPidsSelfLocked.get(pids[i]); 5392 oomAdj = proc != null ? proc.setAdj : 0; 5393 } 5394 } 5395 infos[i] = new Debug.MemoryInfo(); 5396 Debug.getMemoryInfo(pids[i], infos[i]); 5397 if (proc != null) { 5398 synchronized (this) { 5399 if (proc.thread != null && proc.setAdj == oomAdj) { 5400 // Record this for posterity if the process has been stable. 5401 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5402 infos[i].getTotalUss(), false, proc.pkgList); 5403 } 5404 } 5405 } 5406 } 5407 return infos; 5408 } 5409 5410 @Override 5411 public long[] getProcessPss(int[] pids) { 5412 enforceNotIsolatedCaller("getProcessPss"); 5413 long[] pss = new long[pids.length]; 5414 for (int i=pids.length-1; i>=0; i--) { 5415 ProcessRecord proc; 5416 int oomAdj; 5417 synchronized (this) { 5418 synchronized (mPidsSelfLocked) { 5419 proc = mPidsSelfLocked.get(pids[i]); 5420 oomAdj = proc != null ? proc.setAdj : 0; 5421 } 5422 } 5423 long[] tmpUss = new long[1]; 5424 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5425 if (proc != null) { 5426 synchronized (this) { 5427 if (proc.thread != null && proc.setAdj == oomAdj) { 5428 // Record this for posterity if the process has been stable. 5429 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5430 } 5431 } 5432 } 5433 } 5434 return pss; 5435 } 5436 5437 @Override 5438 public void killApplicationProcess(String processName, int uid) { 5439 if (processName == null) { 5440 return; 5441 } 5442 5443 int callerUid = Binder.getCallingUid(); 5444 // Only the system server can kill an application 5445 if (callerUid == Process.SYSTEM_UID) { 5446 synchronized (this) { 5447 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5448 if (app != null && app.thread != null) { 5449 try { 5450 app.thread.scheduleSuicide(); 5451 } catch (RemoteException e) { 5452 // If the other end already died, then our work here is done. 5453 } 5454 } else { 5455 Slog.w(TAG, "Process/uid not found attempting kill of " 5456 + processName + " / " + uid); 5457 } 5458 } 5459 } else { 5460 throw new SecurityException(callerUid + " cannot kill app process: " + 5461 processName); 5462 } 5463 } 5464 5465 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5466 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5467 false, true, false, false, UserHandle.getUserId(uid), reason); 5468 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5469 Uri.fromParts("package", packageName, null)); 5470 if (!mProcessesReady) { 5471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5472 | Intent.FLAG_RECEIVER_FOREGROUND); 5473 } 5474 intent.putExtra(Intent.EXTRA_UID, uid); 5475 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5476 broadcastIntentLocked(null, null, intent, 5477 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5478 false, false, 5479 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5480 } 5481 5482 private void forceStopUserLocked(int userId, String reason) { 5483 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5484 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5485 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5486 | Intent.FLAG_RECEIVER_FOREGROUND); 5487 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5488 broadcastIntentLocked(null, null, intent, 5489 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5490 false, false, 5491 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5492 } 5493 5494 private final boolean killPackageProcessesLocked(String packageName, int appId, 5495 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5496 boolean doit, boolean evenPersistent, String reason) { 5497 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5498 5499 // Remove all processes this package may have touched: all with the 5500 // same UID (except for the system or root user), and all whose name 5501 // matches the package name. 5502 final int NP = mProcessNames.getMap().size(); 5503 for (int ip=0; ip<NP; ip++) { 5504 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5505 final int NA = apps.size(); 5506 for (int ia=0; ia<NA; ia++) { 5507 ProcessRecord app = apps.valueAt(ia); 5508 if (app.persistent && !evenPersistent) { 5509 // we don't kill persistent processes 5510 continue; 5511 } 5512 if (app.removed) { 5513 if (doit) { 5514 procs.add(app); 5515 } 5516 continue; 5517 } 5518 5519 // Skip process if it doesn't meet our oom adj requirement. 5520 if (app.setAdj < minOomAdj) { 5521 continue; 5522 } 5523 5524 // If no package is specified, we call all processes under the 5525 // give user id. 5526 if (packageName == null) { 5527 if (app.userId != userId) { 5528 continue; 5529 } 5530 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5531 continue; 5532 } 5533 // Package has been specified, we want to hit all processes 5534 // that match it. We need to qualify this by the processes 5535 // that are running under the specified app and user ID. 5536 } else { 5537 final boolean isDep = app.pkgDeps != null 5538 && app.pkgDeps.contains(packageName); 5539 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5540 continue; 5541 } 5542 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5543 continue; 5544 } 5545 if (!app.pkgList.containsKey(packageName) && !isDep) { 5546 continue; 5547 } 5548 } 5549 5550 // Process has passed all conditions, kill it! 5551 if (!doit) { 5552 return true; 5553 } 5554 app.removed = true; 5555 procs.add(app); 5556 } 5557 } 5558 5559 int N = procs.size(); 5560 for (int i=0; i<N; i++) { 5561 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5562 } 5563 updateOomAdjLocked(); 5564 return N > 0; 5565 } 5566 5567 private final boolean forceStopPackageLocked(String name, int appId, 5568 boolean callerWillRestart, boolean purgeCache, boolean doit, 5569 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5570 int i; 5571 int N; 5572 5573 if (userId == UserHandle.USER_ALL && name == null) { 5574 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5575 } 5576 5577 if (appId < 0 && name != null) { 5578 try { 5579 appId = UserHandle.getAppId( 5580 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5581 } catch (RemoteException e) { 5582 } 5583 } 5584 5585 if (doit) { 5586 if (name != null) { 5587 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5588 + " user=" + userId + ": " + reason); 5589 } else { 5590 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5591 } 5592 5593 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5594 for (int ip=pmap.size()-1; ip>=0; ip--) { 5595 SparseArray<Long> ba = pmap.valueAt(ip); 5596 for (i=ba.size()-1; i>=0; i--) { 5597 boolean remove = false; 5598 final int entUid = ba.keyAt(i); 5599 if (name != null) { 5600 if (userId == UserHandle.USER_ALL) { 5601 if (UserHandle.getAppId(entUid) == appId) { 5602 remove = true; 5603 } 5604 } else { 5605 if (entUid == UserHandle.getUid(userId, appId)) { 5606 remove = true; 5607 } 5608 } 5609 } else if (UserHandle.getUserId(entUid) == userId) { 5610 remove = true; 5611 } 5612 if (remove) { 5613 ba.removeAt(i); 5614 } 5615 } 5616 if (ba.size() == 0) { 5617 pmap.removeAt(ip); 5618 } 5619 } 5620 } 5621 5622 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5623 -100, callerWillRestart, true, doit, evenPersistent, 5624 name == null ? ("stop user " + userId) : ("stop " + name)); 5625 5626 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5627 if (!doit) { 5628 return true; 5629 } 5630 didSomething = true; 5631 } 5632 5633 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5634 if (!doit) { 5635 return true; 5636 } 5637 didSomething = true; 5638 } 5639 5640 if (name == null) { 5641 // Remove all sticky broadcasts from this user. 5642 mStickyBroadcasts.remove(userId); 5643 } 5644 5645 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5646 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5647 userId, providers)) { 5648 if (!doit) { 5649 return true; 5650 } 5651 didSomething = true; 5652 } 5653 N = providers.size(); 5654 for (i=0; i<N; i++) { 5655 removeDyingProviderLocked(null, providers.get(i), true); 5656 } 5657 5658 // Remove transient permissions granted from/to this package/user 5659 removeUriPermissionsForPackageLocked(name, userId, false); 5660 5661 if (name == null || uninstalling) { 5662 // Remove pending intents. For now we only do this when force 5663 // stopping users, because we have some problems when doing this 5664 // for packages -- app widgets are not currently cleaned up for 5665 // such packages, so they can be left with bad pending intents. 5666 if (mIntentSenderRecords.size() > 0) { 5667 Iterator<WeakReference<PendingIntentRecord>> it 5668 = mIntentSenderRecords.values().iterator(); 5669 while (it.hasNext()) { 5670 WeakReference<PendingIntentRecord> wpir = it.next(); 5671 if (wpir == null) { 5672 it.remove(); 5673 continue; 5674 } 5675 PendingIntentRecord pir = wpir.get(); 5676 if (pir == null) { 5677 it.remove(); 5678 continue; 5679 } 5680 if (name == null) { 5681 // Stopping user, remove all objects for the user. 5682 if (pir.key.userId != userId) { 5683 // Not the same user, skip it. 5684 continue; 5685 } 5686 } else { 5687 if (UserHandle.getAppId(pir.uid) != appId) { 5688 // Different app id, skip it. 5689 continue; 5690 } 5691 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5692 // Different user, skip it. 5693 continue; 5694 } 5695 if (!pir.key.packageName.equals(name)) { 5696 // Different package, skip it. 5697 continue; 5698 } 5699 } 5700 if (!doit) { 5701 return true; 5702 } 5703 didSomething = true; 5704 it.remove(); 5705 pir.canceled = true; 5706 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5707 pir.key.activity.pendingResults.remove(pir.ref); 5708 } 5709 } 5710 } 5711 } 5712 5713 if (doit) { 5714 if (purgeCache && name != null) { 5715 AttributeCache ac = AttributeCache.instance(); 5716 if (ac != null) { 5717 ac.removePackage(name); 5718 } 5719 } 5720 if (mBooted) { 5721 mStackSupervisor.resumeTopActivitiesLocked(); 5722 mStackSupervisor.scheduleIdleLocked(); 5723 } 5724 } 5725 5726 return didSomething; 5727 } 5728 5729 private final boolean removeProcessLocked(ProcessRecord app, 5730 boolean callerWillRestart, boolean allowRestart, String reason) { 5731 final String name = app.processName; 5732 final int uid = app.uid; 5733 if (DEBUG_PROCESSES) Slog.d( 5734 TAG, "Force removing proc " + app.toShortString() + " (" + name 5735 + "/" + uid + ")"); 5736 5737 mProcessNames.remove(name, uid); 5738 mIsolatedProcesses.remove(app.uid); 5739 if (mHeavyWeightProcess == app) { 5740 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5741 mHeavyWeightProcess.userId, 0)); 5742 mHeavyWeightProcess = null; 5743 } 5744 boolean needRestart = false; 5745 if (app.pid > 0 && app.pid != MY_PID) { 5746 int pid = app.pid; 5747 synchronized (mPidsSelfLocked) { 5748 mPidsSelfLocked.remove(pid); 5749 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5750 } 5751 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5752 if (app.isolated) { 5753 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5754 } 5755 app.kill(reason, true); 5756 handleAppDiedLocked(app, true, allowRestart); 5757 removeLruProcessLocked(app); 5758 5759 if (app.persistent && !app.isolated) { 5760 if (!callerWillRestart) { 5761 addAppLocked(app.info, false, null /* ABI override */); 5762 } else { 5763 needRestart = true; 5764 } 5765 } 5766 } else { 5767 mRemovedProcesses.add(app); 5768 } 5769 5770 return needRestart; 5771 } 5772 5773 private final void processStartTimedOutLocked(ProcessRecord app) { 5774 final int pid = app.pid; 5775 boolean gone = false; 5776 synchronized (mPidsSelfLocked) { 5777 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5778 if (knownApp != null && knownApp.thread == null) { 5779 mPidsSelfLocked.remove(pid); 5780 gone = true; 5781 } 5782 } 5783 5784 if (gone) { 5785 Slog.w(TAG, "Process " + app + " failed to attach"); 5786 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5787 pid, app.uid, app.processName); 5788 mProcessNames.remove(app.processName, app.uid); 5789 mIsolatedProcesses.remove(app.uid); 5790 if (mHeavyWeightProcess == app) { 5791 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5792 mHeavyWeightProcess.userId, 0)); 5793 mHeavyWeightProcess = null; 5794 } 5795 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5796 if (app.isolated) { 5797 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5798 } 5799 // Take care of any launching providers waiting for this process. 5800 checkAppInLaunchingProvidersLocked(app, true); 5801 // Take care of any services that are waiting for the process. 5802 mServices.processStartTimedOutLocked(app); 5803 app.kill("start timeout", true); 5804 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5805 Slog.w(TAG, "Unattached app died before backup, skipping"); 5806 try { 5807 IBackupManager bm = IBackupManager.Stub.asInterface( 5808 ServiceManager.getService(Context.BACKUP_SERVICE)); 5809 bm.agentDisconnected(app.info.packageName); 5810 } catch (RemoteException e) { 5811 // Can't happen; the backup manager is local 5812 } 5813 } 5814 if (isPendingBroadcastProcessLocked(pid)) { 5815 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5816 skipPendingBroadcastLocked(pid); 5817 } 5818 } else { 5819 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5820 } 5821 } 5822 5823 private final boolean attachApplicationLocked(IApplicationThread thread, 5824 int pid) { 5825 5826 // Find the application record that is being attached... either via 5827 // the pid if we are running in multiple processes, or just pull the 5828 // next app record if we are emulating process with anonymous threads. 5829 ProcessRecord app; 5830 if (pid != MY_PID && pid >= 0) { 5831 synchronized (mPidsSelfLocked) { 5832 app = mPidsSelfLocked.get(pid); 5833 } 5834 } else { 5835 app = null; 5836 } 5837 5838 if (app == null) { 5839 Slog.w(TAG, "No pending application record for pid " + pid 5840 + " (IApplicationThread " + thread + "); dropping process"); 5841 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5842 if (pid > 0 && pid != MY_PID) { 5843 Process.killProcessQuiet(pid); 5844 //TODO: Process.killProcessGroup(app.info.uid, pid); 5845 } else { 5846 try { 5847 thread.scheduleExit(); 5848 } catch (Exception e) { 5849 // Ignore exceptions. 5850 } 5851 } 5852 return false; 5853 } 5854 5855 // If this application record is still attached to a previous 5856 // process, clean it up now. 5857 if (app.thread != null) { 5858 handleAppDiedLocked(app, true, true); 5859 } 5860 5861 // Tell the process all about itself. 5862 5863 if (localLOGV) Slog.v( 5864 TAG, "Binding process pid " + pid + " to record " + app); 5865 5866 final String processName = app.processName; 5867 try { 5868 AppDeathRecipient adr = new AppDeathRecipient( 5869 app, pid, thread); 5870 thread.asBinder().linkToDeath(adr, 0); 5871 app.deathRecipient = adr; 5872 } catch (RemoteException e) { 5873 app.resetPackageList(mProcessStats); 5874 startProcessLocked(app, "link fail", processName); 5875 return false; 5876 } 5877 5878 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5879 5880 app.makeActive(thread, mProcessStats); 5881 app.curAdj = app.setAdj = -100; 5882 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5883 app.forcingToForeground = null; 5884 updateProcessForegroundLocked(app, false, false); 5885 app.hasShownUi = false; 5886 app.debugging = false; 5887 app.cached = false; 5888 app.killedByAm = false; 5889 5890 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5891 5892 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5893 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5894 5895 if (!normalMode) { 5896 Slog.i(TAG, "Launching preboot mode app: " + app); 5897 } 5898 5899 if (localLOGV) Slog.v( 5900 TAG, "New app record " + app 5901 + " thread=" + thread.asBinder() + " pid=" + pid); 5902 try { 5903 int testMode = IApplicationThread.DEBUG_OFF; 5904 if (mDebugApp != null && mDebugApp.equals(processName)) { 5905 testMode = mWaitForDebugger 5906 ? IApplicationThread.DEBUG_WAIT 5907 : IApplicationThread.DEBUG_ON; 5908 app.debugging = true; 5909 if (mDebugTransient) { 5910 mDebugApp = mOrigDebugApp; 5911 mWaitForDebugger = mOrigWaitForDebugger; 5912 } 5913 } 5914 String profileFile = app.instrumentationProfileFile; 5915 ParcelFileDescriptor profileFd = null; 5916 int samplingInterval = 0; 5917 boolean profileAutoStop = false; 5918 if (mProfileApp != null && mProfileApp.equals(processName)) { 5919 mProfileProc = app; 5920 profileFile = mProfileFile; 5921 profileFd = mProfileFd; 5922 samplingInterval = mSamplingInterval; 5923 profileAutoStop = mAutoStopProfiler; 5924 } 5925 boolean enableOpenGlTrace = false; 5926 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5927 enableOpenGlTrace = true; 5928 mOpenGlTraceApp = null; 5929 } 5930 5931 // If the app is being launched for restore or full backup, set it up specially 5932 boolean isRestrictedBackupMode = false; 5933 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5934 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5935 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5936 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5937 } 5938 5939 ensurePackageDexOpt(app.instrumentationInfo != null 5940 ? app.instrumentationInfo.packageName 5941 : app.info.packageName); 5942 if (app.instrumentationClass != null) { 5943 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5944 } 5945 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5946 + processName + " with config " + mConfiguration); 5947 ApplicationInfo appInfo = app.instrumentationInfo != null 5948 ? app.instrumentationInfo : app.info; 5949 app.compat = compatibilityInfoForPackageLocked(appInfo); 5950 if (profileFd != null) { 5951 profileFd = profileFd.dup(); 5952 } 5953 ProfilerInfo profilerInfo = profileFile == null ? null 5954 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5955 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5956 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5957 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5958 isRestrictedBackupMode || !normalMode, app.persistent, 5959 new Configuration(mConfiguration), app.compat, 5960 getCommonServicesLocked(app.isolated), 5961 mCoreSettingsObserver.getCoreSettingsLocked()); 5962 updateLruProcessLocked(app, false, null); 5963 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5964 } catch (Exception e) { 5965 // todo: Yikes! What should we do? For now we will try to 5966 // start another process, but that could easily get us in 5967 // an infinite loop of restarting processes... 5968 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5969 5970 app.resetPackageList(mProcessStats); 5971 app.unlinkDeathRecipient(); 5972 startProcessLocked(app, "bind fail", processName); 5973 return false; 5974 } 5975 5976 // Remove this record from the list of starting applications. 5977 mPersistentStartingProcesses.remove(app); 5978 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5979 "Attach application locked removing on hold: " + app); 5980 mProcessesOnHold.remove(app); 5981 5982 boolean badApp = false; 5983 boolean didSomething = false; 5984 5985 // See if the top visible activity is waiting to run in this process... 5986 if (normalMode) { 5987 try { 5988 if (mStackSupervisor.attachApplicationLocked(app)) { 5989 didSomething = true; 5990 } 5991 } catch (Exception e) { 5992 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5993 badApp = true; 5994 } 5995 } 5996 5997 // Find any services that should be running in this process... 5998 if (!badApp) { 5999 try { 6000 didSomething |= mServices.attachApplicationLocked(app, processName); 6001 } catch (Exception e) { 6002 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6003 badApp = true; 6004 } 6005 } 6006 6007 // Check if a next-broadcast receiver is in this process... 6008 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6009 try { 6010 didSomething |= sendPendingBroadcastsLocked(app); 6011 } catch (Exception e) { 6012 // If the app died trying to launch the receiver we declare it 'bad' 6013 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6014 badApp = true; 6015 } 6016 } 6017 6018 // Check whether the next backup agent is in this process... 6019 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6020 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6021 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6022 try { 6023 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6024 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6025 mBackupTarget.backupMode); 6026 } catch (Exception e) { 6027 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6028 badApp = true; 6029 } 6030 } 6031 6032 if (badApp) { 6033 app.kill("error during init", true); 6034 handleAppDiedLocked(app, false, true); 6035 return false; 6036 } 6037 6038 if (!didSomething) { 6039 updateOomAdjLocked(); 6040 } 6041 6042 return true; 6043 } 6044 6045 @Override 6046 public final void attachApplication(IApplicationThread thread) { 6047 synchronized (this) { 6048 int callingPid = Binder.getCallingPid(); 6049 final long origId = Binder.clearCallingIdentity(); 6050 attachApplicationLocked(thread, callingPid); 6051 Binder.restoreCallingIdentity(origId); 6052 } 6053 } 6054 6055 @Override 6056 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6057 final long origId = Binder.clearCallingIdentity(); 6058 synchronized (this) { 6059 ActivityStack stack = ActivityRecord.getStackLocked(token); 6060 if (stack != null) { 6061 ActivityRecord r = 6062 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6063 if (stopProfiling) { 6064 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6065 try { 6066 mProfileFd.close(); 6067 } catch (IOException e) { 6068 } 6069 clearProfilerLocked(); 6070 } 6071 } 6072 } 6073 } 6074 Binder.restoreCallingIdentity(origId); 6075 } 6076 6077 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6078 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6079 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6080 } 6081 6082 void enableScreenAfterBoot() { 6083 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6084 SystemClock.uptimeMillis()); 6085 mWindowManager.enableScreenAfterBoot(); 6086 6087 synchronized (this) { 6088 updateEventDispatchingLocked(); 6089 } 6090 } 6091 6092 @Override 6093 public void showBootMessage(final CharSequence msg, final boolean always) { 6094 enforceNotIsolatedCaller("showBootMessage"); 6095 mWindowManager.showBootMessage(msg, always); 6096 } 6097 6098 @Override 6099 public void keyguardWaitingForActivityDrawn() { 6100 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6101 final long token = Binder.clearCallingIdentity(); 6102 try { 6103 synchronized (this) { 6104 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6105 mWindowManager.keyguardWaitingForActivityDrawn(); 6106 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6107 mLockScreenShown = LOCK_SCREEN_LEAVING; 6108 updateSleepIfNeededLocked(); 6109 } 6110 } 6111 } finally { 6112 Binder.restoreCallingIdentity(token); 6113 } 6114 } 6115 6116 final void finishBooting() { 6117 synchronized (this) { 6118 if (!mBootAnimationComplete) { 6119 mCallFinishBooting = true; 6120 return; 6121 } 6122 mCallFinishBooting = false; 6123 } 6124 6125 ArraySet<String> completedIsas = new ArraySet<String>(); 6126 for (String abi : Build.SUPPORTED_ABIS) { 6127 Process.establishZygoteConnectionForAbi(abi); 6128 final String instructionSet = VMRuntime.getInstructionSet(abi); 6129 if (!completedIsas.contains(instructionSet)) { 6130 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6131 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6132 } 6133 completedIsas.add(instructionSet); 6134 } 6135 } 6136 6137 IntentFilter pkgFilter = new IntentFilter(); 6138 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6139 pkgFilter.addDataScheme("package"); 6140 mContext.registerReceiver(new BroadcastReceiver() { 6141 @Override 6142 public void onReceive(Context context, Intent intent) { 6143 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6144 if (pkgs != null) { 6145 for (String pkg : pkgs) { 6146 synchronized (ActivityManagerService.this) { 6147 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6148 0, "finished booting")) { 6149 setResultCode(Activity.RESULT_OK); 6150 return; 6151 } 6152 } 6153 } 6154 } 6155 } 6156 }, pkgFilter); 6157 6158 // Let system services know. 6159 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6160 6161 synchronized (this) { 6162 // Ensure that any processes we had put on hold are now started 6163 // up. 6164 final int NP = mProcessesOnHold.size(); 6165 if (NP > 0) { 6166 ArrayList<ProcessRecord> procs = 6167 new ArrayList<ProcessRecord>(mProcessesOnHold); 6168 for (int ip=0; ip<NP; ip++) { 6169 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6170 + procs.get(ip)); 6171 startProcessLocked(procs.get(ip), "on-hold", null); 6172 } 6173 } 6174 6175 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6176 // Start looking for apps that are abusing wake locks. 6177 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6178 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6179 // Tell anyone interested that we are done booting! 6180 SystemProperties.set("sys.boot_completed", "1"); 6181 6182 // And trigger dev.bootcomplete if we are not showing encryption progress 6183 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6184 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6185 SystemProperties.set("dev.bootcomplete", "1"); 6186 } 6187 for (int i=0; i<mStartedUsers.size(); i++) { 6188 UserStartedState uss = mStartedUsers.valueAt(i); 6189 if (uss.mState == UserStartedState.STATE_BOOTING) { 6190 uss.mState = UserStartedState.STATE_RUNNING; 6191 final int userId = mStartedUsers.keyAt(i); 6192 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6193 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6194 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6195 broadcastIntentLocked(null, null, intent, null, 6196 new IIntentReceiver.Stub() { 6197 @Override 6198 public void performReceive(Intent intent, int resultCode, 6199 String data, Bundle extras, boolean ordered, 6200 boolean sticky, int sendingUser) { 6201 synchronized (ActivityManagerService.this) { 6202 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6203 true, false); 6204 } 6205 } 6206 }, 6207 0, null, null, 6208 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6209 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6210 userId); 6211 } 6212 } 6213 scheduleStartProfilesLocked(); 6214 } 6215 } 6216 } 6217 6218 @Override 6219 public void bootAnimationComplete() { 6220 final boolean callFinishBooting; 6221 synchronized (this) { 6222 callFinishBooting = mCallFinishBooting; 6223 mBootAnimationComplete = true; 6224 } 6225 if (callFinishBooting) { 6226 finishBooting(); 6227 } 6228 } 6229 6230 @Override 6231 public void systemBackupRestored() { 6232 synchronized (this) { 6233 if (mSystemReady) { 6234 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6235 } else { 6236 Slog.w(TAG, "System backup restored before system is ready"); 6237 } 6238 } 6239 } 6240 6241 final void ensureBootCompleted() { 6242 boolean booting; 6243 boolean enableScreen; 6244 synchronized (this) { 6245 booting = mBooting; 6246 mBooting = false; 6247 enableScreen = !mBooted; 6248 mBooted = true; 6249 } 6250 6251 if (booting) { 6252 finishBooting(); 6253 } 6254 6255 if (enableScreen) { 6256 enableScreenAfterBoot(); 6257 } 6258 } 6259 6260 @Override 6261 public final void activityResumed(IBinder token) { 6262 final long origId = Binder.clearCallingIdentity(); 6263 synchronized(this) { 6264 ActivityStack stack = ActivityRecord.getStackLocked(token); 6265 if (stack != null) { 6266 ActivityRecord.activityResumedLocked(token); 6267 } 6268 } 6269 Binder.restoreCallingIdentity(origId); 6270 } 6271 6272 @Override 6273 public final void activityPaused(IBinder token) { 6274 final long origId = Binder.clearCallingIdentity(); 6275 synchronized(this) { 6276 ActivityStack stack = ActivityRecord.getStackLocked(token); 6277 if (stack != null) { 6278 stack.activityPausedLocked(token, false); 6279 } 6280 } 6281 Binder.restoreCallingIdentity(origId); 6282 } 6283 6284 @Override 6285 public final void activityStopped(IBinder token, Bundle icicle, 6286 PersistableBundle persistentState, CharSequence description) { 6287 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6288 6289 // Refuse possible leaked file descriptors 6290 if (icicle != null && icicle.hasFileDescriptors()) { 6291 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6292 } 6293 6294 final long origId = Binder.clearCallingIdentity(); 6295 6296 synchronized (this) { 6297 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6298 if (r != null) { 6299 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6300 } 6301 } 6302 6303 trimApplications(); 6304 6305 Binder.restoreCallingIdentity(origId); 6306 } 6307 6308 @Override 6309 public final void activityDestroyed(IBinder token) { 6310 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6311 synchronized (this) { 6312 ActivityStack stack = ActivityRecord.getStackLocked(token); 6313 if (stack != null) { 6314 stack.activityDestroyedLocked(token); 6315 } 6316 } 6317 } 6318 6319 @Override 6320 public final void backgroundResourcesReleased(IBinder token) { 6321 final long origId = Binder.clearCallingIdentity(); 6322 try { 6323 synchronized (this) { 6324 ActivityStack stack = ActivityRecord.getStackLocked(token); 6325 if (stack != null) { 6326 stack.backgroundResourcesReleased(); 6327 } 6328 } 6329 } finally { 6330 Binder.restoreCallingIdentity(origId); 6331 } 6332 } 6333 6334 @Override 6335 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6336 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6337 } 6338 6339 @Override 6340 public final void notifyEnterAnimationComplete(IBinder token) { 6341 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6342 } 6343 6344 @Override 6345 public String getCallingPackage(IBinder token) { 6346 synchronized (this) { 6347 ActivityRecord r = getCallingRecordLocked(token); 6348 return r != null ? r.info.packageName : null; 6349 } 6350 } 6351 6352 @Override 6353 public ComponentName getCallingActivity(IBinder token) { 6354 synchronized (this) { 6355 ActivityRecord r = getCallingRecordLocked(token); 6356 return r != null ? r.intent.getComponent() : null; 6357 } 6358 } 6359 6360 private ActivityRecord getCallingRecordLocked(IBinder token) { 6361 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6362 if (r == null) { 6363 return null; 6364 } 6365 return r.resultTo; 6366 } 6367 6368 @Override 6369 public ComponentName getActivityClassForToken(IBinder token) { 6370 synchronized(this) { 6371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6372 if (r == null) { 6373 return null; 6374 } 6375 return r.intent.getComponent(); 6376 } 6377 } 6378 6379 @Override 6380 public String getPackageForToken(IBinder token) { 6381 synchronized(this) { 6382 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6383 if (r == null) { 6384 return null; 6385 } 6386 return r.packageName; 6387 } 6388 } 6389 6390 @Override 6391 public IIntentSender getIntentSender(int type, 6392 String packageName, IBinder token, String resultWho, 6393 int requestCode, Intent[] intents, String[] resolvedTypes, 6394 int flags, Bundle options, int userId) { 6395 enforceNotIsolatedCaller("getIntentSender"); 6396 // Refuse possible leaked file descriptors 6397 if (intents != null) { 6398 if (intents.length < 1) { 6399 throw new IllegalArgumentException("Intents array length must be >= 1"); 6400 } 6401 for (int i=0; i<intents.length; i++) { 6402 Intent intent = intents[i]; 6403 if (intent != null) { 6404 if (intent.hasFileDescriptors()) { 6405 throw new IllegalArgumentException("File descriptors passed in Intent"); 6406 } 6407 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6408 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6409 throw new IllegalArgumentException( 6410 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6411 } 6412 intents[i] = new Intent(intent); 6413 } 6414 } 6415 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6416 throw new IllegalArgumentException( 6417 "Intent array length does not match resolvedTypes length"); 6418 } 6419 } 6420 if (options != null) { 6421 if (options.hasFileDescriptors()) { 6422 throw new IllegalArgumentException("File descriptors passed in options"); 6423 } 6424 } 6425 6426 synchronized(this) { 6427 int callingUid = Binder.getCallingUid(); 6428 int origUserId = userId; 6429 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6430 type == ActivityManager.INTENT_SENDER_BROADCAST, 6431 ALLOW_NON_FULL, "getIntentSender", null); 6432 if (origUserId == UserHandle.USER_CURRENT) { 6433 // We don't want to evaluate this until the pending intent is 6434 // actually executed. However, we do want to always do the 6435 // security checking for it above. 6436 userId = UserHandle.USER_CURRENT; 6437 } 6438 try { 6439 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6440 int uid = AppGlobals.getPackageManager() 6441 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6442 if (!UserHandle.isSameApp(callingUid, uid)) { 6443 String msg = "Permission Denial: getIntentSender() from pid=" 6444 + Binder.getCallingPid() 6445 + ", uid=" + Binder.getCallingUid() 6446 + ", (need uid=" + uid + ")" 6447 + " is not allowed to send as package " + packageName; 6448 Slog.w(TAG, msg); 6449 throw new SecurityException(msg); 6450 } 6451 } 6452 6453 return getIntentSenderLocked(type, packageName, callingUid, userId, 6454 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6455 6456 } catch (RemoteException e) { 6457 throw new SecurityException(e); 6458 } 6459 } 6460 } 6461 6462 IIntentSender getIntentSenderLocked(int type, String packageName, 6463 int callingUid, int userId, IBinder token, String resultWho, 6464 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6465 Bundle options) { 6466 if (DEBUG_MU) 6467 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6468 ActivityRecord activity = null; 6469 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6470 activity = ActivityRecord.isInStackLocked(token); 6471 if (activity == null) { 6472 return null; 6473 } 6474 if (activity.finishing) { 6475 return null; 6476 } 6477 } 6478 6479 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6480 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6481 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6482 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6483 |PendingIntent.FLAG_UPDATE_CURRENT); 6484 6485 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6486 type, packageName, activity, resultWho, 6487 requestCode, intents, resolvedTypes, flags, options, userId); 6488 WeakReference<PendingIntentRecord> ref; 6489 ref = mIntentSenderRecords.get(key); 6490 PendingIntentRecord rec = ref != null ? ref.get() : null; 6491 if (rec != null) { 6492 if (!cancelCurrent) { 6493 if (updateCurrent) { 6494 if (rec.key.requestIntent != null) { 6495 rec.key.requestIntent.replaceExtras(intents != null ? 6496 intents[intents.length - 1] : null); 6497 } 6498 if (intents != null) { 6499 intents[intents.length-1] = rec.key.requestIntent; 6500 rec.key.allIntents = intents; 6501 rec.key.allResolvedTypes = resolvedTypes; 6502 } else { 6503 rec.key.allIntents = null; 6504 rec.key.allResolvedTypes = null; 6505 } 6506 } 6507 return rec; 6508 } 6509 rec.canceled = true; 6510 mIntentSenderRecords.remove(key); 6511 } 6512 if (noCreate) { 6513 return rec; 6514 } 6515 rec = new PendingIntentRecord(this, key, callingUid); 6516 mIntentSenderRecords.put(key, rec.ref); 6517 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6518 if (activity.pendingResults == null) { 6519 activity.pendingResults 6520 = new HashSet<WeakReference<PendingIntentRecord>>(); 6521 } 6522 activity.pendingResults.add(rec.ref); 6523 } 6524 return rec; 6525 } 6526 6527 @Override 6528 public void cancelIntentSender(IIntentSender sender) { 6529 if (!(sender instanceof PendingIntentRecord)) { 6530 return; 6531 } 6532 synchronized(this) { 6533 PendingIntentRecord rec = (PendingIntentRecord)sender; 6534 try { 6535 int uid = AppGlobals.getPackageManager() 6536 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6537 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6538 String msg = "Permission Denial: cancelIntentSender() from pid=" 6539 + Binder.getCallingPid() 6540 + ", uid=" + Binder.getCallingUid() 6541 + " is not allowed to cancel packges " 6542 + rec.key.packageName; 6543 Slog.w(TAG, msg); 6544 throw new SecurityException(msg); 6545 } 6546 } catch (RemoteException e) { 6547 throw new SecurityException(e); 6548 } 6549 cancelIntentSenderLocked(rec, true); 6550 } 6551 } 6552 6553 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6554 rec.canceled = true; 6555 mIntentSenderRecords.remove(rec.key); 6556 if (cleanActivity && rec.key.activity != null) { 6557 rec.key.activity.pendingResults.remove(rec.ref); 6558 } 6559 } 6560 6561 @Override 6562 public String getPackageForIntentSender(IIntentSender pendingResult) { 6563 if (!(pendingResult instanceof PendingIntentRecord)) { 6564 return null; 6565 } 6566 try { 6567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6568 return res.key.packageName; 6569 } catch (ClassCastException e) { 6570 } 6571 return null; 6572 } 6573 6574 @Override 6575 public int getUidForIntentSender(IIntentSender sender) { 6576 if (sender instanceof PendingIntentRecord) { 6577 try { 6578 PendingIntentRecord res = (PendingIntentRecord)sender; 6579 return res.uid; 6580 } catch (ClassCastException e) { 6581 } 6582 } 6583 return -1; 6584 } 6585 6586 @Override 6587 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6588 if (!(pendingResult instanceof PendingIntentRecord)) { 6589 return false; 6590 } 6591 try { 6592 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6593 if (res.key.allIntents == null) { 6594 return false; 6595 } 6596 for (int i=0; i<res.key.allIntents.length; i++) { 6597 Intent intent = res.key.allIntents[i]; 6598 if (intent.getPackage() != null && intent.getComponent() != null) { 6599 return false; 6600 } 6601 } 6602 return true; 6603 } catch (ClassCastException e) { 6604 } 6605 return false; 6606 } 6607 6608 @Override 6609 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6610 if (!(pendingResult instanceof PendingIntentRecord)) { 6611 return false; 6612 } 6613 try { 6614 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6615 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6616 return true; 6617 } 6618 return false; 6619 } catch (ClassCastException e) { 6620 } 6621 return false; 6622 } 6623 6624 @Override 6625 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6626 if (!(pendingResult instanceof PendingIntentRecord)) { 6627 return null; 6628 } 6629 try { 6630 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6631 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6632 } catch (ClassCastException e) { 6633 } 6634 return null; 6635 } 6636 6637 @Override 6638 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6639 if (!(pendingResult instanceof PendingIntentRecord)) { 6640 return null; 6641 } 6642 try { 6643 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6644 Intent intent = res.key.requestIntent; 6645 if (intent != null) { 6646 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6647 || res.lastTagPrefix.equals(prefix))) { 6648 return res.lastTag; 6649 } 6650 res.lastTagPrefix = prefix; 6651 StringBuilder sb = new StringBuilder(128); 6652 if (prefix != null) { 6653 sb.append(prefix); 6654 } 6655 if (intent.getAction() != null) { 6656 sb.append(intent.getAction()); 6657 } else if (intent.getComponent() != null) { 6658 intent.getComponent().appendShortString(sb); 6659 } else { 6660 sb.append("?"); 6661 } 6662 return res.lastTag = sb.toString(); 6663 } 6664 } catch (ClassCastException e) { 6665 } 6666 return null; 6667 } 6668 6669 @Override 6670 public void setProcessLimit(int max) { 6671 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6672 "setProcessLimit()"); 6673 synchronized (this) { 6674 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6675 mProcessLimitOverride = max; 6676 } 6677 trimApplications(); 6678 } 6679 6680 @Override 6681 public int getProcessLimit() { 6682 synchronized (this) { 6683 return mProcessLimitOverride; 6684 } 6685 } 6686 6687 void foregroundTokenDied(ForegroundToken token) { 6688 synchronized (ActivityManagerService.this) { 6689 synchronized (mPidsSelfLocked) { 6690 ForegroundToken cur 6691 = mForegroundProcesses.get(token.pid); 6692 if (cur != token) { 6693 return; 6694 } 6695 mForegroundProcesses.remove(token.pid); 6696 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6697 if (pr == null) { 6698 return; 6699 } 6700 pr.forcingToForeground = null; 6701 updateProcessForegroundLocked(pr, false, false); 6702 } 6703 updateOomAdjLocked(); 6704 } 6705 } 6706 6707 @Override 6708 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6709 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6710 "setProcessForeground()"); 6711 synchronized(this) { 6712 boolean changed = false; 6713 6714 synchronized (mPidsSelfLocked) { 6715 ProcessRecord pr = mPidsSelfLocked.get(pid); 6716 if (pr == null && isForeground) { 6717 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6718 return; 6719 } 6720 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6721 if (oldToken != null) { 6722 oldToken.token.unlinkToDeath(oldToken, 0); 6723 mForegroundProcesses.remove(pid); 6724 if (pr != null) { 6725 pr.forcingToForeground = null; 6726 } 6727 changed = true; 6728 } 6729 if (isForeground && token != null) { 6730 ForegroundToken newToken = new ForegroundToken() { 6731 @Override 6732 public void binderDied() { 6733 foregroundTokenDied(this); 6734 } 6735 }; 6736 newToken.pid = pid; 6737 newToken.token = token; 6738 try { 6739 token.linkToDeath(newToken, 0); 6740 mForegroundProcesses.put(pid, newToken); 6741 pr.forcingToForeground = token; 6742 changed = true; 6743 } catch (RemoteException e) { 6744 // If the process died while doing this, we will later 6745 // do the cleanup with the process death link. 6746 } 6747 } 6748 } 6749 6750 if (changed) { 6751 updateOomAdjLocked(); 6752 } 6753 } 6754 } 6755 6756 // ========================================================= 6757 // PERMISSIONS 6758 // ========================================================= 6759 6760 static class PermissionController extends IPermissionController.Stub { 6761 ActivityManagerService mActivityManagerService; 6762 PermissionController(ActivityManagerService activityManagerService) { 6763 mActivityManagerService = activityManagerService; 6764 } 6765 6766 @Override 6767 public boolean checkPermission(String permission, int pid, int uid) { 6768 return mActivityManagerService.checkPermission(permission, pid, 6769 uid) == PackageManager.PERMISSION_GRANTED; 6770 } 6771 } 6772 6773 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6774 @Override 6775 public int checkComponentPermission(String permission, int pid, int uid, 6776 int owningUid, boolean exported) { 6777 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6778 owningUid, exported); 6779 } 6780 6781 @Override 6782 public Object getAMSLock() { 6783 return ActivityManagerService.this; 6784 } 6785 } 6786 6787 /** 6788 * This can be called with or without the global lock held. 6789 */ 6790 int checkComponentPermission(String permission, int pid, int uid, 6791 int owningUid, boolean exported) { 6792 if (pid == MY_PID) { 6793 return PackageManager.PERMISSION_GRANTED; 6794 } 6795 return ActivityManager.checkComponentPermission(permission, uid, 6796 owningUid, exported); 6797 } 6798 6799 /** 6800 * As the only public entry point for permissions checking, this method 6801 * can enforce the semantic that requesting a check on a null global 6802 * permission is automatically denied. (Internally a null permission 6803 * string is used when calling {@link #checkComponentPermission} in cases 6804 * when only uid-based security is needed.) 6805 * 6806 * This can be called with or without the global lock held. 6807 */ 6808 @Override 6809 public int checkPermission(String permission, int pid, int uid) { 6810 if (permission == null) { 6811 return PackageManager.PERMISSION_DENIED; 6812 } 6813 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6814 } 6815 6816 @Override 6817 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6818 if (permission == null) { 6819 return PackageManager.PERMISSION_DENIED; 6820 } 6821 6822 // We might be performing an operation on behalf of an indirect binder 6823 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6824 // client identity accordingly before proceeding. 6825 Identity tlsIdentity = sCallerIdentity.get(); 6826 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6827 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6828 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6829 uid = tlsIdentity.uid; 6830 pid = tlsIdentity.pid; 6831 } 6832 6833 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6834 } 6835 6836 /** 6837 * Binder IPC calls go through the public entry point. 6838 * This can be called with or without the global lock held. 6839 */ 6840 int checkCallingPermission(String permission) { 6841 return checkPermission(permission, 6842 Binder.getCallingPid(), 6843 UserHandle.getAppId(Binder.getCallingUid())); 6844 } 6845 6846 /** 6847 * This can be called with or without the global lock held. 6848 */ 6849 void enforceCallingPermission(String permission, String func) { 6850 if (checkCallingPermission(permission) 6851 == PackageManager.PERMISSION_GRANTED) { 6852 return; 6853 } 6854 6855 String msg = "Permission Denial: " + func + " from pid=" 6856 + Binder.getCallingPid() 6857 + ", uid=" + Binder.getCallingUid() 6858 + " requires " + permission; 6859 Slog.w(TAG, msg); 6860 throw new SecurityException(msg); 6861 } 6862 6863 /** 6864 * Determine if UID is holding permissions required to access {@link Uri} in 6865 * the given {@link ProviderInfo}. Final permission checking is always done 6866 * in {@link ContentProvider}. 6867 */ 6868 private final boolean checkHoldingPermissionsLocked( 6869 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6870 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6871 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6872 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6873 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6874 != PERMISSION_GRANTED) { 6875 return false; 6876 } 6877 } 6878 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6879 } 6880 6881 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6882 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6883 if (pi.applicationInfo.uid == uid) { 6884 return true; 6885 } else if (!pi.exported) { 6886 return false; 6887 } 6888 6889 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6890 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6891 try { 6892 // check if target holds top-level <provider> permissions 6893 if (!readMet && pi.readPermission != null && considerUidPermissions 6894 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6895 readMet = true; 6896 } 6897 if (!writeMet && pi.writePermission != null && considerUidPermissions 6898 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6899 writeMet = true; 6900 } 6901 6902 // track if unprotected read/write is allowed; any denied 6903 // <path-permission> below removes this ability 6904 boolean allowDefaultRead = pi.readPermission == null; 6905 boolean allowDefaultWrite = pi.writePermission == null; 6906 6907 // check if target holds any <path-permission> that match uri 6908 final PathPermission[] pps = pi.pathPermissions; 6909 if (pps != null) { 6910 final String path = grantUri.uri.getPath(); 6911 int i = pps.length; 6912 while (i > 0 && (!readMet || !writeMet)) { 6913 i--; 6914 PathPermission pp = pps[i]; 6915 if (pp.match(path)) { 6916 if (!readMet) { 6917 final String pprperm = pp.getReadPermission(); 6918 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6919 + pprperm + " for " + pp.getPath() 6920 + ": match=" + pp.match(path) 6921 + " check=" + pm.checkUidPermission(pprperm, uid)); 6922 if (pprperm != null) { 6923 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6924 == PERMISSION_GRANTED) { 6925 readMet = true; 6926 } else { 6927 allowDefaultRead = false; 6928 } 6929 } 6930 } 6931 if (!writeMet) { 6932 final String ppwperm = pp.getWritePermission(); 6933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6934 + ppwperm + " for " + pp.getPath() 6935 + ": match=" + pp.match(path) 6936 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6937 if (ppwperm != null) { 6938 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6939 == PERMISSION_GRANTED) { 6940 writeMet = true; 6941 } else { 6942 allowDefaultWrite = false; 6943 } 6944 } 6945 } 6946 } 6947 } 6948 } 6949 6950 // grant unprotected <provider> read/write, if not blocked by 6951 // <path-permission> above 6952 if (allowDefaultRead) readMet = true; 6953 if (allowDefaultWrite) writeMet = true; 6954 6955 } catch (RemoteException e) { 6956 return false; 6957 } 6958 6959 return readMet && writeMet; 6960 } 6961 6962 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6963 ProviderInfo pi = null; 6964 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6965 if (cpr != null) { 6966 pi = cpr.info; 6967 } else { 6968 try { 6969 pi = AppGlobals.getPackageManager().resolveContentProvider( 6970 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6971 } catch (RemoteException ex) { 6972 } 6973 } 6974 return pi; 6975 } 6976 6977 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6978 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6979 if (targetUris != null) { 6980 return targetUris.get(grantUri); 6981 } 6982 return null; 6983 } 6984 6985 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6986 String targetPkg, int targetUid, GrantUri grantUri) { 6987 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6988 if (targetUris == null) { 6989 targetUris = Maps.newArrayMap(); 6990 mGrantedUriPermissions.put(targetUid, targetUris); 6991 } 6992 6993 UriPermission perm = targetUris.get(grantUri); 6994 if (perm == null) { 6995 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6996 targetUris.put(grantUri, perm); 6997 } 6998 6999 return perm; 7000 } 7001 7002 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7003 final int modeFlags) { 7004 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7005 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7006 : UriPermission.STRENGTH_OWNED; 7007 7008 // Root gets to do everything. 7009 if (uid == 0) { 7010 return true; 7011 } 7012 7013 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7014 if (perms == null) return false; 7015 7016 // First look for exact match 7017 final UriPermission exactPerm = perms.get(grantUri); 7018 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7019 return true; 7020 } 7021 7022 // No exact match, look for prefixes 7023 final int N = perms.size(); 7024 for (int i = 0; i < N; i++) { 7025 final UriPermission perm = perms.valueAt(i); 7026 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7027 && perm.getStrength(modeFlags) >= minStrength) { 7028 return true; 7029 } 7030 } 7031 7032 return false; 7033 } 7034 7035 /** 7036 * @param uri This uri must NOT contain an embedded userId. 7037 * @param userId The userId in which the uri is to be resolved. 7038 */ 7039 @Override 7040 public int checkUriPermission(Uri uri, int pid, int uid, 7041 final int modeFlags, int userId, IBinder callerToken) { 7042 enforceNotIsolatedCaller("checkUriPermission"); 7043 7044 // Another redirected-binder-call permissions check as in 7045 // {@link checkPermissionWithToken}. 7046 Identity tlsIdentity = sCallerIdentity.get(); 7047 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7048 uid = tlsIdentity.uid; 7049 pid = tlsIdentity.pid; 7050 } 7051 7052 // Our own process gets to do everything. 7053 if (pid == MY_PID) { 7054 return PackageManager.PERMISSION_GRANTED; 7055 } 7056 synchronized (this) { 7057 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7058 ? PackageManager.PERMISSION_GRANTED 7059 : PackageManager.PERMISSION_DENIED; 7060 } 7061 } 7062 7063 /** 7064 * Check if the targetPkg can be granted permission to access uri by 7065 * the callingUid using the given modeFlags. Throws a security exception 7066 * if callingUid is not allowed to do this. Returns the uid of the target 7067 * if the URI permission grant should be performed; returns -1 if it is not 7068 * needed (for example targetPkg already has permission to access the URI). 7069 * If you already know the uid of the target, you can supply it in 7070 * lastTargetUid else set that to -1. 7071 */ 7072 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7073 final int modeFlags, int lastTargetUid) { 7074 if (!Intent.isAccessUriMode(modeFlags)) { 7075 return -1; 7076 } 7077 7078 if (targetPkg != null) { 7079 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7080 "Checking grant " + targetPkg + " permission to " + grantUri); 7081 } 7082 7083 final IPackageManager pm = AppGlobals.getPackageManager(); 7084 7085 // If this is not a content: uri, we can't do anything with it. 7086 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7087 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7088 "Can't grant URI permission for non-content URI: " + grantUri); 7089 return -1; 7090 } 7091 7092 final String authority = grantUri.uri.getAuthority(); 7093 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7094 if (pi == null) { 7095 Slog.w(TAG, "No content provider found for permission check: " + 7096 grantUri.uri.toSafeString()); 7097 return -1; 7098 } 7099 7100 int targetUid = lastTargetUid; 7101 if (targetUid < 0 && targetPkg != null) { 7102 try { 7103 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7104 if (targetUid < 0) { 7105 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7106 "Can't grant URI permission no uid for: " + targetPkg); 7107 return -1; 7108 } 7109 } catch (RemoteException ex) { 7110 return -1; 7111 } 7112 } 7113 7114 if (targetUid >= 0) { 7115 // First... does the target actually need this permission? 7116 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7117 // No need to grant the target this permission. 7118 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7119 "Target " + targetPkg + " already has full permission to " + grantUri); 7120 return -1; 7121 } 7122 } else { 7123 // First... there is no target package, so can anyone access it? 7124 boolean allowed = pi.exported; 7125 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7126 if (pi.readPermission != null) { 7127 allowed = false; 7128 } 7129 } 7130 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7131 if (pi.writePermission != null) { 7132 allowed = false; 7133 } 7134 } 7135 if (allowed) { 7136 return -1; 7137 } 7138 } 7139 7140 /* There is a special cross user grant if: 7141 * - The target is on another user. 7142 * - Apps on the current user can access the uri without any uid permissions. 7143 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7144 * grant uri permissions. 7145 */ 7146 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7147 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7148 modeFlags, false /*without considering the uid permissions*/); 7149 7150 // Second... is the provider allowing granting of URI permissions? 7151 if (!specialCrossUserGrant) { 7152 if (!pi.grantUriPermissions) { 7153 throw new SecurityException("Provider " + pi.packageName 7154 + "/" + pi.name 7155 + " does not allow granting of Uri permissions (uri " 7156 + grantUri + ")"); 7157 } 7158 if (pi.uriPermissionPatterns != null) { 7159 final int N = pi.uriPermissionPatterns.length; 7160 boolean allowed = false; 7161 for (int i=0; i<N; i++) { 7162 if (pi.uriPermissionPatterns[i] != null 7163 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7164 allowed = true; 7165 break; 7166 } 7167 } 7168 if (!allowed) { 7169 throw new SecurityException("Provider " + pi.packageName 7170 + "/" + pi.name 7171 + " does not allow granting of permission to path of Uri " 7172 + grantUri); 7173 } 7174 } 7175 } 7176 7177 // Third... does the caller itself have permission to access 7178 // this uri? 7179 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7180 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7181 // Require they hold a strong enough Uri permission 7182 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7183 throw new SecurityException("Uid " + callingUid 7184 + " does not have permission to uri " + grantUri); 7185 } 7186 } 7187 } 7188 return targetUid; 7189 } 7190 7191 /** 7192 * @param uri This uri must NOT contain an embedded userId. 7193 * @param userId The userId in which the uri is to be resolved. 7194 */ 7195 @Override 7196 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7197 final int modeFlags, int userId) { 7198 enforceNotIsolatedCaller("checkGrantUriPermission"); 7199 synchronized(this) { 7200 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7201 new GrantUri(userId, uri, false), modeFlags, -1); 7202 } 7203 } 7204 7205 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7206 final int modeFlags, UriPermissionOwner owner) { 7207 if (!Intent.isAccessUriMode(modeFlags)) { 7208 return; 7209 } 7210 7211 // So here we are: the caller has the assumed permission 7212 // to the uri, and the target doesn't. Let's now give this to 7213 // the target. 7214 7215 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7216 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7217 7218 final String authority = grantUri.uri.getAuthority(); 7219 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7220 if (pi == null) { 7221 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7222 return; 7223 } 7224 7225 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7226 grantUri.prefix = true; 7227 } 7228 final UriPermission perm = findOrCreateUriPermissionLocked( 7229 pi.packageName, targetPkg, targetUid, grantUri); 7230 perm.grantModes(modeFlags, owner); 7231 } 7232 7233 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7234 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7235 if (targetPkg == null) { 7236 throw new NullPointerException("targetPkg"); 7237 } 7238 int targetUid; 7239 final IPackageManager pm = AppGlobals.getPackageManager(); 7240 try { 7241 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7242 } catch (RemoteException ex) { 7243 return; 7244 } 7245 7246 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7247 targetUid); 7248 if (targetUid < 0) { 7249 return; 7250 } 7251 7252 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7253 owner); 7254 } 7255 7256 static class NeededUriGrants extends ArrayList<GrantUri> { 7257 final String targetPkg; 7258 final int targetUid; 7259 final int flags; 7260 7261 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7262 this.targetPkg = targetPkg; 7263 this.targetUid = targetUid; 7264 this.flags = flags; 7265 } 7266 } 7267 7268 /** 7269 * Like checkGrantUriPermissionLocked, but takes an Intent. 7270 */ 7271 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7272 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7273 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7274 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7275 + " clip=" + (intent != null ? intent.getClipData() : null) 7276 + " from " + intent + "; flags=0x" 7277 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7278 7279 if (targetPkg == null) { 7280 throw new NullPointerException("targetPkg"); 7281 } 7282 7283 if (intent == null) { 7284 return null; 7285 } 7286 Uri data = intent.getData(); 7287 ClipData clip = intent.getClipData(); 7288 if (data == null && clip == null) { 7289 return null; 7290 } 7291 // Default userId for uris in the intent (if they don't specify it themselves) 7292 int contentUserHint = intent.getContentUserHint(); 7293 if (contentUserHint == UserHandle.USER_CURRENT) { 7294 contentUserHint = UserHandle.getUserId(callingUid); 7295 } 7296 final IPackageManager pm = AppGlobals.getPackageManager(); 7297 int targetUid; 7298 if (needed != null) { 7299 targetUid = needed.targetUid; 7300 } else { 7301 try { 7302 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7303 } catch (RemoteException ex) { 7304 return null; 7305 } 7306 if (targetUid < 0) { 7307 if (DEBUG_URI_PERMISSION) { 7308 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7309 + " on user " + targetUserId); 7310 } 7311 return null; 7312 } 7313 } 7314 if (data != null) { 7315 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7316 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7317 targetUid); 7318 if (targetUid > 0) { 7319 if (needed == null) { 7320 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7321 } 7322 needed.add(grantUri); 7323 } 7324 } 7325 if (clip != null) { 7326 for (int i=0; i<clip.getItemCount(); i++) { 7327 Uri uri = clip.getItemAt(i).getUri(); 7328 if (uri != null) { 7329 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7330 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7331 targetUid); 7332 if (targetUid > 0) { 7333 if (needed == null) { 7334 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7335 } 7336 needed.add(grantUri); 7337 } 7338 } else { 7339 Intent clipIntent = clip.getItemAt(i).getIntent(); 7340 if (clipIntent != null) { 7341 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7342 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7343 if (newNeeded != null) { 7344 needed = newNeeded; 7345 } 7346 } 7347 } 7348 } 7349 } 7350 7351 return needed; 7352 } 7353 7354 /** 7355 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7356 */ 7357 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7358 UriPermissionOwner owner) { 7359 if (needed != null) { 7360 for (int i=0; i<needed.size(); i++) { 7361 GrantUri grantUri = needed.get(i); 7362 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7363 grantUri, needed.flags, owner); 7364 } 7365 } 7366 } 7367 7368 void grantUriPermissionFromIntentLocked(int callingUid, 7369 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7370 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7371 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7372 if (needed == null) { 7373 return; 7374 } 7375 7376 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7377 } 7378 7379 /** 7380 * @param uri This uri must NOT contain an embedded userId. 7381 * @param userId The userId in which the uri is to be resolved. 7382 */ 7383 @Override 7384 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7385 final int modeFlags, int userId) { 7386 enforceNotIsolatedCaller("grantUriPermission"); 7387 GrantUri grantUri = new GrantUri(userId, uri, false); 7388 synchronized(this) { 7389 final ProcessRecord r = getRecordForAppLocked(caller); 7390 if (r == null) { 7391 throw new SecurityException("Unable to find app for caller " 7392 + caller 7393 + " when granting permission to uri " + grantUri); 7394 } 7395 if (targetPkg == null) { 7396 throw new IllegalArgumentException("null target"); 7397 } 7398 if (grantUri == null) { 7399 throw new IllegalArgumentException("null uri"); 7400 } 7401 7402 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7403 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7404 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7405 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7406 7407 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7408 UserHandle.getUserId(r.uid)); 7409 } 7410 } 7411 7412 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7413 if (perm.modeFlags == 0) { 7414 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7415 perm.targetUid); 7416 if (perms != null) { 7417 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7418 "Removing " + perm.targetUid + " permission to " + perm.uri); 7419 7420 perms.remove(perm.uri); 7421 if (perms.isEmpty()) { 7422 mGrantedUriPermissions.remove(perm.targetUid); 7423 } 7424 } 7425 } 7426 } 7427 7428 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7429 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7430 7431 final IPackageManager pm = AppGlobals.getPackageManager(); 7432 final String authority = grantUri.uri.getAuthority(); 7433 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7434 if (pi == null) { 7435 Slog.w(TAG, "No content provider found for permission revoke: " 7436 + grantUri.toSafeString()); 7437 return; 7438 } 7439 7440 // Does the caller have this permission on the URI? 7441 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7442 // If they don't have direct access to the URI, then revoke any 7443 // ownerless URI permissions that have been granted to them. 7444 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7445 if (perms != null) { 7446 boolean persistChanged = false; 7447 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7448 final UriPermission perm = it.next(); 7449 if (perm.uri.sourceUserId == grantUri.sourceUserId 7450 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7451 if (DEBUG_URI_PERMISSION) 7452 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7453 " permission to " + perm.uri); 7454 persistChanged |= perm.revokeModes( 7455 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7456 if (perm.modeFlags == 0) { 7457 it.remove(); 7458 } 7459 } 7460 } 7461 if (perms.isEmpty()) { 7462 mGrantedUriPermissions.remove(callingUid); 7463 } 7464 if (persistChanged) { 7465 schedulePersistUriGrants(); 7466 } 7467 } 7468 return; 7469 } 7470 7471 boolean persistChanged = false; 7472 7473 // Go through all of the permissions and remove any that match. 7474 int N = mGrantedUriPermissions.size(); 7475 for (int i = 0; i < N; i++) { 7476 final int targetUid = mGrantedUriPermissions.keyAt(i); 7477 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7478 7479 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7480 final UriPermission perm = it.next(); 7481 if (perm.uri.sourceUserId == grantUri.sourceUserId 7482 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7483 if (DEBUG_URI_PERMISSION) 7484 Slog.v(TAG, 7485 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7486 persistChanged |= perm.revokeModes( 7487 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7488 if (perm.modeFlags == 0) { 7489 it.remove(); 7490 } 7491 } 7492 } 7493 7494 if (perms.isEmpty()) { 7495 mGrantedUriPermissions.remove(targetUid); 7496 N--; 7497 i--; 7498 } 7499 } 7500 7501 if (persistChanged) { 7502 schedulePersistUriGrants(); 7503 } 7504 } 7505 7506 /** 7507 * @param uri This uri must NOT contain an embedded userId. 7508 * @param userId The userId in which the uri is to be resolved. 7509 */ 7510 @Override 7511 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7512 int userId) { 7513 enforceNotIsolatedCaller("revokeUriPermission"); 7514 synchronized(this) { 7515 final ProcessRecord r = getRecordForAppLocked(caller); 7516 if (r == null) { 7517 throw new SecurityException("Unable to find app for caller " 7518 + caller 7519 + " when revoking permission to uri " + uri); 7520 } 7521 if (uri == null) { 7522 Slog.w(TAG, "revokeUriPermission: null uri"); 7523 return; 7524 } 7525 7526 if (!Intent.isAccessUriMode(modeFlags)) { 7527 return; 7528 } 7529 7530 final IPackageManager pm = AppGlobals.getPackageManager(); 7531 final String authority = uri.getAuthority(); 7532 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7533 if (pi == null) { 7534 Slog.w(TAG, "No content provider found for permission revoke: " 7535 + uri.toSafeString()); 7536 return; 7537 } 7538 7539 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7540 } 7541 } 7542 7543 /** 7544 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7545 * given package. 7546 * 7547 * @param packageName Package name to match, or {@code null} to apply to all 7548 * packages. 7549 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7550 * to all users. 7551 * @param persistable If persistable grants should be removed. 7552 */ 7553 private void removeUriPermissionsForPackageLocked( 7554 String packageName, int userHandle, boolean persistable) { 7555 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7556 throw new IllegalArgumentException("Must narrow by either package or user"); 7557 } 7558 7559 boolean persistChanged = false; 7560 7561 int N = mGrantedUriPermissions.size(); 7562 for (int i = 0; i < N; i++) { 7563 final int targetUid = mGrantedUriPermissions.keyAt(i); 7564 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7565 7566 // Only inspect grants matching user 7567 if (userHandle == UserHandle.USER_ALL 7568 || userHandle == UserHandle.getUserId(targetUid)) { 7569 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7570 final UriPermission perm = it.next(); 7571 7572 // Only inspect grants matching package 7573 if (packageName == null || perm.sourcePkg.equals(packageName) 7574 || perm.targetPkg.equals(packageName)) { 7575 persistChanged |= perm.revokeModes(persistable 7576 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7577 7578 // Only remove when no modes remain; any persisted grants 7579 // will keep this alive. 7580 if (perm.modeFlags == 0) { 7581 it.remove(); 7582 } 7583 } 7584 } 7585 7586 if (perms.isEmpty()) { 7587 mGrantedUriPermissions.remove(targetUid); 7588 N--; 7589 i--; 7590 } 7591 } 7592 } 7593 7594 if (persistChanged) { 7595 schedulePersistUriGrants(); 7596 } 7597 } 7598 7599 @Override 7600 public IBinder newUriPermissionOwner(String name) { 7601 enforceNotIsolatedCaller("newUriPermissionOwner"); 7602 synchronized(this) { 7603 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7604 return owner.getExternalTokenLocked(); 7605 } 7606 } 7607 7608 /** 7609 * @param uri This uri must NOT contain an embedded userId. 7610 * @param sourceUserId The userId in which the uri is to be resolved. 7611 * @param targetUserId The userId of the app that receives the grant. 7612 */ 7613 @Override 7614 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7615 final int modeFlags, int sourceUserId, int targetUserId) { 7616 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7617 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7618 synchronized(this) { 7619 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7620 if (owner == null) { 7621 throw new IllegalArgumentException("Unknown owner: " + token); 7622 } 7623 if (fromUid != Binder.getCallingUid()) { 7624 if (Binder.getCallingUid() != Process.myUid()) { 7625 // Only system code can grant URI permissions on behalf 7626 // of other users. 7627 throw new SecurityException("nice try"); 7628 } 7629 } 7630 if (targetPkg == null) { 7631 throw new IllegalArgumentException("null target"); 7632 } 7633 if (uri == null) { 7634 throw new IllegalArgumentException("null uri"); 7635 } 7636 7637 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7638 modeFlags, owner, targetUserId); 7639 } 7640 } 7641 7642 /** 7643 * @param uri This uri must NOT contain an embedded userId. 7644 * @param userId The userId in which the uri is to be resolved. 7645 */ 7646 @Override 7647 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7648 synchronized(this) { 7649 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7650 if (owner == null) { 7651 throw new IllegalArgumentException("Unknown owner: " + token); 7652 } 7653 7654 if (uri == null) { 7655 owner.removeUriPermissionsLocked(mode); 7656 } else { 7657 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7658 } 7659 } 7660 } 7661 7662 private void schedulePersistUriGrants() { 7663 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7664 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7665 10 * DateUtils.SECOND_IN_MILLIS); 7666 } 7667 } 7668 7669 private void writeGrantedUriPermissions() { 7670 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7671 7672 // Snapshot permissions so we can persist without lock 7673 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7674 synchronized (this) { 7675 final int size = mGrantedUriPermissions.size(); 7676 for (int i = 0; i < size; i++) { 7677 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7678 for (UriPermission perm : perms.values()) { 7679 if (perm.persistedModeFlags != 0) { 7680 persist.add(perm.snapshot()); 7681 } 7682 } 7683 } 7684 } 7685 7686 FileOutputStream fos = null; 7687 try { 7688 fos = mGrantFile.startWrite(); 7689 7690 XmlSerializer out = new FastXmlSerializer(); 7691 out.setOutput(fos, "utf-8"); 7692 out.startDocument(null, true); 7693 out.startTag(null, TAG_URI_GRANTS); 7694 for (UriPermission.Snapshot perm : persist) { 7695 out.startTag(null, TAG_URI_GRANT); 7696 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7697 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7698 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7699 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7700 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7701 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7702 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7703 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7704 out.endTag(null, TAG_URI_GRANT); 7705 } 7706 out.endTag(null, TAG_URI_GRANTS); 7707 out.endDocument(); 7708 7709 mGrantFile.finishWrite(fos); 7710 } catch (IOException e) { 7711 if (fos != null) { 7712 mGrantFile.failWrite(fos); 7713 } 7714 } 7715 } 7716 7717 private void readGrantedUriPermissionsLocked() { 7718 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7719 7720 final long now = System.currentTimeMillis(); 7721 7722 FileInputStream fis = null; 7723 try { 7724 fis = mGrantFile.openRead(); 7725 final XmlPullParser in = Xml.newPullParser(); 7726 in.setInput(fis, null); 7727 7728 int type; 7729 while ((type = in.next()) != END_DOCUMENT) { 7730 final String tag = in.getName(); 7731 if (type == START_TAG) { 7732 if (TAG_URI_GRANT.equals(tag)) { 7733 final int sourceUserId; 7734 final int targetUserId; 7735 final int userHandle = readIntAttribute(in, 7736 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7737 if (userHandle != UserHandle.USER_NULL) { 7738 // For backwards compatibility. 7739 sourceUserId = userHandle; 7740 targetUserId = userHandle; 7741 } else { 7742 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7743 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7744 } 7745 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7746 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7747 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7748 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7749 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7750 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7751 7752 // Sanity check that provider still belongs to source package 7753 final ProviderInfo pi = getProviderInfoLocked( 7754 uri.getAuthority(), sourceUserId); 7755 if (pi != null && sourcePkg.equals(pi.packageName)) { 7756 int targetUid = -1; 7757 try { 7758 targetUid = AppGlobals.getPackageManager() 7759 .getPackageUid(targetPkg, targetUserId); 7760 } catch (RemoteException e) { 7761 } 7762 if (targetUid != -1) { 7763 final UriPermission perm = findOrCreateUriPermissionLocked( 7764 sourcePkg, targetPkg, targetUid, 7765 new GrantUri(sourceUserId, uri, prefix)); 7766 perm.initPersistedModes(modeFlags, createdTime); 7767 } 7768 } else { 7769 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7770 + " but instead found " + pi); 7771 } 7772 } 7773 } 7774 } 7775 } catch (FileNotFoundException e) { 7776 // Missing grants is okay 7777 } catch (IOException e) { 7778 Slog.wtf(TAG, "Failed reading Uri grants", e); 7779 } catch (XmlPullParserException e) { 7780 Slog.wtf(TAG, "Failed reading Uri grants", e); 7781 } finally { 7782 IoUtils.closeQuietly(fis); 7783 } 7784 } 7785 7786 /** 7787 * @param uri This uri must NOT contain an embedded userId. 7788 * @param userId The userId in which the uri is to be resolved. 7789 */ 7790 @Override 7791 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7792 enforceNotIsolatedCaller("takePersistableUriPermission"); 7793 7794 Preconditions.checkFlagsArgument(modeFlags, 7795 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7796 7797 synchronized (this) { 7798 final int callingUid = Binder.getCallingUid(); 7799 boolean persistChanged = false; 7800 GrantUri grantUri = new GrantUri(userId, uri, false); 7801 7802 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7803 new GrantUri(userId, uri, false)); 7804 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7805 new GrantUri(userId, uri, true)); 7806 7807 final boolean exactValid = (exactPerm != null) 7808 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7809 final boolean prefixValid = (prefixPerm != null) 7810 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7811 7812 if (!(exactValid || prefixValid)) { 7813 throw new SecurityException("No persistable permission grants found for UID " 7814 + callingUid + " and Uri " + grantUri.toSafeString()); 7815 } 7816 7817 if (exactValid) { 7818 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7819 } 7820 if (prefixValid) { 7821 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7822 } 7823 7824 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7825 7826 if (persistChanged) { 7827 schedulePersistUriGrants(); 7828 } 7829 } 7830 } 7831 7832 /** 7833 * @param uri This uri must NOT contain an embedded userId. 7834 * @param userId The userId in which the uri is to be resolved. 7835 */ 7836 @Override 7837 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7838 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7839 7840 Preconditions.checkFlagsArgument(modeFlags, 7841 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7842 7843 synchronized (this) { 7844 final int callingUid = Binder.getCallingUid(); 7845 boolean persistChanged = false; 7846 7847 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7848 new GrantUri(userId, uri, false)); 7849 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7850 new GrantUri(userId, uri, true)); 7851 if (exactPerm == null && prefixPerm == null) { 7852 throw new SecurityException("No permission grants found for UID " + callingUid 7853 + " and Uri " + uri.toSafeString()); 7854 } 7855 7856 if (exactPerm != null) { 7857 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7858 removeUriPermissionIfNeededLocked(exactPerm); 7859 } 7860 if (prefixPerm != null) { 7861 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7862 removeUriPermissionIfNeededLocked(prefixPerm); 7863 } 7864 7865 if (persistChanged) { 7866 schedulePersistUriGrants(); 7867 } 7868 } 7869 } 7870 7871 /** 7872 * Prune any older {@link UriPermission} for the given UID until outstanding 7873 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7874 * 7875 * @return if any mutations occured that require persisting. 7876 */ 7877 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7878 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7879 if (perms == null) return false; 7880 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7881 7882 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7883 for (UriPermission perm : perms.values()) { 7884 if (perm.persistedModeFlags != 0) { 7885 persisted.add(perm); 7886 } 7887 } 7888 7889 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7890 if (trimCount <= 0) return false; 7891 7892 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7893 for (int i = 0; i < trimCount; i++) { 7894 final UriPermission perm = persisted.get(i); 7895 7896 if (DEBUG_URI_PERMISSION) { 7897 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7898 } 7899 7900 perm.releasePersistableModes(~0); 7901 removeUriPermissionIfNeededLocked(perm); 7902 } 7903 7904 return true; 7905 } 7906 7907 @Override 7908 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7909 String packageName, boolean incoming) { 7910 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7911 Preconditions.checkNotNull(packageName, "packageName"); 7912 7913 final int callingUid = Binder.getCallingUid(); 7914 final IPackageManager pm = AppGlobals.getPackageManager(); 7915 try { 7916 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7917 if (packageUid != callingUid) { 7918 throw new SecurityException( 7919 "Package " + packageName + " does not belong to calling UID " + callingUid); 7920 } 7921 } catch (RemoteException e) { 7922 throw new SecurityException("Failed to verify package name ownership"); 7923 } 7924 7925 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7926 synchronized (this) { 7927 if (incoming) { 7928 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7929 callingUid); 7930 if (perms == null) { 7931 Slog.w(TAG, "No permission grants found for " + packageName); 7932 } else { 7933 for (UriPermission perm : perms.values()) { 7934 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7935 result.add(perm.buildPersistedPublicApiObject()); 7936 } 7937 } 7938 } 7939 } else { 7940 final int size = mGrantedUriPermissions.size(); 7941 for (int i = 0; i < size; i++) { 7942 final ArrayMap<GrantUri, UriPermission> perms = 7943 mGrantedUriPermissions.valueAt(i); 7944 for (UriPermission perm : perms.values()) { 7945 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7946 result.add(perm.buildPersistedPublicApiObject()); 7947 } 7948 } 7949 } 7950 } 7951 } 7952 return new ParceledListSlice<android.content.UriPermission>(result); 7953 } 7954 7955 @Override 7956 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7957 synchronized (this) { 7958 ProcessRecord app = 7959 who != null ? getRecordForAppLocked(who) : null; 7960 if (app == null) return; 7961 7962 Message msg = Message.obtain(); 7963 msg.what = WAIT_FOR_DEBUGGER_MSG; 7964 msg.obj = app; 7965 msg.arg1 = waiting ? 1 : 0; 7966 mHandler.sendMessage(msg); 7967 } 7968 } 7969 7970 @Override 7971 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7972 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7973 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7974 outInfo.availMem = Process.getFreeMemory(); 7975 outInfo.totalMem = Process.getTotalMemory(); 7976 outInfo.threshold = homeAppMem; 7977 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7978 outInfo.hiddenAppThreshold = cachedAppMem; 7979 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7980 ProcessList.SERVICE_ADJ); 7981 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7982 ProcessList.VISIBLE_APP_ADJ); 7983 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7984 ProcessList.FOREGROUND_APP_ADJ); 7985 } 7986 7987 // ========================================================= 7988 // TASK MANAGEMENT 7989 // ========================================================= 7990 7991 @Override 7992 public List<IAppTask> getAppTasks(String callingPackage) { 7993 int callingUid = Binder.getCallingUid(); 7994 long ident = Binder.clearCallingIdentity(); 7995 7996 synchronized(this) { 7997 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7998 try { 7999 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8000 8001 final int N = mRecentTasks.size(); 8002 for (int i = 0; i < N; i++) { 8003 TaskRecord tr = mRecentTasks.get(i); 8004 // Skip tasks that do not match the caller. We don't need to verify 8005 // callingPackage, because we are also limiting to callingUid and know 8006 // that will limit to the correct security sandbox. 8007 if (tr.effectiveUid != callingUid) { 8008 continue; 8009 } 8010 Intent intent = tr.getBaseIntent(); 8011 if (intent == null || 8012 !callingPackage.equals(intent.getComponent().getPackageName())) { 8013 continue; 8014 } 8015 ActivityManager.RecentTaskInfo taskInfo = 8016 createRecentTaskInfoFromTaskRecord(tr); 8017 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8018 list.add(taskImpl); 8019 } 8020 } finally { 8021 Binder.restoreCallingIdentity(ident); 8022 } 8023 return list; 8024 } 8025 } 8026 8027 @Override 8028 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8029 final int callingUid = Binder.getCallingUid(); 8030 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8031 8032 synchronized(this) { 8033 if (localLOGV) Slog.v( 8034 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8035 8036 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8037 callingUid); 8038 8039 // TODO: Improve with MRU list from all ActivityStacks. 8040 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8041 } 8042 8043 return list; 8044 } 8045 8046 /** 8047 * Creates a new RecentTaskInfo from a TaskRecord. 8048 */ 8049 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8050 // Update the task description to reflect any changes in the task stack 8051 tr.updateTaskDescription(); 8052 8053 // Compose the recent task info 8054 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8055 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8056 rti.persistentId = tr.taskId; 8057 rti.baseIntent = new Intent(tr.getBaseIntent()); 8058 rti.origActivity = tr.origActivity; 8059 rti.description = tr.lastDescription; 8060 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8061 rti.userId = tr.userId; 8062 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8063 rti.firstActiveTime = tr.firstActiveTime; 8064 rti.lastActiveTime = tr.lastActiveTime; 8065 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8066 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8067 return rti; 8068 } 8069 8070 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8071 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8072 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8073 if (!allowed) { 8074 if (checkPermission(android.Manifest.permission.GET_TASKS, 8075 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8076 // Temporary compatibility: some existing apps on the system image may 8077 // still be requesting the old permission and not switched to the new 8078 // one; if so, we'll still allow them full access. This means we need 8079 // to see if they are holding the old permission and are a system app. 8080 try { 8081 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8082 allowed = true; 8083 Slog.w(TAG, caller + ": caller " + callingUid 8084 + " is using old GET_TASKS but privileged; allowing"); 8085 } 8086 } catch (RemoteException e) { 8087 } 8088 } 8089 } 8090 if (!allowed) { 8091 Slog.w(TAG, caller + ": caller " + callingUid 8092 + " does not hold GET_TASKS; limiting output"); 8093 } 8094 return allowed; 8095 } 8096 8097 @Override 8098 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8099 final int callingUid = Binder.getCallingUid(); 8100 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8101 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8102 8103 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8104 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8105 synchronized (this) { 8106 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8107 callingUid); 8108 final boolean detailed = checkCallingPermission( 8109 android.Manifest.permission.GET_DETAILED_TASKS) 8110 == PackageManager.PERMISSION_GRANTED; 8111 8112 final int N = mRecentTasks.size(); 8113 ArrayList<ActivityManager.RecentTaskInfo> res 8114 = new ArrayList<ActivityManager.RecentTaskInfo>( 8115 maxNum < N ? maxNum : N); 8116 8117 final Set<Integer> includedUsers; 8118 if (includeProfiles) { 8119 includedUsers = getProfileIdsLocked(userId); 8120 } else { 8121 includedUsers = new HashSet<Integer>(); 8122 } 8123 includedUsers.add(Integer.valueOf(userId)); 8124 8125 for (int i=0; i<N && maxNum > 0; i++) { 8126 TaskRecord tr = mRecentTasks.get(i); 8127 // Only add calling user or related users recent tasks 8128 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8129 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8130 continue; 8131 } 8132 8133 // Return the entry if desired by the caller. We always return 8134 // the first entry, because callers always expect this to be the 8135 // foreground app. We may filter others if the caller has 8136 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8137 // we should exclude the entry. 8138 8139 if (i == 0 8140 || withExcluded 8141 || (tr.intent == null) 8142 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8143 == 0)) { 8144 if (!allowed) { 8145 // If the caller doesn't have the GET_TASKS permission, then only 8146 // allow them to see a small subset of tasks -- their own and home. 8147 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8148 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8149 continue; 8150 } 8151 } 8152 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8153 if (tr.stack != null && tr.stack.isHomeStack()) { 8154 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8155 continue; 8156 } 8157 } 8158 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8159 // Don't include auto remove tasks that are finished or finishing. 8160 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8161 + tr); 8162 continue; 8163 } 8164 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8165 && !tr.isAvailable) { 8166 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8167 continue; 8168 } 8169 8170 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8171 if (!detailed) { 8172 rti.baseIntent.replaceExtras((Bundle)null); 8173 } 8174 8175 res.add(rti); 8176 maxNum--; 8177 } 8178 } 8179 return res; 8180 } 8181 } 8182 8183 private TaskRecord taskForIdLocked(int id) { 8184 final TaskRecord task = recentTaskForIdLocked(id); 8185 if (task != null) { 8186 return task; 8187 } 8188 8189 // Don't give up. Sometimes it just hasn't made it to recents yet. 8190 return mStackSupervisor.anyTaskForIdLocked(id); 8191 } 8192 8193 private TaskRecord recentTaskForIdLocked(int id) { 8194 final int N = mRecentTasks.size(); 8195 for (int i=0; i<N; i++) { 8196 TaskRecord tr = mRecentTasks.get(i); 8197 if (tr.taskId == id) { 8198 return tr; 8199 } 8200 } 8201 return null; 8202 } 8203 8204 @Override 8205 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8206 synchronized (this) { 8207 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8208 "getTaskThumbnail()"); 8209 TaskRecord tr = recentTaskForIdLocked(id); 8210 if (tr != null) { 8211 return tr.getTaskThumbnailLocked(); 8212 } 8213 } 8214 return null; 8215 } 8216 8217 @Override 8218 public int addAppTask(IBinder activityToken, Intent intent, 8219 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8220 final int callingUid = Binder.getCallingUid(); 8221 final long callingIdent = Binder.clearCallingIdentity(); 8222 8223 try { 8224 synchronized (this) { 8225 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8226 if (r == null) { 8227 throw new IllegalArgumentException("Activity does not exist; token=" 8228 + activityToken); 8229 } 8230 ComponentName comp = intent.getComponent(); 8231 if (comp == null) { 8232 throw new IllegalArgumentException("Intent " + intent 8233 + " must specify explicit component"); 8234 } 8235 if (thumbnail.getWidth() != mThumbnailWidth 8236 || thumbnail.getHeight() != mThumbnailHeight) { 8237 throw new IllegalArgumentException("Bad thumbnail size: got " 8238 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8239 + mThumbnailWidth + "x" + mThumbnailHeight); 8240 } 8241 if (intent.getSelector() != null) { 8242 intent.setSelector(null); 8243 } 8244 if (intent.getSourceBounds() != null) { 8245 intent.setSourceBounds(null); 8246 } 8247 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8248 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8249 // The caller has added this as an auto-remove task... that makes no 8250 // sense, so turn off auto-remove. 8251 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8252 } 8253 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8254 // Must be a new task. 8255 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8256 } 8257 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8258 mLastAddedTaskActivity = null; 8259 } 8260 ActivityInfo ainfo = mLastAddedTaskActivity; 8261 if (ainfo == null) { 8262 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8263 comp, 0, UserHandle.getUserId(callingUid)); 8264 if (ainfo.applicationInfo.uid != callingUid) { 8265 throw new SecurityException( 8266 "Can't add task for another application: target uid=" 8267 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8268 } 8269 } 8270 8271 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8272 intent, description); 8273 8274 int trimIdx = trimRecentsForTaskLocked(task, false); 8275 if (trimIdx >= 0) { 8276 // If this would have caused a trim, then we'll abort because that 8277 // means it would be added at the end of the list but then just removed. 8278 return INVALID_TASK_ID; 8279 } 8280 8281 final int N = mRecentTasks.size(); 8282 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8283 final TaskRecord tr = mRecentTasks.remove(N - 1); 8284 tr.removedFromRecents(); 8285 } 8286 8287 task.inRecents = true; 8288 mRecentTasks.add(task); 8289 r.task.stack.addTask(task, false, false); 8290 8291 task.setLastThumbnail(thumbnail); 8292 task.freeLastThumbnail(); 8293 8294 return task.taskId; 8295 } 8296 } finally { 8297 Binder.restoreCallingIdentity(callingIdent); 8298 } 8299 } 8300 8301 @Override 8302 public Point getAppTaskThumbnailSize() { 8303 synchronized (this) { 8304 return new Point(mThumbnailWidth, mThumbnailHeight); 8305 } 8306 } 8307 8308 @Override 8309 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8310 synchronized (this) { 8311 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8312 if (r != null) { 8313 r.setTaskDescription(td); 8314 r.task.updateTaskDescription(); 8315 } 8316 } 8317 } 8318 8319 @Override 8320 public Bitmap getTaskDescriptionIcon(String filename) { 8321 if (!FileUtils.isValidExtFilename(filename) 8322 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8323 throw new IllegalArgumentException("Bad filename: " + filename); 8324 } 8325 return mTaskPersister.getTaskDescriptionIcon(filename); 8326 } 8327 8328 @Override 8329 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8330 throws RemoteException { 8331 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8332 opts.getCustomInPlaceResId() == 0) { 8333 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8334 "with valid animation"); 8335 } 8336 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8337 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8338 opts.getCustomInPlaceResId()); 8339 mWindowManager.executeAppTransition(); 8340 } 8341 8342 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8343 mRecentTasks.remove(tr); 8344 tr.removedFromRecents(); 8345 ComponentName component = tr.getBaseIntent().getComponent(); 8346 if (component == null) { 8347 Slog.w(TAG, "No component for base intent of task: " + tr); 8348 return; 8349 } 8350 8351 if (!killProcess) { 8352 return; 8353 } 8354 8355 // Determine if the process(es) for this task should be killed. 8356 final String pkg = component.getPackageName(); 8357 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8358 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8359 for (int i = 0; i < pmap.size(); i++) { 8360 8361 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8362 for (int j = 0; j < uids.size(); j++) { 8363 ProcessRecord proc = uids.valueAt(j); 8364 if (proc.userId != tr.userId) { 8365 // Don't kill process for a different user. 8366 continue; 8367 } 8368 if (proc == mHomeProcess) { 8369 // Don't kill the home process along with tasks from the same package. 8370 continue; 8371 } 8372 if (!proc.pkgList.containsKey(pkg)) { 8373 // Don't kill process that is not associated with this task. 8374 continue; 8375 } 8376 8377 for (int k = 0; k < proc.activities.size(); k++) { 8378 TaskRecord otherTask = proc.activities.get(k).task; 8379 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8380 // Don't kill process(es) that has an activity in a different task that is 8381 // also in recents. 8382 return; 8383 } 8384 } 8385 8386 // Add process to kill list. 8387 procsToKill.add(proc); 8388 } 8389 } 8390 8391 // Find any running services associated with this app and stop if needed. 8392 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8393 8394 // Kill the running processes. 8395 for (int i = 0; i < procsToKill.size(); i++) { 8396 ProcessRecord pr = procsToKill.get(i); 8397 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8398 pr.kill("remove task", true); 8399 } else { 8400 pr.waitingToKill = "remove task"; 8401 } 8402 } 8403 } 8404 8405 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8406 // Remove all tasks with activities in the specified package from the list of recent tasks 8407 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8408 TaskRecord tr = mRecentTasks.get(i); 8409 if (tr.userId != userId) continue; 8410 8411 ComponentName cn = tr.intent.getComponent(); 8412 if (cn != null && cn.getPackageName().equals(packageName)) { 8413 // If the package name matches, remove the task. 8414 removeTaskByIdLocked(tr.taskId, true); 8415 } 8416 } 8417 } 8418 8419 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8420 final IPackageManager pm = AppGlobals.getPackageManager(); 8421 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8422 8423 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8424 TaskRecord tr = mRecentTasks.get(i); 8425 if (tr.userId != userId) continue; 8426 8427 ComponentName cn = tr.intent.getComponent(); 8428 if (cn != null && cn.getPackageName().equals(packageName)) { 8429 // Skip if component still exists in the package. 8430 if (componentsKnownToExist.contains(cn)) continue; 8431 8432 try { 8433 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8434 if (info != null) { 8435 componentsKnownToExist.add(cn); 8436 } else { 8437 removeTaskByIdLocked(tr.taskId, false); 8438 } 8439 } catch (RemoteException e) { 8440 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8441 } 8442 } 8443 } 8444 } 8445 8446 /** 8447 * Removes the task with the specified task id. 8448 * 8449 * @param taskId Identifier of the task to be removed. 8450 * @param killProcess Kill any process associated with the task if possible. 8451 * @return Returns true if the given task was found and removed. 8452 */ 8453 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8454 TaskRecord tr = taskForIdLocked(taskId); 8455 if (tr != null) { 8456 tr.removeTaskActivitiesLocked(); 8457 cleanUpRemovedTaskLocked(tr, killProcess); 8458 if (tr.isPersistable) { 8459 notifyTaskPersisterLocked(null, true); 8460 } 8461 return true; 8462 } 8463 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8464 return false; 8465 } 8466 8467 @Override 8468 public boolean removeTask(int taskId) { 8469 synchronized (this) { 8470 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8471 "removeTask()"); 8472 long ident = Binder.clearCallingIdentity(); 8473 try { 8474 return removeTaskByIdLocked(taskId, true); 8475 } finally { 8476 Binder.restoreCallingIdentity(ident); 8477 } 8478 } 8479 } 8480 8481 /** 8482 * TODO: Add mController hook 8483 */ 8484 @Override 8485 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8486 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8487 "moveTaskToFront()"); 8488 8489 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8490 synchronized(this) { 8491 moveTaskToFrontLocked(taskId, flags, options); 8492 } 8493 } 8494 8495 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8496 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8497 Binder.getCallingUid(), -1, -1, "Task to front")) { 8498 ActivityOptions.abort(options); 8499 return; 8500 } 8501 final long origId = Binder.clearCallingIdentity(); 8502 try { 8503 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8504 if (task == null) { 8505 Slog.d(TAG, "Could not find task for id: "+ taskId); 8506 return; 8507 } 8508 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8509 mStackSupervisor.showLockTaskToast(); 8510 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8511 return; 8512 } 8513 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8514 if (prev != null && prev.isRecentsActivity()) { 8515 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8516 } 8517 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8518 } finally { 8519 Binder.restoreCallingIdentity(origId); 8520 } 8521 ActivityOptions.abort(options); 8522 } 8523 8524 @Override 8525 public void moveTaskToBack(int taskId) { 8526 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8527 "moveTaskToBack()"); 8528 8529 synchronized(this) { 8530 TaskRecord tr = taskForIdLocked(taskId); 8531 if (tr != null) { 8532 if (tr == mStackSupervisor.mLockTaskModeTask) { 8533 mStackSupervisor.showLockTaskToast(); 8534 return; 8535 } 8536 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8537 ActivityStack stack = tr.stack; 8538 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8539 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8540 Binder.getCallingUid(), -1, -1, "Task to back")) { 8541 return; 8542 } 8543 } 8544 final long origId = Binder.clearCallingIdentity(); 8545 try { 8546 stack.moveTaskToBackLocked(taskId, null); 8547 } finally { 8548 Binder.restoreCallingIdentity(origId); 8549 } 8550 } 8551 } 8552 } 8553 8554 /** 8555 * Moves an activity, and all of the other activities within the same task, to the bottom 8556 * of the history stack. The activity's order within the task is unchanged. 8557 * 8558 * @param token A reference to the activity we wish to move 8559 * @param nonRoot If false then this only works if the activity is the root 8560 * of a task; if true it will work for any activity in a task. 8561 * @return Returns true if the move completed, false if not. 8562 */ 8563 @Override 8564 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8565 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8566 synchronized(this) { 8567 final long origId = Binder.clearCallingIdentity(); 8568 try { 8569 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8570 if (taskId >= 0) { 8571 if ((mStackSupervisor.mLockTaskModeTask != null) 8572 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8573 mStackSupervisor.showLockTaskToast(); 8574 return false; 8575 } 8576 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8577 } 8578 } finally { 8579 Binder.restoreCallingIdentity(origId); 8580 } 8581 } 8582 return false; 8583 } 8584 8585 @Override 8586 public void moveTaskBackwards(int task) { 8587 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8588 "moveTaskBackwards()"); 8589 8590 synchronized(this) { 8591 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8592 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8593 return; 8594 } 8595 final long origId = Binder.clearCallingIdentity(); 8596 moveTaskBackwardsLocked(task); 8597 Binder.restoreCallingIdentity(origId); 8598 } 8599 } 8600 8601 private final void moveTaskBackwardsLocked(int task) { 8602 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8603 } 8604 8605 @Override 8606 public IBinder getHomeActivityToken() throws RemoteException { 8607 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8608 "getHomeActivityToken()"); 8609 synchronized (this) { 8610 return mStackSupervisor.getHomeActivityToken(); 8611 } 8612 } 8613 8614 @Override 8615 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8616 IActivityContainerCallback callback) throws RemoteException { 8617 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8618 "createActivityContainer()"); 8619 synchronized (this) { 8620 if (parentActivityToken == null) { 8621 throw new IllegalArgumentException("parent token must not be null"); 8622 } 8623 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8624 if (r == null) { 8625 return null; 8626 } 8627 if (callback == null) { 8628 throw new IllegalArgumentException("callback must not be null"); 8629 } 8630 return mStackSupervisor.createActivityContainer(r, callback); 8631 } 8632 } 8633 8634 @Override 8635 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8636 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8637 "deleteActivityContainer()"); 8638 synchronized (this) { 8639 mStackSupervisor.deleteActivityContainer(container); 8640 } 8641 } 8642 8643 @Override 8644 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8645 throws RemoteException { 8646 synchronized (this) { 8647 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8648 if (stack != null) { 8649 return stack.mActivityContainer; 8650 } 8651 return null; 8652 } 8653 } 8654 8655 @Override 8656 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8657 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8658 "moveTaskToStack()"); 8659 if (stackId == HOME_STACK_ID) { 8660 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8661 new RuntimeException("here").fillInStackTrace()); 8662 } 8663 synchronized (this) { 8664 long ident = Binder.clearCallingIdentity(); 8665 try { 8666 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8667 + stackId + " toTop=" + toTop); 8668 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8669 } finally { 8670 Binder.restoreCallingIdentity(ident); 8671 } 8672 } 8673 } 8674 8675 @Override 8676 public void resizeStack(int stackBoxId, Rect bounds) { 8677 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8678 "resizeStackBox()"); 8679 long ident = Binder.clearCallingIdentity(); 8680 try { 8681 mWindowManager.resizeStack(stackBoxId, bounds); 8682 } finally { 8683 Binder.restoreCallingIdentity(ident); 8684 } 8685 } 8686 8687 @Override 8688 public List<StackInfo> getAllStackInfos() { 8689 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8690 "getAllStackInfos()"); 8691 long ident = Binder.clearCallingIdentity(); 8692 try { 8693 synchronized (this) { 8694 return mStackSupervisor.getAllStackInfosLocked(); 8695 } 8696 } finally { 8697 Binder.restoreCallingIdentity(ident); 8698 } 8699 } 8700 8701 @Override 8702 public StackInfo getStackInfo(int stackId) { 8703 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8704 "getStackInfo()"); 8705 long ident = Binder.clearCallingIdentity(); 8706 try { 8707 synchronized (this) { 8708 return mStackSupervisor.getStackInfoLocked(stackId); 8709 } 8710 } finally { 8711 Binder.restoreCallingIdentity(ident); 8712 } 8713 } 8714 8715 @Override 8716 public boolean isInHomeStack(int taskId) { 8717 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8718 "getStackInfo()"); 8719 long ident = Binder.clearCallingIdentity(); 8720 try { 8721 synchronized (this) { 8722 TaskRecord tr = taskForIdLocked(taskId); 8723 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8724 } 8725 } finally { 8726 Binder.restoreCallingIdentity(ident); 8727 } 8728 } 8729 8730 @Override 8731 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8732 synchronized(this) { 8733 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8734 } 8735 } 8736 8737 private boolean isLockTaskAuthorized(String pkg) { 8738 final DevicePolicyManager dpm = (DevicePolicyManager) 8739 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8740 try { 8741 int uid = mContext.getPackageManager().getPackageUid(pkg, 8742 Binder.getCallingUserHandle().getIdentifier()); 8743 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8744 } catch (NameNotFoundException e) { 8745 return false; 8746 } 8747 } 8748 8749 void startLockTaskMode(TaskRecord task) { 8750 final String pkg; 8751 synchronized (this) { 8752 pkg = task.intent.getComponent().getPackageName(); 8753 } 8754 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8755 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8756 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8757 StatusBarManagerInternal.class); 8758 if (statusBarManager != null) { 8759 statusBarManager.showScreenPinningRequest(); 8760 } 8761 return; 8762 } 8763 long ident = Binder.clearCallingIdentity(); 8764 try { 8765 synchronized (this) { 8766 // Since we lost lock on task, make sure it is still there. 8767 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8768 if (task != null) { 8769 if (!isSystemInitiated 8770 && ((mStackSupervisor.getFocusedStack() == null) 8771 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8772 throw new IllegalArgumentException("Invalid task, not in foreground"); 8773 } 8774 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8775 } 8776 } 8777 } finally { 8778 Binder.restoreCallingIdentity(ident); 8779 } 8780 } 8781 8782 @Override 8783 public void startLockTaskMode(int taskId) { 8784 final TaskRecord task; 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 if (task != null) { 8794 startLockTaskMode(task); 8795 } 8796 } 8797 8798 @Override 8799 public void startLockTaskMode(IBinder token) { 8800 final TaskRecord task; 8801 long ident = Binder.clearCallingIdentity(); 8802 try { 8803 synchronized (this) { 8804 final ActivityRecord r = ActivityRecord.forToken(token); 8805 if (r == null) { 8806 return; 8807 } 8808 task = r.task; 8809 } 8810 } finally { 8811 Binder.restoreCallingIdentity(ident); 8812 } 8813 if (task != null) { 8814 startLockTaskMode(task); 8815 } 8816 } 8817 8818 @Override 8819 public void startLockTaskModeOnCurrent() throws RemoteException { 8820 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8821 "startLockTaskModeOnCurrent"); 8822 long ident = Binder.clearCallingIdentity(); 8823 try { 8824 ActivityRecord r = null; 8825 synchronized (this) { 8826 r = mStackSupervisor.topRunningActivityLocked(); 8827 } 8828 startLockTaskMode(r.task); 8829 } finally { 8830 Binder.restoreCallingIdentity(ident); 8831 } 8832 } 8833 8834 @Override 8835 public void stopLockTaskMode() { 8836 // Verify that the user matches the package of the intent for the TaskRecord 8837 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8838 // and stopLockTaskMode. 8839 final int callingUid = Binder.getCallingUid(); 8840 if (callingUid != Process.SYSTEM_UID) { 8841 try { 8842 String pkg = 8843 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8844 int uid = mContext.getPackageManager().getPackageUid(pkg, 8845 Binder.getCallingUserHandle().getIdentifier()); 8846 if (uid != callingUid) { 8847 throw new SecurityException("Invalid uid, expected " + uid); 8848 } 8849 } catch (NameNotFoundException e) { 8850 Log.d(TAG, "stopLockTaskMode " + e); 8851 return; 8852 } 8853 } 8854 long ident = Binder.clearCallingIdentity(); 8855 try { 8856 Log.d(TAG, "stopLockTaskMode"); 8857 // Stop lock task 8858 synchronized (this) { 8859 mStackSupervisor.setLockTaskModeLocked(null, false); 8860 } 8861 } finally { 8862 Binder.restoreCallingIdentity(ident); 8863 } 8864 } 8865 8866 @Override 8867 public void stopLockTaskModeOnCurrent() throws RemoteException { 8868 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8869 "stopLockTaskModeOnCurrent"); 8870 long ident = Binder.clearCallingIdentity(); 8871 try { 8872 stopLockTaskMode(); 8873 } finally { 8874 Binder.restoreCallingIdentity(ident); 8875 } 8876 } 8877 8878 @Override 8879 public boolean isInLockTaskMode() { 8880 synchronized (this) { 8881 return mStackSupervisor.isInLockTaskMode(); 8882 } 8883 } 8884 8885 // ========================================================= 8886 // CONTENT PROVIDERS 8887 // ========================================================= 8888 8889 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8890 List<ProviderInfo> providers = null; 8891 try { 8892 providers = AppGlobals.getPackageManager(). 8893 queryContentProviders(app.processName, app.uid, 8894 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8895 } catch (RemoteException ex) { 8896 } 8897 if (DEBUG_MU) 8898 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8899 int userId = app.userId; 8900 if (providers != null) { 8901 int N = providers.size(); 8902 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8903 for (int i=0; i<N; i++) { 8904 ProviderInfo cpi = 8905 (ProviderInfo)providers.get(i); 8906 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8907 cpi.name, cpi.flags); 8908 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8909 // This is a singleton provider, but a user besides the 8910 // default user is asking to initialize a process it runs 8911 // in... well, no, it doesn't actually run in this process, 8912 // it runs in the process of the default user. Get rid of it. 8913 providers.remove(i); 8914 N--; 8915 i--; 8916 continue; 8917 } 8918 8919 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8920 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8921 if (cpr == null) { 8922 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8923 mProviderMap.putProviderByClass(comp, cpr); 8924 } 8925 if (DEBUG_MU) 8926 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8927 app.pubProviders.put(cpi.name, cpr); 8928 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8929 // Don't add this if it is a platform component that is marked 8930 // to run in multiple processes, because this is actually 8931 // part of the framework so doesn't make sense to track as a 8932 // separate apk in the process. 8933 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8934 mProcessStats); 8935 } 8936 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8937 } 8938 } 8939 return providers; 8940 } 8941 8942 /** 8943 * Check if {@link ProcessRecord} has a possible chance at accessing the 8944 * given {@link ProviderInfo}. Final permission checking is always done 8945 * in {@link ContentProvider}. 8946 */ 8947 private final String checkContentProviderPermissionLocked( 8948 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8949 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8950 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8951 boolean checkedGrants = false; 8952 if (checkUser) { 8953 // Looking for cross-user grants before enforcing the typical cross-users permissions 8954 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8955 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8956 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8957 return null; 8958 } 8959 checkedGrants = true; 8960 } 8961 userId = handleIncomingUser(callingPid, callingUid, userId, 8962 false, ALLOW_NON_FULL, 8963 "checkContentProviderPermissionLocked " + cpi.authority, null); 8964 if (userId != tmpTargetUserId) { 8965 // When we actually went to determine the final targer user ID, this ended 8966 // up different than our initial check for the authority. This is because 8967 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8968 // SELF. So we need to re-check the grants again. 8969 checkedGrants = false; 8970 } 8971 } 8972 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8973 cpi.applicationInfo.uid, cpi.exported) 8974 == PackageManager.PERMISSION_GRANTED) { 8975 return null; 8976 } 8977 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8978 cpi.applicationInfo.uid, cpi.exported) 8979 == PackageManager.PERMISSION_GRANTED) { 8980 return null; 8981 } 8982 8983 PathPermission[] pps = cpi.pathPermissions; 8984 if (pps != null) { 8985 int i = pps.length; 8986 while (i > 0) { 8987 i--; 8988 PathPermission pp = pps[i]; 8989 String pprperm = pp.getReadPermission(); 8990 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8991 cpi.applicationInfo.uid, cpi.exported) 8992 == PackageManager.PERMISSION_GRANTED) { 8993 return null; 8994 } 8995 String ppwperm = pp.getWritePermission(); 8996 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8997 cpi.applicationInfo.uid, cpi.exported) 8998 == PackageManager.PERMISSION_GRANTED) { 8999 return null; 9000 } 9001 } 9002 } 9003 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9004 return null; 9005 } 9006 9007 String msg; 9008 if (!cpi.exported) { 9009 msg = "Permission Denial: opening provider " + cpi.name 9010 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9011 + ", uid=" + callingUid + ") that is not exported from uid " 9012 + cpi.applicationInfo.uid; 9013 } else { 9014 msg = "Permission Denial: opening provider " + cpi.name 9015 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9016 + ", uid=" + callingUid + ") requires " 9017 + cpi.readPermission + " or " + cpi.writePermission; 9018 } 9019 Slog.w(TAG, msg); 9020 return msg; 9021 } 9022 9023 /** 9024 * Returns if the ContentProvider has granted a uri to callingUid 9025 */ 9026 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9027 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9028 if (perms != null) { 9029 for (int i=perms.size()-1; i>=0; i--) { 9030 GrantUri grantUri = perms.keyAt(i); 9031 if (grantUri.sourceUserId == userId || !checkUser) { 9032 if (matchesProvider(grantUri.uri, cpi)) { 9033 return true; 9034 } 9035 } 9036 } 9037 } 9038 return false; 9039 } 9040 9041 /** 9042 * Returns true if the uri authority is one of the authorities specified in the provider. 9043 */ 9044 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9045 String uriAuth = uri.getAuthority(); 9046 String cpiAuth = cpi.authority; 9047 if (cpiAuth.indexOf(';') == -1) { 9048 return cpiAuth.equals(uriAuth); 9049 } 9050 String[] cpiAuths = cpiAuth.split(";"); 9051 int length = cpiAuths.length; 9052 for (int i = 0; i < length; i++) { 9053 if (cpiAuths[i].equals(uriAuth)) return true; 9054 } 9055 return false; 9056 } 9057 9058 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9059 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9060 if (r != null) { 9061 for (int i=0; i<r.conProviders.size(); i++) { 9062 ContentProviderConnection conn = r.conProviders.get(i); 9063 if (conn.provider == cpr) { 9064 if (DEBUG_PROVIDER) Slog.v(TAG, 9065 "Adding provider requested by " 9066 + r.processName + " from process " 9067 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9068 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9069 if (stable) { 9070 conn.stableCount++; 9071 conn.numStableIncs++; 9072 } else { 9073 conn.unstableCount++; 9074 conn.numUnstableIncs++; 9075 } 9076 return conn; 9077 } 9078 } 9079 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9080 if (stable) { 9081 conn.stableCount = 1; 9082 conn.numStableIncs = 1; 9083 } else { 9084 conn.unstableCount = 1; 9085 conn.numUnstableIncs = 1; 9086 } 9087 cpr.connections.add(conn); 9088 r.conProviders.add(conn); 9089 return conn; 9090 } 9091 cpr.addExternalProcessHandleLocked(externalProcessToken); 9092 return null; 9093 } 9094 9095 boolean decProviderCountLocked(ContentProviderConnection conn, 9096 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9097 if (conn != null) { 9098 cpr = conn.provider; 9099 if (DEBUG_PROVIDER) Slog.v(TAG, 9100 "Removing provider requested by " 9101 + conn.client.processName + " from process " 9102 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9103 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9104 if (stable) { 9105 conn.stableCount--; 9106 } else { 9107 conn.unstableCount--; 9108 } 9109 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9110 cpr.connections.remove(conn); 9111 conn.client.conProviders.remove(conn); 9112 return true; 9113 } 9114 return false; 9115 } 9116 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9117 return false; 9118 } 9119 9120 private void checkTime(long startTime, String where) { 9121 long now = SystemClock.elapsedRealtime(); 9122 if ((now-startTime) > 1000) { 9123 // If we are taking more than a second, log about it. 9124 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9125 } 9126 } 9127 9128 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9129 String name, IBinder token, boolean stable, int userId) { 9130 ContentProviderRecord cpr; 9131 ContentProviderConnection conn = null; 9132 ProviderInfo cpi = null; 9133 9134 synchronized(this) { 9135 long startTime = SystemClock.elapsedRealtime(); 9136 9137 ProcessRecord r = null; 9138 if (caller != null) { 9139 r = getRecordForAppLocked(caller); 9140 if (r == null) { 9141 throw new SecurityException( 9142 "Unable to find app for caller " + caller 9143 + " (pid=" + Binder.getCallingPid() 9144 + ") when getting content provider " + name); 9145 } 9146 } 9147 9148 boolean checkCrossUser = true; 9149 9150 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9151 9152 // First check if this content provider has been published... 9153 cpr = mProviderMap.getProviderByName(name, userId); 9154 // If that didn't work, check if it exists for user 0 and then 9155 // verify that it's a singleton provider before using it. 9156 if (cpr == null && userId != UserHandle.USER_OWNER) { 9157 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9158 if (cpr != null) { 9159 cpi = cpr.info; 9160 if (isSingleton(cpi.processName, cpi.applicationInfo, 9161 cpi.name, cpi.flags) 9162 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9163 userId = UserHandle.USER_OWNER; 9164 checkCrossUser = false; 9165 } else { 9166 cpr = null; 9167 cpi = null; 9168 } 9169 } 9170 } 9171 9172 boolean providerRunning = cpr != null; 9173 if (providerRunning) { 9174 cpi = cpr.info; 9175 String msg; 9176 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9177 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9178 != null) { 9179 throw new SecurityException(msg); 9180 } 9181 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9182 9183 if (r != null && cpr.canRunHere(r)) { 9184 // This provider has been published or is in the process 9185 // of being published... but it is also allowed to run 9186 // in the caller's process, so don't make a connection 9187 // and just let the caller instantiate its own instance. 9188 ContentProviderHolder holder = cpr.newHolder(null); 9189 // don't give caller the provider object, it needs 9190 // to make its own. 9191 holder.provider = null; 9192 return holder; 9193 } 9194 9195 final long origId = Binder.clearCallingIdentity(); 9196 9197 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9198 9199 // In this case the provider instance already exists, so we can 9200 // return it right away. 9201 conn = incProviderCountLocked(r, cpr, token, stable); 9202 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9203 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9204 // If this is a perceptible app accessing the provider, 9205 // make sure to count it as being accessed and thus 9206 // back up on the LRU list. This is good because 9207 // content providers are often expensive to start. 9208 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9209 updateLruProcessLocked(cpr.proc, false, null); 9210 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9211 } 9212 } 9213 9214 if (cpr.proc != null) { 9215 if (false) { 9216 if (cpr.name.flattenToShortString().equals( 9217 "com.android.providers.calendar/.CalendarProvider2")) { 9218 Slog.v(TAG, "****************** KILLING " 9219 + cpr.name.flattenToShortString()); 9220 Process.killProcess(cpr.proc.pid); 9221 } 9222 } 9223 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9224 boolean success = updateOomAdjLocked(cpr.proc); 9225 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9226 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9227 // NOTE: there is still a race here where a signal could be 9228 // pending on the process even though we managed to update its 9229 // adj level. Not sure what to do about this, but at least 9230 // the race is now smaller. 9231 if (!success) { 9232 // Uh oh... it looks like the provider's process 9233 // has been killed on us. We need to wait for a new 9234 // process to be started, and make sure its death 9235 // doesn't kill our process. 9236 Slog.i(TAG, 9237 "Existing provider " + cpr.name.flattenToShortString() 9238 + " is crashing; detaching " + r); 9239 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9240 checkTime(startTime, "getContentProviderImpl: before appDied"); 9241 appDiedLocked(cpr.proc); 9242 checkTime(startTime, "getContentProviderImpl: after appDied"); 9243 if (!lastRef) { 9244 // This wasn't the last ref our process had on 9245 // the provider... we have now been killed, bail. 9246 return null; 9247 } 9248 providerRunning = false; 9249 conn = null; 9250 } 9251 } 9252 9253 Binder.restoreCallingIdentity(origId); 9254 } 9255 9256 boolean singleton; 9257 if (!providerRunning) { 9258 try { 9259 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9260 cpi = AppGlobals.getPackageManager(). 9261 resolveContentProvider(name, 9262 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9263 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9264 } catch (RemoteException ex) { 9265 } 9266 if (cpi == null) { 9267 return null; 9268 } 9269 // If the provider is a singleton AND 9270 // (it's a call within the same user || the provider is a 9271 // privileged app) 9272 // Then allow connecting to the singleton provider 9273 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9274 cpi.name, cpi.flags) 9275 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9276 if (singleton) { 9277 userId = UserHandle.USER_OWNER; 9278 } 9279 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9280 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9281 9282 String msg; 9283 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9284 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9285 != null) { 9286 throw new SecurityException(msg); 9287 } 9288 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9289 9290 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9291 && !cpi.processName.equals("system")) { 9292 // If this content provider does not run in the system 9293 // process, and the system is not yet ready to run other 9294 // processes, then fail fast instead of hanging. 9295 throw new IllegalArgumentException( 9296 "Attempt to launch content provider before system ready"); 9297 } 9298 9299 // Make sure that the user who owns this provider is running. If not, 9300 // we don't want to allow it to run. 9301 if (!isUserRunningLocked(userId, false)) { 9302 Slog.w(TAG, "Unable to launch app " 9303 + cpi.applicationInfo.packageName + "/" 9304 + cpi.applicationInfo.uid + " for provider " 9305 + name + ": user " + userId + " is stopped"); 9306 return null; 9307 } 9308 9309 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9310 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9311 cpr = mProviderMap.getProviderByClass(comp, userId); 9312 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9313 final boolean firstClass = cpr == null; 9314 if (firstClass) { 9315 final long ident = Binder.clearCallingIdentity(); 9316 try { 9317 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9318 ApplicationInfo ai = 9319 AppGlobals.getPackageManager(). 9320 getApplicationInfo( 9321 cpi.applicationInfo.packageName, 9322 STOCK_PM_FLAGS, userId); 9323 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9324 if (ai == null) { 9325 Slog.w(TAG, "No package info for content provider " 9326 + cpi.name); 9327 return null; 9328 } 9329 ai = getAppInfoForUser(ai, userId); 9330 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9331 } catch (RemoteException ex) { 9332 // pm is in same process, this will never happen. 9333 } finally { 9334 Binder.restoreCallingIdentity(ident); 9335 } 9336 } 9337 9338 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9339 9340 if (r != null && cpr.canRunHere(r)) { 9341 // If this is a multiprocess provider, then just return its 9342 // info and allow the caller to instantiate it. Only do 9343 // this if the provider is the same user as the caller's 9344 // process, or can run as root (so can be in any process). 9345 return cpr.newHolder(null); 9346 } 9347 9348 if (DEBUG_PROVIDER) { 9349 RuntimeException e = new RuntimeException("here"); 9350 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9351 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9352 } 9353 9354 // This is single process, and our app is now connecting to it. 9355 // See if we are already in the process of launching this 9356 // provider. 9357 final int N = mLaunchingProviders.size(); 9358 int i; 9359 for (i=0; i<N; i++) { 9360 if (mLaunchingProviders.get(i) == cpr) { 9361 break; 9362 } 9363 } 9364 9365 // If the provider is not already being launched, then get it 9366 // started. 9367 if (i >= N) { 9368 final long origId = Binder.clearCallingIdentity(); 9369 9370 try { 9371 // Content provider is now in use, its package can't be stopped. 9372 try { 9373 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9374 AppGlobals.getPackageManager().setPackageStoppedState( 9375 cpr.appInfo.packageName, false, userId); 9376 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9377 } catch (RemoteException e) { 9378 } catch (IllegalArgumentException e) { 9379 Slog.w(TAG, "Failed trying to unstop package " 9380 + cpr.appInfo.packageName + ": " + e); 9381 } 9382 9383 // Use existing process if already started 9384 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9385 ProcessRecord proc = getProcessRecordLocked( 9386 cpi.processName, cpr.appInfo.uid, false); 9387 if (proc != null && proc.thread != null) { 9388 if (DEBUG_PROVIDER) { 9389 Slog.d(TAG, "Installing in existing process " + proc); 9390 } 9391 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9392 proc.pubProviders.put(cpi.name, cpr); 9393 try { 9394 proc.thread.scheduleInstallProvider(cpi); 9395 } catch (RemoteException e) { 9396 } 9397 } else { 9398 checkTime(startTime, "getContentProviderImpl: before start process"); 9399 proc = startProcessLocked(cpi.processName, 9400 cpr.appInfo, false, 0, "content provider", 9401 new ComponentName(cpi.applicationInfo.packageName, 9402 cpi.name), false, false, false); 9403 checkTime(startTime, "getContentProviderImpl: after start process"); 9404 if (proc == null) { 9405 Slog.w(TAG, "Unable to launch app " 9406 + cpi.applicationInfo.packageName + "/" 9407 + cpi.applicationInfo.uid + " for provider " 9408 + name + ": process is bad"); 9409 return null; 9410 } 9411 } 9412 cpr.launchingApp = proc; 9413 mLaunchingProviders.add(cpr); 9414 } finally { 9415 Binder.restoreCallingIdentity(origId); 9416 } 9417 } 9418 9419 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9420 9421 // Make sure the provider is published (the same provider class 9422 // may be published under multiple names). 9423 if (firstClass) { 9424 mProviderMap.putProviderByClass(comp, cpr); 9425 } 9426 9427 mProviderMap.putProviderByName(name, cpr); 9428 conn = incProviderCountLocked(r, cpr, token, stable); 9429 if (conn != null) { 9430 conn.waiting = true; 9431 } 9432 } 9433 checkTime(startTime, "getContentProviderImpl: done!"); 9434 } 9435 9436 // Wait for the provider to be published... 9437 synchronized (cpr) { 9438 while (cpr.provider == null) { 9439 if (cpr.launchingApp == null) { 9440 Slog.w(TAG, "Unable to launch app " 9441 + cpi.applicationInfo.packageName + "/" 9442 + cpi.applicationInfo.uid + " for provider " 9443 + name + ": launching app became null"); 9444 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9445 UserHandle.getUserId(cpi.applicationInfo.uid), 9446 cpi.applicationInfo.packageName, 9447 cpi.applicationInfo.uid, name); 9448 return null; 9449 } 9450 try { 9451 if (DEBUG_MU) { 9452 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9453 + cpr.launchingApp); 9454 } 9455 if (conn != null) { 9456 conn.waiting = true; 9457 } 9458 cpr.wait(); 9459 } catch (InterruptedException ex) { 9460 } finally { 9461 if (conn != null) { 9462 conn.waiting = false; 9463 } 9464 } 9465 } 9466 } 9467 return cpr != null ? cpr.newHolder(conn) : null; 9468 } 9469 9470 @Override 9471 public final ContentProviderHolder getContentProvider( 9472 IApplicationThread caller, String name, int userId, boolean stable) { 9473 enforceNotIsolatedCaller("getContentProvider"); 9474 if (caller == null) { 9475 String msg = "null IApplicationThread when getting content provider " 9476 + name; 9477 Slog.w(TAG, msg); 9478 throw new SecurityException(msg); 9479 } 9480 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9481 // with cross-user grant. 9482 return getContentProviderImpl(caller, name, null, stable, userId); 9483 } 9484 9485 public ContentProviderHolder getContentProviderExternal( 9486 String name, int userId, IBinder token) { 9487 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9488 "Do not have permission in call getContentProviderExternal()"); 9489 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9490 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9491 return getContentProviderExternalUnchecked(name, token, userId); 9492 } 9493 9494 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9495 IBinder token, int userId) { 9496 return getContentProviderImpl(null, name, token, true, userId); 9497 } 9498 9499 /** 9500 * Drop a content provider from a ProcessRecord's bookkeeping 9501 */ 9502 public void removeContentProvider(IBinder connection, boolean stable) { 9503 enforceNotIsolatedCaller("removeContentProvider"); 9504 long ident = Binder.clearCallingIdentity(); 9505 try { 9506 synchronized (this) { 9507 ContentProviderConnection conn; 9508 try { 9509 conn = (ContentProviderConnection)connection; 9510 } catch (ClassCastException e) { 9511 String msg ="removeContentProvider: " + connection 9512 + " not a ContentProviderConnection"; 9513 Slog.w(TAG, msg); 9514 throw new IllegalArgumentException(msg); 9515 } 9516 if (conn == null) { 9517 throw new NullPointerException("connection is null"); 9518 } 9519 if (decProviderCountLocked(conn, null, null, stable)) { 9520 updateOomAdjLocked(); 9521 } 9522 } 9523 } finally { 9524 Binder.restoreCallingIdentity(ident); 9525 } 9526 } 9527 9528 public void removeContentProviderExternal(String name, IBinder token) { 9529 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9530 "Do not have permission in call removeContentProviderExternal()"); 9531 int userId = UserHandle.getCallingUserId(); 9532 long ident = Binder.clearCallingIdentity(); 9533 try { 9534 removeContentProviderExternalUnchecked(name, token, userId); 9535 } finally { 9536 Binder.restoreCallingIdentity(ident); 9537 } 9538 } 9539 9540 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9541 synchronized (this) { 9542 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9543 if(cpr == null) { 9544 //remove from mProvidersByClass 9545 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9546 return; 9547 } 9548 9549 //update content provider record entry info 9550 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9551 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9552 if (localCpr.hasExternalProcessHandles()) { 9553 if (localCpr.removeExternalProcessHandleLocked(token)) { 9554 updateOomAdjLocked(); 9555 } else { 9556 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9557 + " with no external reference for token: " 9558 + token + "."); 9559 } 9560 } else { 9561 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9562 + " with no external references."); 9563 } 9564 } 9565 } 9566 9567 public final void publishContentProviders(IApplicationThread caller, 9568 List<ContentProviderHolder> providers) { 9569 if (providers == null) { 9570 return; 9571 } 9572 9573 enforceNotIsolatedCaller("publishContentProviders"); 9574 synchronized (this) { 9575 final ProcessRecord r = getRecordForAppLocked(caller); 9576 if (DEBUG_MU) 9577 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9578 if (r == null) { 9579 throw new SecurityException( 9580 "Unable to find app for caller " + caller 9581 + " (pid=" + Binder.getCallingPid() 9582 + ") when publishing content providers"); 9583 } 9584 9585 final long origId = Binder.clearCallingIdentity(); 9586 9587 final int N = providers.size(); 9588 for (int i=0; i<N; i++) { 9589 ContentProviderHolder src = providers.get(i); 9590 if (src == null || src.info == null || src.provider == null) { 9591 continue; 9592 } 9593 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9594 if (DEBUG_MU) 9595 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9596 if (dst != null) { 9597 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9598 mProviderMap.putProviderByClass(comp, dst); 9599 String names[] = dst.info.authority.split(";"); 9600 for (int j = 0; j < names.length; j++) { 9601 mProviderMap.putProviderByName(names[j], dst); 9602 } 9603 9604 int NL = mLaunchingProviders.size(); 9605 int j; 9606 for (j=0; j<NL; j++) { 9607 if (mLaunchingProviders.get(j) == dst) { 9608 mLaunchingProviders.remove(j); 9609 j--; 9610 NL--; 9611 } 9612 } 9613 synchronized (dst) { 9614 dst.provider = src.provider; 9615 dst.proc = r; 9616 dst.notifyAll(); 9617 } 9618 updateOomAdjLocked(r); 9619 } 9620 } 9621 9622 Binder.restoreCallingIdentity(origId); 9623 } 9624 } 9625 9626 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9627 ContentProviderConnection conn; 9628 try { 9629 conn = (ContentProviderConnection)connection; 9630 } catch (ClassCastException e) { 9631 String msg ="refContentProvider: " + connection 9632 + " not a ContentProviderConnection"; 9633 Slog.w(TAG, msg); 9634 throw new IllegalArgumentException(msg); 9635 } 9636 if (conn == null) { 9637 throw new NullPointerException("connection is null"); 9638 } 9639 9640 synchronized (this) { 9641 if (stable > 0) { 9642 conn.numStableIncs += stable; 9643 } 9644 stable = conn.stableCount + stable; 9645 if (stable < 0) { 9646 throw new IllegalStateException("stableCount < 0: " + stable); 9647 } 9648 9649 if (unstable > 0) { 9650 conn.numUnstableIncs += unstable; 9651 } 9652 unstable = conn.unstableCount + unstable; 9653 if (unstable < 0) { 9654 throw new IllegalStateException("unstableCount < 0: " + unstable); 9655 } 9656 9657 if ((stable+unstable) <= 0) { 9658 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9659 + stable + " unstable=" + unstable); 9660 } 9661 conn.stableCount = stable; 9662 conn.unstableCount = unstable; 9663 return !conn.dead; 9664 } 9665 } 9666 9667 public void unstableProviderDied(IBinder connection) { 9668 ContentProviderConnection conn; 9669 try { 9670 conn = (ContentProviderConnection)connection; 9671 } catch (ClassCastException e) { 9672 String msg ="refContentProvider: " + connection 9673 + " not a ContentProviderConnection"; 9674 Slog.w(TAG, msg); 9675 throw new IllegalArgumentException(msg); 9676 } 9677 if (conn == null) { 9678 throw new NullPointerException("connection is null"); 9679 } 9680 9681 // Safely retrieve the content provider associated with the connection. 9682 IContentProvider provider; 9683 synchronized (this) { 9684 provider = conn.provider.provider; 9685 } 9686 9687 if (provider == null) { 9688 // Um, yeah, we're way ahead of you. 9689 return; 9690 } 9691 9692 // Make sure the caller is being honest with us. 9693 if (provider.asBinder().pingBinder()) { 9694 // Er, no, still looks good to us. 9695 synchronized (this) { 9696 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9697 + " says " + conn + " died, but we don't agree"); 9698 return; 9699 } 9700 } 9701 9702 // Well look at that! It's dead! 9703 synchronized (this) { 9704 if (conn.provider.provider != provider) { 9705 // But something changed... good enough. 9706 return; 9707 } 9708 9709 ProcessRecord proc = conn.provider.proc; 9710 if (proc == null || proc.thread == null) { 9711 // Seems like the process is already cleaned up. 9712 return; 9713 } 9714 9715 // As far as we're concerned, this is just like receiving a 9716 // death notification... just a bit prematurely. 9717 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9718 + ") early provider death"); 9719 final long ident = Binder.clearCallingIdentity(); 9720 try { 9721 appDiedLocked(proc); 9722 } finally { 9723 Binder.restoreCallingIdentity(ident); 9724 } 9725 } 9726 } 9727 9728 @Override 9729 public void appNotRespondingViaProvider(IBinder connection) { 9730 enforceCallingPermission( 9731 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9732 9733 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9734 if (conn == null) { 9735 Slog.w(TAG, "ContentProviderConnection is null"); 9736 return; 9737 } 9738 9739 final ProcessRecord host = conn.provider.proc; 9740 if (host == null) { 9741 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9742 return; 9743 } 9744 9745 final long token = Binder.clearCallingIdentity(); 9746 try { 9747 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9748 } finally { 9749 Binder.restoreCallingIdentity(token); 9750 } 9751 } 9752 9753 public final void installSystemProviders() { 9754 List<ProviderInfo> providers; 9755 synchronized (this) { 9756 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9757 providers = generateApplicationProvidersLocked(app); 9758 if (providers != null) { 9759 for (int i=providers.size()-1; i>=0; i--) { 9760 ProviderInfo pi = (ProviderInfo)providers.get(i); 9761 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9762 Slog.w(TAG, "Not installing system proc provider " + pi.name 9763 + ": not system .apk"); 9764 providers.remove(i); 9765 } 9766 } 9767 } 9768 } 9769 if (providers != null) { 9770 mSystemThread.installSystemProviders(providers); 9771 } 9772 9773 mCoreSettingsObserver = new CoreSettingsObserver(this); 9774 9775 //mUsageStatsService.monitorPackages(); 9776 } 9777 9778 /** 9779 * Allows apps to retrieve the MIME type of a URI. 9780 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9781 * users, then it does not need permission to access the ContentProvider. 9782 * Either, it needs cross-user uri grants. 9783 * 9784 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9785 * 9786 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9787 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9788 */ 9789 public String getProviderMimeType(Uri uri, int userId) { 9790 enforceNotIsolatedCaller("getProviderMimeType"); 9791 final String name = uri.getAuthority(); 9792 int callingUid = Binder.getCallingUid(); 9793 int callingPid = Binder.getCallingPid(); 9794 long ident = 0; 9795 boolean clearedIdentity = false; 9796 userId = unsafeConvertIncomingUser(userId); 9797 if (canClearIdentity(callingPid, callingUid, userId)) { 9798 clearedIdentity = true; 9799 ident = Binder.clearCallingIdentity(); 9800 } 9801 ContentProviderHolder holder = null; 9802 try { 9803 holder = getContentProviderExternalUnchecked(name, null, userId); 9804 if (holder != null) { 9805 return holder.provider.getType(uri); 9806 } 9807 } catch (RemoteException e) { 9808 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9809 return null; 9810 } finally { 9811 // We need to clear the identity to call removeContentProviderExternalUnchecked 9812 if (!clearedIdentity) { 9813 ident = Binder.clearCallingIdentity(); 9814 } 9815 try { 9816 if (holder != null) { 9817 removeContentProviderExternalUnchecked(name, null, userId); 9818 } 9819 } finally { 9820 Binder.restoreCallingIdentity(ident); 9821 } 9822 } 9823 9824 return null; 9825 } 9826 9827 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9828 if (UserHandle.getUserId(callingUid) == userId) { 9829 return true; 9830 } 9831 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9832 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9833 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9834 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9835 return true; 9836 } 9837 return false; 9838 } 9839 9840 // ========================================================= 9841 // GLOBAL MANAGEMENT 9842 // ========================================================= 9843 9844 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9845 boolean isolated, int isolatedUid) { 9846 String proc = customProcess != null ? customProcess : info.processName; 9847 BatteryStatsImpl.Uid.Proc ps = null; 9848 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9849 int uid = info.uid; 9850 if (isolated) { 9851 if (isolatedUid == 0) { 9852 int userId = UserHandle.getUserId(uid); 9853 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9854 while (true) { 9855 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9856 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9857 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9858 } 9859 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9860 mNextIsolatedProcessUid++; 9861 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9862 // No process for this uid, use it. 9863 break; 9864 } 9865 stepsLeft--; 9866 if (stepsLeft <= 0) { 9867 return null; 9868 } 9869 } 9870 } else { 9871 // Special case for startIsolatedProcess (internal only), where 9872 // the uid of the isolated process is specified by the caller. 9873 uid = isolatedUid; 9874 } 9875 } 9876 return new ProcessRecord(stats, info, proc, uid); 9877 } 9878 9879 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9880 String abiOverride) { 9881 ProcessRecord app; 9882 if (!isolated) { 9883 app = getProcessRecordLocked(info.processName, info.uid, true); 9884 } else { 9885 app = null; 9886 } 9887 9888 if (app == null) { 9889 app = newProcessRecordLocked(info, null, isolated, 0); 9890 mProcessNames.put(info.processName, app.uid, app); 9891 if (isolated) { 9892 mIsolatedProcesses.put(app.uid, app); 9893 } 9894 updateLruProcessLocked(app, false, null); 9895 updateOomAdjLocked(); 9896 } 9897 9898 // This package really, really can not be stopped. 9899 try { 9900 AppGlobals.getPackageManager().setPackageStoppedState( 9901 info.packageName, false, UserHandle.getUserId(app.uid)); 9902 } catch (RemoteException e) { 9903 } catch (IllegalArgumentException e) { 9904 Slog.w(TAG, "Failed trying to unstop package " 9905 + info.packageName + ": " + e); 9906 } 9907 9908 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9909 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9910 app.persistent = true; 9911 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9912 } 9913 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9914 mPersistentStartingProcesses.add(app); 9915 startProcessLocked(app, "added application", app.processName, abiOverride, 9916 null /* entryPoint */, null /* entryPointArgs */); 9917 } 9918 9919 return app; 9920 } 9921 9922 public void unhandledBack() { 9923 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9924 "unhandledBack()"); 9925 9926 synchronized(this) { 9927 final long origId = Binder.clearCallingIdentity(); 9928 try { 9929 getFocusedStack().unhandledBackLocked(); 9930 } finally { 9931 Binder.restoreCallingIdentity(origId); 9932 } 9933 } 9934 } 9935 9936 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9937 enforceNotIsolatedCaller("openContentUri"); 9938 final int userId = UserHandle.getCallingUserId(); 9939 String name = uri.getAuthority(); 9940 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9941 ParcelFileDescriptor pfd = null; 9942 if (cph != null) { 9943 // We record the binder invoker's uid in thread-local storage before 9944 // going to the content provider to open the file. Later, in the code 9945 // that handles all permissions checks, we look for this uid and use 9946 // that rather than the Activity Manager's own uid. The effect is that 9947 // we do the check against the caller's permissions even though it looks 9948 // to the content provider like the Activity Manager itself is making 9949 // the request. 9950 Binder token = new Binder(); 9951 sCallerIdentity.set(new Identity( 9952 token, Binder.getCallingPid(), Binder.getCallingUid())); 9953 try { 9954 pfd = cph.provider.openFile(null, uri, "r", null, token); 9955 } catch (FileNotFoundException e) { 9956 // do nothing; pfd will be returned null 9957 } finally { 9958 // Ensure that whatever happens, we clean up the identity state 9959 sCallerIdentity.remove(); 9960 } 9961 9962 // We've got the fd now, so we're done with the provider. 9963 removeContentProviderExternalUnchecked(name, null, userId); 9964 } else { 9965 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9966 } 9967 return pfd; 9968 } 9969 9970 // Actually is sleeping or shutting down or whatever else in the future 9971 // is an inactive state. 9972 public boolean isSleepingOrShuttingDown() { 9973 return isSleeping() || mShuttingDown; 9974 } 9975 9976 public boolean isSleeping() { 9977 return mSleeping; 9978 } 9979 9980 void onWakefulnessChanged(int wakefulness) { 9981 synchronized(this) { 9982 mWakefulness = wakefulness; 9983 updateSleepIfNeededLocked(); 9984 } 9985 } 9986 9987 void finishRunningVoiceLocked() { 9988 if (mRunningVoice) { 9989 mRunningVoice = false; 9990 updateSleepIfNeededLocked(); 9991 } 9992 } 9993 9994 void updateSleepIfNeededLocked() { 9995 if (mSleeping && !shouldSleepLocked()) { 9996 mSleeping = false; 9997 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9998 } else if (!mSleeping && shouldSleepLocked()) { 9999 mSleeping = true; 10000 mStackSupervisor.goingToSleepLocked(); 10001 10002 // Initialize the wake times of all processes. 10003 checkExcessivePowerUsageLocked(false); 10004 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10005 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10006 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10007 } 10008 } 10009 10010 private boolean shouldSleepLocked() { 10011 // Resume applications while running a voice interactor. 10012 if (mRunningVoice) { 10013 return false; 10014 } 10015 10016 switch (mWakefulness) { 10017 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10018 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10019 // If we're interactive but applications are already paused then defer 10020 // resuming them until the lock screen is hidden. 10021 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10022 case PowerManagerInternal.WAKEFULNESS_DOZING: 10023 // If we're dozing then pause applications whenever the lock screen is shown. 10024 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10025 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10026 default: 10027 // If we're asleep then pause applications unconditionally. 10028 return true; 10029 } 10030 } 10031 10032 /** Pokes the task persister. */ 10033 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10034 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10035 // Never persist the home stack. 10036 return; 10037 } 10038 mTaskPersister.wakeup(task, flush); 10039 } 10040 10041 /** Notifies all listeners when the task stack has changed. */ 10042 void notifyTaskStackChangedLocked() { 10043 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10044 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10045 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10046 } 10047 10048 @Override 10049 public boolean shutdown(int timeout) { 10050 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10051 != PackageManager.PERMISSION_GRANTED) { 10052 throw new SecurityException("Requires permission " 10053 + android.Manifest.permission.SHUTDOWN); 10054 } 10055 10056 boolean timedout = false; 10057 10058 synchronized(this) { 10059 mShuttingDown = true; 10060 updateEventDispatchingLocked(); 10061 timedout = mStackSupervisor.shutdownLocked(timeout); 10062 } 10063 10064 mAppOpsService.shutdown(); 10065 if (mUsageStatsService != null) { 10066 mUsageStatsService.prepareShutdown(); 10067 } 10068 mBatteryStatsService.shutdown(); 10069 synchronized (this) { 10070 mProcessStats.shutdownLocked(); 10071 notifyTaskPersisterLocked(null, true); 10072 } 10073 10074 return timedout; 10075 } 10076 10077 public final void activitySlept(IBinder token) { 10078 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10079 10080 final long origId = Binder.clearCallingIdentity(); 10081 10082 synchronized (this) { 10083 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10084 if (r != null) { 10085 mStackSupervisor.activitySleptLocked(r); 10086 } 10087 } 10088 10089 Binder.restoreCallingIdentity(origId); 10090 } 10091 10092 private String lockScreenShownToString() { 10093 switch (mLockScreenShown) { 10094 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10095 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10096 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10097 default: return "Unknown=" + mLockScreenShown; 10098 } 10099 } 10100 10101 void logLockScreen(String msg) { 10102 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10103 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10104 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10105 + " mSleeping=" + mSleeping); 10106 } 10107 10108 void startRunningVoiceLocked() { 10109 if (!mRunningVoice) { 10110 mRunningVoice = true; 10111 updateSleepIfNeededLocked(); 10112 } 10113 } 10114 10115 private void updateEventDispatchingLocked() { 10116 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10117 } 10118 10119 public void setLockScreenShown(boolean shown) { 10120 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10121 != PackageManager.PERMISSION_GRANTED) { 10122 throw new SecurityException("Requires permission " 10123 + android.Manifest.permission.DEVICE_POWER); 10124 } 10125 10126 synchronized(this) { 10127 long ident = Binder.clearCallingIdentity(); 10128 try { 10129 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10130 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10131 updateSleepIfNeededLocked(); 10132 } finally { 10133 Binder.restoreCallingIdentity(ident); 10134 } 10135 } 10136 } 10137 10138 @Override 10139 public void stopAppSwitches() { 10140 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10141 != PackageManager.PERMISSION_GRANTED) { 10142 throw new SecurityException("Requires permission " 10143 + android.Manifest.permission.STOP_APP_SWITCHES); 10144 } 10145 10146 synchronized(this) { 10147 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10148 + APP_SWITCH_DELAY_TIME; 10149 mDidAppSwitch = false; 10150 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10151 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10152 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10153 } 10154 } 10155 10156 public void resumeAppSwitches() { 10157 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10158 != PackageManager.PERMISSION_GRANTED) { 10159 throw new SecurityException("Requires permission " 10160 + android.Manifest.permission.STOP_APP_SWITCHES); 10161 } 10162 10163 synchronized(this) { 10164 // Note that we don't execute any pending app switches... we will 10165 // let those wait until either the timeout, or the next start 10166 // activity request. 10167 mAppSwitchesAllowedTime = 0; 10168 } 10169 } 10170 10171 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10172 int callingPid, int callingUid, String name) { 10173 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10174 return true; 10175 } 10176 10177 int perm = checkComponentPermission( 10178 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10179 sourceUid, -1, true); 10180 if (perm == PackageManager.PERMISSION_GRANTED) { 10181 return true; 10182 } 10183 10184 // If the actual IPC caller is different from the logical source, then 10185 // also see if they are allowed to control app switches. 10186 if (callingUid != -1 && callingUid != sourceUid) { 10187 perm = checkComponentPermission( 10188 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10189 callingUid, -1, true); 10190 if (perm == PackageManager.PERMISSION_GRANTED) { 10191 return true; 10192 } 10193 } 10194 10195 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10196 return false; 10197 } 10198 10199 public void setDebugApp(String packageName, boolean waitForDebugger, 10200 boolean persistent) { 10201 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10202 "setDebugApp()"); 10203 10204 long ident = Binder.clearCallingIdentity(); 10205 try { 10206 // Note that this is not really thread safe if there are multiple 10207 // callers into it at the same time, but that's not a situation we 10208 // care about. 10209 if (persistent) { 10210 final ContentResolver resolver = mContext.getContentResolver(); 10211 Settings.Global.putString( 10212 resolver, Settings.Global.DEBUG_APP, 10213 packageName); 10214 Settings.Global.putInt( 10215 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10216 waitForDebugger ? 1 : 0); 10217 } 10218 10219 synchronized (this) { 10220 if (!persistent) { 10221 mOrigDebugApp = mDebugApp; 10222 mOrigWaitForDebugger = mWaitForDebugger; 10223 } 10224 mDebugApp = packageName; 10225 mWaitForDebugger = waitForDebugger; 10226 mDebugTransient = !persistent; 10227 if (packageName != null) { 10228 forceStopPackageLocked(packageName, -1, false, false, true, true, 10229 false, UserHandle.USER_ALL, "set debug app"); 10230 } 10231 } 10232 } finally { 10233 Binder.restoreCallingIdentity(ident); 10234 } 10235 } 10236 10237 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10238 synchronized (this) { 10239 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10240 if (!isDebuggable) { 10241 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10242 throw new SecurityException("Process not debuggable: " + app.packageName); 10243 } 10244 } 10245 10246 mOpenGlTraceApp = processName; 10247 } 10248 } 10249 10250 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10251 synchronized (this) { 10252 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10253 if (!isDebuggable) { 10254 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10255 throw new SecurityException("Process not debuggable: " + app.packageName); 10256 } 10257 } 10258 mProfileApp = processName; 10259 mProfileFile = profilerInfo.profileFile; 10260 if (mProfileFd != null) { 10261 try { 10262 mProfileFd.close(); 10263 } catch (IOException e) { 10264 } 10265 mProfileFd = null; 10266 } 10267 mProfileFd = profilerInfo.profileFd; 10268 mSamplingInterval = profilerInfo.samplingInterval; 10269 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10270 mProfileType = 0; 10271 } 10272 } 10273 10274 @Override 10275 public void setAlwaysFinish(boolean enabled) { 10276 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10277 "setAlwaysFinish()"); 10278 10279 Settings.Global.putInt( 10280 mContext.getContentResolver(), 10281 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10282 10283 synchronized (this) { 10284 mAlwaysFinishActivities = enabled; 10285 } 10286 } 10287 10288 @Override 10289 public void setActivityController(IActivityController controller) { 10290 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10291 "setActivityController()"); 10292 synchronized (this) { 10293 mController = controller; 10294 Watchdog.getInstance().setActivityController(controller); 10295 } 10296 } 10297 10298 @Override 10299 public void setUserIsMonkey(boolean userIsMonkey) { 10300 synchronized (this) { 10301 synchronized (mPidsSelfLocked) { 10302 final int callingPid = Binder.getCallingPid(); 10303 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10304 if (precessRecord == null) { 10305 throw new SecurityException("Unknown process: " + callingPid); 10306 } 10307 if (precessRecord.instrumentationUiAutomationConnection == null) { 10308 throw new SecurityException("Only an instrumentation process " 10309 + "with a UiAutomation can call setUserIsMonkey"); 10310 } 10311 } 10312 mUserIsMonkey = userIsMonkey; 10313 } 10314 } 10315 10316 @Override 10317 public boolean isUserAMonkey() { 10318 synchronized (this) { 10319 // If there is a controller also implies the user is a monkey. 10320 return (mUserIsMonkey || mController != null); 10321 } 10322 } 10323 10324 public void requestBugReport() { 10325 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10326 SystemProperties.set("ctl.start", "bugreport"); 10327 } 10328 10329 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10330 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10331 } 10332 10333 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10334 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10335 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10336 } 10337 return KEY_DISPATCHING_TIMEOUT; 10338 } 10339 10340 @Override 10341 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10342 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10343 != PackageManager.PERMISSION_GRANTED) { 10344 throw new SecurityException("Requires permission " 10345 + android.Manifest.permission.FILTER_EVENTS); 10346 } 10347 ProcessRecord proc; 10348 long timeout; 10349 synchronized (this) { 10350 synchronized (mPidsSelfLocked) { 10351 proc = mPidsSelfLocked.get(pid); 10352 } 10353 timeout = getInputDispatchingTimeoutLocked(proc); 10354 } 10355 10356 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10357 return -1; 10358 } 10359 10360 return timeout; 10361 } 10362 10363 /** 10364 * Handle input dispatching timeouts. 10365 * Returns whether input dispatching should be aborted or not. 10366 */ 10367 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10368 final ActivityRecord activity, final ActivityRecord parent, 10369 final boolean aboveSystem, String reason) { 10370 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10371 != PackageManager.PERMISSION_GRANTED) { 10372 throw new SecurityException("Requires permission " 10373 + android.Manifest.permission.FILTER_EVENTS); 10374 } 10375 10376 final String annotation; 10377 if (reason == null) { 10378 annotation = "Input dispatching timed out"; 10379 } else { 10380 annotation = "Input dispatching timed out (" + reason + ")"; 10381 } 10382 10383 if (proc != null) { 10384 synchronized (this) { 10385 if (proc.debugging) { 10386 return false; 10387 } 10388 10389 if (mDidDexOpt) { 10390 // Give more time since we were dexopting. 10391 mDidDexOpt = false; 10392 return false; 10393 } 10394 10395 if (proc.instrumentationClass != null) { 10396 Bundle info = new Bundle(); 10397 info.putString("shortMsg", "keyDispatchingTimedOut"); 10398 info.putString("longMsg", annotation); 10399 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10400 return true; 10401 } 10402 } 10403 mHandler.post(new Runnable() { 10404 @Override 10405 public void run() { 10406 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10407 } 10408 }); 10409 } 10410 10411 return true; 10412 } 10413 10414 public Bundle getAssistContextExtras(int requestType) { 10415 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10416 UserHandle.getCallingUserId()); 10417 if (pae == null) { 10418 return null; 10419 } 10420 synchronized (pae) { 10421 while (!pae.haveResult) { 10422 try { 10423 pae.wait(); 10424 } catch (InterruptedException e) { 10425 } 10426 } 10427 if (pae.result != null) { 10428 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10429 } 10430 } 10431 synchronized (this) { 10432 mPendingAssistExtras.remove(pae); 10433 mHandler.removeCallbacks(pae); 10434 } 10435 return pae.extras; 10436 } 10437 10438 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10439 int userHandle) { 10440 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10441 "getAssistContextExtras()"); 10442 PendingAssistExtras pae; 10443 Bundle extras = new Bundle(); 10444 synchronized (this) { 10445 ActivityRecord activity = getFocusedStack().mResumedActivity; 10446 if (activity == null) { 10447 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10448 return null; 10449 } 10450 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10451 if (activity.app == null || activity.app.thread == null) { 10452 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10453 return null; 10454 } 10455 if (activity.app.pid == Binder.getCallingPid()) { 10456 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10457 return null; 10458 } 10459 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10460 try { 10461 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10462 requestType); 10463 mPendingAssistExtras.add(pae); 10464 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10465 } catch (RemoteException e) { 10466 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10467 return null; 10468 } 10469 return pae; 10470 } 10471 } 10472 10473 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10474 PendingAssistExtras pae = (PendingAssistExtras)token; 10475 synchronized (pae) { 10476 pae.result = extras; 10477 pae.haveResult = true; 10478 pae.notifyAll(); 10479 if (pae.intent == null) { 10480 // Caller is just waiting for the result. 10481 return; 10482 } 10483 } 10484 10485 // We are now ready to launch the assist activity. 10486 synchronized (this) { 10487 boolean exists = mPendingAssistExtras.remove(pae); 10488 mHandler.removeCallbacks(pae); 10489 if (!exists) { 10490 // Timed out. 10491 return; 10492 } 10493 } 10494 pae.intent.replaceExtras(extras); 10495 if (pae.hint != null) { 10496 pae.intent.putExtra(pae.hint, true); 10497 } 10498 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10499 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10500 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10501 closeSystemDialogs("assist"); 10502 try { 10503 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10504 } catch (ActivityNotFoundException e) { 10505 Slog.w(TAG, "No activity to handle assist action.", e); 10506 } 10507 } 10508 10509 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10510 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10511 } 10512 10513 public void registerProcessObserver(IProcessObserver observer) { 10514 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10515 "registerProcessObserver()"); 10516 synchronized (this) { 10517 mProcessObservers.register(observer); 10518 } 10519 } 10520 10521 @Override 10522 public void unregisterProcessObserver(IProcessObserver observer) { 10523 synchronized (this) { 10524 mProcessObservers.unregister(observer); 10525 } 10526 } 10527 10528 @Override 10529 public boolean convertFromTranslucent(IBinder token) { 10530 final long origId = Binder.clearCallingIdentity(); 10531 try { 10532 synchronized (this) { 10533 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10534 if (r == null) { 10535 return false; 10536 } 10537 final boolean translucentChanged = r.changeWindowTranslucency(true); 10538 if (translucentChanged) { 10539 r.task.stack.releaseBackgroundResources(); 10540 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10541 } 10542 mWindowManager.setAppFullscreen(token, true); 10543 return translucentChanged; 10544 } 10545 } finally { 10546 Binder.restoreCallingIdentity(origId); 10547 } 10548 } 10549 10550 @Override 10551 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10552 final long origId = Binder.clearCallingIdentity(); 10553 try { 10554 synchronized (this) { 10555 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10556 if (r == null) { 10557 return false; 10558 } 10559 int index = r.task.mActivities.lastIndexOf(r); 10560 if (index > 0) { 10561 ActivityRecord under = r.task.mActivities.get(index - 1); 10562 under.returningOptions = options; 10563 } 10564 final boolean translucentChanged = r.changeWindowTranslucency(false); 10565 if (translucentChanged) { 10566 r.task.stack.convertToTranslucent(r); 10567 } 10568 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10569 mWindowManager.setAppFullscreen(token, false); 10570 return translucentChanged; 10571 } 10572 } finally { 10573 Binder.restoreCallingIdentity(origId); 10574 } 10575 } 10576 10577 @Override 10578 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10579 final long origId = Binder.clearCallingIdentity(); 10580 try { 10581 synchronized (this) { 10582 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10583 if (r != null) { 10584 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10585 } 10586 } 10587 return false; 10588 } finally { 10589 Binder.restoreCallingIdentity(origId); 10590 } 10591 } 10592 10593 @Override 10594 public boolean isBackgroundVisibleBehind(IBinder token) { 10595 final long origId = Binder.clearCallingIdentity(); 10596 try { 10597 synchronized (this) { 10598 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10599 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10600 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10601 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10602 return visible; 10603 } 10604 } finally { 10605 Binder.restoreCallingIdentity(origId); 10606 } 10607 } 10608 10609 @Override 10610 public ActivityOptions getActivityOptions(IBinder token) { 10611 final long origId = Binder.clearCallingIdentity(); 10612 try { 10613 synchronized (this) { 10614 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10615 if (r != null) { 10616 final ActivityOptions activityOptions = r.pendingOptions; 10617 r.pendingOptions = null; 10618 return activityOptions; 10619 } 10620 return null; 10621 } 10622 } finally { 10623 Binder.restoreCallingIdentity(origId); 10624 } 10625 } 10626 10627 @Override 10628 public void setImmersive(IBinder token, boolean immersive) { 10629 synchronized(this) { 10630 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10631 if (r == null) { 10632 throw new IllegalArgumentException(); 10633 } 10634 r.immersive = immersive; 10635 10636 // update associated state if we're frontmost 10637 if (r == mFocusedActivity) { 10638 if (DEBUG_IMMERSIVE) { 10639 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10640 } 10641 applyUpdateLockStateLocked(r); 10642 } 10643 } 10644 } 10645 10646 @Override 10647 public boolean isImmersive(IBinder token) { 10648 synchronized (this) { 10649 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10650 if (r == null) { 10651 throw new IllegalArgumentException(); 10652 } 10653 return r.immersive; 10654 } 10655 } 10656 10657 public boolean isTopActivityImmersive() { 10658 enforceNotIsolatedCaller("startActivity"); 10659 synchronized (this) { 10660 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10661 return (r != null) ? r.immersive : false; 10662 } 10663 } 10664 10665 @Override 10666 public boolean isTopOfTask(IBinder token) { 10667 synchronized (this) { 10668 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10669 if (r == null) { 10670 throw new IllegalArgumentException(); 10671 } 10672 return r.task.getTopActivity() == r; 10673 } 10674 } 10675 10676 public final void enterSafeMode() { 10677 synchronized(this) { 10678 // It only makes sense to do this before the system is ready 10679 // and started launching other packages. 10680 if (!mSystemReady) { 10681 try { 10682 AppGlobals.getPackageManager().enterSafeMode(); 10683 } catch (RemoteException e) { 10684 } 10685 } 10686 10687 mSafeMode = true; 10688 } 10689 } 10690 10691 public final void showSafeModeOverlay() { 10692 View v = LayoutInflater.from(mContext).inflate( 10693 com.android.internal.R.layout.safe_mode, null); 10694 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10695 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10696 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10697 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10698 lp.gravity = Gravity.BOTTOM | Gravity.START; 10699 lp.format = v.getBackground().getOpacity(); 10700 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10701 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10702 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10703 ((WindowManager)mContext.getSystemService( 10704 Context.WINDOW_SERVICE)).addView(v, lp); 10705 } 10706 10707 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10708 if (!(sender instanceof PendingIntentRecord)) { 10709 return; 10710 } 10711 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10712 synchronized (stats) { 10713 if (mBatteryStatsService.isOnBattery()) { 10714 mBatteryStatsService.enforceCallingPermission(); 10715 PendingIntentRecord rec = (PendingIntentRecord)sender; 10716 int MY_UID = Binder.getCallingUid(); 10717 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10718 BatteryStatsImpl.Uid.Pkg pkg = 10719 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10720 sourcePkg != null ? sourcePkg : rec.key.packageName); 10721 pkg.incWakeupsLocked(); 10722 } 10723 } 10724 } 10725 10726 public boolean killPids(int[] pids, String pReason, boolean secure) { 10727 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10728 throw new SecurityException("killPids only available to the system"); 10729 } 10730 String reason = (pReason == null) ? "Unknown" : pReason; 10731 // XXX Note: don't acquire main activity lock here, because the window 10732 // manager calls in with its locks held. 10733 10734 boolean killed = false; 10735 synchronized (mPidsSelfLocked) { 10736 int[] types = new int[pids.length]; 10737 int worstType = 0; 10738 for (int i=0; i<pids.length; i++) { 10739 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10740 if (proc != null) { 10741 int type = proc.setAdj; 10742 types[i] = type; 10743 if (type > worstType) { 10744 worstType = type; 10745 } 10746 } 10747 } 10748 10749 // If the worst oom_adj is somewhere in the cached proc LRU range, 10750 // then constrain it so we will kill all cached procs. 10751 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10752 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10753 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10754 } 10755 10756 // If this is not a secure call, don't let it kill processes that 10757 // are important. 10758 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10759 worstType = ProcessList.SERVICE_ADJ; 10760 } 10761 10762 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10763 for (int i=0; i<pids.length; i++) { 10764 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10765 if (proc == null) { 10766 continue; 10767 } 10768 int adj = proc.setAdj; 10769 if (adj >= worstType && !proc.killedByAm) { 10770 proc.kill(reason, true); 10771 killed = true; 10772 } 10773 } 10774 } 10775 return killed; 10776 } 10777 10778 @Override 10779 public void killUid(int uid, String reason) { 10780 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10781 throw new SecurityException("killUid only available to the system"); 10782 } 10783 synchronized (this) { 10784 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10785 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10786 reason != null ? reason : "kill uid"); 10787 } 10788 } 10789 10790 @Override 10791 public boolean killProcessesBelowForeground(String reason) { 10792 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10793 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10794 } 10795 10796 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10797 } 10798 10799 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10800 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10801 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10802 } 10803 10804 boolean killed = false; 10805 synchronized (mPidsSelfLocked) { 10806 final int size = mPidsSelfLocked.size(); 10807 for (int i = 0; i < size; i++) { 10808 final int pid = mPidsSelfLocked.keyAt(i); 10809 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10810 if (proc == null) continue; 10811 10812 final int adj = proc.setAdj; 10813 if (adj > belowAdj && !proc.killedByAm) { 10814 proc.kill(reason, true); 10815 killed = true; 10816 } 10817 } 10818 } 10819 return killed; 10820 } 10821 10822 @Override 10823 public void hang(final IBinder who, boolean allowRestart) { 10824 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10825 != PackageManager.PERMISSION_GRANTED) { 10826 throw new SecurityException("Requires permission " 10827 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10828 } 10829 10830 final IBinder.DeathRecipient death = new DeathRecipient() { 10831 @Override 10832 public void binderDied() { 10833 synchronized (this) { 10834 notifyAll(); 10835 } 10836 } 10837 }; 10838 10839 try { 10840 who.linkToDeath(death, 0); 10841 } catch (RemoteException e) { 10842 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10843 return; 10844 } 10845 10846 synchronized (this) { 10847 Watchdog.getInstance().setAllowRestart(allowRestart); 10848 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10849 synchronized (death) { 10850 while (who.isBinderAlive()) { 10851 try { 10852 death.wait(); 10853 } catch (InterruptedException e) { 10854 } 10855 } 10856 } 10857 Watchdog.getInstance().setAllowRestart(true); 10858 } 10859 } 10860 10861 @Override 10862 public void restart() { 10863 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10864 != PackageManager.PERMISSION_GRANTED) { 10865 throw new SecurityException("Requires permission " 10866 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10867 } 10868 10869 Log.i(TAG, "Sending shutdown broadcast..."); 10870 10871 BroadcastReceiver br = new BroadcastReceiver() { 10872 @Override public void onReceive(Context context, Intent intent) { 10873 // Now the broadcast is done, finish up the low-level shutdown. 10874 Log.i(TAG, "Shutting down activity manager..."); 10875 shutdown(10000); 10876 Log.i(TAG, "Shutdown complete, restarting!"); 10877 Process.killProcess(Process.myPid()); 10878 System.exit(10); 10879 } 10880 }; 10881 10882 // First send the high-level shut down broadcast. 10883 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10884 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10885 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10886 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10887 mContext.sendOrderedBroadcastAsUser(intent, 10888 UserHandle.ALL, null, br, mHandler, 0, null, null); 10889 */ 10890 br.onReceive(mContext, intent); 10891 } 10892 10893 private long getLowRamTimeSinceIdle(long now) { 10894 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10895 } 10896 10897 @Override 10898 public void performIdleMaintenance() { 10899 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10900 != PackageManager.PERMISSION_GRANTED) { 10901 throw new SecurityException("Requires permission " 10902 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10903 } 10904 10905 synchronized (this) { 10906 final long now = SystemClock.uptimeMillis(); 10907 final long timeSinceLastIdle = now - mLastIdleTime; 10908 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10909 mLastIdleTime = now; 10910 mLowRamTimeSinceLastIdle = 0; 10911 if (mLowRamStartTime != 0) { 10912 mLowRamStartTime = now; 10913 } 10914 10915 StringBuilder sb = new StringBuilder(128); 10916 sb.append("Idle maintenance over "); 10917 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10918 sb.append(" low RAM for "); 10919 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10920 Slog.i(TAG, sb.toString()); 10921 10922 // If at least 1/3 of our time since the last idle period has been spent 10923 // with RAM low, then we want to kill processes. 10924 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10925 10926 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10927 ProcessRecord proc = mLruProcesses.get(i); 10928 if (proc.notCachedSinceIdle) { 10929 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10930 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10931 if (doKilling && proc.initialIdlePss != 0 10932 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10933 sb = new StringBuilder(128); 10934 sb.append("Kill"); 10935 sb.append(proc.processName); 10936 sb.append(" in idle maint: pss="); 10937 sb.append(proc.lastPss); 10938 sb.append(", initialPss="); 10939 sb.append(proc.initialIdlePss); 10940 sb.append(", period="); 10941 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10942 sb.append(", lowRamPeriod="); 10943 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10944 Slog.wtfQuiet(TAG, sb.toString()); 10945 proc.kill("idle maint (pss " + proc.lastPss 10946 + " from " + proc.initialIdlePss + ")", true); 10947 } 10948 } 10949 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10950 proc.notCachedSinceIdle = true; 10951 proc.initialIdlePss = 0; 10952 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10953 mTestPssMode, isSleeping(), now); 10954 } 10955 } 10956 10957 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10958 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10959 } 10960 } 10961 10962 private void retrieveSettings() { 10963 final ContentResolver resolver = mContext.getContentResolver(); 10964 String debugApp = Settings.Global.getString( 10965 resolver, Settings.Global.DEBUG_APP); 10966 boolean waitForDebugger = Settings.Global.getInt( 10967 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10968 boolean alwaysFinishActivities = Settings.Global.getInt( 10969 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10970 boolean forceRtl = Settings.Global.getInt( 10971 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10972 // Transfer any global setting for forcing RTL layout, into a System Property 10973 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10974 10975 Configuration configuration = new Configuration(); 10976 Settings.System.getConfiguration(resolver, configuration); 10977 if (forceRtl) { 10978 // This will take care of setting the correct layout direction flags 10979 configuration.setLayoutDirection(configuration.locale); 10980 } 10981 10982 synchronized (this) { 10983 mDebugApp = mOrigDebugApp = debugApp; 10984 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10985 mAlwaysFinishActivities = alwaysFinishActivities; 10986 // This happens before any activities are started, so we can 10987 // change mConfiguration in-place. 10988 updateConfigurationLocked(configuration, null, false, true); 10989 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10990 } 10991 } 10992 10993 /** Loads resources after the current configuration has been set. */ 10994 private void loadResourcesOnSystemReady() { 10995 final Resources res = mContext.getResources(); 10996 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10997 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10998 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10999 } 11000 11001 public boolean testIsSystemReady() { 11002 // no need to synchronize(this) just to read & return the value 11003 return mSystemReady; 11004 } 11005 11006 private static File getCalledPreBootReceiversFile() { 11007 File dataDir = Environment.getDataDirectory(); 11008 File systemDir = new File(dataDir, "system"); 11009 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11010 return fname; 11011 } 11012 11013 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11014 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11015 File file = getCalledPreBootReceiversFile(); 11016 FileInputStream fis = null; 11017 try { 11018 fis = new FileInputStream(file); 11019 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11020 int fvers = dis.readInt(); 11021 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11022 String vers = dis.readUTF(); 11023 String codename = dis.readUTF(); 11024 String build = dis.readUTF(); 11025 if (android.os.Build.VERSION.RELEASE.equals(vers) 11026 && android.os.Build.VERSION.CODENAME.equals(codename) 11027 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11028 int num = dis.readInt(); 11029 while (num > 0) { 11030 num--; 11031 String pkg = dis.readUTF(); 11032 String cls = dis.readUTF(); 11033 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11034 } 11035 } 11036 } 11037 } catch (FileNotFoundException e) { 11038 } catch (IOException e) { 11039 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11040 } finally { 11041 if (fis != null) { 11042 try { 11043 fis.close(); 11044 } catch (IOException e) { 11045 } 11046 } 11047 } 11048 return lastDoneReceivers; 11049 } 11050 11051 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11052 File file = getCalledPreBootReceiversFile(); 11053 FileOutputStream fos = null; 11054 DataOutputStream dos = null; 11055 try { 11056 fos = new FileOutputStream(file); 11057 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11058 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11059 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11060 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11061 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11062 dos.writeInt(list.size()); 11063 for (int i=0; i<list.size(); i++) { 11064 dos.writeUTF(list.get(i).getPackageName()); 11065 dos.writeUTF(list.get(i).getClassName()); 11066 } 11067 } catch (IOException e) { 11068 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11069 file.delete(); 11070 } finally { 11071 FileUtils.sync(fos); 11072 if (dos != null) { 11073 try { 11074 dos.close(); 11075 } catch (IOException e) { 11076 // TODO Auto-generated catch block 11077 e.printStackTrace(); 11078 } 11079 } 11080 } 11081 } 11082 11083 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11084 ArrayList<ComponentName> doneReceivers, int userId) { 11085 boolean waitingUpdate = false; 11086 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11087 List<ResolveInfo> ris = null; 11088 try { 11089 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11090 intent, null, 0, userId); 11091 } catch (RemoteException e) { 11092 } 11093 if (ris != null) { 11094 for (int i=ris.size()-1; i>=0; i--) { 11095 if ((ris.get(i).activityInfo.applicationInfo.flags 11096 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11097 ris.remove(i); 11098 } 11099 } 11100 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11101 11102 // For User 0, load the version number. When delivering to a new user, deliver 11103 // to all receivers. 11104 if (userId == UserHandle.USER_OWNER) { 11105 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11106 for (int i=0; i<ris.size(); i++) { 11107 ActivityInfo ai = ris.get(i).activityInfo; 11108 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11109 if (lastDoneReceivers.contains(comp)) { 11110 // We already did the pre boot receiver for this app with the current 11111 // platform version, so don't do it again... 11112 ris.remove(i); 11113 i--; 11114 // ...however, do keep it as one that has been done, so we don't 11115 // forget about it when rewriting the file of last done receivers. 11116 doneReceivers.add(comp); 11117 } 11118 } 11119 } 11120 11121 // If primary user, send broadcast to all available users, else just to userId 11122 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11123 : new int[] { userId }; 11124 for (int i = 0; i < ris.size(); i++) { 11125 ActivityInfo ai = ris.get(i).activityInfo; 11126 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11127 doneReceivers.add(comp); 11128 intent.setComponent(comp); 11129 for (int j=0; j<users.length; j++) { 11130 IIntentReceiver finisher = null; 11131 // On last receiver and user, set up a completion callback 11132 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11133 finisher = new IIntentReceiver.Stub() { 11134 public void performReceive(Intent intent, int resultCode, 11135 String data, Bundle extras, boolean ordered, 11136 boolean sticky, int sendingUser) { 11137 // The raw IIntentReceiver interface is called 11138 // with the AM lock held, so redispatch to 11139 // execute our code without the lock. 11140 mHandler.post(onFinishCallback); 11141 } 11142 }; 11143 } 11144 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11145 + " for user " + users[j]); 11146 broadcastIntentLocked(null, null, intent, null, finisher, 11147 0, null, null, null, AppOpsManager.OP_NONE, 11148 true, false, MY_PID, Process.SYSTEM_UID, 11149 users[j]); 11150 if (finisher != null) { 11151 waitingUpdate = true; 11152 } 11153 } 11154 } 11155 } 11156 11157 return waitingUpdate; 11158 } 11159 11160 public void systemReady(final Runnable goingCallback) { 11161 synchronized(this) { 11162 if (mSystemReady) { 11163 // If we're done calling all the receivers, run the next "boot phase" passed in 11164 // by the SystemServer 11165 if (goingCallback != null) { 11166 goingCallback.run(); 11167 } 11168 return; 11169 } 11170 11171 // Make sure we have the current profile info, since it is needed for 11172 // security checks. 11173 updateCurrentProfileIdsLocked(); 11174 11175 if (mRecentTasks == null) { 11176 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11177 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11178 if (!mRecentTasks.isEmpty()) { 11179 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11180 } 11181 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11182 mTaskPersister.startPersisting(); 11183 } 11184 11185 // Check to see if there are any update receivers to run. 11186 if (!mDidUpdate) { 11187 if (mWaitingUpdate) { 11188 return; 11189 } 11190 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11191 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11192 public void run() { 11193 synchronized (ActivityManagerService.this) { 11194 mDidUpdate = true; 11195 } 11196 writeLastDonePreBootReceivers(doneReceivers); 11197 showBootMessage(mContext.getText( 11198 R.string.android_upgrading_complete), 11199 false); 11200 systemReady(goingCallback); 11201 } 11202 }, doneReceivers, UserHandle.USER_OWNER); 11203 11204 if (mWaitingUpdate) { 11205 return; 11206 } 11207 mDidUpdate = true; 11208 } 11209 11210 mAppOpsService.systemReady(); 11211 mSystemReady = true; 11212 } 11213 11214 ArrayList<ProcessRecord> procsToKill = null; 11215 synchronized(mPidsSelfLocked) { 11216 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11217 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11218 if (!isAllowedWhileBooting(proc.info)){ 11219 if (procsToKill == null) { 11220 procsToKill = new ArrayList<ProcessRecord>(); 11221 } 11222 procsToKill.add(proc); 11223 } 11224 } 11225 } 11226 11227 synchronized(this) { 11228 if (procsToKill != null) { 11229 for (int i=procsToKill.size()-1; i>=0; i--) { 11230 ProcessRecord proc = procsToKill.get(i); 11231 Slog.i(TAG, "Removing system update proc: " + proc); 11232 removeProcessLocked(proc, true, false, "system update done"); 11233 } 11234 } 11235 11236 // Now that we have cleaned up any update processes, we 11237 // are ready to start launching real processes and know that 11238 // we won't trample on them any more. 11239 mProcessesReady = true; 11240 } 11241 11242 Slog.i(TAG, "System now ready"); 11243 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11244 SystemClock.uptimeMillis()); 11245 11246 synchronized(this) { 11247 // Make sure we have no pre-ready processes sitting around. 11248 11249 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11250 ResolveInfo ri = mContext.getPackageManager() 11251 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11252 STOCK_PM_FLAGS); 11253 CharSequence errorMsg = null; 11254 if (ri != null) { 11255 ActivityInfo ai = ri.activityInfo; 11256 ApplicationInfo app = ai.applicationInfo; 11257 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11258 mTopAction = Intent.ACTION_FACTORY_TEST; 11259 mTopData = null; 11260 mTopComponent = new ComponentName(app.packageName, 11261 ai.name); 11262 } else { 11263 errorMsg = mContext.getResources().getText( 11264 com.android.internal.R.string.factorytest_not_system); 11265 } 11266 } else { 11267 errorMsg = mContext.getResources().getText( 11268 com.android.internal.R.string.factorytest_no_action); 11269 } 11270 if (errorMsg != null) { 11271 mTopAction = null; 11272 mTopData = null; 11273 mTopComponent = null; 11274 Message msg = Message.obtain(); 11275 msg.what = SHOW_FACTORY_ERROR_MSG; 11276 msg.getData().putCharSequence("msg", errorMsg); 11277 mHandler.sendMessage(msg); 11278 } 11279 } 11280 } 11281 11282 retrieveSettings(); 11283 loadResourcesOnSystemReady(); 11284 11285 synchronized (this) { 11286 readGrantedUriPermissionsLocked(); 11287 } 11288 11289 if (goingCallback != null) goingCallback.run(); 11290 11291 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11292 Integer.toString(mCurrentUserId), mCurrentUserId); 11293 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11294 Integer.toString(mCurrentUserId), mCurrentUserId); 11295 mSystemServiceManager.startUser(mCurrentUserId); 11296 11297 synchronized (this) { 11298 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11299 try { 11300 List apps = AppGlobals.getPackageManager(). 11301 getPersistentApplications(STOCK_PM_FLAGS); 11302 if (apps != null) { 11303 int N = apps.size(); 11304 int i; 11305 for (i=0; i<N; i++) { 11306 ApplicationInfo info 11307 = (ApplicationInfo)apps.get(i); 11308 if (info != null && 11309 !info.packageName.equals("android")) { 11310 addAppLocked(info, false, null /* ABI override */); 11311 } 11312 } 11313 } 11314 } catch (RemoteException ex) { 11315 // pm is in same process, this will never happen. 11316 } 11317 } 11318 11319 // Start up initial activity. 11320 mBooting = true; 11321 startHomeActivityLocked(mCurrentUserId); 11322 11323 try { 11324 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11325 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11326 + " data partition or your device will be unstable."); 11327 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11328 } 11329 } catch (RemoteException e) { 11330 } 11331 11332 if (!Build.isFingerprintConsistent()) { 11333 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11334 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11335 } 11336 11337 long ident = Binder.clearCallingIdentity(); 11338 try { 11339 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11340 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11341 | Intent.FLAG_RECEIVER_FOREGROUND); 11342 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11343 broadcastIntentLocked(null, null, intent, 11344 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11345 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11346 intent = new Intent(Intent.ACTION_USER_STARTING); 11347 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11348 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11349 broadcastIntentLocked(null, null, intent, 11350 null, new IIntentReceiver.Stub() { 11351 @Override 11352 public void performReceive(Intent intent, int resultCode, String data, 11353 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11354 throws RemoteException { 11355 } 11356 }, 0, null, null, 11357 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11358 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11359 } catch (Throwable t) { 11360 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11361 } finally { 11362 Binder.restoreCallingIdentity(ident); 11363 } 11364 mStackSupervisor.resumeTopActivitiesLocked(); 11365 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11366 } 11367 } 11368 11369 private boolean makeAppCrashingLocked(ProcessRecord app, 11370 String shortMsg, String longMsg, String stackTrace) { 11371 app.crashing = true; 11372 app.crashingReport = generateProcessError(app, 11373 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11374 startAppProblemLocked(app); 11375 app.stopFreezingAllLocked(); 11376 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11377 } 11378 11379 private void makeAppNotRespondingLocked(ProcessRecord app, 11380 String activity, String shortMsg, String longMsg) { 11381 app.notResponding = true; 11382 app.notRespondingReport = generateProcessError(app, 11383 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11384 activity, shortMsg, longMsg, null); 11385 startAppProblemLocked(app); 11386 app.stopFreezingAllLocked(); 11387 } 11388 11389 /** 11390 * Generate a process error record, suitable for attachment to a ProcessRecord. 11391 * 11392 * @param app The ProcessRecord in which the error occurred. 11393 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11394 * ActivityManager.AppErrorStateInfo 11395 * @param activity The activity associated with the crash, if known. 11396 * @param shortMsg Short message describing the crash. 11397 * @param longMsg Long message describing the crash. 11398 * @param stackTrace Full crash stack trace, may be null. 11399 * 11400 * @return Returns a fully-formed AppErrorStateInfo record. 11401 */ 11402 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11403 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11404 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11405 11406 report.condition = condition; 11407 report.processName = app.processName; 11408 report.pid = app.pid; 11409 report.uid = app.info.uid; 11410 report.tag = activity; 11411 report.shortMsg = shortMsg; 11412 report.longMsg = longMsg; 11413 report.stackTrace = stackTrace; 11414 11415 return report; 11416 } 11417 11418 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11419 synchronized (this) { 11420 app.crashing = false; 11421 app.crashingReport = null; 11422 app.notResponding = false; 11423 app.notRespondingReport = null; 11424 if (app.anrDialog == fromDialog) { 11425 app.anrDialog = null; 11426 } 11427 if (app.waitDialog == fromDialog) { 11428 app.waitDialog = null; 11429 } 11430 if (app.pid > 0 && app.pid != MY_PID) { 11431 handleAppCrashLocked(app, null, null, null); 11432 app.kill("user request after error", true); 11433 } 11434 } 11435 } 11436 11437 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11438 String stackTrace) { 11439 long now = SystemClock.uptimeMillis(); 11440 11441 Long crashTime; 11442 if (!app.isolated) { 11443 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11444 } else { 11445 crashTime = null; 11446 } 11447 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11448 // This process loses! 11449 Slog.w(TAG, "Process " + app.info.processName 11450 + " has crashed too many times: killing!"); 11451 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11452 app.userId, app.info.processName, app.uid); 11453 mStackSupervisor.handleAppCrashLocked(app); 11454 if (!app.persistent) { 11455 // We don't want to start this process again until the user 11456 // explicitly does so... but for persistent process, we really 11457 // need to keep it running. If a persistent process is actually 11458 // repeatedly crashing, then badness for everyone. 11459 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11460 app.info.processName); 11461 if (!app.isolated) { 11462 // XXX We don't have a way to mark isolated processes 11463 // as bad, since they don't have a peristent identity. 11464 mBadProcesses.put(app.info.processName, app.uid, 11465 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11466 mProcessCrashTimes.remove(app.info.processName, app.uid); 11467 } 11468 app.bad = true; 11469 app.removed = true; 11470 // Don't let services in this process be restarted and potentially 11471 // annoy the user repeatedly. Unless it is persistent, since those 11472 // processes run critical code. 11473 removeProcessLocked(app, false, false, "crash"); 11474 mStackSupervisor.resumeTopActivitiesLocked(); 11475 return false; 11476 } 11477 mStackSupervisor.resumeTopActivitiesLocked(); 11478 } else { 11479 mStackSupervisor.finishTopRunningActivityLocked(app); 11480 } 11481 11482 // Bump up the crash count of any services currently running in the proc. 11483 for (int i=app.services.size()-1; i>=0; i--) { 11484 // Any services running in the application need to be placed 11485 // back in the pending list. 11486 ServiceRecord sr = app.services.valueAt(i); 11487 sr.crashCount++; 11488 } 11489 11490 // If the crashing process is what we consider to be the "home process" and it has been 11491 // replaced by a third-party app, clear the package preferred activities from packages 11492 // with a home activity running in the process to prevent a repeatedly crashing app 11493 // from blocking the user to manually clear the list. 11494 final ArrayList<ActivityRecord> activities = app.activities; 11495 if (app == mHomeProcess && activities.size() > 0 11496 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11497 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11498 final ActivityRecord r = activities.get(activityNdx); 11499 if (r.isHomeActivity()) { 11500 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11501 try { 11502 ActivityThread.getPackageManager() 11503 .clearPackagePreferredActivities(r.packageName); 11504 } catch (RemoteException c) { 11505 // pm is in same process, this will never happen. 11506 } 11507 } 11508 } 11509 } 11510 11511 if (!app.isolated) { 11512 // XXX Can't keep track of crash times for isolated processes, 11513 // because they don't have a perisistent identity. 11514 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11515 } 11516 11517 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11518 return true; 11519 } 11520 11521 void startAppProblemLocked(ProcessRecord app) { 11522 // If this app is not running under the current user, then we 11523 // can't give it a report button because that would require 11524 // launching the report UI under a different user. 11525 app.errorReportReceiver = null; 11526 11527 for (int userId : mCurrentProfileIds) { 11528 if (app.userId == userId) { 11529 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11530 mContext, app.info.packageName, app.info.flags); 11531 } 11532 } 11533 skipCurrentReceiverLocked(app); 11534 } 11535 11536 void skipCurrentReceiverLocked(ProcessRecord app) { 11537 for (BroadcastQueue queue : mBroadcastQueues) { 11538 queue.skipCurrentReceiverLocked(app); 11539 } 11540 } 11541 11542 /** 11543 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11544 * The application process will exit immediately after this call returns. 11545 * @param app object of the crashing app, null for the system server 11546 * @param crashInfo describing the exception 11547 */ 11548 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11549 ProcessRecord r = findAppProcess(app, "Crash"); 11550 final String processName = app == null ? "system_server" 11551 : (r == null ? "unknown" : r.processName); 11552 11553 handleApplicationCrashInner("crash", r, processName, crashInfo); 11554 } 11555 11556 /* Native crash reporting uses this inner version because it needs to be somewhat 11557 * decoupled from the AM-managed cleanup lifecycle 11558 */ 11559 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11560 ApplicationErrorReport.CrashInfo crashInfo) { 11561 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11562 UserHandle.getUserId(Binder.getCallingUid()), processName, 11563 r == null ? -1 : r.info.flags, 11564 crashInfo.exceptionClassName, 11565 crashInfo.exceptionMessage, 11566 crashInfo.throwFileName, 11567 crashInfo.throwLineNumber); 11568 11569 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11570 11571 crashApplication(r, crashInfo); 11572 } 11573 11574 public void handleApplicationStrictModeViolation( 11575 IBinder app, 11576 int violationMask, 11577 StrictMode.ViolationInfo info) { 11578 ProcessRecord r = findAppProcess(app, "StrictMode"); 11579 if (r == null) { 11580 return; 11581 } 11582 11583 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11584 Integer stackFingerprint = info.hashCode(); 11585 boolean logIt = true; 11586 synchronized (mAlreadyLoggedViolatedStacks) { 11587 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11588 logIt = false; 11589 // TODO: sub-sample into EventLog for these, with 11590 // the info.durationMillis? Then we'd get 11591 // the relative pain numbers, without logging all 11592 // the stack traces repeatedly. We'd want to do 11593 // likewise in the client code, which also does 11594 // dup suppression, before the Binder call. 11595 } else { 11596 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11597 mAlreadyLoggedViolatedStacks.clear(); 11598 } 11599 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11600 } 11601 } 11602 if (logIt) { 11603 logStrictModeViolationToDropBox(r, info); 11604 } 11605 } 11606 11607 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11608 AppErrorResult result = new AppErrorResult(); 11609 synchronized (this) { 11610 final long origId = Binder.clearCallingIdentity(); 11611 11612 Message msg = Message.obtain(); 11613 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11614 HashMap<String, Object> data = new HashMap<String, Object>(); 11615 data.put("result", result); 11616 data.put("app", r); 11617 data.put("violationMask", violationMask); 11618 data.put("info", info); 11619 msg.obj = data; 11620 mHandler.sendMessage(msg); 11621 11622 Binder.restoreCallingIdentity(origId); 11623 } 11624 int res = result.get(); 11625 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11626 } 11627 } 11628 11629 // Depending on the policy in effect, there could be a bunch of 11630 // these in quick succession so we try to batch these together to 11631 // minimize disk writes, number of dropbox entries, and maximize 11632 // compression, by having more fewer, larger records. 11633 private void logStrictModeViolationToDropBox( 11634 ProcessRecord process, 11635 StrictMode.ViolationInfo info) { 11636 if (info == null) { 11637 return; 11638 } 11639 final boolean isSystemApp = process == null || 11640 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11641 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11642 final String processName = process == null ? "unknown" : process.processName; 11643 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11644 final DropBoxManager dbox = (DropBoxManager) 11645 mContext.getSystemService(Context.DROPBOX_SERVICE); 11646 11647 // Exit early if the dropbox isn't configured to accept this report type. 11648 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11649 11650 boolean bufferWasEmpty; 11651 boolean needsFlush; 11652 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11653 synchronized (sb) { 11654 bufferWasEmpty = sb.length() == 0; 11655 appendDropBoxProcessHeaders(process, processName, sb); 11656 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11657 sb.append("System-App: ").append(isSystemApp).append("\n"); 11658 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11659 if (info.violationNumThisLoop != 0) { 11660 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11661 } 11662 if (info.numAnimationsRunning != 0) { 11663 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11664 } 11665 if (info.broadcastIntentAction != null) { 11666 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11667 } 11668 if (info.durationMillis != -1) { 11669 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11670 } 11671 if (info.numInstances != -1) { 11672 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11673 } 11674 if (info.tags != null) { 11675 for (String tag : info.tags) { 11676 sb.append("Span-Tag: ").append(tag).append("\n"); 11677 } 11678 } 11679 sb.append("\n"); 11680 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11681 sb.append(info.crashInfo.stackTrace); 11682 } 11683 sb.append("\n"); 11684 11685 // Only buffer up to ~64k. Various logging bits truncate 11686 // things at 128k. 11687 needsFlush = (sb.length() > 64 * 1024); 11688 } 11689 11690 // Flush immediately if the buffer's grown too large, or this 11691 // is a non-system app. Non-system apps are isolated with a 11692 // different tag & policy and not batched. 11693 // 11694 // Batching is useful during internal testing with 11695 // StrictMode settings turned up high. Without batching, 11696 // thousands of separate files could be created on boot. 11697 if (!isSystemApp || needsFlush) { 11698 new Thread("Error dump: " + dropboxTag) { 11699 @Override 11700 public void run() { 11701 String report; 11702 synchronized (sb) { 11703 report = sb.toString(); 11704 sb.delete(0, sb.length()); 11705 sb.trimToSize(); 11706 } 11707 if (report.length() != 0) { 11708 dbox.addText(dropboxTag, report); 11709 } 11710 } 11711 }.start(); 11712 return; 11713 } 11714 11715 // System app batching: 11716 if (!bufferWasEmpty) { 11717 // An existing dropbox-writing thread is outstanding, so 11718 // we don't need to start it up. The existing thread will 11719 // catch the buffer appends we just did. 11720 return; 11721 } 11722 11723 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11724 // (After this point, we shouldn't access AMS internal data structures.) 11725 new Thread("Error dump: " + dropboxTag) { 11726 @Override 11727 public void run() { 11728 // 5 second sleep to let stacks arrive and be batched together 11729 try { 11730 Thread.sleep(5000); // 5 seconds 11731 } catch (InterruptedException e) {} 11732 11733 String errorReport; 11734 synchronized (mStrictModeBuffer) { 11735 errorReport = mStrictModeBuffer.toString(); 11736 if (errorReport.length() == 0) { 11737 return; 11738 } 11739 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11740 mStrictModeBuffer.trimToSize(); 11741 } 11742 dbox.addText(dropboxTag, errorReport); 11743 } 11744 }.start(); 11745 } 11746 11747 /** 11748 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11749 * @param app object of the crashing app, null for the system server 11750 * @param tag reported by the caller 11751 * @param system whether this wtf is coming from the system 11752 * @param crashInfo describing the context of the error 11753 * @return true if the process should exit immediately (WTF is fatal) 11754 */ 11755 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11756 final ApplicationErrorReport.CrashInfo crashInfo) { 11757 final int callingUid = Binder.getCallingUid(); 11758 final int callingPid = Binder.getCallingPid(); 11759 11760 if (system) { 11761 // If this is coming from the system, we could very well have low-level 11762 // system locks held, so we want to do this all asynchronously. And we 11763 // never want this to become fatal, so there is that too. 11764 mHandler.post(new Runnable() { 11765 @Override public void run() { 11766 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11767 } 11768 }); 11769 return false; 11770 } 11771 11772 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11773 crashInfo); 11774 11775 if (r != null && r.pid != Process.myPid() && 11776 Settings.Global.getInt(mContext.getContentResolver(), 11777 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11778 crashApplication(r, crashInfo); 11779 return true; 11780 } else { 11781 return false; 11782 } 11783 } 11784 11785 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11786 final ApplicationErrorReport.CrashInfo crashInfo) { 11787 final ProcessRecord r = findAppProcess(app, "WTF"); 11788 final String processName = app == null ? "system_server" 11789 : (r == null ? "unknown" : r.processName); 11790 11791 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11792 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11793 11794 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11795 11796 return r; 11797 } 11798 11799 /** 11800 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11801 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11802 */ 11803 private ProcessRecord findAppProcess(IBinder app, String reason) { 11804 if (app == null) { 11805 return null; 11806 } 11807 11808 synchronized (this) { 11809 final int NP = mProcessNames.getMap().size(); 11810 for (int ip=0; ip<NP; ip++) { 11811 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11812 final int NA = apps.size(); 11813 for (int ia=0; ia<NA; ia++) { 11814 ProcessRecord p = apps.valueAt(ia); 11815 if (p.thread != null && p.thread.asBinder() == app) { 11816 return p; 11817 } 11818 } 11819 } 11820 11821 Slog.w(TAG, "Can't find mystery application for " + reason 11822 + " from pid=" + Binder.getCallingPid() 11823 + " uid=" + Binder.getCallingUid() + ": " + app); 11824 return null; 11825 } 11826 } 11827 11828 /** 11829 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11830 * to append various headers to the dropbox log text. 11831 */ 11832 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11833 StringBuilder sb) { 11834 // Watchdog thread ends up invoking this function (with 11835 // a null ProcessRecord) to add the stack file to dropbox. 11836 // Do not acquire a lock on this (am) in such cases, as it 11837 // could cause a potential deadlock, if and when watchdog 11838 // is invoked due to unavailability of lock on am and it 11839 // would prevent watchdog from killing system_server. 11840 if (process == null) { 11841 sb.append("Process: ").append(processName).append("\n"); 11842 return; 11843 } 11844 // Note: ProcessRecord 'process' is guarded by the service 11845 // instance. (notably process.pkgList, which could otherwise change 11846 // concurrently during execution of this method) 11847 synchronized (this) { 11848 sb.append("Process: ").append(processName).append("\n"); 11849 int flags = process.info.flags; 11850 IPackageManager pm = AppGlobals.getPackageManager(); 11851 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11852 for (int ip=0; ip<process.pkgList.size(); ip++) { 11853 String pkg = process.pkgList.keyAt(ip); 11854 sb.append("Package: ").append(pkg); 11855 try { 11856 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11857 if (pi != null) { 11858 sb.append(" v").append(pi.versionCode); 11859 if (pi.versionName != null) { 11860 sb.append(" (").append(pi.versionName).append(")"); 11861 } 11862 } 11863 } catch (RemoteException e) { 11864 Slog.e(TAG, "Error getting package info: " + pkg, e); 11865 } 11866 sb.append("\n"); 11867 } 11868 } 11869 } 11870 11871 private static String processClass(ProcessRecord process) { 11872 if (process == null || process.pid == MY_PID) { 11873 return "system_server"; 11874 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11875 return "system_app"; 11876 } else { 11877 return "data_app"; 11878 } 11879 } 11880 11881 /** 11882 * Write a description of an error (crash, WTF, ANR) to the drop box. 11883 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11884 * @param process which caused the error, null means the system server 11885 * @param activity which triggered the error, null if unknown 11886 * @param parent activity related to the error, null if unknown 11887 * @param subject line related to the error, null if absent 11888 * @param report in long form describing the error, null if absent 11889 * @param logFile to include in the report, null if none 11890 * @param crashInfo giving an application stack trace, null if absent 11891 */ 11892 public void addErrorToDropBox(String eventType, 11893 ProcessRecord process, String processName, ActivityRecord activity, 11894 ActivityRecord parent, String subject, 11895 final String report, final File logFile, 11896 final ApplicationErrorReport.CrashInfo crashInfo) { 11897 // NOTE -- this must never acquire the ActivityManagerService lock, 11898 // otherwise the watchdog may be prevented from resetting the system. 11899 11900 final String dropboxTag = processClass(process) + "_" + eventType; 11901 final DropBoxManager dbox = (DropBoxManager) 11902 mContext.getSystemService(Context.DROPBOX_SERVICE); 11903 11904 // Exit early if the dropbox isn't configured to accept this report type. 11905 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11906 11907 final StringBuilder sb = new StringBuilder(1024); 11908 appendDropBoxProcessHeaders(process, processName, sb); 11909 if (activity != null) { 11910 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11911 } 11912 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11913 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11914 } 11915 if (parent != null && parent != activity) { 11916 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11917 } 11918 if (subject != null) { 11919 sb.append("Subject: ").append(subject).append("\n"); 11920 } 11921 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11922 if (Debug.isDebuggerConnected()) { 11923 sb.append("Debugger: Connected\n"); 11924 } 11925 sb.append("\n"); 11926 11927 // Do the rest in a worker thread to avoid blocking the caller on I/O 11928 // (After this point, we shouldn't access AMS internal data structures.) 11929 Thread worker = new Thread("Error dump: " + dropboxTag) { 11930 @Override 11931 public void run() { 11932 if (report != null) { 11933 sb.append(report); 11934 } 11935 if (logFile != null) { 11936 try { 11937 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11938 "\n\n[[TRUNCATED]]")); 11939 } catch (IOException e) { 11940 Slog.e(TAG, "Error reading " + logFile, e); 11941 } 11942 } 11943 if (crashInfo != null && crashInfo.stackTrace != null) { 11944 sb.append(crashInfo.stackTrace); 11945 } 11946 11947 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11948 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11949 if (lines > 0) { 11950 sb.append("\n"); 11951 11952 // Merge several logcat streams, and take the last N lines 11953 InputStreamReader input = null; 11954 try { 11955 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11956 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11957 "-b", "crash", 11958 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11959 11960 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11961 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11962 input = new InputStreamReader(logcat.getInputStream()); 11963 11964 int num; 11965 char[] buf = new char[8192]; 11966 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11967 } catch (IOException e) { 11968 Slog.e(TAG, "Error running logcat", e); 11969 } finally { 11970 if (input != null) try { input.close(); } catch (IOException e) {} 11971 } 11972 } 11973 11974 dbox.addText(dropboxTag, sb.toString()); 11975 } 11976 }; 11977 11978 if (process == null) { 11979 // If process is null, we are being called from some internal code 11980 // and may be about to die -- run this synchronously. 11981 worker.run(); 11982 } else { 11983 worker.start(); 11984 } 11985 } 11986 11987 /** 11988 * Bring up the "unexpected error" dialog box for a crashing app. 11989 * Deal with edge cases (intercepts from instrumented applications, 11990 * ActivityController, error intent receivers, that sort of thing). 11991 * @param r the application crashing 11992 * @param crashInfo describing the failure 11993 */ 11994 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11995 long timeMillis = System.currentTimeMillis(); 11996 String shortMsg = crashInfo.exceptionClassName; 11997 String longMsg = crashInfo.exceptionMessage; 11998 String stackTrace = crashInfo.stackTrace; 11999 if (shortMsg != null && longMsg != null) { 12000 longMsg = shortMsg + ": " + longMsg; 12001 } else if (shortMsg != null) { 12002 longMsg = shortMsg; 12003 } 12004 12005 AppErrorResult result = new AppErrorResult(); 12006 synchronized (this) { 12007 if (mController != null) { 12008 try { 12009 String name = r != null ? r.processName : null; 12010 int pid = r != null ? r.pid : Binder.getCallingPid(); 12011 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12012 if (!mController.appCrashed(name, pid, 12013 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12014 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12015 && "Native crash".equals(crashInfo.exceptionClassName)) { 12016 Slog.w(TAG, "Skip killing native crashed app " + name 12017 + "(" + pid + ") during testing"); 12018 } else { 12019 Slog.w(TAG, "Force-killing crashed app " + name 12020 + " at watcher's request"); 12021 if (r != null) { 12022 r.kill("crash", true); 12023 } else { 12024 // Huh. 12025 Process.killProcess(pid); 12026 Process.killProcessGroup(uid, pid); 12027 } 12028 } 12029 return; 12030 } 12031 } catch (RemoteException e) { 12032 mController = null; 12033 Watchdog.getInstance().setActivityController(null); 12034 } 12035 } 12036 12037 final long origId = Binder.clearCallingIdentity(); 12038 12039 // If this process is running instrumentation, finish it. 12040 if (r != null && r.instrumentationClass != null) { 12041 Slog.w(TAG, "Error in app " + r.processName 12042 + " running instrumentation " + r.instrumentationClass + ":"); 12043 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12044 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12045 Bundle info = new Bundle(); 12046 info.putString("shortMsg", shortMsg); 12047 info.putString("longMsg", longMsg); 12048 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12049 Binder.restoreCallingIdentity(origId); 12050 return; 12051 } 12052 12053 // Log crash in battery stats. 12054 if (r != null) { 12055 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12056 } 12057 12058 // If we can't identify the process or it's already exceeded its crash quota, 12059 // quit right away without showing a crash dialog. 12060 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12061 Binder.restoreCallingIdentity(origId); 12062 return; 12063 } 12064 12065 Message msg = Message.obtain(); 12066 msg.what = SHOW_ERROR_MSG; 12067 HashMap data = new HashMap(); 12068 data.put("result", result); 12069 data.put("app", r); 12070 msg.obj = data; 12071 mHandler.sendMessage(msg); 12072 12073 Binder.restoreCallingIdentity(origId); 12074 } 12075 12076 int res = result.get(); 12077 12078 Intent appErrorIntent = null; 12079 synchronized (this) { 12080 if (r != null && !r.isolated) { 12081 // XXX Can't keep track of crash time for isolated processes, 12082 // since they don't have a persistent identity. 12083 mProcessCrashTimes.put(r.info.processName, r.uid, 12084 SystemClock.uptimeMillis()); 12085 } 12086 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12087 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12088 } 12089 } 12090 12091 if (appErrorIntent != null) { 12092 try { 12093 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12094 } catch (ActivityNotFoundException e) { 12095 Slog.w(TAG, "bug report receiver dissappeared", e); 12096 } 12097 } 12098 } 12099 12100 Intent createAppErrorIntentLocked(ProcessRecord r, 12101 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12102 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12103 if (report == null) { 12104 return null; 12105 } 12106 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12107 result.setComponent(r.errorReportReceiver); 12108 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12109 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12110 return result; 12111 } 12112 12113 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12114 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12115 if (r.errorReportReceiver == null) { 12116 return null; 12117 } 12118 12119 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12120 return null; 12121 } 12122 12123 ApplicationErrorReport report = new ApplicationErrorReport(); 12124 report.packageName = r.info.packageName; 12125 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12126 report.processName = r.processName; 12127 report.time = timeMillis; 12128 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12129 12130 if (r.crashing || r.forceCrashReport) { 12131 report.type = ApplicationErrorReport.TYPE_CRASH; 12132 report.crashInfo = crashInfo; 12133 } else if (r.notResponding) { 12134 report.type = ApplicationErrorReport.TYPE_ANR; 12135 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12136 12137 report.anrInfo.activity = r.notRespondingReport.tag; 12138 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12139 report.anrInfo.info = r.notRespondingReport.longMsg; 12140 } 12141 12142 return report; 12143 } 12144 12145 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12146 enforceNotIsolatedCaller("getProcessesInErrorState"); 12147 // assume our apps are happy - lazy create the list 12148 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12149 12150 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12151 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12152 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12153 12154 synchronized (this) { 12155 12156 // iterate across all processes 12157 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12158 ProcessRecord app = mLruProcesses.get(i); 12159 if (!allUsers && app.userId != userId) { 12160 continue; 12161 } 12162 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12163 // This one's in trouble, so we'll generate a report for it 12164 // crashes are higher priority (in case there's a crash *and* an anr) 12165 ActivityManager.ProcessErrorStateInfo report = null; 12166 if (app.crashing) { 12167 report = app.crashingReport; 12168 } else if (app.notResponding) { 12169 report = app.notRespondingReport; 12170 } 12171 12172 if (report != null) { 12173 if (errList == null) { 12174 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12175 } 12176 errList.add(report); 12177 } else { 12178 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12179 " crashing = " + app.crashing + 12180 " notResponding = " + app.notResponding); 12181 } 12182 } 12183 } 12184 } 12185 12186 return errList; 12187 } 12188 12189 static int procStateToImportance(int procState, int memAdj, 12190 ActivityManager.RunningAppProcessInfo currApp) { 12191 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12192 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12193 currApp.lru = memAdj; 12194 } else { 12195 currApp.lru = 0; 12196 } 12197 return imp; 12198 } 12199 12200 private void fillInProcMemInfo(ProcessRecord app, 12201 ActivityManager.RunningAppProcessInfo outInfo) { 12202 outInfo.pid = app.pid; 12203 outInfo.uid = app.info.uid; 12204 if (mHeavyWeightProcess == app) { 12205 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12206 } 12207 if (app.persistent) { 12208 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12209 } 12210 if (app.activities.size() > 0) { 12211 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12212 } 12213 outInfo.lastTrimLevel = app.trimMemoryLevel; 12214 int adj = app.curAdj; 12215 int procState = app.curProcState; 12216 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12217 outInfo.importanceReasonCode = app.adjTypeCode; 12218 outInfo.processState = app.curProcState; 12219 } 12220 12221 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12222 enforceNotIsolatedCaller("getRunningAppProcesses"); 12223 // Lazy instantiation of list 12224 List<ActivityManager.RunningAppProcessInfo> runList = null; 12225 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12226 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12227 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12228 synchronized (this) { 12229 // Iterate across all processes 12230 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12231 ProcessRecord app = mLruProcesses.get(i); 12232 if (!allUsers && app.userId != userId) { 12233 continue; 12234 } 12235 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12236 // Generate process state info for running application 12237 ActivityManager.RunningAppProcessInfo currApp = 12238 new ActivityManager.RunningAppProcessInfo(app.processName, 12239 app.pid, app.getPackageList()); 12240 fillInProcMemInfo(app, currApp); 12241 if (app.adjSource instanceof ProcessRecord) { 12242 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12243 currApp.importanceReasonImportance = 12244 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12245 app.adjSourceProcState); 12246 } else if (app.adjSource instanceof ActivityRecord) { 12247 ActivityRecord r = (ActivityRecord)app.adjSource; 12248 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12249 } 12250 if (app.adjTarget instanceof ComponentName) { 12251 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12252 } 12253 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12254 // + " lru=" + currApp.lru); 12255 if (runList == null) { 12256 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12257 } 12258 runList.add(currApp); 12259 } 12260 } 12261 } 12262 return runList; 12263 } 12264 12265 public List<ApplicationInfo> getRunningExternalApplications() { 12266 enforceNotIsolatedCaller("getRunningExternalApplications"); 12267 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12268 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12269 if (runningApps != null && runningApps.size() > 0) { 12270 Set<String> extList = new HashSet<String>(); 12271 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12272 if (app.pkgList != null) { 12273 for (String pkg : app.pkgList) { 12274 extList.add(pkg); 12275 } 12276 } 12277 } 12278 IPackageManager pm = AppGlobals.getPackageManager(); 12279 for (String pkg : extList) { 12280 try { 12281 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12282 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12283 retList.add(info); 12284 } 12285 } catch (RemoteException e) { 12286 } 12287 } 12288 } 12289 return retList; 12290 } 12291 12292 @Override 12293 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12294 enforceNotIsolatedCaller("getMyMemoryState"); 12295 synchronized (this) { 12296 ProcessRecord proc; 12297 synchronized (mPidsSelfLocked) { 12298 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12299 } 12300 fillInProcMemInfo(proc, outInfo); 12301 } 12302 } 12303 12304 @Override 12305 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12306 if (checkCallingPermission(android.Manifest.permission.DUMP) 12307 != PackageManager.PERMISSION_GRANTED) { 12308 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12309 + Binder.getCallingPid() 12310 + ", uid=" + Binder.getCallingUid() 12311 + " without permission " 12312 + android.Manifest.permission.DUMP); 12313 return; 12314 } 12315 12316 boolean dumpAll = false; 12317 boolean dumpClient = false; 12318 String dumpPackage = null; 12319 12320 int opti = 0; 12321 while (opti < args.length) { 12322 String opt = args[opti]; 12323 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12324 break; 12325 } 12326 opti++; 12327 if ("-a".equals(opt)) { 12328 dumpAll = true; 12329 } else if ("-c".equals(opt)) { 12330 dumpClient = true; 12331 } else if ("-h".equals(opt)) { 12332 pw.println("Activity manager dump options:"); 12333 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12334 pw.println(" cmd may be one of:"); 12335 pw.println(" a[ctivities]: activity stack state"); 12336 pw.println(" r[recents]: recent activities state"); 12337 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12338 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12339 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12340 pw.println(" o[om]: out of memory management"); 12341 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12342 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12343 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12344 pw.println(" service [COMP_SPEC]: service client-side state"); 12345 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12346 pw.println(" all: dump all activities"); 12347 pw.println(" top: dump the top activity"); 12348 pw.println(" write: write all pending state to storage"); 12349 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12350 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12351 pw.println(" a partial substring in a component name, a"); 12352 pw.println(" hex object identifier."); 12353 pw.println(" -a: include all available server state."); 12354 pw.println(" -c: include client state."); 12355 return; 12356 } else { 12357 pw.println("Unknown argument: " + opt + "; use -h for help"); 12358 } 12359 } 12360 12361 long origId = Binder.clearCallingIdentity(); 12362 boolean more = false; 12363 // Is the caller requesting to dump a particular piece of data? 12364 if (opti < args.length) { 12365 String cmd = args[opti]; 12366 opti++; 12367 if ("activities".equals(cmd) || "a".equals(cmd)) { 12368 synchronized (this) { 12369 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12370 } 12371 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12372 synchronized (this) { 12373 dumpRecentsLocked(fd, pw, args, opti, true, null); 12374 } 12375 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12376 String[] newArgs; 12377 String name; 12378 if (opti >= args.length) { 12379 name = null; 12380 newArgs = EMPTY_STRING_ARRAY; 12381 } else { 12382 name = args[opti]; 12383 opti++; 12384 newArgs = new String[args.length - opti]; 12385 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12386 args.length - opti); 12387 } 12388 synchronized (this) { 12389 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12390 } 12391 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12392 String[] newArgs; 12393 String name; 12394 if (opti >= args.length) { 12395 name = null; 12396 newArgs = EMPTY_STRING_ARRAY; 12397 } else { 12398 name = args[opti]; 12399 opti++; 12400 newArgs = new String[args.length - opti]; 12401 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12402 args.length - opti); 12403 } 12404 synchronized (this) { 12405 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12406 } 12407 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12408 String[] newArgs; 12409 String name; 12410 if (opti >= args.length) { 12411 name = null; 12412 newArgs = EMPTY_STRING_ARRAY; 12413 } else { 12414 name = args[opti]; 12415 opti++; 12416 newArgs = new String[args.length - opti]; 12417 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12418 args.length - opti); 12419 } 12420 synchronized (this) { 12421 dumpProcessesLocked(fd, pw, args, opti, true, name); 12422 } 12423 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12424 synchronized (this) { 12425 dumpOomLocked(fd, pw, args, opti, true); 12426 } 12427 } else if ("provider".equals(cmd)) { 12428 String[] newArgs; 12429 String name; 12430 if (opti >= args.length) { 12431 name = null; 12432 newArgs = EMPTY_STRING_ARRAY; 12433 } else { 12434 name = args[opti]; 12435 opti++; 12436 newArgs = new String[args.length - opti]; 12437 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12438 } 12439 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12440 pw.println("No providers match: " + name); 12441 pw.println("Use -h for help."); 12442 } 12443 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12444 synchronized (this) { 12445 dumpProvidersLocked(fd, pw, args, opti, true, null); 12446 } 12447 } else if ("service".equals(cmd)) { 12448 String[] newArgs; 12449 String name; 12450 if (opti >= args.length) { 12451 name = null; 12452 newArgs = EMPTY_STRING_ARRAY; 12453 } else { 12454 name = args[opti]; 12455 opti++; 12456 newArgs = new String[args.length - opti]; 12457 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12458 args.length - opti); 12459 } 12460 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12461 pw.println("No services match: " + name); 12462 pw.println("Use -h for help."); 12463 } 12464 } else if ("package".equals(cmd)) { 12465 String[] newArgs; 12466 if (opti >= args.length) { 12467 pw.println("package: no package name specified"); 12468 pw.println("Use -h for help."); 12469 } else { 12470 dumpPackage = args[opti]; 12471 opti++; 12472 newArgs = new String[args.length - opti]; 12473 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12474 args.length - opti); 12475 args = newArgs; 12476 opti = 0; 12477 more = true; 12478 } 12479 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12480 synchronized (this) { 12481 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12482 } 12483 } else if ("write".equals(cmd)) { 12484 mTaskPersister.flush(); 12485 pw.println("All tasks persisted."); 12486 return; 12487 } else { 12488 // Dumping a single activity? 12489 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12490 pw.println("Bad activity command, or no activities match: " + cmd); 12491 pw.println("Use -h for help."); 12492 } 12493 } 12494 if (!more) { 12495 Binder.restoreCallingIdentity(origId); 12496 return; 12497 } 12498 } 12499 12500 // No piece of data specified, dump everything. 12501 synchronized (this) { 12502 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12503 pw.println(); 12504 if (dumpAll) { 12505 pw.println("-------------------------------------------------------------------------------"); 12506 } 12507 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12508 pw.println(); 12509 if (dumpAll) { 12510 pw.println("-------------------------------------------------------------------------------"); 12511 } 12512 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12513 pw.println(); 12514 if (dumpAll) { 12515 pw.println("-------------------------------------------------------------------------------"); 12516 } 12517 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12518 pw.println(); 12519 if (dumpAll) { 12520 pw.println("-------------------------------------------------------------------------------"); 12521 } 12522 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12523 pw.println(); 12524 if (dumpAll) { 12525 pw.println("-------------------------------------------------------------------------------"); 12526 } 12527 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12528 pw.println(); 12529 if (dumpAll) { 12530 pw.println("-------------------------------------------------------------------------------"); 12531 } 12532 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12533 } 12534 Binder.restoreCallingIdentity(origId); 12535 } 12536 12537 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12538 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12539 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12540 12541 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12542 dumpPackage); 12543 boolean needSep = printedAnything; 12544 12545 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12546 dumpPackage, needSep, " mFocusedActivity: "); 12547 if (printed) { 12548 printedAnything = true; 12549 needSep = false; 12550 } 12551 12552 if (dumpPackage == null) { 12553 if (needSep) { 12554 pw.println(); 12555 } 12556 needSep = true; 12557 printedAnything = true; 12558 mStackSupervisor.dump(pw, " "); 12559 } 12560 12561 if (!printedAnything) { 12562 pw.println(" (nothing)"); 12563 } 12564 } 12565 12566 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12567 int opti, boolean dumpAll, String dumpPackage) { 12568 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12569 12570 boolean printedAnything = false; 12571 12572 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12573 boolean printedHeader = false; 12574 12575 final int N = mRecentTasks.size(); 12576 for (int i=0; i<N; i++) { 12577 TaskRecord tr = mRecentTasks.get(i); 12578 if (dumpPackage != null) { 12579 if (tr.realActivity == null || 12580 !dumpPackage.equals(tr.realActivity)) { 12581 continue; 12582 } 12583 } 12584 if (!printedHeader) { 12585 pw.println(" Recent tasks:"); 12586 printedHeader = true; 12587 printedAnything = true; 12588 } 12589 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12590 pw.println(tr); 12591 if (dumpAll) { 12592 mRecentTasks.get(i).dump(pw, " "); 12593 } 12594 } 12595 } 12596 12597 if (!printedAnything) { 12598 pw.println(" (nothing)"); 12599 } 12600 } 12601 12602 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12603 int opti, boolean dumpAll, String dumpPackage) { 12604 boolean needSep = false; 12605 boolean printedAnything = false; 12606 int numPers = 0; 12607 12608 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12609 12610 if (dumpAll) { 12611 final int NP = mProcessNames.getMap().size(); 12612 for (int ip=0; ip<NP; ip++) { 12613 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12614 final int NA = procs.size(); 12615 for (int ia=0; ia<NA; ia++) { 12616 ProcessRecord r = procs.valueAt(ia); 12617 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12618 continue; 12619 } 12620 if (!needSep) { 12621 pw.println(" All known processes:"); 12622 needSep = true; 12623 printedAnything = true; 12624 } 12625 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12626 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12627 pw.print(" "); pw.println(r); 12628 r.dump(pw, " "); 12629 if (r.persistent) { 12630 numPers++; 12631 } 12632 } 12633 } 12634 } 12635 12636 if (mIsolatedProcesses.size() > 0) { 12637 boolean printed = false; 12638 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12639 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12640 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12641 continue; 12642 } 12643 if (!printed) { 12644 if (needSep) { 12645 pw.println(); 12646 } 12647 pw.println(" Isolated process list (sorted by uid):"); 12648 printedAnything = true; 12649 printed = true; 12650 needSep = true; 12651 } 12652 pw.println(String.format("%sIsolated #%2d: %s", 12653 " ", i, r.toString())); 12654 } 12655 } 12656 12657 if (mLruProcesses.size() > 0) { 12658 if (needSep) { 12659 pw.println(); 12660 } 12661 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12662 pw.print(" total, non-act at "); 12663 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12664 pw.print(", non-svc at "); 12665 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12666 pw.println("):"); 12667 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12668 needSep = true; 12669 printedAnything = true; 12670 } 12671 12672 if (dumpAll || dumpPackage != null) { 12673 synchronized (mPidsSelfLocked) { 12674 boolean printed = false; 12675 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12676 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12677 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12678 continue; 12679 } 12680 if (!printed) { 12681 if (needSep) pw.println(); 12682 needSep = true; 12683 pw.println(" PID mappings:"); 12684 printed = true; 12685 printedAnything = true; 12686 } 12687 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12688 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12689 } 12690 } 12691 } 12692 12693 if (mForegroundProcesses.size() > 0) { 12694 synchronized (mPidsSelfLocked) { 12695 boolean printed = false; 12696 for (int i=0; i<mForegroundProcesses.size(); i++) { 12697 ProcessRecord r = mPidsSelfLocked.get( 12698 mForegroundProcesses.valueAt(i).pid); 12699 if (dumpPackage != null && (r == null 12700 || !r.pkgList.containsKey(dumpPackage))) { 12701 continue; 12702 } 12703 if (!printed) { 12704 if (needSep) pw.println(); 12705 needSep = true; 12706 pw.println(" Foreground Processes:"); 12707 printed = true; 12708 printedAnything = true; 12709 } 12710 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12711 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12712 } 12713 } 12714 } 12715 12716 if (mPersistentStartingProcesses.size() > 0) { 12717 if (needSep) pw.println(); 12718 needSep = true; 12719 printedAnything = true; 12720 pw.println(" Persisent processes that are starting:"); 12721 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12722 "Starting Norm", "Restarting PERS", dumpPackage); 12723 } 12724 12725 if (mRemovedProcesses.size() > 0) { 12726 if (needSep) pw.println(); 12727 needSep = true; 12728 printedAnything = true; 12729 pw.println(" Processes that are being removed:"); 12730 dumpProcessList(pw, this, mRemovedProcesses, " ", 12731 "Removed Norm", "Removed PERS", dumpPackage); 12732 } 12733 12734 if (mProcessesOnHold.size() > 0) { 12735 if (needSep) pw.println(); 12736 needSep = true; 12737 printedAnything = true; 12738 pw.println(" Processes that are on old until the system is ready:"); 12739 dumpProcessList(pw, this, mProcessesOnHold, " ", 12740 "OnHold Norm", "OnHold PERS", dumpPackage); 12741 } 12742 12743 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12744 12745 if (mProcessCrashTimes.getMap().size() > 0) { 12746 boolean printed = false; 12747 long now = SystemClock.uptimeMillis(); 12748 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12749 final int NP = pmap.size(); 12750 for (int ip=0; ip<NP; ip++) { 12751 String pname = pmap.keyAt(ip); 12752 SparseArray<Long> uids = pmap.valueAt(ip); 12753 final int N = uids.size(); 12754 for (int i=0; i<N; i++) { 12755 int puid = uids.keyAt(i); 12756 ProcessRecord r = mProcessNames.get(pname, puid); 12757 if (dumpPackage != null && (r == null 12758 || !r.pkgList.containsKey(dumpPackage))) { 12759 continue; 12760 } 12761 if (!printed) { 12762 if (needSep) pw.println(); 12763 needSep = true; 12764 pw.println(" Time since processes crashed:"); 12765 printed = true; 12766 printedAnything = true; 12767 } 12768 pw.print(" Process "); pw.print(pname); 12769 pw.print(" uid "); pw.print(puid); 12770 pw.print(": last crashed "); 12771 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12772 pw.println(" ago"); 12773 } 12774 } 12775 } 12776 12777 if (mBadProcesses.getMap().size() > 0) { 12778 boolean printed = false; 12779 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12780 final int NP = pmap.size(); 12781 for (int ip=0; ip<NP; ip++) { 12782 String pname = pmap.keyAt(ip); 12783 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12784 final int N = uids.size(); 12785 for (int i=0; i<N; i++) { 12786 int puid = uids.keyAt(i); 12787 ProcessRecord r = mProcessNames.get(pname, puid); 12788 if (dumpPackage != null && (r == null 12789 || !r.pkgList.containsKey(dumpPackage))) { 12790 continue; 12791 } 12792 if (!printed) { 12793 if (needSep) pw.println(); 12794 needSep = true; 12795 pw.println(" Bad processes:"); 12796 printedAnything = true; 12797 } 12798 BadProcessInfo info = uids.valueAt(i); 12799 pw.print(" Bad process "); pw.print(pname); 12800 pw.print(" uid "); pw.print(puid); 12801 pw.print(": crashed at time "); pw.println(info.time); 12802 if (info.shortMsg != null) { 12803 pw.print(" Short msg: "); pw.println(info.shortMsg); 12804 } 12805 if (info.longMsg != null) { 12806 pw.print(" Long msg: "); pw.println(info.longMsg); 12807 } 12808 if (info.stack != null) { 12809 pw.println(" Stack:"); 12810 int lastPos = 0; 12811 for (int pos=0; pos<info.stack.length(); pos++) { 12812 if (info.stack.charAt(pos) == '\n') { 12813 pw.print(" "); 12814 pw.write(info.stack, lastPos, pos-lastPos); 12815 pw.println(); 12816 lastPos = pos+1; 12817 } 12818 } 12819 if (lastPos < info.stack.length()) { 12820 pw.print(" "); 12821 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12822 pw.println(); 12823 } 12824 } 12825 } 12826 } 12827 } 12828 12829 if (dumpPackage == null) { 12830 pw.println(); 12831 needSep = false; 12832 pw.println(" mStartedUsers:"); 12833 for (int i=0; i<mStartedUsers.size(); i++) { 12834 UserStartedState uss = mStartedUsers.valueAt(i); 12835 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12836 pw.print(": "); uss.dump("", pw); 12837 } 12838 pw.print(" mStartedUserArray: ["); 12839 for (int i=0; i<mStartedUserArray.length; i++) { 12840 if (i > 0) pw.print(", "); 12841 pw.print(mStartedUserArray[i]); 12842 } 12843 pw.println("]"); 12844 pw.print(" mUserLru: ["); 12845 for (int i=0; i<mUserLru.size(); i++) { 12846 if (i > 0) pw.print(", "); 12847 pw.print(mUserLru.get(i)); 12848 } 12849 pw.println("]"); 12850 if (dumpAll) { 12851 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12852 } 12853 synchronized (mUserProfileGroupIdsSelfLocked) { 12854 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12855 pw.println(" mUserProfileGroupIds:"); 12856 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12857 pw.print(" User #"); 12858 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12859 pw.print(" -> profile #"); 12860 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12861 } 12862 } 12863 } 12864 } 12865 if (mHomeProcess != null && (dumpPackage == null 12866 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12867 if (needSep) { 12868 pw.println(); 12869 needSep = false; 12870 } 12871 pw.println(" mHomeProcess: " + mHomeProcess); 12872 } 12873 if (mPreviousProcess != null && (dumpPackage == null 12874 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12875 if (needSep) { 12876 pw.println(); 12877 needSep = false; 12878 } 12879 pw.println(" mPreviousProcess: " + mPreviousProcess); 12880 } 12881 if (dumpAll) { 12882 StringBuilder sb = new StringBuilder(128); 12883 sb.append(" mPreviousProcessVisibleTime: "); 12884 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12885 pw.println(sb); 12886 } 12887 if (mHeavyWeightProcess != null && (dumpPackage == null 12888 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12889 if (needSep) { 12890 pw.println(); 12891 needSep = false; 12892 } 12893 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12894 } 12895 if (dumpPackage == null) { 12896 pw.println(" mConfiguration: " + mConfiguration); 12897 } 12898 if (dumpAll) { 12899 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12900 if (mCompatModePackages.getPackages().size() > 0) { 12901 boolean printed = false; 12902 for (Map.Entry<String, Integer> entry 12903 : mCompatModePackages.getPackages().entrySet()) { 12904 String pkg = entry.getKey(); 12905 int mode = entry.getValue(); 12906 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12907 continue; 12908 } 12909 if (!printed) { 12910 pw.println(" mScreenCompatPackages:"); 12911 printed = true; 12912 } 12913 pw.print(" "); pw.print(pkg); pw.print(": "); 12914 pw.print(mode); pw.println(); 12915 } 12916 } 12917 } 12918 if (dumpPackage == null) { 12919 pw.println(" mWakefulness=" 12920 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12921 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12922 + lockScreenShownToString()); 12923 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 12924 + " mTestPssMode=" + mTestPssMode); 12925 } 12926 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12927 || mOrigWaitForDebugger) { 12928 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12929 || dumpPackage.equals(mOrigDebugApp)) { 12930 if (needSep) { 12931 pw.println(); 12932 needSep = false; 12933 } 12934 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12935 + " mDebugTransient=" + mDebugTransient 12936 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12937 } 12938 } 12939 if (mOpenGlTraceApp != null) { 12940 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12941 if (needSep) { 12942 pw.println(); 12943 needSep = false; 12944 } 12945 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12946 } 12947 } 12948 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12949 || mProfileFd != null) { 12950 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12951 if (needSep) { 12952 pw.println(); 12953 needSep = false; 12954 } 12955 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12956 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12957 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12958 + mAutoStopProfiler); 12959 pw.println(" mProfileType=" + mProfileType); 12960 } 12961 } 12962 if (dumpPackage == null) { 12963 if (mAlwaysFinishActivities || mController != null) { 12964 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12965 + " mController=" + mController); 12966 } 12967 if (dumpAll) { 12968 pw.println(" Total persistent processes: " + numPers); 12969 pw.println(" mProcessesReady=" + mProcessesReady 12970 + " mSystemReady=" + mSystemReady 12971 + " mBooted=" + mBooted 12972 + " mFactoryTest=" + mFactoryTest); 12973 pw.println(" mBooting=" + mBooting 12974 + " mCallFinishBooting=" + mCallFinishBooting 12975 + " mBootAnimationComplete=" + mBootAnimationComplete); 12976 pw.print(" mLastPowerCheckRealtime="); 12977 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12978 pw.println(""); 12979 pw.print(" mLastPowerCheckUptime="); 12980 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12981 pw.println(""); 12982 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12983 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12984 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12985 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12986 + " (" + mLruProcesses.size() + " total)" 12987 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12988 + " mNumServiceProcs=" + mNumServiceProcs 12989 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12990 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12991 + " mLastMemoryLevel" + mLastMemoryLevel 12992 + " mLastNumProcesses" + mLastNumProcesses); 12993 long now = SystemClock.uptimeMillis(); 12994 pw.print(" mLastIdleTime="); 12995 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12996 pw.print(" mLowRamSinceLastIdle="); 12997 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12998 pw.println(); 12999 } 13000 } 13001 13002 if (!printedAnything) { 13003 pw.println(" (nothing)"); 13004 } 13005 } 13006 13007 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13008 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13009 if (mProcessesToGc.size() > 0) { 13010 boolean printed = false; 13011 long now = SystemClock.uptimeMillis(); 13012 for (int i=0; i<mProcessesToGc.size(); i++) { 13013 ProcessRecord proc = mProcessesToGc.get(i); 13014 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13015 continue; 13016 } 13017 if (!printed) { 13018 if (needSep) pw.println(); 13019 needSep = true; 13020 pw.println(" Processes that are waiting to GC:"); 13021 printed = true; 13022 } 13023 pw.print(" Process "); pw.println(proc); 13024 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13025 pw.print(", last gced="); 13026 pw.print(now-proc.lastRequestedGc); 13027 pw.print(" ms ago, last lowMem="); 13028 pw.print(now-proc.lastLowMemory); 13029 pw.println(" ms ago"); 13030 13031 } 13032 } 13033 return needSep; 13034 } 13035 13036 void printOomLevel(PrintWriter pw, String name, int adj) { 13037 pw.print(" "); 13038 if (adj >= 0) { 13039 pw.print(' '); 13040 if (adj < 10) pw.print(' '); 13041 } else { 13042 if (adj > -10) pw.print(' '); 13043 } 13044 pw.print(adj); 13045 pw.print(": "); 13046 pw.print(name); 13047 pw.print(" ("); 13048 pw.print(mProcessList.getMemLevel(adj)/1024); 13049 pw.println(" kB)"); 13050 } 13051 13052 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13053 int opti, boolean dumpAll) { 13054 boolean needSep = false; 13055 13056 if (mLruProcesses.size() > 0) { 13057 if (needSep) pw.println(); 13058 needSep = true; 13059 pw.println(" OOM levels:"); 13060 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13061 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13062 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13063 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13064 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13065 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13066 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13067 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13068 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13069 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13070 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13071 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13072 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13073 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13074 13075 if (needSep) pw.println(); 13076 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13077 pw.print(" total, non-act at "); 13078 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13079 pw.print(", non-svc at "); 13080 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13081 pw.println("):"); 13082 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13083 needSep = true; 13084 } 13085 13086 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13087 13088 pw.println(); 13089 pw.println(" mHomeProcess: " + mHomeProcess); 13090 pw.println(" mPreviousProcess: " + mPreviousProcess); 13091 if (mHeavyWeightProcess != null) { 13092 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13093 } 13094 13095 return true; 13096 } 13097 13098 /** 13099 * There are three ways to call this: 13100 * - no provider specified: dump all the providers 13101 * - a flattened component name that matched an existing provider was specified as the 13102 * first arg: dump that one provider 13103 * - the first arg isn't the flattened component name of an existing provider: 13104 * dump all providers whose component contains the first arg as a substring 13105 */ 13106 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13107 int opti, boolean dumpAll) { 13108 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13109 } 13110 13111 static class ItemMatcher { 13112 ArrayList<ComponentName> components; 13113 ArrayList<String> strings; 13114 ArrayList<Integer> objects; 13115 boolean all; 13116 13117 ItemMatcher() { 13118 all = true; 13119 } 13120 13121 void build(String name) { 13122 ComponentName componentName = ComponentName.unflattenFromString(name); 13123 if (componentName != null) { 13124 if (components == null) { 13125 components = new ArrayList<ComponentName>(); 13126 } 13127 components.add(componentName); 13128 all = false; 13129 } else { 13130 int objectId = 0; 13131 // Not a '/' separated full component name; maybe an object ID? 13132 try { 13133 objectId = Integer.parseInt(name, 16); 13134 if (objects == null) { 13135 objects = new ArrayList<Integer>(); 13136 } 13137 objects.add(objectId); 13138 all = false; 13139 } catch (RuntimeException e) { 13140 // Not an integer; just do string match. 13141 if (strings == null) { 13142 strings = new ArrayList<String>(); 13143 } 13144 strings.add(name); 13145 all = false; 13146 } 13147 } 13148 } 13149 13150 int build(String[] args, int opti) { 13151 for (; opti<args.length; opti++) { 13152 String name = args[opti]; 13153 if ("--".equals(name)) { 13154 return opti+1; 13155 } 13156 build(name); 13157 } 13158 return opti; 13159 } 13160 13161 boolean match(Object object, ComponentName comp) { 13162 if (all) { 13163 return true; 13164 } 13165 if (components != null) { 13166 for (int i=0; i<components.size(); i++) { 13167 if (components.get(i).equals(comp)) { 13168 return true; 13169 } 13170 } 13171 } 13172 if (objects != null) { 13173 for (int i=0; i<objects.size(); i++) { 13174 if (System.identityHashCode(object) == objects.get(i)) { 13175 return true; 13176 } 13177 } 13178 } 13179 if (strings != null) { 13180 String flat = comp.flattenToString(); 13181 for (int i=0; i<strings.size(); i++) { 13182 if (flat.contains(strings.get(i))) { 13183 return true; 13184 } 13185 } 13186 } 13187 return false; 13188 } 13189 } 13190 13191 /** 13192 * There are three things that cmd can be: 13193 * - a flattened component name that matches an existing activity 13194 * - the cmd arg isn't the flattened component name of an existing activity: 13195 * dump all activity whose component contains the cmd as a substring 13196 * - A hex number of the ActivityRecord object instance. 13197 */ 13198 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13199 int opti, boolean dumpAll) { 13200 ArrayList<ActivityRecord> activities; 13201 13202 synchronized (this) { 13203 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13204 } 13205 13206 if (activities.size() <= 0) { 13207 return false; 13208 } 13209 13210 String[] newArgs = new String[args.length - opti]; 13211 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13212 13213 TaskRecord lastTask = null; 13214 boolean needSep = false; 13215 for (int i=activities.size()-1; i>=0; i--) { 13216 ActivityRecord r = activities.get(i); 13217 if (needSep) { 13218 pw.println(); 13219 } 13220 needSep = true; 13221 synchronized (this) { 13222 if (lastTask != r.task) { 13223 lastTask = r.task; 13224 pw.print("TASK "); pw.print(lastTask.affinity); 13225 pw.print(" id="); pw.println(lastTask.taskId); 13226 if (dumpAll) { 13227 lastTask.dump(pw, " "); 13228 } 13229 } 13230 } 13231 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13232 } 13233 return true; 13234 } 13235 13236 /** 13237 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13238 * there is a thread associated with the activity. 13239 */ 13240 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13241 final ActivityRecord r, String[] args, boolean dumpAll) { 13242 String innerPrefix = prefix + " "; 13243 synchronized (this) { 13244 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13245 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13246 pw.print(" pid="); 13247 if (r.app != null) pw.println(r.app.pid); 13248 else pw.println("(not running)"); 13249 if (dumpAll) { 13250 r.dump(pw, innerPrefix); 13251 } 13252 } 13253 if (r.app != null && r.app.thread != null) { 13254 // flush anything that is already in the PrintWriter since the thread is going 13255 // to write to the file descriptor directly 13256 pw.flush(); 13257 try { 13258 TransferPipe tp = new TransferPipe(); 13259 try { 13260 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13261 r.appToken, innerPrefix, args); 13262 tp.go(fd); 13263 } finally { 13264 tp.kill(); 13265 } 13266 } catch (IOException e) { 13267 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13268 } catch (RemoteException e) { 13269 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13270 } 13271 } 13272 } 13273 13274 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13275 int opti, boolean dumpAll, String dumpPackage) { 13276 boolean needSep = false; 13277 boolean onlyHistory = false; 13278 boolean printedAnything = false; 13279 13280 if ("history".equals(dumpPackage)) { 13281 if (opti < args.length && "-s".equals(args[opti])) { 13282 dumpAll = false; 13283 } 13284 onlyHistory = true; 13285 dumpPackage = null; 13286 } 13287 13288 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13289 if (!onlyHistory && dumpAll) { 13290 if (mRegisteredReceivers.size() > 0) { 13291 boolean printed = false; 13292 Iterator it = mRegisteredReceivers.values().iterator(); 13293 while (it.hasNext()) { 13294 ReceiverList r = (ReceiverList)it.next(); 13295 if (dumpPackage != null && (r.app == null || 13296 !dumpPackage.equals(r.app.info.packageName))) { 13297 continue; 13298 } 13299 if (!printed) { 13300 pw.println(" Registered Receivers:"); 13301 needSep = true; 13302 printed = true; 13303 printedAnything = true; 13304 } 13305 pw.print(" * "); pw.println(r); 13306 r.dump(pw, " "); 13307 } 13308 } 13309 13310 if (mReceiverResolver.dump(pw, needSep ? 13311 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13312 " ", dumpPackage, false, false)) { 13313 needSep = true; 13314 printedAnything = true; 13315 } 13316 } 13317 13318 for (BroadcastQueue q : mBroadcastQueues) { 13319 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13320 printedAnything |= needSep; 13321 } 13322 13323 needSep = true; 13324 13325 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13326 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13327 if (needSep) { 13328 pw.println(); 13329 } 13330 needSep = true; 13331 printedAnything = true; 13332 pw.print(" Sticky broadcasts for user "); 13333 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13334 StringBuilder sb = new StringBuilder(128); 13335 for (Map.Entry<String, ArrayList<Intent>> ent 13336 : mStickyBroadcasts.valueAt(user).entrySet()) { 13337 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13338 if (dumpAll) { 13339 pw.println(":"); 13340 ArrayList<Intent> intents = ent.getValue(); 13341 final int N = intents.size(); 13342 for (int i=0; i<N; i++) { 13343 sb.setLength(0); 13344 sb.append(" Intent: "); 13345 intents.get(i).toShortString(sb, false, true, false, false); 13346 pw.println(sb.toString()); 13347 Bundle bundle = intents.get(i).getExtras(); 13348 if (bundle != null) { 13349 pw.print(" "); 13350 pw.println(bundle.toString()); 13351 } 13352 } 13353 } else { 13354 pw.println(""); 13355 } 13356 } 13357 } 13358 } 13359 13360 if (!onlyHistory && dumpAll) { 13361 pw.println(); 13362 for (BroadcastQueue queue : mBroadcastQueues) { 13363 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13364 + queue.mBroadcastsScheduled); 13365 } 13366 pw.println(" mHandler:"); 13367 mHandler.dump(new PrintWriterPrinter(pw), " "); 13368 needSep = true; 13369 printedAnything = true; 13370 } 13371 13372 if (!printedAnything) { 13373 pw.println(" (nothing)"); 13374 } 13375 } 13376 13377 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13378 int opti, boolean dumpAll, String dumpPackage) { 13379 boolean needSep; 13380 boolean printedAnything = false; 13381 13382 ItemMatcher matcher = new ItemMatcher(); 13383 matcher.build(args, opti); 13384 13385 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13386 13387 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13388 printedAnything |= needSep; 13389 13390 if (mLaunchingProviders.size() > 0) { 13391 boolean printed = false; 13392 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13393 ContentProviderRecord r = mLaunchingProviders.get(i); 13394 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13395 continue; 13396 } 13397 if (!printed) { 13398 if (needSep) pw.println(); 13399 needSep = true; 13400 pw.println(" Launching content providers:"); 13401 printed = true; 13402 printedAnything = true; 13403 } 13404 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13405 pw.println(r); 13406 } 13407 } 13408 13409 if (mGrantedUriPermissions.size() > 0) { 13410 boolean printed = false; 13411 int dumpUid = -2; 13412 if (dumpPackage != null) { 13413 try { 13414 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13415 } catch (NameNotFoundException e) { 13416 dumpUid = -1; 13417 } 13418 } 13419 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13420 int uid = mGrantedUriPermissions.keyAt(i); 13421 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13422 continue; 13423 } 13424 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13425 if (!printed) { 13426 if (needSep) pw.println(); 13427 needSep = true; 13428 pw.println(" Granted Uri Permissions:"); 13429 printed = true; 13430 printedAnything = true; 13431 } 13432 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13433 for (UriPermission perm : perms.values()) { 13434 pw.print(" "); pw.println(perm); 13435 if (dumpAll) { 13436 perm.dump(pw, " "); 13437 } 13438 } 13439 } 13440 } 13441 13442 if (!printedAnything) { 13443 pw.println(" (nothing)"); 13444 } 13445 } 13446 13447 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13448 int opti, boolean dumpAll, String dumpPackage) { 13449 boolean printed = false; 13450 13451 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13452 13453 if (mIntentSenderRecords.size() > 0) { 13454 Iterator<WeakReference<PendingIntentRecord>> it 13455 = mIntentSenderRecords.values().iterator(); 13456 while (it.hasNext()) { 13457 WeakReference<PendingIntentRecord> ref = it.next(); 13458 PendingIntentRecord rec = ref != null ? ref.get(): null; 13459 if (dumpPackage != null && (rec == null 13460 || !dumpPackage.equals(rec.key.packageName))) { 13461 continue; 13462 } 13463 printed = true; 13464 if (rec != null) { 13465 pw.print(" * "); pw.println(rec); 13466 if (dumpAll) { 13467 rec.dump(pw, " "); 13468 } 13469 } else { 13470 pw.print(" * "); pw.println(ref); 13471 } 13472 } 13473 } 13474 13475 if (!printed) { 13476 pw.println(" (nothing)"); 13477 } 13478 } 13479 13480 private static final int dumpProcessList(PrintWriter pw, 13481 ActivityManagerService service, List list, 13482 String prefix, String normalLabel, String persistentLabel, 13483 String dumpPackage) { 13484 int numPers = 0; 13485 final int N = list.size()-1; 13486 for (int i=N; i>=0; i--) { 13487 ProcessRecord r = (ProcessRecord)list.get(i); 13488 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13489 continue; 13490 } 13491 pw.println(String.format("%s%s #%2d: %s", 13492 prefix, (r.persistent ? persistentLabel : normalLabel), 13493 i, r.toString())); 13494 if (r.persistent) { 13495 numPers++; 13496 } 13497 } 13498 return numPers; 13499 } 13500 13501 private static final boolean dumpProcessOomList(PrintWriter pw, 13502 ActivityManagerService service, List<ProcessRecord> origList, 13503 String prefix, String normalLabel, String persistentLabel, 13504 boolean inclDetails, String dumpPackage) { 13505 13506 ArrayList<Pair<ProcessRecord, Integer>> list 13507 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13508 for (int i=0; i<origList.size(); i++) { 13509 ProcessRecord r = origList.get(i); 13510 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13511 continue; 13512 } 13513 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13514 } 13515 13516 if (list.size() <= 0) { 13517 return false; 13518 } 13519 13520 Comparator<Pair<ProcessRecord, Integer>> comparator 13521 = new Comparator<Pair<ProcessRecord, Integer>>() { 13522 @Override 13523 public int compare(Pair<ProcessRecord, Integer> object1, 13524 Pair<ProcessRecord, Integer> object2) { 13525 if (object1.first.setAdj != object2.first.setAdj) { 13526 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13527 } 13528 if (object1.second.intValue() != object2.second.intValue()) { 13529 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13530 } 13531 return 0; 13532 } 13533 }; 13534 13535 Collections.sort(list, comparator); 13536 13537 final long curRealtime = SystemClock.elapsedRealtime(); 13538 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13539 final long curUptime = SystemClock.uptimeMillis(); 13540 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13541 13542 for (int i=list.size()-1; i>=0; i--) { 13543 ProcessRecord r = list.get(i).first; 13544 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13545 char schedGroup; 13546 switch (r.setSchedGroup) { 13547 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13548 schedGroup = 'B'; 13549 break; 13550 case Process.THREAD_GROUP_DEFAULT: 13551 schedGroup = 'F'; 13552 break; 13553 default: 13554 schedGroup = '?'; 13555 break; 13556 } 13557 char foreground; 13558 if (r.foregroundActivities) { 13559 foreground = 'A'; 13560 } else if (r.foregroundServices) { 13561 foreground = 'S'; 13562 } else { 13563 foreground = ' '; 13564 } 13565 String procState = ProcessList.makeProcStateString(r.curProcState); 13566 pw.print(prefix); 13567 pw.print(r.persistent ? persistentLabel : normalLabel); 13568 pw.print(" #"); 13569 int num = (origList.size()-1)-list.get(i).second; 13570 if (num < 10) pw.print(' '); 13571 pw.print(num); 13572 pw.print(": "); 13573 pw.print(oomAdj); 13574 pw.print(' '); 13575 pw.print(schedGroup); 13576 pw.print('/'); 13577 pw.print(foreground); 13578 pw.print('/'); 13579 pw.print(procState); 13580 pw.print(" trm:"); 13581 if (r.trimMemoryLevel < 10) pw.print(' '); 13582 pw.print(r.trimMemoryLevel); 13583 pw.print(' '); 13584 pw.print(r.toShortString()); 13585 pw.print(" ("); 13586 pw.print(r.adjType); 13587 pw.println(')'); 13588 if (r.adjSource != null || r.adjTarget != null) { 13589 pw.print(prefix); 13590 pw.print(" "); 13591 if (r.adjTarget instanceof ComponentName) { 13592 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13593 } else if (r.adjTarget != null) { 13594 pw.print(r.adjTarget.toString()); 13595 } else { 13596 pw.print("{null}"); 13597 } 13598 pw.print("<="); 13599 if (r.adjSource instanceof ProcessRecord) { 13600 pw.print("Proc{"); 13601 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13602 pw.println("}"); 13603 } else if (r.adjSource != null) { 13604 pw.println(r.adjSource.toString()); 13605 } else { 13606 pw.println("{null}"); 13607 } 13608 } 13609 if (inclDetails) { 13610 pw.print(prefix); 13611 pw.print(" "); 13612 pw.print("oom: max="); pw.print(r.maxAdj); 13613 pw.print(" curRaw="); pw.print(r.curRawAdj); 13614 pw.print(" setRaw="); pw.print(r.setRawAdj); 13615 pw.print(" cur="); pw.print(r.curAdj); 13616 pw.print(" set="); pw.println(r.setAdj); 13617 pw.print(prefix); 13618 pw.print(" "); 13619 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13620 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13621 pw.print(" lastPss="); pw.print(r.lastPss); 13622 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13623 pw.print(prefix); 13624 pw.print(" "); 13625 pw.print("cached="); pw.print(r.cached); 13626 pw.print(" empty="); pw.print(r.empty); 13627 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13628 13629 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13630 if (r.lastWakeTime != 0) { 13631 long wtime; 13632 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13633 synchronized (stats) { 13634 wtime = stats.getProcessWakeTime(r.info.uid, 13635 r.pid, curRealtime); 13636 } 13637 long timeUsed = wtime - r.lastWakeTime; 13638 pw.print(prefix); 13639 pw.print(" "); 13640 pw.print("keep awake over "); 13641 TimeUtils.formatDuration(realtimeSince, pw); 13642 pw.print(" used "); 13643 TimeUtils.formatDuration(timeUsed, pw); 13644 pw.print(" ("); 13645 pw.print((timeUsed*100)/realtimeSince); 13646 pw.println("%)"); 13647 } 13648 if (r.lastCpuTime != 0) { 13649 long timeUsed = r.curCpuTime - r.lastCpuTime; 13650 pw.print(prefix); 13651 pw.print(" "); 13652 pw.print("run cpu over "); 13653 TimeUtils.formatDuration(uptimeSince, pw); 13654 pw.print(" used "); 13655 TimeUtils.formatDuration(timeUsed, pw); 13656 pw.print(" ("); 13657 pw.print((timeUsed*100)/uptimeSince); 13658 pw.println("%)"); 13659 } 13660 } 13661 } 13662 } 13663 return true; 13664 } 13665 13666 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13667 String[] args) { 13668 ArrayList<ProcessRecord> procs; 13669 synchronized (this) { 13670 if (args != null && args.length > start 13671 && args[start].charAt(0) != '-') { 13672 procs = new ArrayList<ProcessRecord>(); 13673 int pid = -1; 13674 try { 13675 pid = Integer.parseInt(args[start]); 13676 } catch (NumberFormatException e) { 13677 } 13678 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13679 ProcessRecord proc = mLruProcesses.get(i); 13680 if (proc.pid == pid) { 13681 procs.add(proc); 13682 } else if (allPkgs && proc.pkgList != null 13683 && proc.pkgList.containsKey(args[start])) { 13684 procs.add(proc); 13685 } else if (proc.processName.equals(args[start])) { 13686 procs.add(proc); 13687 } 13688 } 13689 if (procs.size() <= 0) { 13690 return null; 13691 } 13692 } else { 13693 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13694 } 13695 } 13696 return procs; 13697 } 13698 13699 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13700 PrintWriter pw, String[] args) { 13701 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13702 if (procs == null) { 13703 pw.println("No process found for: " + args[0]); 13704 return; 13705 } 13706 13707 long uptime = SystemClock.uptimeMillis(); 13708 long realtime = SystemClock.elapsedRealtime(); 13709 pw.println("Applications Graphics Acceleration Info:"); 13710 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13711 13712 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13713 ProcessRecord r = procs.get(i); 13714 if (r.thread != null) { 13715 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13716 pw.flush(); 13717 try { 13718 TransferPipe tp = new TransferPipe(); 13719 try { 13720 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13721 tp.go(fd); 13722 } finally { 13723 tp.kill(); 13724 } 13725 } catch (IOException e) { 13726 pw.println("Failure while dumping the app: " + r); 13727 pw.flush(); 13728 } catch (RemoteException e) { 13729 pw.println("Got a RemoteException while dumping the app " + r); 13730 pw.flush(); 13731 } 13732 } 13733 } 13734 } 13735 13736 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13737 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13738 if (procs == null) { 13739 pw.println("No process found for: " + args[0]); 13740 return; 13741 } 13742 13743 pw.println("Applications Database Info:"); 13744 13745 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13746 ProcessRecord r = procs.get(i); 13747 if (r.thread != null) { 13748 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13749 pw.flush(); 13750 try { 13751 TransferPipe tp = new TransferPipe(); 13752 try { 13753 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13754 tp.go(fd); 13755 } finally { 13756 tp.kill(); 13757 } 13758 } catch (IOException e) { 13759 pw.println("Failure while dumping the app: " + r); 13760 pw.flush(); 13761 } catch (RemoteException e) { 13762 pw.println("Got a RemoteException while dumping the app " + r); 13763 pw.flush(); 13764 } 13765 } 13766 } 13767 } 13768 13769 final static class MemItem { 13770 final boolean isProc; 13771 final String label; 13772 final String shortLabel; 13773 final long pss; 13774 final int id; 13775 final boolean hasActivities; 13776 ArrayList<MemItem> subitems; 13777 13778 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13779 boolean _hasActivities) { 13780 isProc = true; 13781 label = _label; 13782 shortLabel = _shortLabel; 13783 pss = _pss; 13784 id = _id; 13785 hasActivities = _hasActivities; 13786 } 13787 13788 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13789 isProc = false; 13790 label = _label; 13791 shortLabel = _shortLabel; 13792 pss = _pss; 13793 id = _id; 13794 hasActivities = false; 13795 } 13796 } 13797 13798 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13799 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13800 if (sort && !isCompact) { 13801 Collections.sort(items, new Comparator<MemItem>() { 13802 @Override 13803 public int compare(MemItem lhs, MemItem rhs) { 13804 if (lhs.pss < rhs.pss) { 13805 return 1; 13806 } else if (lhs.pss > rhs.pss) { 13807 return -1; 13808 } 13809 return 0; 13810 } 13811 }); 13812 } 13813 13814 for (int i=0; i<items.size(); i++) { 13815 MemItem mi = items.get(i); 13816 if (!isCompact) { 13817 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13818 } else if (mi.isProc) { 13819 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13820 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13821 pw.println(mi.hasActivities ? ",a" : ",e"); 13822 } else { 13823 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13824 pw.println(mi.pss); 13825 } 13826 if (mi.subitems != null) { 13827 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13828 true, isCompact); 13829 } 13830 } 13831 } 13832 13833 // These are in KB. 13834 static final long[] DUMP_MEM_BUCKETS = new long[] { 13835 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13836 120*1024, 160*1024, 200*1024, 13837 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13838 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13839 }; 13840 13841 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13842 boolean stackLike) { 13843 int start = label.lastIndexOf('.'); 13844 if (start >= 0) start++; 13845 else start = 0; 13846 int end = label.length(); 13847 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13848 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13849 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13850 out.append(bucket); 13851 out.append(stackLike ? "MB." : "MB "); 13852 out.append(label, start, end); 13853 return; 13854 } 13855 } 13856 out.append(memKB/1024); 13857 out.append(stackLike ? "MB." : "MB "); 13858 out.append(label, start, end); 13859 } 13860 13861 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13862 ProcessList.NATIVE_ADJ, 13863 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13864 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13865 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13866 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13867 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13868 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13869 }; 13870 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13871 "Native", 13872 "System", "Persistent", "Persistent Service", "Foreground", 13873 "Visible", "Perceptible", 13874 "Heavy Weight", "Backup", 13875 "A Services", "Home", 13876 "Previous", "B Services", "Cached" 13877 }; 13878 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13879 "native", 13880 "sys", "pers", "persvc", "fore", 13881 "vis", "percept", 13882 "heavy", "backup", 13883 "servicea", "home", 13884 "prev", "serviceb", "cached" 13885 }; 13886 13887 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13888 long realtime, boolean isCheckinRequest, boolean isCompact) { 13889 if (isCheckinRequest || isCompact) { 13890 // short checkin version 13891 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13892 } else { 13893 pw.println("Applications Memory Usage (kB):"); 13894 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13895 } 13896 } 13897 13898 private static final int KSM_SHARED = 0; 13899 private static final int KSM_SHARING = 1; 13900 private static final int KSM_UNSHARED = 2; 13901 private static final int KSM_VOLATILE = 3; 13902 13903 private final long[] getKsmInfo() { 13904 long[] longOut = new long[4]; 13905 final int[] SINGLE_LONG_FORMAT = new int[] { 13906 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13907 }; 13908 long[] longTmp = new long[1]; 13909 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13910 SINGLE_LONG_FORMAT, null, longTmp, null); 13911 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13912 longTmp[0] = 0; 13913 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13914 SINGLE_LONG_FORMAT, null, longTmp, null); 13915 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13916 longTmp[0] = 0; 13917 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13918 SINGLE_LONG_FORMAT, null, longTmp, null); 13919 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13920 longTmp[0] = 0; 13921 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13922 SINGLE_LONG_FORMAT, null, longTmp, null); 13923 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13924 return longOut; 13925 } 13926 13927 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13928 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13929 boolean dumpDetails = false; 13930 boolean dumpFullDetails = false; 13931 boolean dumpDalvik = false; 13932 boolean oomOnly = false; 13933 boolean isCompact = false; 13934 boolean localOnly = false; 13935 boolean packages = false; 13936 13937 int opti = 0; 13938 while (opti < args.length) { 13939 String opt = args[opti]; 13940 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13941 break; 13942 } 13943 opti++; 13944 if ("-a".equals(opt)) { 13945 dumpDetails = true; 13946 dumpFullDetails = true; 13947 dumpDalvik = true; 13948 } else if ("-d".equals(opt)) { 13949 dumpDalvik = true; 13950 } else if ("-c".equals(opt)) { 13951 isCompact = true; 13952 } else if ("--oom".equals(opt)) { 13953 oomOnly = true; 13954 } else if ("--local".equals(opt)) { 13955 localOnly = true; 13956 } else if ("--package".equals(opt)) { 13957 packages = true; 13958 } else if ("-h".equals(opt)) { 13959 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13960 pw.println(" -a: include all available information for each process."); 13961 pw.println(" -d: include dalvik details when dumping process details."); 13962 pw.println(" -c: dump in a compact machine-parseable representation."); 13963 pw.println(" --oom: only show processes organized by oom adj."); 13964 pw.println(" --local: only collect details locally, don't call process."); 13965 pw.println(" --package: interpret process arg as package, dumping all"); 13966 pw.println(" processes that have loaded that package."); 13967 pw.println("If [process] is specified it can be the name or "); 13968 pw.println("pid of a specific process to dump."); 13969 return; 13970 } else { 13971 pw.println("Unknown argument: " + opt + "; use -h for help"); 13972 } 13973 } 13974 13975 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13976 long uptime = SystemClock.uptimeMillis(); 13977 long realtime = SystemClock.elapsedRealtime(); 13978 final long[] tmpLong = new long[1]; 13979 13980 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13981 if (procs == null) { 13982 // No Java processes. Maybe they want to print a native process. 13983 if (args != null && args.length > opti 13984 && args[opti].charAt(0) != '-') { 13985 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13986 = new ArrayList<ProcessCpuTracker.Stats>(); 13987 updateCpuStatsNow(); 13988 int findPid = -1; 13989 try { 13990 findPid = Integer.parseInt(args[opti]); 13991 } catch (NumberFormatException e) { 13992 } 13993 synchronized (mProcessCpuTracker) { 13994 final int N = mProcessCpuTracker.countStats(); 13995 for (int i=0; i<N; i++) { 13996 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13997 if (st.pid == findPid || (st.baseName != null 13998 && st.baseName.equals(args[opti]))) { 13999 nativeProcs.add(st); 14000 } 14001 } 14002 } 14003 if (nativeProcs.size() > 0) { 14004 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14005 isCompact); 14006 Debug.MemoryInfo mi = null; 14007 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14008 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14009 final int pid = r.pid; 14010 if (!isCheckinRequest && dumpDetails) { 14011 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14012 } 14013 if (mi == null) { 14014 mi = new Debug.MemoryInfo(); 14015 } 14016 if (dumpDetails || (!brief && !oomOnly)) { 14017 Debug.getMemoryInfo(pid, mi); 14018 } else { 14019 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14020 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14021 } 14022 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14023 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14024 if (isCheckinRequest) { 14025 pw.println(); 14026 } 14027 } 14028 return; 14029 } 14030 } 14031 pw.println("No process found for: " + args[opti]); 14032 return; 14033 } 14034 14035 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14036 dumpDetails = true; 14037 } 14038 14039 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14040 14041 String[] innerArgs = new String[args.length-opti]; 14042 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14043 14044 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14045 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14046 long nativePss = 0; 14047 long dalvikPss = 0; 14048 long otherPss = 0; 14049 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14050 14051 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14052 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14053 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14054 14055 long totalPss = 0; 14056 long cachedPss = 0; 14057 14058 Debug.MemoryInfo mi = null; 14059 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14060 final ProcessRecord r = procs.get(i); 14061 final IApplicationThread thread; 14062 final int pid; 14063 final int oomAdj; 14064 final boolean hasActivities; 14065 synchronized (this) { 14066 thread = r.thread; 14067 pid = r.pid; 14068 oomAdj = r.getSetAdjWithServices(); 14069 hasActivities = r.activities.size() > 0; 14070 } 14071 if (thread != null) { 14072 if (!isCheckinRequest && dumpDetails) { 14073 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14074 } 14075 if (mi == null) { 14076 mi = new Debug.MemoryInfo(); 14077 } 14078 if (dumpDetails || (!brief && !oomOnly)) { 14079 Debug.getMemoryInfo(pid, mi); 14080 } else { 14081 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14082 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14083 } 14084 if (dumpDetails) { 14085 if (localOnly) { 14086 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14087 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14088 if (isCheckinRequest) { 14089 pw.println(); 14090 } 14091 } else { 14092 try { 14093 pw.flush(); 14094 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14095 dumpDalvik, innerArgs); 14096 } catch (RemoteException e) { 14097 if (!isCheckinRequest) { 14098 pw.println("Got RemoteException!"); 14099 pw.flush(); 14100 } 14101 } 14102 } 14103 } 14104 14105 final long myTotalPss = mi.getTotalPss(); 14106 final long myTotalUss = mi.getTotalUss(); 14107 14108 synchronized (this) { 14109 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14110 // Record this for posterity if the process has been stable. 14111 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14112 } 14113 } 14114 14115 if (!isCheckinRequest && mi != null) { 14116 totalPss += myTotalPss; 14117 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14118 (hasActivities ? " / activities)" : ")"), 14119 r.processName, myTotalPss, pid, hasActivities); 14120 procMems.add(pssItem); 14121 procMemsMap.put(pid, pssItem); 14122 14123 nativePss += mi.nativePss; 14124 dalvikPss += mi.dalvikPss; 14125 otherPss += mi.otherPss; 14126 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14127 long mem = mi.getOtherPss(j); 14128 miscPss[j] += mem; 14129 otherPss -= mem; 14130 } 14131 14132 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14133 cachedPss += myTotalPss; 14134 } 14135 14136 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14137 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14138 || oomIndex == (oomPss.length-1)) { 14139 oomPss[oomIndex] += myTotalPss; 14140 if (oomProcs[oomIndex] == null) { 14141 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14142 } 14143 oomProcs[oomIndex].add(pssItem); 14144 break; 14145 } 14146 } 14147 } 14148 } 14149 } 14150 14151 long nativeProcTotalPss = 0; 14152 14153 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14154 // If we are showing aggregations, also look for native processes to 14155 // include so that our aggregations are more accurate. 14156 updateCpuStatsNow(); 14157 mi = null; 14158 synchronized (mProcessCpuTracker) { 14159 final int N = mProcessCpuTracker.countStats(); 14160 for (int i=0; i<N; i++) { 14161 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14162 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14163 if (mi == null) { 14164 mi = new Debug.MemoryInfo(); 14165 } 14166 if (!brief && !oomOnly) { 14167 Debug.getMemoryInfo(st.pid, mi); 14168 } else { 14169 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14170 mi.nativePrivateDirty = (int)tmpLong[0]; 14171 } 14172 14173 final long myTotalPss = mi.getTotalPss(); 14174 totalPss += myTotalPss; 14175 nativeProcTotalPss += myTotalPss; 14176 14177 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14178 st.name, myTotalPss, st.pid, false); 14179 procMems.add(pssItem); 14180 14181 nativePss += mi.nativePss; 14182 dalvikPss += mi.dalvikPss; 14183 otherPss += mi.otherPss; 14184 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14185 long mem = mi.getOtherPss(j); 14186 miscPss[j] += mem; 14187 otherPss -= mem; 14188 } 14189 oomPss[0] += myTotalPss; 14190 if (oomProcs[0] == null) { 14191 oomProcs[0] = new ArrayList<MemItem>(); 14192 } 14193 oomProcs[0].add(pssItem); 14194 } 14195 } 14196 } 14197 14198 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14199 14200 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14201 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14202 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14203 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14204 String label = Debug.MemoryInfo.getOtherLabel(j); 14205 catMems.add(new MemItem(label, label, miscPss[j], j)); 14206 } 14207 14208 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14209 for (int j=0; j<oomPss.length; j++) { 14210 if (oomPss[j] != 0) { 14211 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14212 : DUMP_MEM_OOM_LABEL[j]; 14213 MemItem item = new MemItem(label, label, oomPss[j], 14214 DUMP_MEM_OOM_ADJ[j]); 14215 item.subitems = oomProcs[j]; 14216 oomMems.add(item); 14217 } 14218 } 14219 14220 if (!brief && !oomOnly && !isCompact) { 14221 pw.println(); 14222 pw.println("Total PSS by process:"); 14223 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14224 pw.println(); 14225 } 14226 if (!isCompact) { 14227 pw.println("Total PSS by OOM adjustment:"); 14228 } 14229 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14230 if (!brief && !oomOnly) { 14231 PrintWriter out = categoryPw != null ? categoryPw : pw; 14232 if (!isCompact) { 14233 out.println(); 14234 out.println("Total PSS by category:"); 14235 } 14236 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14237 } 14238 if (!isCompact) { 14239 pw.println(); 14240 } 14241 MemInfoReader memInfo = new MemInfoReader(); 14242 memInfo.readMemInfo(); 14243 if (nativeProcTotalPss > 0) { 14244 synchronized (this) { 14245 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14246 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14247 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14248 } 14249 } 14250 if (!brief) { 14251 if (!isCompact) { 14252 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14253 pw.print(" kB (status "); 14254 switch (mLastMemoryLevel) { 14255 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14256 pw.println("normal)"); 14257 break; 14258 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14259 pw.println("moderate)"); 14260 break; 14261 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14262 pw.println("low)"); 14263 break; 14264 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14265 pw.println("critical)"); 14266 break; 14267 default: 14268 pw.print(mLastMemoryLevel); 14269 pw.println(")"); 14270 break; 14271 } 14272 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14273 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14274 pw.print(cachedPss); pw.print(" cached pss + "); 14275 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14276 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14277 } else { 14278 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14279 pw.print(cachedPss + memInfo.getCachedSizeKb() 14280 + memInfo.getFreeSizeKb()); pw.print(","); 14281 pw.println(totalPss - cachedPss); 14282 } 14283 } 14284 if (!isCompact) { 14285 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14286 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14287 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14288 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14289 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14290 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14291 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14292 } 14293 if (!brief) { 14294 if (memInfo.getZramTotalSizeKb() != 0) { 14295 if (!isCompact) { 14296 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14297 pw.print(" kB physical used for "); 14298 pw.print(memInfo.getSwapTotalSizeKb() 14299 - memInfo.getSwapFreeSizeKb()); 14300 pw.print(" kB in swap ("); 14301 pw.print(memInfo.getSwapTotalSizeKb()); 14302 pw.println(" kB total swap)"); 14303 } else { 14304 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14305 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14306 pw.println(memInfo.getSwapFreeSizeKb()); 14307 } 14308 } 14309 final long[] ksm = getKsmInfo(); 14310 if (!isCompact) { 14311 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14312 || ksm[KSM_VOLATILE] != 0) { 14313 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14314 pw.print(" kB saved from shared "); 14315 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14316 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14317 pw.print(" kB unshared; "); 14318 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14319 } 14320 pw.print(" Tuning: "); 14321 pw.print(ActivityManager.staticGetMemoryClass()); 14322 pw.print(" (large "); 14323 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14324 pw.print("), oom "); 14325 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14326 pw.print(" kB"); 14327 pw.print(", restore limit "); 14328 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14329 pw.print(" kB"); 14330 if (ActivityManager.isLowRamDeviceStatic()) { 14331 pw.print(" (low-ram)"); 14332 } 14333 if (ActivityManager.isHighEndGfx()) { 14334 pw.print(" (high-end-gfx)"); 14335 } 14336 pw.println(); 14337 } else { 14338 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14339 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14340 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14341 pw.print("tuning,"); 14342 pw.print(ActivityManager.staticGetMemoryClass()); 14343 pw.print(','); 14344 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14345 pw.print(','); 14346 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14347 if (ActivityManager.isLowRamDeviceStatic()) { 14348 pw.print(",low-ram"); 14349 } 14350 if (ActivityManager.isHighEndGfx()) { 14351 pw.print(",high-end-gfx"); 14352 } 14353 pw.println(); 14354 } 14355 } 14356 } 14357 } 14358 14359 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14360 long memtrack, String name) { 14361 sb.append(" "); 14362 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14363 sb.append(' '); 14364 sb.append(ProcessList.makeProcStateString(procState)); 14365 sb.append(' '); 14366 ProcessList.appendRamKb(sb, pss); 14367 sb.append(" kB: "); 14368 sb.append(name); 14369 if (memtrack > 0) { 14370 sb.append(" ("); 14371 sb.append(memtrack); 14372 sb.append(" kB memtrack)"); 14373 } 14374 } 14375 14376 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14377 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14378 sb.append(" (pid "); 14379 sb.append(mi.pid); 14380 sb.append(") "); 14381 sb.append(mi.adjType); 14382 sb.append('\n'); 14383 if (mi.adjReason != null) { 14384 sb.append(" "); 14385 sb.append(mi.adjReason); 14386 sb.append('\n'); 14387 } 14388 } 14389 14390 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14391 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14392 for (int i=0, N=memInfos.size(); i<N; i++) { 14393 ProcessMemInfo mi = memInfos.get(i); 14394 infoMap.put(mi.pid, mi); 14395 } 14396 updateCpuStatsNow(); 14397 long[] memtrackTmp = new long[1]; 14398 synchronized (mProcessCpuTracker) { 14399 final int N = mProcessCpuTracker.countStats(); 14400 for (int i=0; i<N; i++) { 14401 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14402 if (st.vsize > 0) { 14403 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14404 if (pss > 0) { 14405 if (infoMap.indexOfKey(st.pid) < 0) { 14406 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14407 ProcessList.NATIVE_ADJ, -1, "native", null); 14408 mi.pss = pss; 14409 mi.memtrack = memtrackTmp[0]; 14410 memInfos.add(mi); 14411 } 14412 } 14413 } 14414 } 14415 } 14416 14417 long totalPss = 0; 14418 long totalMemtrack = 0; 14419 for (int i=0, N=memInfos.size(); i<N; i++) { 14420 ProcessMemInfo mi = memInfos.get(i); 14421 if (mi.pss == 0) { 14422 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14423 mi.memtrack = memtrackTmp[0]; 14424 } 14425 totalPss += mi.pss; 14426 totalMemtrack += mi.memtrack; 14427 } 14428 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14429 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14430 if (lhs.oomAdj != rhs.oomAdj) { 14431 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14432 } 14433 if (lhs.pss != rhs.pss) { 14434 return lhs.pss < rhs.pss ? 1 : -1; 14435 } 14436 return 0; 14437 } 14438 }); 14439 14440 StringBuilder tag = new StringBuilder(128); 14441 StringBuilder stack = new StringBuilder(128); 14442 tag.append("Low on memory -- "); 14443 appendMemBucket(tag, totalPss, "total", false); 14444 appendMemBucket(stack, totalPss, "total", true); 14445 14446 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14447 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14448 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14449 14450 boolean firstLine = true; 14451 int lastOomAdj = Integer.MIN_VALUE; 14452 long extraNativeRam = 0; 14453 long extraNativeMemtrack = 0; 14454 long cachedPss = 0; 14455 for (int i=0, N=memInfos.size(); i<N; i++) { 14456 ProcessMemInfo mi = memInfos.get(i); 14457 14458 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14459 cachedPss += mi.pss; 14460 } 14461 14462 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14463 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14464 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14465 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14466 if (lastOomAdj != mi.oomAdj) { 14467 lastOomAdj = mi.oomAdj; 14468 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14469 tag.append(" / "); 14470 } 14471 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14472 if (firstLine) { 14473 stack.append(":"); 14474 firstLine = false; 14475 } 14476 stack.append("\n\t at "); 14477 } else { 14478 stack.append("$"); 14479 } 14480 } else { 14481 tag.append(" "); 14482 stack.append("$"); 14483 } 14484 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14485 appendMemBucket(tag, mi.pss, mi.name, false); 14486 } 14487 appendMemBucket(stack, mi.pss, mi.name, true); 14488 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14489 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14490 stack.append("("); 14491 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14492 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14493 stack.append(DUMP_MEM_OOM_LABEL[k]); 14494 stack.append(":"); 14495 stack.append(DUMP_MEM_OOM_ADJ[k]); 14496 } 14497 } 14498 stack.append(")"); 14499 } 14500 } 14501 14502 appendMemInfo(fullNativeBuilder, mi); 14503 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14504 // The short form only has native processes that are >= 512K. 14505 if (mi.pss >= 512) { 14506 appendMemInfo(shortNativeBuilder, mi); 14507 } else { 14508 extraNativeRam += mi.pss; 14509 extraNativeMemtrack += mi.memtrack; 14510 } 14511 } else { 14512 // Short form has all other details, but if we have collected RAM 14513 // from smaller native processes let's dump a summary of that. 14514 if (extraNativeRam > 0) { 14515 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14516 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14517 shortNativeBuilder.append('\n'); 14518 extraNativeRam = 0; 14519 } 14520 appendMemInfo(fullJavaBuilder, mi); 14521 } 14522 } 14523 14524 fullJavaBuilder.append(" "); 14525 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14526 fullJavaBuilder.append(" kB: TOTAL"); 14527 if (totalMemtrack > 0) { 14528 fullJavaBuilder.append(" ("); 14529 fullJavaBuilder.append(totalMemtrack); 14530 fullJavaBuilder.append(" kB memtrack)"); 14531 } else { 14532 } 14533 fullJavaBuilder.append("\n"); 14534 14535 MemInfoReader memInfo = new MemInfoReader(); 14536 memInfo.readMemInfo(); 14537 final long[] infos = memInfo.getRawInfo(); 14538 14539 StringBuilder memInfoBuilder = new StringBuilder(1024); 14540 Debug.getMemInfo(infos); 14541 memInfoBuilder.append(" MemInfo: "); 14542 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14543 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14544 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14545 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14546 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14547 memInfoBuilder.append(" "); 14548 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14549 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14550 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14551 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14552 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14553 memInfoBuilder.append(" ZRAM: "); 14554 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14555 memInfoBuilder.append(" kB RAM, "); 14556 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14557 memInfoBuilder.append(" kB swap total, "); 14558 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14559 memInfoBuilder.append(" kB swap free\n"); 14560 } 14561 final long[] ksm = getKsmInfo(); 14562 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14563 || ksm[KSM_VOLATILE] != 0) { 14564 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14565 memInfoBuilder.append(" kB saved from shared "); 14566 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14567 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14568 memInfoBuilder.append(" kB unshared; "); 14569 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14570 } 14571 memInfoBuilder.append(" Free RAM: "); 14572 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14573 + memInfo.getFreeSizeKb()); 14574 memInfoBuilder.append(" kB\n"); 14575 memInfoBuilder.append(" Used RAM: "); 14576 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14577 memInfoBuilder.append(" kB\n"); 14578 memInfoBuilder.append(" Lost RAM: "); 14579 memInfoBuilder.append(memInfo.getTotalSizeKb() 14580 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14581 - memInfo.getKernelUsedSizeKb()); 14582 memInfoBuilder.append(" kB\n"); 14583 Slog.i(TAG, "Low on memory:"); 14584 Slog.i(TAG, shortNativeBuilder.toString()); 14585 Slog.i(TAG, fullJavaBuilder.toString()); 14586 Slog.i(TAG, memInfoBuilder.toString()); 14587 14588 StringBuilder dropBuilder = new StringBuilder(1024); 14589 /* 14590 StringWriter oomSw = new StringWriter(); 14591 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14592 StringWriter catSw = new StringWriter(); 14593 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14594 String[] emptyArgs = new String[] { }; 14595 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14596 oomPw.flush(); 14597 String oomString = oomSw.toString(); 14598 */ 14599 dropBuilder.append("Low on memory:"); 14600 dropBuilder.append(stack); 14601 dropBuilder.append('\n'); 14602 dropBuilder.append(fullNativeBuilder); 14603 dropBuilder.append(fullJavaBuilder); 14604 dropBuilder.append('\n'); 14605 dropBuilder.append(memInfoBuilder); 14606 dropBuilder.append('\n'); 14607 /* 14608 dropBuilder.append(oomString); 14609 dropBuilder.append('\n'); 14610 */ 14611 StringWriter catSw = new StringWriter(); 14612 synchronized (ActivityManagerService.this) { 14613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14614 String[] emptyArgs = new String[] { }; 14615 catPw.println(); 14616 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14617 catPw.println(); 14618 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14619 false, false, null); 14620 catPw.println(); 14621 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14622 catPw.flush(); 14623 } 14624 dropBuilder.append(catSw.toString()); 14625 addErrorToDropBox("lowmem", null, "system_server", null, 14626 null, tag.toString(), dropBuilder.toString(), null, null); 14627 //Slog.i(TAG, "Sent to dropbox:"); 14628 //Slog.i(TAG, dropBuilder.toString()); 14629 synchronized (ActivityManagerService.this) { 14630 long now = SystemClock.uptimeMillis(); 14631 if (mLastMemUsageReportTime < now) { 14632 mLastMemUsageReportTime = now; 14633 } 14634 } 14635 } 14636 14637 /** 14638 * Searches array of arguments for the specified string 14639 * @param args array of argument strings 14640 * @param value value to search for 14641 * @return true if the value is contained in the array 14642 */ 14643 private static boolean scanArgs(String[] args, String value) { 14644 if (args != null) { 14645 for (String arg : args) { 14646 if (value.equals(arg)) { 14647 return true; 14648 } 14649 } 14650 } 14651 return false; 14652 } 14653 14654 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14655 ContentProviderRecord cpr, boolean always) { 14656 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14657 14658 if (!inLaunching || always) { 14659 synchronized (cpr) { 14660 cpr.launchingApp = null; 14661 cpr.notifyAll(); 14662 } 14663 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14664 String names[] = cpr.info.authority.split(";"); 14665 for (int j = 0; j < names.length; j++) { 14666 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14667 } 14668 } 14669 14670 for (int i=0; i<cpr.connections.size(); i++) { 14671 ContentProviderConnection conn = cpr.connections.get(i); 14672 if (conn.waiting) { 14673 // If this connection is waiting for the provider, then we don't 14674 // need to mess with its process unless we are always removing 14675 // or for some reason the provider is not currently launching. 14676 if (inLaunching && !always) { 14677 continue; 14678 } 14679 } 14680 ProcessRecord capp = conn.client; 14681 conn.dead = true; 14682 if (conn.stableCount > 0) { 14683 if (!capp.persistent && capp.thread != null 14684 && capp.pid != 0 14685 && capp.pid != MY_PID) { 14686 capp.kill("depends on provider " 14687 + cpr.name.flattenToShortString() 14688 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14689 } 14690 } else if (capp.thread != null && conn.provider.provider != null) { 14691 try { 14692 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14693 } catch (RemoteException e) { 14694 } 14695 // In the protocol here, we don't expect the client to correctly 14696 // clean up this connection, we'll just remove it. 14697 cpr.connections.remove(i); 14698 conn.client.conProviders.remove(conn); 14699 } 14700 } 14701 14702 if (inLaunching && always) { 14703 mLaunchingProviders.remove(cpr); 14704 } 14705 return inLaunching; 14706 } 14707 14708 /** 14709 * Main code for cleaning up a process when it has gone away. This is 14710 * called both as a result of the process dying, or directly when stopping 14711 * a process when running in single process mode. 14712 * 14713 * @return Returns true if the given process has been restarted, so the 14714 * app that was passed in must remain on the process lists. 14715 */ 14716 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14717 boolean restarting, boolean allowRestart, int index) { 14718 if (index >= 0) { 14719 removeLruProcessLocked(app); 14720 ProcessList.remove(app.pid); 14721 } 14722 14723 mProcessesToGc.remove(app); 14724 mPendingPssProcesses.remove(app); 14725 14726 // Dismiss any open dialogs. 14727 if (app.crashDialog != null && !app.forceCrashReport) { 14728 app.crashDialog.dismiss(); 14729 app.crashDialog = null; 14730 } 14731 if (app.anrDialog != null) { 14732 app.anrDialog.dismiss(); 14733 app.anrDialog = null; 14734 } 14735 if (app.waitDialog != null) { 14736 app.waitDialog.dismiss(); 14737 app.waitDialog = null; 14738 } 14739 14740 app.crashing = false; 14741 app.notResponding = false; 14742 14743 app.resetPackageList(mProcessStats); 14744 app.unlinkDeathRecipient(); 14745 app.makeInactive(mProcessStats); 14746 app.waitingToKill = null; 14747 app.forcingToForeground = null; 14748 updateProcessForegroundLocked(app, false, false); 14749 app.foregroundActivities = false; 14750 app.hasShownUi = false; 14751 app.treatLikeActivity = false; 14752 app.hasAboveClient = false; 14753 app.hasClientActivities = false; 14754 14755 mServices.killServicesLocked(app, allowRestart); 14756 14757 boolean restart = false; 14758 14759 // Remove published content providers. 14760 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14761 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14762 final boolean always = app.bad || !allowRestart; 14763 if (removeDyingProviderLocked(app, cpr, always) || always) { 14764 // We left the provider in the launching list, need to 14765 // restart it. 14766 restart = true; 14767 } 14768 14769 cpr.provider = null; 14770 cpr.proc = null; 14771 } 14772 app.pubProviders.clear(); 14773 14774 // Take care of any launching providers waiting for this process. 14775 if (checkAppInLaunchingProvidersLocked(app, false)) { 14776 restart = true; 14777 } 14778 14779 // Unregister from connected content providers. 14780 if (!app.conProviders.isEmpty()) { 14781 for (int i=0; i<app.conProviders.size(); i++) { 14782 ContentProviderConnection conn = app.conProviders.get(i); 14783 conn.provider.connections.remove(conn); 14784 } 14785 app.conProviders.clear(); 14786 } 14787 14788 // At this point there may be remaining entries in mLaunchingProviders 14789 // where we were the only one waiting, so they are no longer of use. 14790 // Look for these and clean up if found. 14791 // XXX Commented out for now. Trying to figure out a way to reproduce 14792 // the actual situation to identify what is actually going on. 14793 if (false) { 14794 for (int i=0; i<mLaunchingProviders.size(); i++) { 14795 ContentProviderRecord cpr = (ContentProviderRecord) 14796 mLaunchingProviders.get(i); 14797 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14798 synchronized (cpr) { 14799 cpr.launchingApp = null; 14800 cpr.notifyAll(); 14801 } 14802 } 14803 } 14804 } 14805 14806 skipCurrentReceiverLocked(app); 14807 14808 // Unregister any receivers. 14809 for (int i=app.receivers.size()-1; i>=0; i--) { 14810 removeReceiverLocked(app.receivers.valueAt(i)); 14811 } 14812 app.receivers.clear(); 14813 14814 // If the app is undergoing backup, tell the backup manager about it 14815 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14816 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14817 + mBackupTarget.appInfo + " died during backup"); 14818 try { 14819 IBackupManager bm = IBackupManager.Stub.asInterface( 14820 ServiceManager.getService(Context.BACKUP_SERVICE)); 14821 bm.agentDisconnected(app.info.packageName); 14822 } catch (RemoteException e) { 14823 // can't happen; backup manager is local 14824 } 14825 } 14826 14827 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14828 ProcessChangeItem item = mPendingProcessChanges.get(i); 14829 if (item.pid == app.pid) { 14830 mPendingProcessChanges.remove(i); 14831 mAvailProcessChanges.add(item); 14832 } 14833 } 14834 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14835 14836 // If the caller is restarting this app, then leave it in its 14837 // current lists and let the caller take care of it. 14838 if (restarting) { 14839 return false; 14840 } 14841 14842 if (!app.persistent || app.isolated) { 14843 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14844 "Removing non-persistent process during cleanup: " + app); 14845 mProcessNames.remove(app.processName, app.uid); 14846 mIsolatedProcesses.remove(app.uid); 14847 if (mHeavyWeightProcess == app) { 14848 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14849 mHeavyWeightProcess.userId, 0)); 14850 mHeavyWeightProcess = null; 14851 } 14852 } else if (!app.removed) { 14853 // This app is persistent, so we need to keep its record around. 14854 // If it is not already on the pending app list, add it there 14855 // and start a new process for it. 14856 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14857 mPersistentStartingProcesses.add(app); 14858 restart = true; 14859 } 14860 } 14861 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14862 "Clean-up removing on hold: " + app); 14863 mProcessesOnHold.remove(app); 14864 14865 if (app == mHomeProcess) { 14866 mHomeProcess = null; 14867 } 14868 if (app == mPreviousProcess) { 14869 mPreviousProcess = null; 14870 } 14871 14872 if (restart && !app.isolated) { 14873 // We have components that still need to be running in the 14874 // process, so re-launch it. 14875 if (index < 0) { 14876 ProcessList.remove(app.pid); 14877 } 14878 mProcessNames.put(app.processName, app.uid, app); 14879 startProcessLocked(app, "restart", app.processName); 14880 return true; 14881 } else if (app.pid > 0 && app.pid != MY_PID) { 14882 // Goodbye! 14883 boolean removed; 14884 synchronized (mPidsSelfLocked) { 14885 mPidsSelfLocked.remove(app.pid); 14886 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14887 } 14888 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14889 if (app.isolated) { 14890 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14891 } 14892 app.setPid(0); 14893 } 14894 return false; 14895 } 14896 14897 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14898 // Look through the content providers we are waiting to have launched, 14899 // and if any run in this process then either schedule a restart of 14900 // the process or kill the client waiting for it if this process has 14901 // gone bad. 14902 int NL = mLaunchingProviders.size(); 14903 boolean restart = false; 14904 for (int i=0; i<NL; i++) { 14905 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14906 if (cpr.launchingApp == app) { 14907 if (!alwaysBad && !app.bad) { 14908 restart = true; 14909 } else { 14910 removeDyingProviderLocked(app, cpr, true); 14911 // cpr should have been removed from mLaunchingProviders 14912 NL = mLaunchingProviders.size(); 14913 i--; 14914 } 14915 } 14916 } 14917 return restart; 14918 } 14919 14920 // ========================================================= 14921 // SERVICES 14922 // ========================================================= 14923 14924 @Override 14925 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14926 int flags) { 14927 enforceNotIsolatedCaller("getServices"); 14928 synchronized (this) { 14929 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14930 } 14931 } 14932 14933 @Override 14934 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14935 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14936 synchronized (this) { 14937 return mServices.getRunningServiceControlPanelLocked(name); 14938 } 14939 } 14940 14941 @Override 14942 public ComponentName startService(IApplicationThread caller, Intent service, 14943 String resolvedType, int userId) { 14944 enforceNotIsolatedCaller("startService"); 14945 // Refuse possible leaked file descriptors 14946 if (service != null && service.hasFileDescriptors() == true) { 14947 throw new IllegalArgumentException("File descriptors passed in Intent"); 14948 } 14949 14950 if (DEBUG_SERVICE) 14951 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14952 synchronized(this) { 14953 final int callingPid = Binder.getCallingPid(); 14954 final int callingUid = Binder.getCallingUid(); 14955 final long origId = Binder.clearCallingIdentity(); 14956 ComponentName res = mServices.startServiceLocked(caller, service, 14957 resolvedType, callingPid, callingUid, userId); 14958 Binder.restoreCallingIdentity(origId); 14959 return res; 14960 } 14961 } 14962 14963 ComponentName startServiceInPackage(int uid, 14964 Intent service, String resolvedType, int userId) { 14965 synchronized(this) { 14966 if (DEBUG_SERVICE) 14967 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14968 final long origId = Binder.clearCallingIdentity(); 14969 ComponentName res = mServices.startServiceLocked(null, service, 14970 resolvedType, -1, uid, userId); 14971 Binder.restoreCallingIdentity(origId); 14972 return res; 14973 } 14974 } 14975 14976 @Override 14977 public int stopService(IApplicationThread caller, Intent service, 14978 String resolvedType, int userId) { 14979 enforceNotIsolatedCaller("stopService"); 14980 // Refuse possible leaked file descriptors 14981 if (service != null && service.hasFileDescriptors() == true) { 14982 throw new IllegalArgumentException("File descriptors passed in Intent"); 14983 } 14984 14985 synchronized(this) { 14986 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14987 } 14988 } 14989 14990 @Override 14991 public IBinder peekService(Intent service, String resolvedType) { 14992 enforceNotIsolatedCaller("peekService"); 14993 // Refuse possible leaked file descriptors 14994 if (service != null && service.hasFileDescriptors() == true) { 14995 throw new IllegalArgumentException("File descriptors passed in Intent"); 14996 } 14997 synchronized(this) { 14998 return mServices.peekServiceLocked(service, resolvedType); 14999 } 15000 } 15001 15002 @Override 15003 public boolean stopServiceToken(ComponentName className, IBinder token, 15004 int startId) { 15005 synchronized(this) { 15006 return mServices.stopServiceTokenLocked(className, token, startId); 15007 } 15008 } 15009 15010 @Override 15011 public void setServiceForeground(ComponentName className, IBinder token, 15012 int id, Notification notification, boolean removeNotification) { 15013 synchronized(this) { 15014 mServices.setServiceForegroundLocked(className, token, id, notification, 15015 removeNotification); 15016 } 15017 } 15018 15019 @Override 15020 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15021 boolean requireFull, String name, String callerPackage) { 15022 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15023 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15024 } 15025 15026 int unsafeConvertIncomingUser(int userId) { 15027 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15028 ? mCurrentUserId : userId; 15029 } 15030 15031 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15032 int allowMode, String name, String callerPackage) { 15033 final int callingUserId = UserHandle.getUserId(callingUid); 15034 if (callingUserId == userId) { 15035 return userId; 15036 } 15037 15038 // Note that we may be accessing mCurrentUserId outside of a lock... 15039 // shouldn't be a big deal, if this is being called outside 15040 // of a locked context there is intrinsically a race with 15041 // the value the caller will receive and someone else changing it. 15042 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15043 // we will switch to the calling user if access to the current user fails. 15044 int targetUserId = unsafeConvertIncomingUser(userId); 15045 15046 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15047 final boolean allow; 15048 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15049 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15050 // If the caller has this permission, they always pass go. And collect $200. 15051 allow = true; 15052 } else if (allowMode == ALLOW_FULL_ONLY) { 15053 // We require full access, sucks to be you. 15054 allow = false; 15055 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15056 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15057 // If the caller does not have either permission, they are always doomed. 15058 allow = false; 15059 } else if (allowMode == ALLOW_NON_FULL) { 15060 // We are blanket allowing non-full access, you lucky caller! 15061 allow = true; 15062 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15063 // We may or may not allow this depending on whether the two users are 15064 // in the same profile. 15065 synchronized (mUserProfileGroupIdsSelfLocked) { 15066 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15067 UserInfo.NO_PROFILE_GROUP_ID); 15068 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15069 UserInfo.NO_PROFILE_GROUP_ID); 15070 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15071 && callingProfile == targetProfile; 15072 } 15073 } else { 15074 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15075 } 15076 if (!allow) { 15077 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15078 // In this case, they would like to just execute as their 15079 // owner user instead of failing. 15080 targetUserId = callingUserId; 15081 } else { 15082 StringBuilder builder = new StringBuilder(128); 15083 builder.append("Permission Denial: "); 15084 builder.append(name); 15085 if (callerPackage != null) { 15086 builder.append(" from "); 15087 builder.append(callerPackage); 15088 } 15089 builder.append(" asks to run as user "); 15090 builder.append(userId); 15091 builder.append(" but is calling from user "); 15092 builder.append(UserHandle.getUserId(callingUid)); 15093 builder.append("; this requires "); 15094 builder.append(INTERACT_ACROSS_USERS_FULL); 15095 if (allowMode != ALLOW_FULL_ONLY) { 15096 builder.append(" or "); 15097 builder.append(INTERACT_ACROSS_USERS); 15098 } 15099 String msg = builder.toString(); 15100 Slog.w(TAG, msg); 15101 throw new SecurityException(msg); 15102 } 15103 } 15104 } 15105 if (!allowAll && targetUserId < 0) { 15106 throw new IllegalArgumentException( 15107 "Call does not support special user #" + targetUserId); 15108 } 15109 // Check shell permission 15110 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15111 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15112 targetUserId)) { 15113 throw new SecurityException("Shell does not have permission to access user " 15114 + targetUserId + "\n " + Debug.getCallers(3)); 15115 } 15116 } 15117 return targetUserId; 15118 } 15119 15120 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15121 String className, int flags) { 15122 boolean result = false; 15123 // For apps that don't have pre-defined UIDs, check for permission 15124 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15125 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15126 if (ActivityManager.checkUidPermission( 15127 INTERACT_ACROSS_USERS, 15128 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15129 ComponentName comp = new ComponentName(aInfo.packageName, className); 15130 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15131 + " requests FLAG_SINGLE_USER, but app does not hold " 15132 + INTERACT_ACROSS_USERS; 15133 Slog.w(TAG, msg); 15134 throw new SecurityException(msg); 15135 } 15136 // Permission passed 15137 result = true; 15138 } 15139 } else if ("system".equals(componentProcessName)) { 15140 result = true; 15141 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15142 // Phone app and persistent apps are allowed to export singleuser providers. 15143 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15144 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15145 } 15146 if (DEBUG_MU) { 15147 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15148 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15149 } 15150 return result; 15151 } 15152 15153 /** 15154 * Checks to see if the caller is in the same app as the singleton 15155 * component, or the component is in a special app. It allows special apps 15156 * to export singleton components but prevents exporting singleton 15157 * components for regular apps. 15158 */ 15159 boolean isValidSingletonCall(int callingUid, int componentUid) { 15160 int componentAppId = UserHandle.getAppId(componentUid); 15161 return UserHandle.isSameApp(callingUid, componentUid) 15162 || componentAppId == Process.SYSTEM_UID 15163 || componentAppId == Process.PHONE_UID 15164 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15165 == PackageManager.PERMISSION_GRANTED; 15166 } 15167 15168 public int bindService(IApplicationThread caller, IBinder token, 15169 Intent service, String resolvedType, 15170 IServiceConnection connection, int flags, int userId) { 15171 enforceNotIsolatedCaller("bindService"); 15172 15173 // Refuse possible leaked file descriptors 15174 if (service != null && service.hasFileDescriptors() == true) { 15175 throw new IllegalArgumentException("File descriptors passed in Intent"); 15176 } 15177 15178 synchronized(this) { 15179 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15180 connection, flags, userId); 15181 } 15182 } 15183 15184 public boolean unbindService(IServiceConnection connection) { 15185 synchronized (this) { 15186 return mServices.unbindServiceLocked(connection); 15187 } 15188 } 15189 15190 public void publishService(IBinder token, Intent intent, IBinder service) { 15191 // Refuse possible leaked file descriptors 15192 if (intent != null && intent.hasFileDescriptors() == true) { 15193 throw new IllegalArgumentException("File descriptors passed in Intent"); 15194 } 15195 15196 synchronized(this) { 15197 if (!(token instanceof ServiceRecord)) { 15198 throw new IllegalArgumentException("Invalid service token"); 15199 } 15200 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15201 } 15202 } 15203 15204 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15205 // Refuse possible leaked file descriptors 15206 if (intent != null && intent.hasFileDescriptors() == true) { 15207 throw new IllegalArgumentException("File descriptors passed in Intent"); 15208 } 15209 15210 synchronized(this) { 15211 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15212 } 15213 } 15214 15215 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15216 synchronized(this) { 15217 if (!(token instanceof ServiceRecord)) { 15218 throw new IllegalArgumentException("Invalid service token"); 15219 } 15220 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15221 } 15222 } 15223 15224 // ========================================================= 15225 // BACKUP AND RESTORE 15226 // ========================================================= 15227 15228 // Cause the target app to be launched if necessary and its backup agent 15229 // instantiated. The backup agent will invoke backupAgentCreated() on the 15230 // activity manager to announce its creation. 15231 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15232 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15233 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15234 15235 synchronized(this) { 15236 // !!! TODO: currently no check here that we're already bound 15237 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15238 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15239 synchronized (stats) { 15240 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15241 } 15242 15243 // Backup agent is now in use, its package can't be stopped. 15244 try { 15245 AppGlobals.getPackageManager().setPackageStoppedState( 15246 app.packageName, false, UserHandle.getUserId(app.uid)); 15247 } catch (RemoteException e) { 15248 } catch (IllegalArgumentException e) { 15249 Slog.w(TAG, "Failed trying to unstop package " 15250 + app.packageName + ": " + e); 15251 } 15252 15253 BackupRecord r = new BackupRecord(ss, app, backupMode); 15254 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15255 ? new ComponentName(app.packageName, app.backupAgentName) 15256 : new ComponentName("android", "FullBackupAgent"); 15257 // startProcessLocked() returns existing proc's record if it's already running 15258 ProcessRecord proc = startProcessLocked(app.processName, app, 15259 false, 0, "backup", hostingName, false, false, false); 15260 if (proc == null) { 15261 Slog.e(TAG, "Unable to start backup agent process " + r); 15262 return false; 15263 } 15264 15265 r.app = proc; 15266 mBackupTarget = r; 15267 mBackupAppName = app.packageName; 15268 15269 // Try not to kill the process during backup 15270 updateOomAdjLocked(proc); 15271 15272 // If the process is already attached, schedule the creation of the backup agent now. 15273 // If it is not yet live, this will be done when it attaches to the framework. 15274 if (proc.thread != null) { 15275 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15276 try { 15277 proc.thread.scheduleCreateBackupAgent(app, 15278 compatibilityInfoForPackageLocked(app), backupMode); 15279 } catch (RemoteException e) { 15280 // Will time out on the backup manager side 15281 } 15282 } else { 15283 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15284 } 15285 // Invariants: at this point, the target app process exists and the application 15286 // is either already running or in the process of coming up. mBackupTarget and 15287 // mBackupAppName describe the app, so that when it binds back to the AM we 15288 // know that it's scheduled for a backup-agent operation. 15289 } 15290 15291 return true; 15292 } 15293 15294 @Override 15295 public void clearPendingBackup() { 15296 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15297 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15298 15299 synchronized (this) { 15300 mBackupTarget = null; 15301 mBackupAppName = null; 15302 } 15303 } 15304 15305 // A backup agent has just come up 15306 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15307 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15308 + " = " + agent); 15309 15310 synchronized(this) { 15311 if (!agentPackageName.equals(mBackupAppName)) { 15312 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15313 return; 15314 } 15315 } 15316 15317 long oldIdent = Binder.clearCallingIdentity(); 15318 try { 15319 IBackupManager bm = IBackupManager.Stub.asInterface( 15320 ServiceManager.getService(Context.BACKUP_SERVICE)); 15321 bm.agentConnected(agentPackageName, agent); 15322 } catch (RemoteException e) { 15323 // can't happen; the backup manager service is local 15324 } catch (Exception e) { 15325 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15326 e.printStackTrace(); 15327 } finally { 15328 Binder.restoreCallingIdentity(oldIdent); 15329 } 15330 } 15331 15332 // done with this agent 15333 public void unbindBackupAgent(ApplicationInfo appInfo) { 15334 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15335 if (appInfo == null) { 15336 Slog.w(TAG, "unbind backup agent for null app"); 15337 return; 15338 } 15339 15340 synchronized(this) { 15341 try { 15342 if (mBackupAppName == null) { 15343 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15344 return; 15345 } 15346 15347 if (!mBackupAppName.equals(appInfo.packageName)) { 15348 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15349 return; 15350 } 15351 15352 // Not backing this app up any more; reset its OOM adjustment 15353 final ProcessRecord proc = mBackupTarget.app; 15354 updateOomAdjLocked(proc); 15355 15356 // If the app crashed during backup, 'thread' will be null here 15357 if (proc.thread != null) { 15358 try { 15359 proc.thread.scheduleDestroyBackupAgent(appInfo, 15360 compatibilityInfoForPackageLocked(appInfo)); 15361 } catch (Exception e) { 15362 Slog.e(TAG, "Exception when unbinding backup agent:"); 15363 e.printStackTrace(); 15364 } 15365 } 15366 } finally { 15367 mBackupTarget = null; 15368 mBackupAppName = null; 15369 } 15370 } 15371 } 15372 // ========================================================= 15373 // BROADCASTS 15374 // ========================================================= 15375 15376 private final List getStickiesLocked(String action, IntentFilter filter, 15377 List cur, int userId) { 15378 final ContentResolver resolver = mContext.getContentResolver(); 15379 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15380 if (stickies == null) { 15381 return cur; 15382 } 15383 final ArrayList<Intent> list = stickies.get(action); 15384 if (list == null) { 15385 return cur; 15386 } 15387 int N = list.size(); 15388 for (int i=0; i<N; i++) { 15389 Intent intent = list.get(i); 15390 if (filter.match(resolver, intent, true, TAG) >= 0) { 15391 if (cur == null) { 15392 cur = new ArrayList<Intent>(); 15393 } 15394 cur.add(intent); 15395 } 15396 } 15397 return cur; 15398 } 15399 15400 boolean isPendingBroadcastProcessLocked(int pid) { 15401 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15402 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15403 } 15404 15405 void skipPendingBroadcastLocked(int pid) { 15406 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15407 for (BroadcastQueue queue : mBroadcastQueues) { 15408 queue.skipPendingBroadcastLocked(pid); 15409 } 15410 } 15411 15412 // The app just attached; send any pending broadcasts that it should receive 15413 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15414 boolean didSomething = false; 15415 for (BroadcastQueue queue : mBroadcastQueues) { 15416 didSomething |= queue.sendPendingBroadcastsLocked(app); 15417 } 15418 return didSomething; 15419 } 15420 15421 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15422 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15423 enforceNotIsolatedCaller("registerReceiver"); 15424 int callingUid; 15425 int callingPid; 15426 synchronized(this) { 15427 ProcessRecord callerApp = null; 15428 if (caller != null) { 15429 callerApp = getRecordForAppLocked(caller); 15430 if (callerApp == null) { 15431 throw new SecurityException( 15432 "Unable to find app for caller " + caller 15433 + " (pid=" + Binder.getCallingPid() 15434 + ") when registering receiver " + receiver); 15435 } 15436 if (callerApp.info.uid != Process.SYSTEM_UID && 15437 !callerApp.pkgList.containsKey(callerPackage) && 15438 !"android".equals(callerPackage)) { 15439 throw new SecurityException("Given caller package " + callerPackage 15440 + " is not running in process " + callerApp); 15441 } 15442 callingUid = callerApp.info.uid; 15443 callingPid = callerApp.pid; 15444 } else { 15445 callerPackage = null; 15446 callingUid = Binder.getCallingUid(); 15447 callingPid = Binder.getCallingPid(); 15448 } 15449 15450 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15451 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15452 15453 List allSticky = null; 15454 15455 // Look for any matching sticky broadcasts... 15456 Iterator actions = filter.actionsIterator(); 15457 if (actions != null) { 15458 while (actions.hasNext()) { 15459 String action = (String)actions.next(); 15460 allSticky = getStickiesLocked(action, filter, allSticky, 15461 UserHandle.USER_ALL); 15462 allSticky = getStickiesLocked(action, filter, allSticky, 15463 UserHandle.getUserId(callingUid)); 15464 } 15465 } else { 15466 allSticky = getStickiesLocked(null, filter, allSticky, 15467 UserHandle.USER_ALL); 15468 allSticky = getStickiesLocked(null, filter, allSticky, 15469 UserHandle.getUserId(callingUid)); 15470 } 15471 15472 // The first sticky in the list is returned directly back to 15473 // the client. 15474 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15475 15476 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15477 + ": " + sticky); 15478 15479 if (receiver == null) { 15480 return sticky; 15481 } 15482 15483 ReceiverList rl 15484 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15485 if (rl == null) { 15486 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15487 userId, receiver); 15488 if (rl.app != null) { 15489 rl.app.receivers.add(rl); 15490 } else { 15491 try { 15492 receiver.asBinder().linkToDeath(rl, 0); 15493 } catch (RemoteException e) { 15494 return sticky; 15495 } 15496 rl.linkedToDeath = true; 15497 } 15498 mRegisteredReceivers.put(receiver.asBinder(), rl); 15499 } else if (rl.uid != callingUid) { 15500 throw new IllegalArgumentException( 15501 "Receiver requested to register for uid " + callingUid 15502 + " was previously registered for uid " + rl.uid); 15503 } else if (rl.pid != callingPid) { 15504 throw new IllegalArgumentException( 15505 "Receiver requested to register for pid " + callingPid 15506 + " was previously registered for pid " + rl.pid); 15507 } else if (rl.userId != userId) { 15508 throw new IllegalArgumentException( 15509 "Receiver requested to register for user " + userId 15510 + " was previously registered for user " + rl.userId); 15511 } 15512 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15513 permission, callingUid, userId); 15514 rl.add(bf); 15515 if (!bf.debugCheck()) { 15516 Slog.w(TAG, "==> For Dynamic broadast"); 15517 } 15518 mReceiverResolver.addFilter(bf); 15519 15520 // Enqueue broadcasts for all existing stickies that match 15521 // this filter. 15522 if (allSticky != null) { 15523 ArrayList receivers = new ArrayList(); 15524 receivers.add(bf); 15525 15526 int N = allSticky.size(); 15527 for (int i=0; i<N; i++) { 15528 Intent intent = (Intent)allSticky.get(i); 15529 BroadcastQueue queue = broadcastQueueForIntent(intent); 15530 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15531 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15532 null, null, false, true, true, -1); 15533 queue.enqueueParallelBroadcastLocked(r); 15534 queue.scheduleBroadcastsLocked(); 15535 } 15536 } 15537 15538 return sticky; 15539 } 15540 } 15541 15542 public void unregisterReceiver(IIntentReceiver receiver) { 15543 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15544 15545 final long origId = Binder.clearCallingIdentity(); 15546 try { 15547 boolean doTrim = false; 15548 15549 synchronized(this) { 15550 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15551 if (rl != null) { 15552 if (rl.curBroadcast != null) { 15553 BroadcastRecord r = rl.curBroadcast; 15554 final boolean doNext = finishReceiverLocked( 15555 receiver.asBinder(), r.resultCode, r.resultData, 15556 r.resultExtras, r.resultAbort); 15557 if (doNext) { 15558 doTrim = true; 15559 r.queue.processNextBroadcast(false); 15560 } 15561 } 15562 15563 if (rl.app != null) { 15564 rl.app.receivers.remove(rl); 15565 } 15566 removeReceiverLocked(rl); 15567 if (rl.linkedToDeath) { 15568 rl.linkedToDeath = false; 15569 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15570 } 15571 } 15572 } 15573 15574 // If we actually concluded any broadcasts, we might now be able 15575 // to trim the recipients' apps from our working set 15576 if (doTrim) { 15577 trimApplications(); 15578 return; 15579 } 15580 15581 } finally { 15582 Binder.restoreCallingIdentity(origId); 15583 } 15584 } 15585 15586 void removeReceiverLocked(ReceiverList rl) { 15587 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15588 int N = rl.size(); 15589 for (int i=0; i<N; i++) { 15590 mReceiverResolver.removeFilter(rl.get(i)); 15591 } 15592 } 15593 15594 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15595 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15596 ProcessRecord r = mLruProcesses.get(i); 15597 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15598 try { 15599 r.thread.dispatchPackageBroadcast(cmd, packages); 15600 } catch (RemoteException ex) { 15601 } 15602 } 15603 } 15604 } 15605 15606 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15607 int callingUid, int[] users) { 15608 List<ResolveInfo> receivers = null; 15609 try { 15610 HashSet<ComponentName> singleUserReceivers = null; 15611 boolean scannedFirstReceivers = false; 15612 for (int user : users) { 15613 // Skip users that have Shell restrictions 15614 if (callingUid == Process.SHELL_UID 15615 && getUserManagerLocked().hasUserRestriction( 15616 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15617 continue; 15618 } 15619 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15620 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15621 if (user != 0 && newReceivers != null) { 15622 // If this is not the primary user, we need to check for 15623 // any receivers that should be filtered out. 15624 for (int i=0; i<newReceivers.size(); i++) { 15625 ResolveInfo ri = newReceivers.get(i); 15626 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15627 newReceivers.remove(i); 15628 i--; 15629 } 15630 } 15631 } 15632 if (newReceivers != null && newReceivers.size() == 0) { 15633 newReceivers = null; 15634 } 15635 if (receivers == null) { 15636 receivers = newReceivers; 15637 } else if (newReceivers != null) { 15638 // We need to concatenate the additional receivers 15639 // found with what we have do far. This would be easy, 15640 // but we also need to de-dup any receivers that are 15641 // singleUser. 15642 if (!scannedFirstReceivers) { 15643 // Collect any single user receivers we had already retrieved. 15644 scannedFirstReceivers = true; 15645 for (int i=0; i<receivers.size(); i++) { 15646 ResolveInfo ri = receivers.get(i); 15647 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15648 ComponentName cn = new ComponentName( 15649 ri.activityInfo.packageName, ri.activityInfo.name); 15650 if (singleUserReceivers == null) { 15651 singleUserReceivers = new HashSet<ComponentName>(); 15652 } 15653 singleUserReceivers.add(cn); 15654 } 15655 } 15656 } 15657 // Add the new results to the existing results, tracking 15658 // and de-dupping single user receivers. 15659 for (int i=0; i<newReceivers.size(); i++) { 15660 ResolveInfo ri = newReceivers.get(i); 15661 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15662 ComponentName cn = new ComponentName( 15663 ri.activityInfo.packageName, ri.activityInfo.name); 15664 if (singleUserReceivers == null) { 15665 singleUserReceivers = new HashSet<ComponentName>(); 15666 } 15667 if (!singleUserReceivers.contains(cn)) { 15668 singleUserReceivers.add(cn); 15669 receivers.add(ri); 15670 } 15671 } else { 15672 receivers.add(ri); 15673 } 15674 } 15675 } 15676 } 15677 } catch (RemoteException ex) { 15678 // pm is in same process, this will never happen. 15679 } 15680 return receivers; 15681 } 15682 15683 private final int broadcastIntentLocked(ProcessRecord callerApp, 15684 String callerPackage, Intent intent, String resolvedType, 15685 IIntentReceiver resultTo, int resultCode, String resultData, 15686 Bundle map, String requiredPermission, int appOp, 15687 boolean ordered, boolean sticky, int callingPid, int callingUid, 15688 int userId) { 15689 intent = new Intent(intent); 15690 15691 // By default broadcasts do not go to stopped apps. 15692 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15693 15694 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15695 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15696 + " ordered=" + ordered + " userid=" + userId); 15697 if ((resultTo != null) && !ordered) { 15698 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15699 } 15700 15701 userId = handleIncomingUser(callingPid, callingUid, userId, 15702 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15703 15704 // Make sure that the user who is receiving this broadcast is running. 15705 // If not, we will just skip it. Make an exception for shutdown broadcasts 15706 // and upgrade steps. 15707 15708 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15709 if ((callingUid != Process.SYSTEM_UID 15710 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15711 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15712 Slog.w(TAG, "Skipping broadcast of " + intent 15713 + ": user " + userId + " is stopped"); 15714 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15715 } 15716 } 15717 15718 /* 15719 * Prevent non-system code (defined here to be non-persistent 15720 * processes) from sending protected broadcasts. 15721 */ 15722 int callingAppId = UserHandle.getAppId(callingUid); 15723 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15724 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15725 || callingAppId == Process.NFC_UID || callingUid == 0) { 15726 // Always okay. 15727 } else if (callerApp == null || !callerApp.persistent) { 15728 try { 15729 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15730 intent.getAction())) { 15731 String msg = "Permission Denial: not allowed to send broadcast " 15732 + intent.getAction() + " from pid=" 15733 + callingPid + ", uid=" + callingUid; 15734 Slog.w(TAG, msg); 15735 throw new SecurityException(msg); 15736 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15737 // Special case for compatibility: we don't want apps to send this, 15738 // but historically it has not been protected and apps may be using it 15739 // to poke their own app widget. So, instead of making it protected, 15740 // just limit it to the caller. 15741 if (callerApp == null) { 15742 String msg = "Permission Denial: not allowed to send broadcast " 15743 + intent.getAction() + " from unknown caller."; 15744 Slog.w(TAG, msg); 15745 throw new SecurityException(msg); 15746 } else if (intent.getComponent() != null) { 15747 // They are good enough to send to an explicit component... verify 15748 // it is being sent to the calling app. 15749 if (!intent.getComponent().getPackageName().equals( 15750 callerApp.info.packageName)) { 15751 String msg = "Permission Denial: not allowed to send broadcast " 15752 + intent.getAction() + " to " 15753 + intent.getComponent().getPackageName() + " from " 15754 + callerApp.info.packageName; 15755 Slog.w(TAG, msg); 15756 throw new SecurityException(msg); 15757 } 15758 } else { 15759 // Limit broadcast to their own package. 15760 intent.setPackage(callerApp.info.packageName); 15761 } 15762 } 15763 } catch (RemoteException e) { 15764 Slog.w(TAG, "Remote exception", e); 15765 return ActivityManager.BROADCAST_SUCCESS; 15766 } 15767 } 15768 15769 final String action = intent.getAction(); 15770 if (action != null) { 15771 switch (action) { 15772 case Intent.ACTION_UID_REMOVED: 15773 case Intent.ACTION_PACKAGE_REMOVED: 15774 case Intent.ACTION_PACKAGE_CHANGED: 15775 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15776 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15777 // Handle special intents: if this broadcast is from the package 15778 // manager about a package being removed, we need to remove all of 15779 // its activities from the history stack. 15780 if (checkComponentPermission( 15781 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15782 callingPid, callingUid, -1, true) 15783 != PackageManager.PERMISSION_GRANTED) { 15784 String msg = "Permission Denial: " + intent.getAction() 15785 + " broadcast from " + callerPackage + " (pid=" + callingPid 15786 + ", uid=" + callingUid + ")" 15787 + " requires " 15788 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15789 Slog.w(TAG, msg); 15790 throw new SecurityException(msg); 15791 } 15792 switch (action) { 15793 case Intent.ACTION_UID_REMOVED: 15794 final Bundle intentExtras = intent.getExtras(); 15795 final int uid = intentExtras != null 15796 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15797 if (uid >= 0) { 15798 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15799 synchronized (bs) { 15800 bs.removeUidStatsLocked(uid); 15801 } 15802 mAppOpsService.uidRemoved(uid); 15803 } 15804 break; 15805 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15806 // If resources are unavailable just force stop all those packages 15807 // and flush the attribute cache as well. 15808 String list[] = 15809 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15810 if (list != null && list.length > 0) { 15811 for (int i = 0; i < list.length; i++) { 15812 forceStopPackageLocked(list[i], -1, false, true, true, 15813 false, false, userId, "storage unmount"); 15814 } 15815 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15816 sendPackageBroadcastLocked( 15817 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15818 userId); 15819 } 15820 break; 15821 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15822 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15823 break; 15824 case Intent.ACTION_PACKAGE_REMOVED: 15825 case Intent.ACTION_PACKAGE_CHANGED: 15826 Uri data = intent.getData(); 15827 String ssp; 15828 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15829 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15830 boolean fullUninstall = removed && 15831 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15832 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15833 forceStopPackageLocked(ssp, UserHandle.getAppId( 15834 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15835 false, true, true, false, fullUninstall, userId, 15836 removed ? "pkg removed" : "pkg changed"); 15837 } 15838 if (removed) { 15839 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15840 new String[] {ssp}, userId); 15841 if (fullUninstall) { 15842 mAppOpsService.packageRemoved( 15843 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15844 15845 // Remove all permissions granted from/to this package 15846 removeUriPermissionsForPackageLocked(ssp, userId, true); 15847 15848 removeTasksByPackageNameLocked(ssp, userId); 15849 } 15850 } else { 15851 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15852 if (userId == UserHandle.USER_OWNER) { 15853 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15854 } 15855 } 15856 } 15857 break; 15858 } 15859 break; 15860 case Intent.ACTION_PACKAGE_ADDED: 15861 // Special case for adding a package: by default turn on compatibility mode. 15862 Uri data = intent.getData(); 15863 String ssp; 15864 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15865 final boolean replacing = 15866 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15867 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15868 15869 if (replacing) { 15870 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15871 } 15872 if (userId == UserHandle.USER_OWNER) { 15873 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15874 } 15875 } 15876 break; 15877 case Intent.ACTION_TIMEZONE_CHANGED: 15878 // If this is the time zone changed action, queue up a message that will reset 15879 // the timezone of all currently running processes. This message will get 15880 // queued up before the broadcast happens. 15881 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15882 break; 15883 case Intent.ACTION_TIME_CHANGED: 15884 // If the user set the time, let all running processes know. 15885 final int is24Hour = 15886 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15887 : 0; 15888 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15889 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15890 synchronized (stats) { 15891 stats.noteCurrentTimeChangedLocked(); 15892 } 15893 break; 15894 case Intent.ACTION_CLEAR_DNS_CACHE: 15895 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15896 break; 15897 case Proxy.PROXY_CHANGE_ACTION: 15898 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15899 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15900 break; 15901 } 15902 } 15903 15904 // Add to the sticky list if requested. 15905 if (sticky) { 15906 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15907 callingPid, callingUid) 15908 != PackageManager.PERMISSION_GRANTED) { 15909 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15910 + callingPid + ", uid=" + callingUid 15911 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15912 Slog.w(TAG, msg); 15913 throw new SecurityException(msg); 15914 } 15915 if (requiredPermission != null) { 15916 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15917 + " and enforce permission " + requiredPermission); 15918 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15919 } 15920 if (intent.getComponent() != null) { 15921 throw new SecurityException( 15922 "Sticky broadcasts can't target a specific component"); 15923 } 15924 // We use userId directly here, since the "all" target is maintained 15925 // as a separate set of sticky broadcasts. 15926 if (userId != UserHandle.USER_ALL) { 15927 // But first, if this is not a broadcast to all users, then 15928 // make sure it doesn't conflict with an existing broadcast to 15929 // all users. 15930 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15931 UserHandle.USER_ALL); 15932 if (stickies != null) { 15933 ArrayList<Intent> list = stickies.get(intent.getAction()); 15934 if (list != null) { 15935 int N = list.size(); 15936 int i; 15937 for (i=0; i<N; i++) { 15938 if (intent.filterEquals(list.get(i))) { 15939 throw new IllegalArgumentException( 15940 "Sticky broadcast " + intent + " for user " 15941 + userId + " conflicts with existing global broadcast"); 15942 } 15943 } 15944 } 15945 } 15946 } 15947 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15948 if (stickies == null) { 15949 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15950 mStickyBroadcasts.put(userId, stickies); 15951 } 15952 ArrayList<Intent> list = stickies.get(intent.getAction()); 15953 if (list == null) { 15954 list = new ArrayList<Intent>(); 15955 stickies.put(intent.getAction(), list); 15956 } 15957 int N = list.size(); 15958 int i; 15959 for (i=0; i<N; i++) { 15960 if (intent.filterEquals(list.get(i))) { 15961 // This sticky already exists, replace it. 15962 list.set(i, new Intent(intent)); 15963 break; 15964 } 15965 } 15966 if (i >= N) { 15967 list.add(new Intent(intent)); 15968 } 15969 } 15970 15971 int[] users; 15972 if (userId == UserHandle.USER_ALL) { 15973 // Caller wants broadcast to go to all started users. 15974 users = mStartedUserArray; 15975 } else { 15976 // Caller wants broadcast to go to one specific user. 15977 users = new int[] {userId}; 15978 } 15979 15980 // Figure out who all will receive this broadcast. 15981 List receivers = null; 15982 List<BroadcastFilter> registeredReceivers = null; 15983 // Need to resolve the intent to interested receivers... 15984 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15985 == 0) { 15986 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15987 } 15988 if (intent.getComponent() == null) { 15989 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15990 // Query one target user at a time, excluding shell-restricted users 15991 UserManagerService ums = getUserManagerLocked(); 15992 for (int i = 0; i < users.length; i++) { 15993 if (ums.hasUserRestriction( 15994 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15995 continue; 15996 } 15997 List<BroadcastFilter> registeredReceiversForUser = 15998 mReceiverResolver.queryIntent(intent, 15999 resolvedType, false, users[i]); 16000 if (registeredReceivers == null) { 16001 registeredReceivers = registeredReceiversForUser; 16002 } else if (registeredReceiversForUser != null) { 16003 registeredReceivers.addAll(registeredReceiversForUser); 16004 } 16005 } 16006 } else { 16007 registeredReceivers = mReceiverResolver.queryIntent(intent, 16008 resolvedType, false, userId); 16009 } 16010 } 16011 16012 final boolean replacePending = 16013 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16014 16015 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16016 + " replacePending=" + replacePending); 16017 16018 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16019 if (!ordered && NR > 0) { 16020 // If we are not serializing this broadcast, then send the 16021 // registered receivers separately so they don't wait for the 16022 // components to be launched. 16023 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16024 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16025 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16026 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16027 ordered, sticky, false, userId); 16028 if (DEBUG_BROADCAST) Slog.v( 16029 TAG, "Enqueueing parallel broadcast " + r); 16030 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16031 if (!replaced) { 16032 queue.enqueueParallelBroadcastLocked(r); 16033 queue.scheduleBroadcastsLocked(); 16034 } 16035 registeredReceivers = null; 16036 NR = 0; 16037 } 16038 16039 // Merge into one list. 16040 int ir = 0; 16041 if (receivers != null) { 16042 // A special case for PACKAGE_ADDED: do not allow the package 16043 // being added to see this broadcast. This prevents them from 16044 // using this as a back door to get run as soon as they are 16045 // installed. Maybe in the future we want to have a special install 16046 // broadcast or such for apps, but we'd like to deliberately make 16047 // this decision. 16048 String skipPackages[] = null; 16049 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16050 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16051 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16052 Uri data = intent.getData(); 16053 if (data != null) { 16054 String pkgName = data.getSchemeSpecificPart(); 16055 if (pkgName != null) { 16056 skipPackages = new String[] { pkgName }; 16057 } 16058 } 16059 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16060 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16061 } 16062 if (skipPackages != null && (skipPackages.length > 0)) { 16063 for (String skipPackage : skipPackages) { 16064 if (skipPackage != null) { 16065 int NT = receivers.size(); 16066 for (int it=0; it<NT; it++) { 16067 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16068 if (curt.activityInfo.packageName.equals(skipPackage)) { 16069 receivers.remove(it); 16070 it--; 16071 NT--; 16072 } 16073 } 16074 } 16075 } 16076 } 16077 16078 int NT = receivers != null ? receivers.size() : 0; 16079 int it = 0; 16080 ResolveInfo curt = null; 16081 BroadcastFilter curr = null; 16082 while (it < NT && ir < NR) { 16083 if (curt == null) { 16084 curt = (ResolveInfo)receivers.get(it); 16085 } 16086 if (curr == null) { 16087 curr = registeredReceivers.get(ir); 16088 } 16089 if (curr.getPriority() >= curt.priority) { 16090 // Insert this broadcast record into the final list. 16091 receivers.add(it, curr); 16092 ir++; 16093 curr = null; 16094 it++; 16095 NT++; 16096 } else { 16097 // Skip to the next ResolveInfo in the final list. 16098 it++; 16099 curt = null; 16100 } 16101 } 16102 } 16103 while (ir < NR) { 16104 if (receivers == null) { 16105 receivers = new ArrayList(); 16106 } 16107 receivers.add(registeredReceivers.get(ir)); 16108 ir++; 16109 } 16110 16111 if ((receivers != null && receivers.size() > 0) 16112 || resultTo != null) { 16113 BroadcastQueue queue = broadcastQueueForIntent(intent); 16114 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16115 callerPackage, callingPid, callingUid, resolvedType, 16116 requiredPermission, appOp, receivers, resultTo, resultCode, 16117 resultData, map, ordered, sticky, false, userId); 16118 if (DEBUG_BROADCAST) Slog.v( 16119 TAG, "Enqueueing ordered broadcast " + r 16120 + ": prev had " + queue.mOrderedBroadcasts.size()); 16121 if (DEBUG_BROADCAST) { 16122 int seq = r.intent.getIntExtra("seq", -1); 16123 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16124 } 16125 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16126 if (!replaced) { 16127 queue.enqueueOrderedBroadcastLocked(r); 16128 queue.scheduleBroadcastsLocked(); 16129 } 16130 } 16131 16132 return ActivityManager.BROADCAST_SUCCESS; 16133 } 16134 16135 final Intent verifyBroadcastLocked(Intent intent) { 16136 // Refuse possible leaked file descriptors 16137 if (intent != null && intent.hasFileDescriptors() == true) { 16138 throw new IllegalArgumentException("File descriptors passed in Intent"); 16139 } 16140 16141 int flags = intent.getFlags(); 16142 16143 if (!mProcessesReady) { 16144 // if the caller really truly claims to know what they're doing, go 16145 // ahead and allow the broadcast without launching any receivers 16146 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16147 intent = new Intent(intent); 16148 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16149 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16150 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16151 + " before boot completion"); 16152 throw new IllegalStateException("Cannot broadcast before boot completed"); 16153 } 16154 } 16155 16156 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16157 throw new IllegalArgumentException( 16158 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16159 } 16160 16161 return intent; 16162 } 16163 16164 public final int broadcastIntent(IApplicationThread caller, 16165 Intent intent, String resolvedType, IIntentReceiver resultTo, 16166 int resultCode, String resultData, Bundle map, 16167 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16168 enforceNotIsolatedCaller("broadcastIntent"); 16169 synchronized(this) { 16170 intent = verifyBroadcastLocked(intent); 16171 16172 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16173 final int callingPid = Binder.getCallingPid(); 16174 final int callingUid = Binder.getCallingUid(); 16175 final long origId = Binder.clearCallingIdentity(); 16176 int res = broadcastIntentLocked(callerApp, 16177 callerApp != null ? callerApp.info.packageName : null, 16178 intent, resolvedType, resultTo, 16179 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16180 callingPid, callingUid, userId); 16181 Binder.restoreCallingIdentity(origId); 16182 return res; 16183 } 16184 } 16185 16186 int broadcastIntentInPackage(String packageName, int uid, 16187 Intent intent, String resolvedType, IIntentReceiver resultTo, 16188 int resultCode, String resultData, Bundle map, 16189 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16190 synchronized(this) { 16191 intent = verifyBroadcastLocked(intent); 16192 16193 final long origId = Binder.clearCallingIdentity(); 16194 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16195 resultTo, resultCode, resultData, map, requiredPermission, 16196 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16197 Binder.restoreCallingIdentity(origId); 16198 return res; 16199 } 16200 } 16201 16202 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16203 // Refuse possible leaked file descriptors 16204 if (intent != null && intent.hasFileDescriptors() == true) { 16205 throw new IllegalArgumentException("File descriptors passed in Intent"); 16206 } 16207 16208 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16209 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16210 16211 synchronized(this) { 16212 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16213 != PackageManager.PERMISSION_GRANTED) { 16214 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16215 + Binder.getCallingPid() 16216 + ", uid=" + Binder.getCallingUid() 16217 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16218 Slog.w(TAG, msg); 16219 throw new SecurityException(msg); 16220 } 16221 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16222 if (stickies != null) { 16223 ArrayList<Intent> list = stickies.get(intent.getAction()); 16224 if (list != null) { 16225 int N = list.size(); 16226 int i; 16227 for (i=0; i<N; i++) { 16228 if (intent.filterEquals(list.get(i))) { 16229 list.remove(i); 16230 break; 16231 } 16232 } 16233 if (list.size() <= 0) { 16234 stickies.remove(intent.getAction()); 16235 } 16236 } 16237 if (stickies.size() <= 0) { 16238 mStickyBroadcasts.remove(userId); 16239 } 16240 } 16241 } 16242 } 16243 16244 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16245 String resultData, Bundle resultExtras, boolean resultAbort) { 16246 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16247 if (r == null) { 16248 Slog.w(TAG, "finishReceiver called but not found on queue"); 16249 return false; 16250 } 16251 16252 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16253 } 16254 16255 void backgroundServicesFinishedLocked(int userId) { 16256 for (BroadcastQueue queue : mBroadcastQueues) { 16257 queue.backgroundServicesFinishedLocked(userId); 16258 } 16259 } 16260 16261 public void finishReceiver(IBinder who, int resultCode, String resultData, 16262 Bundle resultExtras, boolean resultAbort) { 16263 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16264 16265 // Refuse possible leaked file descriptors 16266 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16267 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16268 } 16269 16270 final long origId = Binder.clearCallingIdentity(); 16271 try { 16272 boolean doNext = false; 16273 BroadcastRecord r; 16274 16275 synchronized(this) { 16276 r = broadcastRecordForReceiverLocked(who); 16277 if (r != null) { 16278 doNext = r.queue.finishReceiverLocked(r, resultCode, 16279 resultData, resultExtras, resultAbort, true); 16280 } 16281 } 16282 16283 if (doNext) { 16284 r.queue.processNextBroadcast(false); 16285 } 16286 trimApplications(); 16287 } finally { 16288 Binder.restoreCallingIdentity(origId); 16289 } 16290 } 16291 16292 // ========================================================= 16293 // INSTRUMENTATION 16294 // ========================================================= 16295 16296 public boolean startInstrumentation(ComponentName className, 16297 String profileFile, int flags, Bundle arguments, 16298 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16299 int userId, String abiOverride) { 16300 enforceNotIsolatedCaller("startInstrumentation"); 16301 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16302 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16303 // Refuse possible leaked file descriptors 16304 if (arguments != null && arguments.hasFileDescriptors()) { 16305 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16306 } 16307 16308 synchronized(this) { 16309 InstrumentationInfo ii = null; 16310 ApplicationInfo ai = null; 16311 try { 16312 ii = mContext.getPackageManager().getInstrumentationInfo( 16313 className, STOCK_PM_FLAGS); 16314 ai = AppGlobals.getPackageManager().getApplicationInfo( 16315 ii.targetPackage, STOCK_PM_FLAGS, userId); 16316 } catch (PackageManager.NameNotFoundException e) { 16317 } catch (RemoteException e) { 16318 } 16319 if (ii == null) { 16320 reportStartInstrumentationFailure(watcher, className, 16321 "Unable to find instrumentation info for: " + className); 16322 return false; 16323 } 16324 if (ai == null) { 16325 reportStartInstrumentationFailure(watcher, className, 16326 "Unable to find instrumentation target package: " + ii.targetPackage); 16327 return false; 16328 } 16329 16330 int match = mContext.getPackageManager().checkSignatures( 16331 ii.targetPackage, ii.packageName); 16332 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16333 String msg = "Permission Denial: starting instrumentation " 16334 + className + " from pid=" 16335 + Binder.getCallingPid() 16336 + ", uid=" + Binder.getCallingPid() 16337 + " not allowed because package " + ii.packageName 16338 + " does not have a signature matching the target " 16339 + ii.targetPackage; 16340 reportStartInstrumentationFailure(watcher, className, msg); 16341 throw new SecurityException(msg); 16342 } 16343 16344 final long origId = Binder.clearCallingIdentity(); 16345 // Instrumentation can kill and relaunch even persistent processes 16346 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16347 "start instr"); 16348 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16349 app.instrumentationClass = className; 16350 app.instrumentationInfo = ai; 16351 app.instrumentationProfileFile = profileFile; 16352 app.instrumentationArguments = arguments; 16353 app.instrumentationWatcher = watcher; 16354 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16355 app.instrumentationResultClass = className; 16356 Binder.restoreCallingIdentity(origId); 16357 } 16358 16359 return true; 16360 } 16361 16362 /** 16363 * Report errors that occur while attempting to start Instrumentation. Always writes the 16364 * error to the logs, but if somebody is watching, send the report there too. This enables 16365 * the "am" command to report errors with more information. 16366 * 16367 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16368 * @param cn The component name of the instrumentation. 16369 * @param report The error report. 16370 */ 16371 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16372 ComponentName cn, String report) { 16373 Slog.w(TAG, report); 16374 try { 16375 if (watcher != null) { 16376 Bundle results = new Bundle(); 16377 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16378 results.putString("Error", report); 16379 watcher.instrumentationStatus(cn, -1, results); 16380 } 16381 } catch (RemoteException e) { 16382 Slog.w(TAG, e); 16383 } 16384 } 16385 16386 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16387 if (app.instrumentationWatcher != null) { 16388 try { 16389 // NOTE: IInstrumentationWatcher *must* be oneway here 16390 app.instrumentationWatcher.instrumentationFinished( 16391 app.instrumentationClass, 16392 resultCode, 16393 results); 16394 } catch (RemoteException e) { 16395 } 16396 } 16397 if (app.instrumentationUiAutomationConnection != null) { 16398 try { 16399 app.instrumentationUiAutomationConnection.shutdown(); 16400 } catch (RemoteException re) { 16401 /* ignore */ 16402 } 16403 // Only a UiAutomation can set this flag and now that 16404 // it is finished we make sure it is reset to its default. 16405 mUserIsMonkey = false; 16406 } 16407 app.instrumentationWatcher = null; 16408 app.instrumentationUiAutomationConnection = null; 16409 app.instrumentationClass = null; 16410 app.instrumentationInfo = null; 16411 app.instrumentationProfileFile = null; 16412 app.instrumentationArguments = null; 16413 16414 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16415 "finished inst"); 16416 } 16417 16418 public void finishInstrumentation(IApplicationThread target, 16419 int resultCode, Bundle results) { 16420 int userId = UserHandle.getCallingUserId(); 16421 // Refuse possible leaked file descriptors 16422 if (results != null && results.hasFileDescriptors()) { 16423 throw new IllegalArgumentException("File descriptors passed in Intent"); 16424 } 16425 16426 synchronized(this) { 16427 ProcessRecord app = getRecordForAppLocked(target); 16428 if (app == null) { 16429 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16430 return; 16431 } 16432 final long origId = Binder.clearCallingIdentity(); 16433 finishInstrumentationLocked(app, resultCode, results); 16434 Binder.restoreCallingIdentity(origId); 16435 } 16436 } 16437 16438 // ========================================================= 16439 // CONFIGURATION 16440 // ========================================================= 16441 16442 public ConfigurationInfo getDeviceConfigurationInfo() { 16443 ConfigurationInfo config = new ConfigurationInfo(); 16444 synchronized (this) { 16445 config.reqTouchScreen = mConfiguration.touchscreen; 16446 config.reqKeyboardType = mConfiguration.keyboard; 16447 config.reqNavigation = mConfiguration.navigation; 16448 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16449 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16450 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16451 } 16452 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16453 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16454 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16455 } 16456 config.reqGlEsVersion = GL_ES_VERSION; 16457 } 16458 return config; 16459 } 16460 16461 ActivityStack getFocusedStack() { 16462 return mStackSupervisor.getFocusedStack(); 16463 } 16464 16465 public Configuration getConfiguration() { 16466 Configuration ci; 16467 synchronized(this) { 16468 ci = new Configuration(mConfiguration); 16469 } 16470 return ci; 16471 } 16472 16473 public void updatePersistentConfiguration(Configuration values) { 16474 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16475 "updateConfiguration()"); 16476 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16477 "updateConfiguration()"); 16478 if (values == null) { 16479 throw new NullPointerException("Configuration must not be null"); 16480 } 16481 16482 synchronized(this) { 16483 final long origId = Binder.clearCallingIdentity(); 16484 updateConfigurationLocked(values, null, true, false); 16485 Binder.restoreCallingIdentity(origId); 16486 } 16487 } 16488 16489 public void updateConfiguration(Configuration values) { 16490 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16491 "updateConfiguration()"); 16492 16493 synchronized(this) { 16494 if (values == null && mWindowManager != null) { 16495 // sentinel: fetch the current configuration from the window manager 16496 values = mWindowManager.computeNewConfiguration(); 16497 } 16498 16499 if (mWindowManager != null) { 16500 mProcessList.applyDisplaySize(mWindowManager); 16501 } 16502 16503 final long origId = Binder.clearCallingIdentity(); 16504 if (values != null) { 16505 Settings.System.clearConfiguration(values); 16506 } 16507 updateConfigurationLocked(values, null, false, false); 16508 Binder.restoreCallingIdentity(origId); 16509 } 16510 } 16511 16512 /** 16513 * Do either or both things: (1) change the current configuration, and (2) 16514 * make sure the given activity is running with the (now) current 16515 * configuration. Returns true if the activity has been left running, or 16516 * false if <var>starting</var> is being destroyed to match the new 16517 * configuration. 16518 * @param persistent TODO 16519 */ 16520 boolean updateConfigurationLocked(Configuration values, 16521 ActivityRecord starting, boolean persistent, boolean initLocale) { 16522 int changes = 0; 16523 16524 if (values != null) { 16525 Configuration newConfig = new Configuration(mConfiguration); 16526 changes = newConfig.updateFrom(values); 16527 if (changes != 0) { 16528 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16529 Slog.i(TAG, "Updating configuration to: " + values); 16530 } 16531 16532 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16533 16534 if (values.locale != null && !initLocale) { 16535 saveLocaleLocked(values.locale, 16536 !values.locale.equals(mConfiguration.locale), 16537 values.userSetLocale); 16538 } 16539 16540 mConfigurationSeq++; 16541 if (mConfigurationSeq <= 0) { 16542 mConfigurationSeq = 1; 16543 } 16544 newConfig.seq = mConfigurationSeq; 16545 mConfiguration = newConfig; 16546 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16547 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16548 //mUsageStatsService.noteStartConfig(newConfig); 16549 16550 final Configuration configCopy = new Configuration(mConfiguration); 16551 16552 // TODO: If our config changes, should we auto dismiss any currently 16553 // showing dialogs? 16554 mShowDialogs = shouldShowDialogs(newConfig); 16555 16556 AttributeCache ac = AttributeCache.instance(); 16557 if (ac != null) { 16558 ac.updateConfiguration(configCopy); 16559 } 16560 16561 // Make sure all resources in our process are updated 16562 // right now, so that anyone who is going to retrieve 16563 // resource values after we return will be sure to get 16564 // the new ones. This is especially important during 16565 // boot, where the first config change needs to guarantee 16566 // all resources have that config before following boot 16567 // code is executed. 16568 mSystemThread.applyConfigurationToResources(configCopy); 16569 16570 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16571 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16572 msg.obj = new Configuration(configCopy); 16573 mHandler.sendMessage(msg); 16574 } 16575 16576 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16577 ProcessRecord app = mLruProcesses.get(i); 16578 try { 16579 if (app.thread != null) { 16580 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16581 + app.processName + " new config " + mConfiguration); 16582 app.thread.scheduleConfigurationChanged(configCopy); 16583 } 16584 } catch (Exception e) { 16585 } 16586 } 16587 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16588 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16589 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16590 | Intent.FLAG_RECEIVER_FOREGROUND); 16591 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16592 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16593 Process.SYSTEM_UID, UserHandle.USER_ALL); 16594 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16595 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16596 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16597 broadcastIntentLocked(null, null, intent, 16598 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16599 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16600 } 16601 } 16602 } 16603 16604 boolean kept = true; 16605 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16606 // mainStack is null during startup. 16607 if (mainStack != null) { 16608 if (changes != 0 && starting == null) { 16609 // If the configuration changed, and the caller is not already 16610 // in the process of starting an activity, then find the top 16611 // activity to check if its configuration needs to change. 16612 starting = mainStack.topRunningActivityLocked(null); 16613 } 16614 16615 if (starting != null) { 16616 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16617 // And we need to make sure at this point that all other activities 16618 // are made visible with the correct configuration. 16619 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16620 } 16621 } 16622 16623 if (values != null && mWindowManager != null) { 16624 mWindowManager.setNewConfiguration(mConfiguration); 16625 } 16626 16627 return kept; 16628 } 16629 16630 /** 16631 * Decide based on the configuration whether we should shouw the ANR, 16632 * crash, etc dialogs. The idea is that if there is no affordnace to 16633 * press the on-screen buttons, we shouldn't show the dialog. 16634 * 16635 * A thought: SystemUI might also want to get told about this, the Power 16636 * dialog / global actions also might want different behaviors. 16637 */ 16638 private static final boolean shouldShowDialogs(Configuration config) { 16639 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16640 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16641 } 16642 16643 /** 16644 * Save the locale. You must be inside a synchronized (this) block. 16645 */ 16646 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16647 if(isDiff) { 16648 SystemProperties.set("user.language", l.getLanguage()); 16649 SystemProperties.set("user.region", l.getCountry()); 16650 } 16651 16652 if(isPersist) { 16653 SystemProperties.set("persist.sys.language", l.getLanguage()); 16654 SystemProperties.set("persist.sys.country", l.getCountry()); 16655 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16656 16657 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16658 } 16659 } 16660 16661 @Override 16662 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16663 synchronized (this) { 16664 ActivityRecord srec = ActivityRecord.forToken(token); 16665 if (srec.task != null && srec.task.stack != null) { 16666 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16667 } 16668 } 16669 return false; 16670 } 16671 16672 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16673 Intent resultData) { 16674 16675 synchronized (this) { 16676 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16677 if (stack != null) { 16678 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16679 } 16680 return false; 16681 } 16682 } 16683 16684 public int getLaunchedFromUid(IBinder activityToken) { 16685 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16686 if (srec == null) { 16687 return -1; 16688 } 16689 return srec.launchedFromUid; 16690 } 16691 16692 public String getLaunchedFromPackage(IBinder activityToken) { 16693 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16694 if (srec == null) { 16695 return null; 16696 } 16697 return srec.launchedFromPackage; 16698 } 16699 16700 // ========================================================= 16701 // LIFETIME MANAGEMENT 16702 // ========================================================= 16703 16704 // Returns which broadcast queue the app is the current [or imminent] receiver 16705 // on, or 'null' if the app is not an active broadcast recipient. 16706 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16707 BroadcastRecord r = app.curReceiver; 16708 if (r != null) { 16709 return r.queue; 16710 } 16711 16712 // It's not the current receiver, but it might be starting up to become one 16713 synchronized (this) { 16714 for (BroadcastQueue queue : mBroadcastQueues) { 16715 r = queue.mPendingBroadcast; 16716 if (r != null && r.curApp == app) { 16717 // found it; report which queue it's in 16718 return queue; 16719 } 16720 } 16721 } 16722 16723 return null; 16724 } 16725 16726 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16727 boolean doingAll, long now) { 16728 if (mAdjSeq == app.adjSeq) { 16729 // This adjustment has already been computed. 16730 return app.curRawAdj; 16731 } 16732 16733 if (app.thread == null) { 16734 app.adjSeq = mAdjSeq; 16735 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16736 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16737 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16738 } 16739 16740 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16741 app.adjSource = null; 16742 app.adjTarget = null; 16743 app.empty = false; 16744 app.cached = false; 16745 16746 final int activitiesSize = app.activities.size(); 16747 16748 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16749 // The max adjustment doesn't allow this app to be anything 16750 // below foreground, so it is not worth doing work for it. 16751 app.adjType = "fixed"; 16752 app.adjSeq = mAdjSeq; 16753 app.curRawAdj = app.maxAdj; 16754 app.foregroundActivities = false; 16755 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16756 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16757 // System processes can do UI, and when they do we want to have 16758 // them trim their memory after the user leaves the UI. To 16759 // facilitate this, here we need to determine whether or not it 16760 // is currently showing UI. 16761 app.systemNoUi = true; 16762 if (app == TOP_APP) { 16763 app.systemNoUi = false; 16764 } else if (activitiesSize > 0) { 16765 for (int j = 0; j < activitiesSize; j++) { 16766 final ActivityRecord r = app.activities.get(j); 16767 if (r.visible) { 16768 app.systemNoUi = false; 16769 } 16770 } 16771 } 16772 if (!app.systemNoUi) { 16773 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16774 } 16775 return (app.curAdj=app.maxAdj); 16776 } 16777 16778 app.systemNoUi = false; 16779 16780 // Determine the importance of the process, starting with most 16781 // important to least, and assign an appropriate OOM adjustment. 16782 int adj; 16783 int schedGroup; 16784 int procState; 16785 boolean foregroundActivities = false; 16786 BroadcastQueue queue; 16787 if (app == TOP_APP) { 16788 // The last app on the list is the foreground app. 16789 adj = ProcessList.FOREGROUND_APP_ADJ; 16790 schedGroup = Process.THREAD_GROUP_DEFAULT; 16791 app.adjType = "top-activity"; 16792 foregroundActivities = true; 16793 procState = ActivityManager.PROCESS_STATE_TOP; 16794 } else if (app.instrumentationClass != null) { 16795 // Don't want to kill running instrumentation. 16796 adj = ProcessList.FOREGROUND_APP_ADJ; 16797 schedGroup = Process.THREAD_GROUP_DEFAULT; 16798 app.adjType = "instrumentation"; 16799 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16800 } else if ((queue = isReceivingBroadcast(app)) != null) { 16801 // An app that is currently receiving a broadcast also 16802 // counts as being in the foreground for OOM killer purposes. 16803 // It's placed in a sched group based on the nature of the 16804 // broadcast as reflected by which queue it's active in. 16805 adj = ProcessList.FOREGROUND_APP_ADJ; 16806 schedGroup = (queue == mFgBroadcastQueue) 16807 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16808 app.adjType = "broadcast"; 16809 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16810 } else if (app.executingServices.size() > 0) { 16811 // An app that is currently executing a service callback also 16812 // counts as being in the foreground. 16813 adj = ProcessList.FOREGROUND_APP_ADJ; 16814 schedGroup = app.execServicesFg ? 16815 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16816 app.adjType = "exec-service"; 16817 procState = ActivityManager.PROCESS_STATE_SERVICE; 16818 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16819 } else { 16820 // As far as we know the process is empty. We may change our mind later. 16821 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16822 // At this point we don't actually know the adjustment. Use the cached adj 16823 // value that the caller wants us to. 16824 adj = cachedAdj; 16825 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16826 app.cached = true; 16827 app.empty = true; 16828 app.adjType = "cch-empty"; 16829 } 16830 16831 // Examine all activities if not already foreground. 16832 if (!foregroundActivities && activitiesSize > 0) { 16833 for (int j = 0; j < activitiesSize; j++) { 16834 final ActivityRecord r = app.activities.get(j); 16835 if (r.app != app) { 16836 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16837 + app + "?!?"); 16838 continue; 16839 } 16840 if (r.visible) { 16841 // App has a visible activity; only upgrade adjustment. 16842 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16843 adj = ProcessList.VISIBLE_APP_ADJ; 16844 app.adjType = "visible"; 16845 } 16846 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16847 procState = ActivityManager.PROCESS_STATE_TOP; 16848 } 16849 schedGroup = Process.THREAD_GROUP_DEFAULT; 16850 app.cached = false; 16851 app.empty = false; 16852 foregroundActivities = true; 16853 break; 16854 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16855 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16856 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16857 app.adjType = "pausing"; 16858 } 16859 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16860 procState = ActivityManager.PROCESS_STATE_TOP; 16861 } 16862 schedGroup = Process.THREAD_GROUP_DEFAULT; 16863 app.cached = false; 16864 app.empty = false; 16865 foregroundActivities = true; 16866 } else if (r.state == ActivityState.STOPPING) { 16867 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16868 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16869 app.adjType = "stopping"; 16870 } 16871 // For the process state, we will at this point consider the 16872 // process to be cached. It will be cached either as an activity 16873 // or empty depending on whether the activity is finishing. We do 16874 // this so that we can treat the process as cached for purposes of 16875 // memory trimming (determing current memory level, trim command to 16876 // send to process) since there can be an arbitrary number of stopping 16877 // processes and they should soon all go into the cached state. 16878 if (!r.finishing) { 16879 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16880 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16881 } 16882 } 16883 app.cached = false; 16884 app.empty = false; 16885 foregroundActivities = true; 16886 } else { 16887 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16888 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16889 app.adjType = "cch-act"; 16890 } 16891 } 16892 } 16893 } 16894 16895 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16896 if (app.foregroundServices) { 16897 // The user is aware of this app, so make it visible. 16898 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16899 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16900 app.cached = false; 16901 app.adjType = "fg-service"; 16902 schedGroup = Process.THREAD_GROUP_DEFAULT; 16903 } else if (app.forcingToForeground != null) { 16904 // The user is aware of this app, so make it visible. 16905 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16906 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16907 app.cached = false; 16908 app.adjType = "force-fg"; 16909 app.adjSource = app.forcingToForeground; 16910 schedGroup = Process.THREAD_GROUP_DEFAULT; 16911 } 16912 } 16913 16914 if (app == mHeavyWeightProcess) { 16915 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16916 // We don't want to kill the current heavy-weight process. 16917 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16918 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16919 app.cached = false; 16920 app.adjType = "heavy"; 16921 } 16922 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16923 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16924 } 16925 } 16926 16927 if (app == mHomeProcess) { 16928 if (adj > ProcessList.HOME_APP_ADJ) { 16929 // This process is hosting what we currently consider to be the 16930 // home app, so we don't want to let it go into the background. 16931 adj = ProcessList.HOME_APP_ADJ; 16932 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16933 app.cached = false; 16934 app.adjType = "home"; 16935 } 16936 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16937 procState = ActivityManager.PROCESS_STATE_HOME; 16938 } 16939 } 16940 16941 if (app == mPreviousProcess && app.activities.size() > 0) { 16942 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16943 // This was the previous process that showed UI to the user. 16944 // We want to try to keep it around more aggressively, to give 16945 // a good experience around switching between two apps. 16946 adj = ProcessList.PREVIOUS_APP_ADJ; 16947 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16948 app.cached = false; 16949 app.adjType = "previous"; 16950 } 16951 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16952 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16953 } 16954 } 16955 16956 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16957 + " reason=" + app.adjType); 16958 16959 // By default, we use the computed adjustment. It may be changed if 16960 // there are applications dependent on our services or providers, but 16961 // this gives us a baseline and makes sure we don't get into an 16962 // infinite recursion. 16963 app.adjSeq = mAdjSeq; 16964 app.curRawAdj = adj; 16965 app.hasStartedServices = false; 16966 16967 if (mBackupTarget != null && app == mBackupTarget.app) { 16968 // If possible we want to avoid killing apps while they're being backed up 16969 if (adj > ProcessList.BACKUP_APP_ADJ) { 16970 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16971 adj = ProcessList.BACKUP_APP_ADJ; 16972 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16973 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16974 } 16975 app.adjType = "backup"; 16976 app.cached = false; 16977 } 16978 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16979 procState = ActivityManager.PROCESS_STATE_BACKUP; 16980 } 16981 } 16982 16983 boolean mayBeTop = false; 16984 16985 for (int is = app.services.size()-1; 16986 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16987 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16988 || procState > ActivityManager.PROCESS_STATE_TOP); 16989 is--) { 16990 ServiceRecord s = app.services.valueAt(is); 16991 if (s.startRequested) { 16992 app.hasStartedServices = true; 16993 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16994 procState = ActivityManager.PROCESS_STATE_SERVICE; 16995 } 16996 if (app.hasShownUi && app != mHomeProcess) { 16997 // If this process has shown some UI, let it immediately 16998 // go to the LRU list because it may be pretty heavy with 16999 // UI stuff. We'll tag it with a label just to help 17000 // debug and understand what is going on. 17001 if (adj > ProcessList.SERVICE_ADJ) { 17002 app.adjType = "cch-started-ui-services"; 17003 } 17004 } else { 17005 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17006 // This service has seen some activity within 17007 // recent memory, so we will keep its process ahead 17008 // of the background processes. 17009 if (adj > ProcessList.SERVICE_ADJ) { 17010 adj = ProcessList.SERVICE_ADJ; 17011 app.adjType = "started-services"; 17012 app.cached = false; 17013 } 17014 } 17015 // If we have let the service slide into the background 17016 // state, still have some text describing what it is doing 17017 // even though the service no longer has an impact. 17018 if (adj > ProcessList.SERVICE_ADJ) { 17019 app.adjType = "cch-started-services"; 17020 } 17021 } 17022 } 17023 for (int conni = s.connections.size()-1; 17024 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17025 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17026 || procState > ActivityManager.PROCESS_STATE_TOP); 17027 conni--) { 17028 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17029 for (int i = 0; 17030 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17031 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17032 || procState > ActivityManager.PROCESS_STATE_TOP); 17033 i++) { 17034 // XXX should compute this based on the max of 17035 // all connected clients. 17036 ConnectionRecord cr = clist.get(i); 17037 if (cr.binding.client == app) { 17038 // Binding to ourself is not interesting. 17039 continue; 17040 } 17041 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17042 ProcessRecord client = cr.binding.client; 17043 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17044 TOP_APP, doingAll, now); 17045 int clientProcState = client.curProcState; 17046 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17047 // If the other app is cached for any reason, for purposes here 17048 // we are going to consider it empty. The specific cached state 17049 // doesn't propagate except under certain conditions. 17050 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17051 } 17052 String adjType = null; 17053 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17054 // Not doing bind OOM management, so treat 17055 // this guy more like a started service. 17056 if (app.hasShownUi && app != mHomeProcess) { 17057 // If this process has shown some UI, let it immediately 17058 // go to the LRU list because it may be pretty heavy with 17059 // UI stuff. We'll tag it with a label just to help 17060 // debug and understand what is going on. 17061 if (adj > clientAdj) { 17062 adjType = "cch-bound-ui-services"; 17063 } 17064 app.cached = false; 17065 clientAdj = adj; 17066 clientProcState = procState; 17067 } else { 17068 if (now >= (s.lastActivity 17069 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17070 // This service has not seen activity within 17071 // recent memory, so allow it to drop to the 17072 // LRU list if there is no other reason to keep 17073 // it around. We'll also tag it with a label just 17074 // to help debug and undertand what is going on. 17075 if (adj > clientAdj) { 17076 adjType = "cch-bound-services"; 17077 } 17078 clientAdj = adj; 17079 } 17080 } 17081 } 17082 if (adj > clientAdj) { 17083 // If this process has recently shown UI, and 17084 // the process that is binding to it is less 17085 // important than being visible, then we don't 17086 // care about the binding as much as we care 17087 // about letting this process get into the LRU 17088 // list to be killed and restarted if needed for 17089 // memory. 17090 if (app.hasShownUi && app != mHomeProcess 17091 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17092 adjType = "cch-bound-ui-services"; 17093 } else { 17094 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17095 |Context.BIND_IMPORTANT)) != 0) { 17096 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17097 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17098 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17099 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17100 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17101 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17102 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17103 adj = clientAdj; 17104 } else { 17105 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17106 adj = ProcessList.VISIBLE_APP_ADJ; 17107 } 17108 } 17109 if (!client.cached) { 17110 app.cached = false; 17111 } 17112 adjType = "service"; 17113 } 17114 } 17115 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17116 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17117 schedGroup = Process.THREAD_GROUP_DEFAULT; 17118 } 17119 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17120 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17121 // Special handling of clients who are in the top state. 17122 // We *may* want to consider this process to be in the 17123 // top state as well, but only if there is not another 17124 // reason for it to be running. Being on the top is a 17125 // special state, meaning you are specifically running 17126 // for the current top app. If the process is already 17127 // running in the background for some other reason, it 17128 // is more important to continue considering it to be 17129 // in the background state. 17130 mayBeTop = true; 17131 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17132 } else { 17133 // Special handling for above-top states (persistent 17134 // processes). These should not bring the current process 17135 // into the top state, since they are not on top. Instead 17136 // give them the best state after that. 17137 clientProcState = 17138 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17139 } 17140 } 17141 } else { 17142 if (clientProcState < 17143 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17144 clientProcState = 17145 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17146 } 17147 } 17148 if (procState > clientProcState) { 17149 procState = clientProcState; 17150 } 17151 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17152 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17153 app.pendingUiClean = true; 17154 } 17155 if (adjType != null) { 17156 app.adjType = adjType; 17157 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17158 .REASON_SERVICE_IN_USE; 17159 app.adjSource = cr.binding.client; 17160 app.adjSourceProcState = clientProcState; 17161 app.adjTarget = s.name; 17162 } 17163 } 17164 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17165 app.treatLikeActivity = true; 17166 } 17167 final ActivityRecord a = cr.activity; 17168 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17169 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17170 (a.visible || a.state == ActivityState.RESUMED 17171 || a.state == ActivityState.PAUSING)) { 17172 adj = ProcessList.FOREGROUND_APP_ADJ; 17173 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17174 schedGroup = Process.THREAD_GROUP_DEFAULT; 17175 } 17176 app.cached = false; 17177 app.adjType = "service"; 17178 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17179 .REASON_SERVICE_IN_USE; 17180 app.adjSource = a; 17181 app.adjSourceProcState = procState; 17182 app.adjTarget = s.name; 17183 } 17184 } 17185 } 17186 } 17187 } 17188 17189 for (int provi = app.pubProviders.size()-1; 17190 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17191 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17192 || procState > ActivityManager.PROCESS_STATE_TOP); 17193 provi--) { 17194 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17195 for (int i = cpr.connections.size()-1; 17196 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17197 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17198 || procState > ActivityManager.PROCESS_STATE_TOP); 17199 i--) { 17200 ContentProviderConnection conn = cpr.connections.get(i); 17201 ProcessRecord client = conn.client; 17202 if (client == app) { 17203 // Being our own client is not interesting. 17204 continue; 17205 } 17206 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17207 int clientProcState = client.curProcState; 17208 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17209 // If the other app is cached for any reason, for purposes here 17210 // we are going to consider it empty. 17211 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17212 } 17213 if (adj > clientAdj) { 17214 if (app.hasShownUi && app != mHomeProcess 17215 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17216 app.adjType = "cch-ui-provider"; 17217 } else { 17218 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17219 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17220 app.adjType = "provider"; 17221 } 17222 app.cached &= client.cached; 17223 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17224 .REASON_PROVIDER_IN_USE; 17225 app.adjSource = client; 17226 app.adjSourceProcState = clientProcState; 17227 app.adjTarget = cpr.name; 17228 } 17229 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17230 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17231 // Special handling of clients who are in the top state. 17232 // We *may* want to consider this process to be in the 17233 // top state as well, but only if there is not another 17234 // reason for it to be running. Being on the top is a 17235 // special state, meaning you are specifically running 17236 // for the current top app. If the process is already 17237 // running in the background for some other reason, it 17238 // is more important to continue considering it to be 17239 // in the background state. 17240 mayBeTop = true; 17241 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17242 } else { 17243 // Special handling for above-top states (persistent 17244 // processes). These should not bring the current process 17245 // into the top state, since they are not on top. Instead 17246 // give them the best state after that. 17247 clientProcState = 17248 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17249 } 17250 } 17251 if (procState > clientProcState) { 17252 procState = clientProcState; 17253 } 17254 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17255 schedGroup = Process.THREAD_GROUP_DEFAULT; 17256 } 17257 } 17258 // If the provider has external (non-framework) process 17259 // dependencies, ensure that its adjustment is at least 17260 // FOREGROUND_APP_ADJ. 17261 if (cpr.hasExternalProcessHandles()) { 17262 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17263 adj = ProcessList.FOREGROUND_APP_ADJ; 17264 schedGroup = Process.THREAD_GROUP_DEFAULT; 17265 app.cached = false; 17266 app.adjType = "provider"; 17267 app.adjTarget = cpr.name; 17268 } 17269 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17270 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17271 } 17272 } 17273 } 17274 17275 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17276 // A client of one of our services or providers is in the top state. We 17277 // *may* want to be in the top state, but not if we are already running in 17278 // the background for some other reason. For the decision here, we are going 17279 // to pick out a few specific states that we want to remain in when a client 17280 // is top (states that tend to be longer-term) and otherwise allow it to go 17281 // to the top state. 17282 switch (procState) { 17283 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17284 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17285 case ActivityManager.PROCESS_STATE_SERVICE: 17286 // These all are longer-term states, so pull them up to the top 17287 // of the background states, but not all the way to the top state. 17288 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17289 break; 17290 default: 17291 // Otherwise, top is a better choice, so take it. 17292 procState = ActivityManager.PROCESS_STATE_TOP; 17293 break; 17294 } 17295 } 17296 17297 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17298 if (app.hasClientActivities) { 17299 // This is a cached process, but with client activities. Mark it so. 17300 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17301 app.adjType = "cch-client-act"; 17302 } else if (app.treatLikeActivity) { 17303 // This is a cached process, but somebody wants us to treat it like it has 17304 // an activity, okay! 17305 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17306 app.adjType = "cch-as-act"; 17307 } 17308 } 17309 17310 if (adj == ProcessList.SERVICE_ADJ) { 17311 if (doingAll) { 17312 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17313 mNewNumServiceProcs++; 17314 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17315 if (!app.serviceb) { 17316 // This service isn't far enough down on the LRU list to 17317 // normally be a B service, but if we are low on RAM and it 17318 // is large we want to force it down since we would prefer to 17319 // keep launcher over it. 17320 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17321 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17322 app.serviceHighRam = true; 17323 app.serviceb = true; 17324 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17325 } else { 17326 mNewNumAServiceProcs++; 17327 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17328 } 17329 } else { 17330 app.serviceHighRam = false; 17331 } 17332 } 17333 if (app.serviceb) { 17334 adj = ProcessList.SERVICE_B_ADJ; 17335 } 17336 } 17337 17338 app.curRawAdj = adj; 17339 17340 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17341 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17342 if (adj > app.maxAdj) { 17343 adj = app.maxAdj; 17344 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17345 schedGroup = Process.THREAD_GROUP_DEFAULT; 17346 } 17347 } 17348 17349 // Do final modification to adj. Everything we do between here and applying 17350 // the final setAdj must be done in this function, because we will also use 17351 // it when computing the final cached adj later. Note that we don't need to 17352 // worry about this for max adj above, since max adj will always be used to 17353 // keep it out of the cached vaues. 17354 app.curAdj = app.modifyRawOomAdj(adj); 17355 app.curSchedGroup = schedGroup; 17356 app.curProcState = procState; 17357 app.foregroundActivities = foregroundActivities; 17358 17359 return app.curRawAdj; 17360 } 17361 17362 /** 17363 * Record new PSS sample for a process. 17364 */ 17365 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17366 proc.lastPssTime = now; 17367 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17368 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17369 + ": " + pss + " lastPss=" + proc.lastPss 17370 + " state=" + ProcessList.makeProcStateString(procState)); 17371 if (proc.initialIdlePss == 0) { 17372 proc.initialIdlePss = pss; 17373 } 17374 proc.lastPss = pss; 17375 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17376 proc.lastCachedPss = pss; 17377 } 17378 } 17379 17380 /** 17381 * Schedule PSS collection of a process. 17382 */ 17383 void requestPssLocked(ProcessRecord proc, int procState) { 17384 if (mPendingPssProcesses.contains(proc)) { 17385 return; 17386 } 17387 if (mPendingPssProcesses.size() == 0) { 17388 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17389 } 17390 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17391 proc.pssProcState = procState; 17392 mPendingPssProcesses.add(proc); 17393 } 17394 17395 /** 17396 * Schedule PSS collection of all processes. 17397 */ 17398 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17399 if (!always) { 17400 if (now < (mLastFullPssTime + 17401 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17402 return; 17403 } 17404 } 17405 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17406 mLastFullPssTime = now; 17407 mFullPssPending = true; 17408 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17409 mPendingPssProcesses.clear(); 17410 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17411 ProcessRecord app = mLruProcesses.get(i); 17412 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17413 app.pssProcState = app.setProcState; 17414 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17415 mTestPssMode, isSleeping(), now); 17416 mPendingPssProcesses.add(app); 17417 } 17418 } 17419 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17420 } 17421 17422 public void setTestPssMode(boolean enabled) { 17423 synchronized (this) { 17424 mTestPssMode = enabled; 17425 if (enabled) { 17426 // Whenever we enable the mode, we want to take a snapshot all of current 17427 // process mem use. 17428 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17429 } 17430 } 17431 } 17432 17433 /** 17434 * Ask a given process to GC right now. 17435 */ 17436 final void performAppGcLocked(ProcessRecord app) { 17437 try { 17438 app.lastRequestedGc = SystemClock.uptimeMillis(); 17439 if (app.thread != null) { 17440 if (app.reportLowMemory) { 17441 app.reportLowMemory = false; 17442 app.thread.scheduleLowMemory(); 17443 } else { 17444 app.thread.processInBackground(); 17445 } 17446 } 17447 } catch (Exception e) { 17448 // whatever. 17449 } 17450 } 17451 17452 /** 17453 * Returns true if things are idle enough to perform GCs. 17454 */ 17455 private final boolean canGcNowLocked() { 17456 boolean processingBroadcasts = false; 17457 for (BroadcastQueue q : mBroadcastQueues) { 17458 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17459 processingBroadcasts = true; 17460 } 17461 } 17462 return !processingBroadcasts 17463 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17464 } 17465 17466 /** 17467 * Perform GCs on all processes that are waiting for it, but only 17468 * if things are idle. 17469 */ 17470 final void performAppGcsLocked() { 17471 final int N = mProcessesToGc.size(); 17472 if (N <= 0) { 17473 return; 17474 } 17475 if (canGcNowLocked()) { 17476 while (mProcessesToGc.size() > 0) { 17477 ProcessRecord proc = mProcessesToGc.remove(0); 17478 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17479 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17480 <= SystemClock.uptimeMillis()) { 17481 // To avoid spamming the system, we will GC processes one 17482 // at a time, waiting a few seconds between each. 17483 performAppGcLocked(proc); 17484 scheduleAppGcsLocked(); 17485 return; 17486 } else { 17487 // It hasn't been long enough since we last GCed this 17488 // process... put it in the list to wait for its time. 17489 addProcessToGcListLocked(proc); 17490 break; 17491 } 17492 } 17493 } 17494 17495 scheduleAppGcsLocked(); 17496 } 17497 } 17498 17499 /** 17500 * If all looks good, perform GCs on all processes waiting for them. 17501 */ 17502 final void performAppGcsIfAppropriateLocked() { 17503 if (canGcNowLocked()) { 17504 performAppGcsLocked(); 17505 return; 17506 } 17507 // Still not idle, wait some more. 17508 scheduleAppGcsLocked(); 17509 } 17510 17511 /** 17512 * Schedule the execution of all pending app GCs. 17513 */ 17514 final void scheduleAppGcsLocked() { 17515 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17516 17517 if (mProcessesToGc.size() > 0) { 17518 // Schedule a GC for the time to the next process. 17519 ProcessRecord proc = mProcessesToGc.get(0); 17520 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17521 17522 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17523 long now = SystemClock.uptimeMillis(); 17524 if (when < (now+GC_TIMEOUT)) { 17525 when = now + GC_TIMEOUT; 17526 } 17527 mHandler.sendMessageAtTime(msg, when); 17528 } 17529 } 17530 17531 /** 17532 * Add a process to the array of processes waiting to be GCed. Keeps the 17533 * list in sorted order by the last GC time. The process can't already be 17534 * on the list. 17535 */ 17536 final void addProcessToGcListLocked(ProcessRecord proc) { 17537 boolean added = false; 17538 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17539 if (mProcessesToGc.get(i).lastRequestedGc < 17540 proc.lastRequestedGc) { 17541 added = true; 17542 mProcessesToGc.add(i+1, proc); 17543 break; 17544 } 17545 } 17546 if (!added) { 17547 mProcessesToGc.add(0, proc); 17548 } 17549 } 17550 17551 /** 17552 * Set up to ask a process to GC itself. This will either do it 17553 * immediately, or put it on the list of processes to gc the next 17554 * time things are idle. 17555 */ 17556 final void scheduleAppGcLocked(ProcessRecord app) { 17557 long now = SystemClock.uptimeMillis(); 17558 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17559 return; 17560 } 17561 if (!mProcessesToGc.contains(app)) { 17562 addProcessToGcListLocked(app); 17563 scheduleAppGcsLocked(); 17564 } 17565 } 17566 17567 final void checkExcessivePowerUsageLocked(boolean doKills) { 17568 updateCpuStatsNow(); 17569 17570 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17571 boolean doWakeKills = doKills; 17572 boolean doCpuKills = doKills; 17573 if (mLastPowerCheckRealtime == 0) { 17574 doWakeKills = false; 17575 } 17576 if (mLastPowerCheckUptime == 0) { 17577 doCpuKills = false; 17578 } 17579 if (stats.isScreenOn()) { 17580 doWakeKills = false; 17581 } 17582 final long curRealtime = SystemClock.elapsedRealtime(); 17583 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17584 final long curUptime = SystemClock.uptimeMillis(); 17585 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17586 mLastPowerCheckRealtime = curRealtime; 17587 mLastPowerCheckUptime = curUptime; 17588 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17589 doWakeKills = false; 17590 } 17591 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17592 doCpuKills = false; 17593 } 17594 int i = mLruProcesses.size(); 17595 while (i > 0) { 17596 i--; 17597 ProcessRecord app = mLruProcesses.get(i); 17598 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17599 long wtime; 17600 synchronized (stats) { 17601 wtime = stats.getProcessWakeTime(app.info.uid, 17602 app.pid, curRealtime); 17603 } 17604 long wtimeUsed = wtime - app.lastWakeTime; 17605 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17606 if (DEBUG_POWER) { 17607 StringBuilder sb = new StringBuilder(128); 17608 sb.append("Wake for "); 17609 app.toShortString(sb); 17610 sb.append(": over "); 17611 TimeUtils.formatDuration(realtimeSince, sb); 17612 sb.append(" used "); 17613 TimeUtils.formatDuration(wtimeUsed, sb); 17614 sb.append(" ("); 17615 sb.append((wtimeUsed*100)/realtimeSince); 17616 sb.append("%)"); 17617 Slog.i(TAG, sb.toString()); 17618 sb.setLength(0); 17619 sb.append("CPU for "); 17620 app.toShortString(sb); 17621 sb.append(": over "); 17622 TimeUtils.formatDuration(uptimeSince, sb); 17623 sb.append(" used "); 17624 TimeUtils.formatDuration(cputimeUsed, sb); 17625 sb.append(" ("); 17626 sb.append((cputimeUsed*100)/uptimeSince); 17627 sb.append("%)"); 17628 Slog.i(TAG, sb.toString()); 17629 } 17630 // If a process has held a wake lock for more 17631 // than 50% of the time during this period, 17632 // that sounds bad. Kill! 17633 if (doWakeKills && realtimeSince > 0 17634 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17635 synchronized (stats) { 17636 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17637 realtimeSince, wtimeUsed); 17638 } 17639 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17640 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17641 } else if (doCpuKills && uptimeSince > 0 17642 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17643 synchronized (stats) { 17644 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17645 uptimeSince, cputimeUsed); 17646 } 17647 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17648 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17649 } else { 17650 app.lastWakeTime = wtime; 17651 app.lastCpuTime = app.curCpuTime; 17652 } 17653 } 17654 } 17655 } 17656 17657 private final boolean applyOomAdjLocked(ProcessRecord app, 17658 ProcessRecord TOP_APP, boolean doingAll, long now) { 17659 boolean success = true; 17660 17661 if (app.curRawAdj != app.setRawAdj) { 17662 app.setRawAdj = app.curRawAdj; 17663 } 17664 17665 int changes = 0; 17666 17667 if (app.curAdj != app.setAdj) { 17668 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17669 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17670 TAG, "Set " + app.pid + " " + app.processName + 17671 " adj " + app.curAdj + ": " + app.adjType); 17672 app.setAdj = app.curAdj; 17673 } 17674 17675 if (app.setSchedGroup != app.curSchedGroup) { 17676 app.setSchedGroup = app.curSchedGroup; 17677 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17678 "Setting process group of " + app.processName 17679 + " to " + app.curSchedGroup); 17680 if (app.waitingToKill != null && 17681 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17682 app.kill(app.waitingToKill, true); 17683 success = false; 17684 } else { 17685 if (true) { 17686 long oldId = Binder.clearCallingIdentity(); 17687 try { 17688 Process.setProcessGroup(app.pid, app.curSchedGroup); 17689 } catch (Exception e) { 17690 Slog.w(TAG, "Failed setting process group of " + app.pid 17691 + " to " + app.curSchedGroup); 17692 e.printStackTrace(); 17693 } finally { 17694 Binder.restoreCallingIdentity(oldId); 17695 } 17696 } else { 17697 if (app.thread != null) { 17698 try { 17699 app.thread.setSchedulingGroup(app.curSchedGroup); 17700 } catch (RemoteException e) { 17701 } 17702 } 17703 } 17704 Process.setSwappiness(app.pid, 17705 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17706 } 17707 } 17708 if (app.repForegroundActivities != app.foregroundActivities) { 17709 app.repForegroundActivities = app.foregroundActivities; 17710 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17711 } 17712 if (app.repProcState != app.curProcState) { 17713 app.repProcState = app.curProcState; 17714 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17715 if (app.thread != null) { 17716 try { 17717 if (false) { 17718 //RuntimeException h = new RuntimeException("here"); 17719 Slog.i(TAG, "Sending new process state " + app.repProcState 17720 + " to " + app /*, h*/); 17721 } 17722 app.thread.setProcessState(app.repProcState); 17723 } catch (RemoteException e) { 17724 } 17725 } 17726 } 17727 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17728 app.setProcState)) { 17729 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17730 // Experimental code to more aggressively collect pss while 17731 // running test... the problem is that this tends to collect 17732 // the data right when a process is transitioning between process 17733 // states, which well tend to give noisy data. 17734 long start = SystemClock.uptimeMillis(); 17735 long pss = Debug.getPss(app.pid, mTmpLong, null); 17736 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17737 mPendingPssProcesses.remove(app); 17738 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17739 + " to " + app.curProcState + ": " 17740 + (SystemClock.uptimeMillis()-start) + "ms"); 17741 } 17742 app.lastStateTime = now; 17743 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17744 mTestPssMode, isSleeping(), now); 17745 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17746 + ProcessList.makeProcStateString(app.setProcState) + " to " 17747 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17748 + (app.nextPssTime-now) + ": " + app); 17749 } else { 17750 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17751 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17752 mTestPssMode)))) { 17753 requestPssLocked(app, app.setProcState); 17754 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17755 mTestPssMode, isSleeping(), now); 17756 } else if (false && DEBUG_PSS) { 17757 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17758 } 17759 } 17760 if (app.setProcState != app.curProcState) { 17761 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17762 "Proc state change of " + app.processName 17763 + " to " + app.curProcState); 17764 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17765 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17766 if (setImportant && !curImportant) { 17767 // This app is no longer something we consider important enough to allow to 17768 // use arbitrary amounts of battery power. Note 17769 // its current wake lock time to later know to kill it if 17770 // it is not behaving well. 17771 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17772 synchronized (stats) { 17773 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17774 app.pid, SystemClock.elapsedRealtime()); 17775 } 17776 app.lastCpuTime = app.curCpuTime; 17777 17778 } 17779 app.setProcState = app.curProcState; 17780 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17781 app.notCachedSinceIdle = false; 17782 } 17783 if (!doingAll) { 17784 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17785 } else { 17786 app.procStateChanged = true; 17787 } 17788 } 17789 17790 if (changes != 0) { 17791 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17792 int i = mPendingProcessChanges.size()-1; 17793 ProcessChangeItem item = null; 17794 while (i >= 0) { 17795 item = mPendingProcessChanges.get(i); 17796 if (item.pid == app.pid) { 17797 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17798 break; 17799 } 17800 i--; 17801 } 17802 if (i < 0) { 17803 // No existing item in pending changes; need a new one. 17804 final int NA = mAvailProcessChanges.size(); 17805 if (NA > 0) { 17806 item = mAvailProcessChanges.remove(NA-1); 17807 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17808 } else { 17809 item = new ProcessChangeItem(); 17810 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17811 } 17812 item.changes = 0; 17813 item.pid = app.pid; 17814 item.uid = app.info.uid; 17815 if (mPendingProcessChanges.size() == 0) { 17816 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17817 "*** Enqueueing dispatch processes changed!"); 17818 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17819 } 17820 mPendingProcessChanges.add(item); 17821 } 17822 item.changes |= changes; 17823 item.processState = app.repProcState; 17824 item.foregroundActivities = app.repForegroundActivities; 17825 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17826 + Integer.toHexString(System.identityHashCode(item)) 17827 + " " + app.toShortString() + ": changes=" + item.changes 17828 + " procState=" + item.processState 17829 + " foreground=" + item.foregroundActivities 17830 + " type=" + app.adjType + " source=" + app.adjSource 17831 + " target=" + app.adjTarget); 17832 } 17833 17834 return success; 17835 } 17836 17837 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17838 if (proc.thread != null) { 17839 if (proc.baseProcessTracker != null) { 17840 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17841 } 17842 if (proc.repProcState >= 0) { 17843 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17844 proc.repProcState); 17845 } 17846 } 17847 } 17848 17849 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17850 ProcessRecord TOP_APP, boolean doingAll, long now) { 17851 if (app.thread == null) { 17852 return false; 17853 } 17854 17855 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17856 17857 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17858 } 17859 17860 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17861 boolean oomAdj) { 17862 if (isForeground != proc.foregroundServices) { 17863 proc.foregroundServices = isForeground; 17864 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17865 proc.info.uid); 17866 if (isForeground) { 17867 if (curProcs == null) { 17868 curProcs = new ArrayList<ProcessRecord>(); 17869 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17870 } 17871 if (!curProcs.contains(proc)) { 17872 curProcs.add(proc); 17873 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17874 proc.info.packageName, proc.info.uid); 17875 } 17876 } else { 17877 if (curProcs != null) { 17878 if (curProcs.remove(proc)) { 17879 mBatteryStatsService.noteEvent( 17880 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17881 proc.info.packageName, proc.info.uid); 17882 if (curProcs.size() <= 0) { 17883 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17884 } 17885 } 17886 } 17887 } 17888 if (oomAdj) { 17889 updateOomAdjLocked(); 17890 } 17891 } 17892 } 17893 17894 private final ActivityRecord resumedAppLocked() { 17895 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17896 String pkg; 17897 int uid; 17898 if (act != null) { 17899 pkg = act.packageName; 17900 uid = act.info.applicationInfo.uid; 17901 } else { 17902 pkg = null; 17903 uid = -1; 17904 } 17905 // Has the UID or resumed package name changed? 17906 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17907 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17908 if (mCurResumedPackage != null) { 17909 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17910 mCurResumedPackage, mCurResumedUid); 17911 } 17912 mCurResumedPackage = pkg; 17913 mCurResumedUid = uid; 17914 if (mCurResumedPackage != null) { 17915 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17916 mCurResumedPackage, mCurResumedUid); 17917 } 17918 } 17919 return act; 17920 } 17921 17922 final boolean updateOomAdjLocked(ProcessRecord app) { 17923 final ActivityRecord TOP_ACT = resumedAppLocked(); 17924 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17925 final boolean wasCached = app.cached; 17926 17927 mAdjSeq++; 17928 17929 // This is the desired cached adjusment we want to tell it to use. 17930 // If our app is currently cached, we know it, and that is it. Otherwise, 17931 // we don't know it yet, and it needs to now be cached we will then 17932 // need to do a complete oom adj. 17933 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17934 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17935 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17936 SystemClock.uptimeMillis()); 17937 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17938 // Changed to/from cached state, so apps after it in the LRU 17939 // list may also be changed. 17940 updateOomAdjLocked(); 17941 } 17942 return success; 17943 } 17944 17945 final void updateOomAdjLocked() { 17946 final ActivityRecord TOP_ACT = resumedAppLocked(); 17947 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17948 final long now = SystemClock.uptimeMillis(); 17949 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17950 final int N = mLruProcesses.size(); 17951 17952 if (false) { 17953 RuntimeException e = new RuntimeException(); 17954 e.fillInStackTrace(); 17955 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17956 } 17957 17958 mAdjSeq++; 17959 mNewNumServiceProcs = 0; 17960 mNewNumAServiceProcs = 0; 17961 17962 final int emptyProcessLimit; 17963 final int cachedProcessLimit; 17964 if (mProcessLimit <= 0) { 17965 emptyProcessLimit = cachedProcessLimit = 0; 17966 } else if (mProcessLimit == 1) { 17967 emptyProcessLimit = 1; 17968 cachedProcessLimit = 0; 17969 } else { 17970 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17971 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17972 } 17973 17974 // Let's determine how many processes we have running vs. 17975 // how many slots we have for background processes; we may want 17976 // to put multiple processes in a slot of there are enough of 17977 // them. 17978 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17979 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17980 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17981 if (numEmptyProcs > cachedProcessLimit) { 17982 // If there are more empty processes than our limit on cached 17983 // processes, then use the cached process limit for the factor. 17984 // This ensures that the really old empty processes get pushed 17985 // down to the bottom, so if we are running low on memory we will 17986 // have a better chance at keeping around more cached processes 17987 // instead of a gazillion empty processes. 17988 numEmptyProcs = cachedProcessLimit; 17989 } 17990 int emptyFactor = numEmptyProcs/numSlots; 17991 if (emptyFactor < 1) emptyFactor = 1; 17992 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17993 if (cachedFactor < 1) cachedFactor = 1; 17994 int stepCached = 0; 17995 int stepEmpty = 0; 17996 int numCached = 0; 17997 int numEmpty = 0; 17998 int numTrimming = 0; 17999 18000 mNumNonCachedProcs = 0; 18001 mNumCachedHiddenProcs = 0; 18002 18003 // First update the OOM adjustment for each of the 18004 // application processes based on their current state. 18005 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18006 int nextCachedAdj = curCachedAdj+1; 18007 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18008 int nextEmptyAdj = curEmptyAdj+2; 18009 for (int i=N-1; i>=0; i--) { 18010 ProcessRecord app = mLruProcesses.get(i); 18011 if (!app.killedByAm && app.thread != null) { 18012 app.procStateChanged = false; 18013 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18014 18015 // If we haven't yet assigned the final cached adj 18016 // to the process, do that now. 18017 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18018 switch (app.curProcState) { 18019 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18020 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18021 // This process is a cached process holding activities... 18022 // assign it the next cached value for that type, and then 18023 // step that cached level. 18024 app.curRawAdj = curCachedAdj; 18025 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18026 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18027 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18028 + ")"); 18029 if (curCachedAdj != nextCachedAdj) { 18030 stepCached++; 18031 if (stepCached >= cachedFactor) { 18032 stepCached = 0; 18033 curCachedAdj = nextCachedAdj; 18034 nextCachedAdj += 2; 18035 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18036 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18037 } 18038 } 18039 } 18040 break; 18041 default: 18042 // For everything else, assign next empty cached process 18043 // level and bump that up. Note that this means that 18044 // long-running services that have dropped down to the 18045 // cached level will be treated as empty (since their process 18046 // state is still as a service), which is what we want. 18047 app.curRawAdj = curEmptyAdj; 18048 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18049 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18050 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18051 + ")"); 18052 if (curEmptyAdj != nextEmptyAdj) { 18053 stepEmpty++; 18054 if (stepEmpty >= emptyFactor) { 18055 stepEmpty = 0; 18056 curEmptyAdj = nextEmptyAdj; 18057 nextEmptyAdj += 2; 18058 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18059 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18060 } 18061 } 18062 } 18063 break; 18064 } 18065 } 18066 18067 applyOomAdjLocked(app, TOP_APP, true, now); 18068 18069 // Count the number of process types. 18070 switch (app.curProcState) { 18071 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18072 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18073 mNumCachedHiddenProcs++; 18074 numCached++; 18075 if (numCached > cachedProcessLimit) { 18076 app.kill("cached #" + numCached, true); 18077 } 18078 break; 18079 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18080 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18081 && app.lastActivityTime < oldTime) { 18082 app.kill("empty for " 18083 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18084 / 1000) + "s", true); 18085 } else { 18086 numEmpty++; 18087 if (numEmpty > emptyProcessLimit) { 18088 app.kill("empty #" + numEmpty, true); 18089 } 18090 } 18091 break; 18092 default: 18093 mNumNonCachedProcs++; 18094 break; 18095 } 18096 18097 if (app.isolated && app.services.size() <= 0) { 18098 // If this is an isolated process, and there are no 18099 // services running in it, then the process is no longer 18100 // needed. We agressively kill these because we can by 18101 // definition not re-use the same process again, and it is 18102 // good to avoid having whatever code was running in them 18103 // left sitting around after no longer needed. 18104 app.kill("isolated not needed", true); 18105 } 18106 18107 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18108 && !app.killedByAm) { 18109 numTrimming++; 18110 } 18111 } 18112 } 18113 18114 mNumServiceProcs = mNewNumServiceProcs; 18115 18116 // Now determine the memory trimming level of background processes. 18117 // Unfortunately we need to start at the back of the list to do this 18118 // properly. We only do this if the number of background apps we 18119 // are managing to keep around is less than half the maximum we desire; 18120 // if we are keeping a good number around, we'll let them use whatever 18121 // memory they want. 18122 final int numCachedAndEmpty = numCached + numEmpty; 18123 int memFactor; 18124 if (numCached <= ProcessList.TRIM_CACHED_APPS 18125 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18126 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18127 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18128 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18129 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18130 } else { 18131 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18132 } 18133 } else { 18134 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18135 } 18136 // We always allow the memory level to go up (better). We only allow it to go 18137 // down if we are in a state where that is allowed, *and* the total number of processes 18138 // has gone down since last time. 18139 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18140 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18141 + " last=" + mLastNumProcesses); 18142 if (memFactor > mLastMemoryLevel) { 18143 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18144 memFactor = mLastMemoryLevel; 18145 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18146 } 18147 } 18148 mLastMemoryLevel = memFactor; 18149 mLastNumProcesses = mLruProcesses.size(); 18150 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18151 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18152 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18153 if (mLowRamStartTime == 0) { 18154 mLowRamStartTime = now; 18155 } 18156 int step = 0; 18157 int fgTrimLevel; 18158 switch (memFactor) { 18159 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18160 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18161 break; 18162 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18163 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18164 break; 18165 default: 18166 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18167 break; 18168 } 18169 int factor = numTrimming/3; 18170 int minFactor = 2; 18171 if (mHomeProcess != null) minFactor++; 18172 if (mPreviousProcess != null) minFactor++; 18173 if (factor < minFactor) factor = minFactor; 18174 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18175 for (int i=N-1; i>=0; i--) { 18176 ProcessRecord app = mLruProcesses.get(i); 18177 if (allChanged || app.procStateChanged) { 18178 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18179 app.procStateChanged = false; 18180 } 18181 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18182 && !app.killedByAm) { 18183 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18184 try { 18185 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18186 "Trimming memory of " + app.processName 18187 + " to " + curLevel); 18188 app.thread.scheduleTrimMemory(curLevel); 18189 } catch (RemoteException e) { 18190 } 18191 if (false) { 18192 // For now we won't do this; our memory trimming seems 18193 // to be good enough at this point that destroying 18194 // activities causes more harm than good. 18195 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18196 && app != mHomeProcess && app != mPreviousProcess) { 18197 // Need to do this on its own message because the stack may not 18198 // be in a consistent state at this point. 18199 // For these apps we will also finish their activities 18200 // to help them free memory. 18201 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18202 } 18203 } 18204 } 18205 app.trimMemoryLevel = curLevel; 18206 step++; 18207 if (step >= factor) { 18208 step = 0; 18209 switch (curLevel) { 18210 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18211 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18212 break; 18213 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18214 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18215 break; 18216 } 18217 } 18218 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18219 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18220 && app.thread != null) { 18221 try { 18222 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18223 "Trimming memory of heavy-weight " + app.processName 18224 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18225 app.thread.scheduleTrimMemory( 18226 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18227 } catch (RemoteException e) { 18228 } 18229 } 18230 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18231 } else { 18232 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18233 || app.systemNoUi) && app.pendingUiClean) { 18234 // If this application is now in the background and it 18235 // had done UI, then give it the special trim level to 18236 // have it free UI resources. 18237 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18238 if (app.trimMemoryLevel < level && app.thread != null) { 18239 try { 18240 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18241 "Trimming memory of bg-ui " + app.processName 18242 + " to " + level); 18243 app.thread.scheduleTrimMemory(level); 18244 } catch (RemoteException e) { 18245 } 18246 } 18247 app.pendingUiClean = false; 18248 } 18249 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18250 try { 18251 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18252 "Trimming memory of fg " + app.processName 18253 + " to " + fgTrimLevel); 18254 app.thread.scheduleTrimMemory(fgTrimLevel); 18255 } catch (RemoteException e) { 18256 } 18257 } 18258 app.trimMemoryLevel = fgTrimLevel; 18259 } 18260 } 18261 } else { 18262 if (mLowRamStartTime != 0) { 18263 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18264 mLowRamStartTime = 0; 18265 } 18266 for (int i=N-1; i>=0; i--) { 18267 ProcessRecord app = mLruProcesses.get(i); 18268 if (allChanged || app.procStateChanged) { 18269 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18270 app.procStateChanged = false; 18271 } 18272 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18273 || app.systemNoUi) && app.pendingUiClean) { 18274 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18275 && app.thread != null) { 18276 try { 18277 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18278 "Trimming memory of ui hidden " + app.processName 18279 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18280 app.thread.scheduleTrimMemory( 18281 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18282 } catch (RemoteException e) { 18283 } 18284 } 18285 app.pendingUiClean = false; 18286 } 18287 app.trimMemoryLevel = 0; 18288 } 18289 } 18290 18291 if (mAlwaysFinishActivities) { 18292 // Need to do this on its own message because the stack may not 18293 // be in a consistent state at this point. 18294 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18295 } 18296 18297 if (allChanged) { 18298 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18299 } 18300 18301 if (mProcessStats.shouldWriteNowLocked(now)) { 18302 mHandler.post(new Runnable() { 18303 @Override public void run() { 18304 synchronized (ActivityManagerService.this) { 18305 mProcessStats.writeStateAsyncLocked(); 18306 } 18307 } 18308 }); 18309 } 18310 18311 if (DEBUG_OOM_ADJ) { 18312 if (false) { 18313 RuntimeException here = new RuntimeException("here"); 18314 here.fillInStackTrace(); 18315 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18316 } else { 18317 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18318 } 18319 } 18320 } 18321 18322 final void trimApplications() { 18323 synchronized (this) { 18324 int i; 18325 18326 // First remove any unused application processes whose package 18327 // has been removed. 18328 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18329 final ProcessRecord app = mRemovedProcesses.get(i); 18330 if (app.activities.size() == 0 18331 && app.curReceiver == null && app.services.size() == 0) { 18332 Slog.i( 18333 TAG, "Exiting empty application process " 18334 + app.processName + " (" 18335 + (app.thread != null ? app.thread.asBinder() : null) 18336 + ")\n"); 18337 if (app.pid > 0 && app.pid != MY_PID) { 18338 app.kill("empty", false); 18339 } else { 18340 try { 18341 app.thread.scheduleExit(); 18342 } catch (Exception e) { 18343 // Ignore exceptions. 18344 } 18345 } 18346 cleanUpApplicationRecordLocked(app, false, true, -1); 18347 mRemovedProcesses.remove(i); 18348 18349 if (app.persistent) { 18350 addAppLocked(app.info, false, null /* ABI override */); 18351 } 18352 } 18353 } 18354 18355 // Now update the oom adj for all processes. 18356 updateOomAdjLocked(); 18357 } 18358 } 18359 18360 /** This method sends the specified signal to each of the persistent apps */ 18361 public void signalPersistentProcesses(int sig) throws RemoteException { 18362 if (sig != Process.SIGNAL_USR1) { 18363 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18364 } 18365 18366 synchronized (this) { 18367 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18368 != PackageManager.PERMISSION_GRANTED) { 18369 throw new SecurityException("Requires permission " 18370 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18371 } 18372 18373 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18374 ProcessRecord r = mLruProcesses.get(i); 18375 if (r.thread != null && r.persistent) { 18376 Process.sendSignal(r.pid, sig); 18377 } 18378 } 18379 } 18380 } 18381 18382 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18383 if (proc == null || proc == mProfileProc) { 18384 proc = mProfileProc; 18385 profileType = mProfileType; 18386 clearProfilerLocked(); 18387 } 18388 if (proc == null) { 18389 return; 18390 } 18391 try { 18392 proc.thread.profilerControl(false, null, profileType); 18393 } catch (RemoteException e) { 18394 throw new IllegalStateException("Process disappeared"); 18395 } 18396 } 18397 18398 private void clearProfilerLocked() { 18399 if (mProfileFd != null) { 18400 try { 18401 mProfileFd.close(); 18402 } catch (IOException e) { 18403 } 18404 } 18405 mProfileApp = null; 18406 mProfileProc = null; 18407 mProfileFile = null; 18408 mProfileType = 0; 18409 mAutoStopProfiler = false; 18410 mSamplingInterval = 0; 18411 } 18412 18413 public boolean profileControl(String process, int userId, boolean start, 18414 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18415 18416 try { 18417 synchronized (this) { 18418 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18419 // its own permission. 18420 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18421 != PackageManager.PERMISSION_GRANTED) { 18422 throw new SecurityException("Requires permission " 18423 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18424 } 18425 18426 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18427 throw new IllegalArgumentException("null profile info or fd"); 18428 } 18429 18430 ProcessRecord proc = null; 18431 if (process != null) { 18432 proc = findProcessLocked(process, userId, "profileControl"); 18433 } 18434 18435 if (start && (proc == null || proc.thread == null)) { 18436 throw new IllegalArgumentException("Unknown process: " + process); 18437 } 18438 18439 if (start) { 18440 stopProfilerLocked(null, 0); 18441 setProfileApp(proc.info, proc.processName, profilerInfo); 18442 mProfileProc = proc; 18443 mProfileType = profileType; 18444 ParcelFileDescriptor fd = profilerInfo.profileFd; 18445 try { 18446 fd = fd.dup(); 18447 } catch (IOException e) { 18448 fd = null; 18449 } 18450 profilerInfo.profileFd = fd; 18451 proc.thread.profilerControl(start, profilerInfo, profileType); 18452 fd = null; 18453 mProfileFd = null; 18454 } else { 18455 stopProfilerLocked(proc, profileType); 18456 if (profilerInfo != null && profilerInfo.profileFd != null) { 18457 try { 18458 profilerInfo.profileFd.close(); 18459 } catch (IOException e) { 18460 } 18461 } 18462 } 18463 18464 return true; 18465 } 18466 } catch (RemoteException e) { 18467 throw new IllegalStateException("Process disappeared"); 18468 } finally { 18469 if (profilerInfo != null && profilerInfo.profileFd != null) { 18470 try { 18471 profilerInfo.profileFd.close(); 18472 } catch (IOException e) { 18473 } 18474 } 18475 } 18476 } 18477 18478 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18479 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18480 userId, true, ALLOW_FULL_ONLY, callName, null); 18481 ProcessRecord proc = null; 18482 try { 18483 int pid = Integer.parseInt(process); 18484 synchronized (mPidsSelfLocked) { 18485 proc = mPidsSelfLocked.get(pid); 18486 } 18487 } catch (NumberFormatException e) { 18488 } 18489 18490 if (proc == null) { 18491 ArrayMap<String, SparseArray<ProcessRecord>> all 18492 = mProcessNames.getMap(); 18493 SparseArray<ProcessRecord> procs = all.get(process); 18494 if (procs != null && procs.size() > 0) { 18495 proc = procs.valueAt(0); 18496 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18497 for (int i=1; i<procs.size(); i++) { 18498 ProcessRecord thisProc = procs.valueAt(i); 18499 if (thisProc.userId == userId) { 18500 proc = thisProc; 18501 break; 18502 } 18503 } 18504 } 18505 } 18506 } 18507 18508 return proc; 18509 } 18510 18511 public boolean dumpHeap(String process, int userId, boolean managed, 18512 String path, ParcelFileDescriptor fd) throws RemoteException { 18513 18514 try { 18515 synchronized (this) { 18516 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18517 // its own permission (same as profileControl). 18518 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18519 != PackageManager.PERMISSION_GRANTED) { 18520 throw new SecurityException("Requires permission " 18521 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18522 } 18523 18524 if (fd == null) { 18525 throw new IllegalArgumentException("null fd"); 18526 } 18527 18528 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18529 if (proc == null || proc.thread == null) { 18530 throw new IllegalArgumentException("Unknown process: " + process); 18531 } 18532 18533 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18534 if (!isDebuggable) { 18535 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18536 throw new SecurityException("Process not debuggable: " + proc); 18537 } 18538 } 18539 18540 proc.thread.dumpHeap(managed, path, fd); 18541 fd = null; 18542 return true; 18543 } 18544 } catch (RemoteException e) { 18545 throw new IllegalStateException("Process disappeared"); 18546 } finally { 18547 if (fd != null) { 18548 try { 18549 fd.close(); 18550 } catch (IOException e) { 18551 } 18552 } 18553 } 18554 } 18555 18556 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18557 public void monitor() { 18558 synchronized (this) { } 18559 } 18560 18561 void onCoreSettingsChange(Bundle settings) { 18562 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18563 ProcessRecord processRecord = mLruProcesses.get(i); 18564 try { 18565 if (processRecord.thread != null) { 18566 processRecord.thread.setCoreSettings(settings); 18567 } 18568 } catch (RemoteException re) { 18569 /* ignore */ 18570 } 18571 } 18572 } 18573 18574 // Multi-user methods 18575 18576 /** 18577 * Start user, if its not already running, but don't bring it to foreground. 18578 */ 18579 @Override 18580 public boolean startUserInBackground(final int userId) { 18581 return startUser(userId, /* foreground */ false); 18582 } 18583 18584 /** 18585 * Start user, if its not already running, and bring it to foreground. 18586 */ 18587 boolean startUserInForeground(final int userId, Dialog dlg) { 18588 boolean result = startUser(userId, /* foreground */ true); 18589 dlg.dismiss(); 18590 return result; 18591 } 18592 18593 /** 18594 * Refreshes the list of users related to the current user when either a 18595 * user switch happens or when a new related user is started in the 18596 * background. 18597 */ 18598 private void updateCurrentProfileIdsLocked() { 18599 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18600 mCurrentUserId, false /* enabledOnly */); 18601 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18602 for (int i = 0; i < currentProfileIds.length; i++) { 18603 currentProfileIds[i] = profiles.get(i).id; 18604 } 18605 mCurrentProfileIds = currentProfileIds; 18606 18607 synchronized (mUserProfileGroupIdsSelfLocked) { 18608 mUserProfileGroupIdsSelfLocked.clear(); 18609 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18610 for (int i = 0; i < users.size(); i++) { 18611 UserInfo user = users.get(i); 18612 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18613 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18614 } 18615 } 18616 } 18617 } 18618 18619 private Set getProfileIdsLocked(int userId) { 18620 Set userIds = new HashSet<Integer>(); 18621 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18622 userId, false /* enabledOnly */); 18623 for (UserInfo user : profiles) { 18624 userIds.add(Integer.valueOf(user.id)); 18625 } 18626 return userIds; 18627 } 18628 18629 @Override 18630 public boolean switchUser(final int userId) { 18631 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18632 String userName; 18633 synchronized (this) { 18634 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18635 if (userInfo == null) { 18636 Slog.w(TAG, "No user info for user #" + userId); 18637 return false; 18638 } 18639 if (userInfo.isManagedProfile()) { 18640 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18641 return false; 18642 } 18643 userName = userInfo.name; 18644 mTargetUserId = userId; 18645 } 18646 mHandler.removeMessages(START_USER_SWITCH_MSG); 18647 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18648 return true; 18649 } 18650 18651 private void showUserSwitchDialog(int userId, String userName) { 18652 // The dialog will show and then initiate the user switch by calling startUserInForeground 18653 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18654 true /* above system */); 18655 d.show(); 18656 } 18657 18658 private boolean startUser(final int userId, final boolean foreground) { 18659 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18660 != PackageManager.PERMISSION_GRANTED) { 18661 String msg = "Permission Denial: switchUser() from pid=" 18662 + Binder.getCallingPid() 18663 + ", uid=" + Binder.getCallingUid() 18664 + " requires " + INTERACT_ACROSS_USERS_FULL; 18665 Slog.w(TAG, msg); 18666 throw new SecurityException(msg); 18667 } 18668 18669 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18670 18671 final long ident = Binder.clearCallingIdentity(); 18672 try { 18673 synchronized (this) { 18674 final int oldUserId = mCurrentUserId; 18675 if (oldUserId == userId) { 18676 return true; 18677 } 18678 18679 mStackSupervisor.setLockTaskModeLocked(null, false); 18680 18681 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18682 if (userInfo == null) { 18683 Slog.w(TAG, "No user info for user #" + userId); 18684 return false; 18685 } 18686 if (foreground && userInfo.isManagedProfile()) { 18687 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18688 return false; 18689 } 18690 18691 if (foreground) { 18692 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18693 R.anim.screen_user_enter); 18694 } 18695 18696 boolean needStart = false; 18697 18698 // If the user we are switching to is not currently started, then 18699 // we need to start it now. 18700 if (mStartedUsers.get(userId) == null) { 18701 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18702 updateStartedUserArrayLocked(); 18703 needStart = true; 18704 } 18705 18706 final Integer userIdInt = Integer.valueOf(userId); 18707 mUserLru.remove(userIdInt); 18708 mUserLru.add(userIdInt); 18709 18710 if (foreground) { 18711 mCurrentUserId = userId; 18712 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18713 updateCurrentProfileIdsLocked(); 18714 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18715 // Once the internal notion of the active user has switched, we lock the device 18716 // with the option to show the user switcher on the keyguard. 18717 mWindowManager.lockNow(null); 18718 } else { 18719 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18720 updateCurrentProfileIdsLocked(); 18721 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18722 mUserLru.remove(currentUserIdInt); 18723 mUserLru.add(currentUserIdInt); 18724 } 18725 18726 final UserStartedState uss = mStartedUsers.get(userId); 18727 18728 // Make sure user is in the started state. If it is currently 18729 // stopping, we need to knock that off. 18730 if (uss.mState == UserStartedState.STATE_STOPPING) { 18731 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18732 // so we can just fairly silently bring the user back from 18733 // the almost-dead. 18734 uss.mState = UserStartedState.STATE_RUNNING; 18735 updateStartedUserArrayLocked(); 18736 needStart = true; 18737 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18738 // This means ACTION_SHUTDOWN has been sent, so we will 18739 // need to treat this as a new boot of the user. 18740 uss.mState = UserStartedState.STATE_BOOTING; 18741 updateStartedUserArrayLocked(); 18742 needStart = true; 18743 } 18744 18745 if (uss.mState == UserStartedState.STATE_BOOTING) { 18746 // Booting up a new user, need to tell system services about it. 18747 // Note that this is on the same handler as scheduling of broadcasts, 18748 // which is important because it needs to go first. 18749 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18750 } 18751 18752 if (foreground) { 18753 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18754 oldUserId)); 18755 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18756 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18757 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18758 oldUserId, userId, uss)); 18759 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18760 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18761 } 18762 18763 if (needStart) { 18764 // Send USER_STARTED broadcast 18765 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18766 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18767 | Intent.FLAG_RECEIVER_FOREGROUND); 18768 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18769 broadcastIntentLocked(null, null, intent, 18770 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18771 false, false, MY_PID, Process.SYSTEM_UID, userId); 18772 } 18773 18774 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18775 if (userId != UserHandle.USER_OWNER) { 18776 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18777 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18778 broadcastIntentLocked(null, null, intent, null, 18779 new IIntentReceiver.Stub() { 18780 public void performReceive(Intent intent, int resultCode, 18781 String data, Bundle extras, boolean ordered, 18782 boolean sticky, int sendingUser) { 18783 onUserInitialized(uss, foreground, oldUserId, userId); 18784 } 18785 }, 0, null, null, null, AppOpsManager.OP_NONE, 18786 true, false, MY_PID, Process.SYSTEM_UID, 18787 userId); 18788 uss.initializing = true; 18789 } else { 18790 getUserManagerLocked().makeInitialized(userInfo.id); 18791 } 18792 } 18793 18794 if (foreground) { 18795 if (!uss.initializing) { 18796 moveUserToForeground(uss, oldUserId, userId); 18797 } 18798 } else { 18799 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18800 } 18801 18802 if (needStart) { 18803 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18804 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18805 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18806 broadcastIntentLocked(null, null, intent, 18807 null, new IIntentReceiver.Stub() { 18808 @Override 18809 public void performReceive(Intent intent, int resultCode, String data, 18810 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18811 throws RemoteException { 18812 } 18813 }, 0, null, null, 18814 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18815 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18816 } 18817 } 18818 } finally { 18819 Binder.restoreCallingIdentity(ident); 18820 } 18821 18822 return true; 18823 } 18824 18825 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18826 long ident = Binder.clearCallingIdentity(); 18827 try { 18828 Intent intent; 18829 if (oldUserId >= 0) { 18830 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18831 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18832 int count = profiles.size(); 18833 for (int i = 0; i < count; i++) { 18834 int profileUserId = profiles.get(i).id; 18835 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18836 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18837 | Intent.FLAG_RECEIVER_FOREGROUND); 18838 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18839 broadcastIntentLocked(null, null, intent, 18840 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18841 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18842 } 18843 } 18844 if (newUserId >= 0) { 18845 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18846 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18847 int count = profiles.size(); 18848 for (int i = 0; i < count; i++) { 18849 int profileUserId = profiles.get(i).id; 18850 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18851 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18852 | Intent.FLAG_RECEIVER_FOREGROUND); 18853 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18854 broadcastIntentLocked(null, null, intent, 18855 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18856 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18857 } 18858 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18859 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18860 | Intent.FLAG_RECEIVER_FOREGROUND); 18861 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18862 broadcastIntentLocked(null, null, intent, 18863 null, null, 0, null, null, 18864 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18865 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18866 } 18867 } finally { 18868 Binder.restoreCallingIdentity(ident); 18869 } 18870 } 18871 18872 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18873 final int newUserId) { 18874 final int N = mUserSwitchObservers.beginBroadcast(); 18875 if (N > 0) { 18876 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18877 int mCount = 0; 18878 @Override 18879 public void sendResult(Bundle data) throws RemoteException { 18880 synchronized (ActivityManagerService.this) { 18881 if (mCurUserSwitchCallback == this) { 18882 mCount++; 18883 if (mCount == N) { 18884 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18885 } 18886 } 18887 } 18888 } 18889 }; 18890 synchronized (this) { 18891 uss.switching = true; 18892 mCurUserSwitchCallback = callback; 18893 } 18894 for (int i=0; i<N; i++) { 18895 try { 18896 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18897 newUserId, callback); 18898 } catch (RemoteException e) { 18899 } 18900 } 18901 } else { 18902 synchronized (this) { 18903 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18904 } 18905 } 18906 mUserSwitchObservers.finishBroadcast(); 18907 } 18908 18909 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18910 synchronized (this) { 18911 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18912 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18913 } 18914 } 18915 18916 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18917 mCurUserSwitchCallback = null; 18918 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18919 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18920 oldUserId, newUserId, uss)); 18921 } 18922 18923 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18924 synchronized (this) { 18925 if (foreground) { 18926 moveUserToForeground(uss, oldUserId, newUserId); 18927 } 18928 } 18929 18930 completeSwitchAndInitalize(uss, newUserId, true, false); 18931 } 18932 18933 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18934 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18935 if (homeInFront) { 18936 startHomeActivityLocked(newUserId); 18937 } else { 18938 mStackSupervisor.resumeTopActivitiesLocked(); 18939 } 18940 EventLogTags.writeAmSwitchUser(newUserId); 18941 getUserManagerLocked().userForeground(newUserId); 18942 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18943 } 18944 18945 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18946 completeSwitchAndInitalize(uss, newUserId, false, true); 18947 } 18948 18949 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18950 boolean clearInitializing, boolean clearSwitching) { 18951 boolean unfrozen = false; 18952 synchronized (this) { 18953 if (clearInitializing) { 18954 uss.initializing = false; 18955 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18956 } 18957 if (clearSwitching) { 18958 uss.switching = false; 18959 } 18960 if (!uss.switching && !uss.initializing) { 18961 mWindowManager.stopFreezingScreen(); 18962 unfrozen = true; 18963 } 18964 } 18965 if (unfrozen) { 18966 final int N = mUserSwitchObservers.beginBroadcast(); 18967 for (int i=0; i<N; i++) { 18968 try { 18969 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18970 } catch (RemoteException e) { 18971 } 18972 } 18973 mUserSwitchObservers.finishBroadcast(); 18974 } 18975 } 18976 18977 void scheduleStartProfilesLocked() { 18978 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18979 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18980 DateUtils.SECOND_IN_MILLIS); 18981 } 18982 } 18983 18984 void startProfilesLocked() { 18985 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18986 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18987 mCurrentUserId, false /* enabledOnly */); 18988 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18989 for (UserInfo user : profiles) { 18990 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18991 && user.id != mCurrentUserId) { 18992 toStart.add(user); 18993 } 18994 } 18995 final int n = toStart.size(); 18996 int i = 0; 18997 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18998 startUserInBackground(toStart.get(i).id); 18999 } 19000 if (i < n) { 19001 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19002 } 19003 } 19004 19005 void finishUserBoot(UserStartedState uss) { 19006 synchronized (this) { 19007 if (uss.mState == UserStartedState.STATE_BOOTING 19008 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19009 uss.mState = UserStartedState.STATE_RUNNING; 19010 final int userId = uss.mHandle.getIdentifier(); 19011 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19012 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19013 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19014 broadcastIntentLocked(null, null, intent, 19015 null, null, 0, null, null, 19016 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19017 true, false, MY_PID, Process.SYSTEM_UID, userId); 19018 } 19019 } 19020 } 19021 19022 void finishUserSwitch(UserStartedState uss) { 19023 synchronized (this) { 19024 finishUserBoot(uss); 19025 19026 startProfilesLocked(); 19027 19028 int num = mUserLru.size(); 19029 int i = 0; 19030 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19031 Integer oldUserId = mUserLru.get(i); 19032 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19033 if (oldUss == null) { 19034 // Shouldn't happen, but be sane if it does. 19035 mUserLru.remove(i); 19036 num--; 19037 continue; 19038 } 19039 if (oldUss.mState == UserStartedState.STATE_STOPPING 19040 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19041 // This user is already stopping, doesn't count. 19042 num--; 19043 i++; 19044 continue; 19045 } 19046 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19047 // Owner and current can't be stopped, but count as running. 19048 i++; 19049 continue; 19050 } 19051 // This is a user to be stopped. 19052 stopUserLocked(oldUserId, null); 19053 num--; 19054 i++; 19055 } 19056 } 19057 } 19058 19059 @Override 19060 public int stopUser(final int userId, final IStopUserCallback callback) { 19061 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19062 != PackageManager.PERMISSION_GRANTED) { 19063 String msg = "Permission Denial: switchUser() from pid=" 19064 + Binder.getCallingPid() 19065 + ", uid=" + Binder.getCallingUid() 19066 + " requires " + INTERACT_ACROSS_USERS_FULL; 19067 Slog.w(TAG, msg); 19068 throw new SecurityException(msg); 19069 } 19070 if (userId <= 0) { 19071 throw new IllegalArgumentException("Can't stop primary user " + userId); 19072 } 19073 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19074 synchronized (this) { 19075 return stopUserLocked(userId, callback); 19076 } 19077 } 19078 19079 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19080 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19081 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19082 return ActivityManager.USER_OP_IS_CURRENT; 19083 } 19084 19085 final UserStartedState uss = mStartedUsers.get(userId); 19086 if (uss == null) { 19087 // User is not started, nothing to do... but we do need to 19088 // callback if requested. 19089 if (callback != null) { 19090 mHandler.post(new Runnable() { 19091 @Override 19092 public void run() { 19093 try { 19094 callback.userStopped(userId); 19095 } catch (RemoteException e) { 19096 } 19097 } 19098 }); 19099 } 19100 return ActivityManager.USER_OP_SUCCESS; 19101 } 19102 19103 if (callback != null) { 19104 uss.mStopCallbacks.add(callback); 19105 } 19106 19107 if (uss.mState != UserStartedState.STATE_STOPPING 19108 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19109 uss.mState = UserStartedState.STATE_STOPPING; 19110 updateStartedUserArrayLocked(); 19111 19112 long ident = Binder.clearCallingIdentity(); 19113 try { 19114 // We are going to broadcast ACTION_USER_STOPPING and then 19115 // once that is done send a final ACTION_SHUTDOWN and then 19116 // stop the user. 19117 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19118 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19119 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19120 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19121 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19122 // This is the result receiver for the final shutdown broadcast. 19123 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19124 @Override 19125 public void performReceive(Intent intent, int resultCode, String data, 19126 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19127 finishUserStop(uss); 19128 } 19129 }; 19130 // This is the result receiver for the initial stopping broadcast. 19131 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19132 @Override 19133 public void performReceive(Intent intent, int resultCode, String data, 19134 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19135 // On to the next. 19136 synchronized (ActivityManagerService.this) { 19137 if (uss.mState != UserStartedState.STATE_STOPPING) { 19138 // Whoops, we are being started back up. Abort, abort! 19139 return; 19140 } 19141 uss.mState = UserStartedState.STATE_SHUTDOWN; 19142 } 19143 mBatteryStatsService.noteEvent( 19144 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19145 Integer.toString(userId), userId); 19146 mSystemServiceManager.stopUser(userId); 19147 broadcastIntentLocked(null, null, shutdownIntent, 19148 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19149 true, false, MY_PID, Process.SYSTEM_UID, userId); 19150 } 19151 }; 19152 // Kick things off. 19153 broadcastIntentLocked(null, null, stoppingIntent, 19154 null, stoppingReceiver, 0, null, null, 19155 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19156 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19157 } finally { 19158 Binder.restoreCallingIdentity(ident); 19159 } 19160 } 19161 19162 return ActivityManager.USER_OP_SUCCESS; 19163 } 19164 19165 void finishUserStop(UserStartedState uss) { 19166 final int userId = uss.mHandle.getIdentifier(); 19167 boolean stopped; 19168 ArrayList<IStopUserCallback> callbacks; 19169 synchronized (this) { 19170 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19171 if (mStartedUsers.get(userId) != uss) { 19172 stopped = false; 19173 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19174 stopped = false; 19175 } else { 19176 stopped = true; 19177 // User can no longer run. 19178 mStartedUsers.remove(userId); 19179 mUserLru.remove(Integer.valueOf(userId)); 19180 updateStartedUserArrayLocked(); 19181 19182 // Clean up all state and processes associated with the user. 19183 // Kill all the processes for the user. 19184 forceStopUserLocked(userId, "finish user"); 19185 } 19186 19187 // Explicitly remove the old information in mRecentTasks. 19188 removeRecentTasksForUserLocked(userId); 19189 } 19190 19191 for (int i=0; i<callbacks.size(); i++) { 19192 try { 19193 if (stopped) callbacks.get(i).userStopped(userId); 19194 else callbacks.get(i).userStopAborted(userId); 19195 } catch (RemoteException e) { 19196 } 19197 } 19198 19199 if (stopped) { 19200 mSystemServiceManager.cleanupUser(userId); 19201 synchronized (this) { 19202 mStackSupervisor.removeUserLocked(userId); 19203 } 19204 } 19205 } 19206 19207 @Override 19208 public UserInfo getCurrentUser() { 19209 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19210 != PackageManager.PERMISSION_GRANTED) && ( 19211 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19212 != PackageManager.PERMISSION_GRANTED)) { 19213 String msg = "Permission Denial: getCurrentUser() from pid=" 19214 + Binder.getCallingPid() 19215 + ", uid=" + Binder.getCallingUid() 19216 + " requires " + INTERACT_ACROSS_USERS; 19217 Slog.w(TAG, msg); 19218 throw new SecurityException(msg); 19219 } 19220 synchronized (this) { 19221 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19222 return getUserManagerLocked().getUserInfo(userId); 19223 } 19224 } 19225 19226 int getCurrentUserIdLocked() { 19227 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19228 } 19229 19230 @Override 19231 public boolean isUserRunning(int userId, boolean orStopped) { 19232 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19233 != PackageManager.PERMISSION_GRANTED) { 19234 String msg = "Permission Denial: isUserRunning() from pid=" 19235 + Binder.getCallingPid() 19236 + ", uid=" + Binder.getCallingUid() 19237 + " requires " + INTERACT_ACROSS_USERS; 19238 Slog.w(TAG, msg); 19239 throw new SecurityException(msg); 19240 } 19241 synchronized (this) { 19242 return isUserRunningLocked(userId, orStopped); 19243 } 19244 } 19245 19246 boolean isUserRunningLocked(int userId, boolean orStopped) { 19247 UserStartedState state = mStartedUsers.get(userId); 19248 if (state == null) { 19249 return false; 19250 } 19251 if (orStopped) { 19252 return true; 19253 } 19254 return state.mState != UserStartedState.STATE_STOPPING 19255 && state.mState != UserStartedState.STATE_SHUTDOWN; 19256 } 19257 19258 @Override 19259 public int[] getRunningUserIds() { 19260 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19261 != PackageManager.PERMISSION_GRANTED) { 19262 String msg = "Permission Denial: isUserRunning() from pid=" 19263 + Binder.getCallingPid() 19264 + ", uid=" + Binder.getCallingUid() 19265 + " requires " + INTERACT_ACROSS_USERS; 19266 Slog.w(TAG, msg); 19267 throw new SecurityException(msg); 19268 } 19269 synchronized (this) { 19270 return mStartedUserArray; 19271 } 19272 } 19273 19274 private void updateStartedUserArrayLocked() { 19275 int num = 0; 19276 for (int i=0; i<mStartedUsers.size(); i++) { 19277 UserStartedState uss = mStartedUsers.valueAt(i); 19278 // This list does not include stopping users. 19279 if (uss.mState != UserStartedState.STATE_STOPPING 19280 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19281 num++; 19282 } 19283 } 19284 mStartedUserArray = new int[num]; 19285 num = 0; 19286 for (int i=0; i<mStartedUsers.size(); i++) { 19287 UserStartedState uss = mStartedUsers.valueAt(i); 19288 if (uss.mState != UserStartedState.STATE_STOPPING 19289 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19290 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19291 num++; 19292 } 19293 } 19294 } 19295 19296 @Override 19297 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19298 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19299 != PackageManager.PERMISSION_GRANTED) { 19300 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19301 + Binder.getCallingPid() 19302 + ", uid=" + Binder.getCallingUid() 19303 + " requires " + INTERACT_ACROSS_USERS_FULL; 19304 Slog.w(TAG, msg); 19305 throw new SecurityException(msg); 19306 } 19307 19308 mUserSwitchObservers.register(observer); 19309 } 19310 19311 @Override 19312 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19313 mUserSwitchObservers.unregister(observer); 19314 } 19315 19316 private boolean userExists(int userId) { 19317 if (userId == 0) { 19318 return true; 19319 } 19320 UserManagerService ums = getUserManagerLocked(); 19321 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19322 } 19323 19324 int[] getUsersLocked() { 19325 UserManagerService ums = getUserManagerLocked(); 19326 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19327 } 19328 19329 UserManagerService getUserManagerLocked() { 19330 if (mUserManager == null) { 19331 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19332 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19333 } 19334 return mUserManager; 19335 } 19336 19337 private int applyUserId(int uid, int userId) { 19338 return UserHandle.getUid(userId, uid); 19339 } 19340 19341 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19342 if (info == null) return null; 19343 ApplicationInfo newInfo = new ApplicationInfo(info); 19344 newInfo.uid = applyUserId(info.uid, userId); 19345 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19346 + info.packageName; 19347 return newInfo; 19348 } 19349 19350 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19351 if (aInfo == null 19352 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19353 return aInfo; 19354 } 19355 19356 ActivityInfo info = new ActivityInfo(aInfo); 19357 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19358 return info; 19359 } 19360 19361 private final class LocalService extends ActivityManagerInternal { 19362 @Override 19363 public void onWakefulnessChanged(int wakefulness) { 19364 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19365 } 19366 19367 @Override 19368 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19369 String processName, String abiOverride, int uid, Runnable crashHandler) { 19370 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19371 processName, abiOverride, uid, crashHandler); 19372 } 19373 } 19374 19375 /** 19376 * An implementation of IAppTask, that allows an app to manage its own tasks via 19377 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19378 * only the process that calls getAppTasks() can call the AppTask methods. 19379 */ 19380 class AppTaskImpl extends IAppTask.Stub { 19381 private int mTaskId; 19382 private int mCallingUid; 19383 19384 public AppTaskImpl(int taskId, int callingUid) { 19385 mTaskId = taskId; 19386 mCallingUid = callingUid; 19387 } 19388 19389 private void checkCaller() { 19390 if (mCallingUid != Binder.getCallingUid()) { 19391 throw new SecurityException("Caller " + mCallingUid 19392 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19393 } 19394 } 19395 19396 @Override 19397 public void finishAndRemoveTask() { 19398 checkCaller(); 19399 19400 synchronized (ActivityManagerService.this) { 19401 long origId = Binder.clearCallingIdentity(); 19402 try { 19403 if (!removeTaskByIdLocked(mTaskId, false)) { 19404 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19405 } 19406 } finally { 19407 Binder.restoreCallingIdentity(origId); 19408 } 19409 } 19410 } 19411 19412 @Override 19413 public ActivityManager.RecentTaskInfo getTaskInfo() { 19414 checkCaller(); 19415 19416 synchronized (ActivityManagerService.this) { 19417 long origId = Binder.clearCallingIdentity(); 19418 try { 19419 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19420 if (tr == null) { 19421 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19422 } 19423 return createRecentTaskInfoFromTaskRecord(tr); 19424 } finally { 19425 Binder.restoreCallingIdentity(origId); 19426 } 19427 } 19428 } 19429 19430 @Override 19431 public void moveToFront() { 19432 checkCaller(); 19433 19434 final TaskRecord tr; 19435 synchronized (ActivityManagerService.this) { 19436 tr = recentTaskForIdLocked(mTaskId); 19437 if (tr == null) { 19438 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19439 } 19440 if (tr.getRootActivity() != null) { 19441 moveTaskToFrontLocked(tr.taskId, 0, null); 19442 return; 19443 } 19444 } 19445 19446 startActivityFromRecentsInner(tr.taskId, null); 19447 } 19448 19449 @Override 19450 public int startActivity(IBinder whoThread, String callingPackage, 19451 Intent intent, String resolvedType, Bundle options) { 19452 checkCaller(); 19453 19454 int callingUser = UserHandle.getCallingUserId(); 19455 TaskRecord tr; 19456 IApplicationThread appThread; 19457 synchronized (ActivityManagerService.this) { 19458 tr = recentTaskForIdLocked(mTaskId); 19459 if (tr == null) { 19460 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19461 } 19462 appThread = ApplicationThreadNative.asInterface(whoThread); 19463 if (appThread == null) { 19464 throw new IllegalArgumentException("Bad app thread " + appThread); 19465 } 19466 } 19467 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19468 resolvedType, null, null, null, null, 0, 0, null, null, 19469 null, options, callingUser, null, tr); 19470 } 19471 19472 @Override 19473 public void setExcludeFromRecents(boolean exclude) { 19474 checkCaller(); 19475 19476 synchronized (ActivityManagerService.this) { 19477 long origId = Binder.clearCallingIdentity(); 19478 try { 19479 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19480 if (tr == null) { 19481 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19482 } 19483 Intent intent = tr.getBaseIntent(); 19484 if (exclude) { 19485 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19486 } else { 19487 intent.setFlags(intent.getFlags() 19488 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19489 } 19490 } finally { 19491 Binder.restoreCallingIdentity(origId); 19492 } 19493 } 19494 } 19495 } 19496} 19497