ActivityManagerService.java revision 299f960e5e5837da44cd81692388f3cbd5d2c362
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35import android.Manifest; 36import android.app.AppOpsManager; 37import android.app.ApplicationThreadNative; 38import android.app.IActivityContainer; 39import android.app.IActivityContainerCallback; 40import android.app.IAppTask; 41import android.app.ITaskStackListener; 42import android.app.ProfilerInfo; 43import android.app.admin.DevicePolicyManager; 44import android.app.usage.UsageEvents; 45import android.app.usage.UsageStatsManagerInternal; 46import android.appwidget.AppWidgetManager; 47import android.content.res.Resources; 48import android.graphics.Bitmap; 49import android.graphics.Point; 50import android.graphics.Rect; 51import android.os.BatteryStats; 52import android.os.PersistableBundle; 53import android.os.storage.IMountService; 54import android.os.storage.StorageManager; 55import android.service.voice.IVoiceInteractionSession; 56import android.util.ArrayMap; 57import android.util.ArraySet; 58import android.util.SparseIntArray; 59 60import com.android.internal.R; 61import com.android.internal.annotations.GuardedBy; 62import com.android.internal.app.IAppOpsService; 63import com.android.internal.app.IVoiceInteractor; 64import com.android.internal.app.ProcessMap; 65import com.android.internal.app.ProcessStats; 66import com.android.internal.os.BackgroundThread; 67import com.android.internal.os.BatteryStatsImpl; 68import com.android.internal.os.ProcessCpuTracker; 69import com.android.internal.os.TransferPipe; 70import com.android.internal.os.Zygote; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.MemInfoReader; 74import com.android.internal.util.Preconditions; 75import com.android.server.AppOpsService; 76import com.android.server.AttributeCache; 77import com.android.server.IntentResolver; 78import com.android.server.LocalServices; 79import com.android.server.ServiceThread; 80import com.android.server.SystemService; 81import com.android.server.SystemServiceManager; 82import com.android.server.Watchdog; 83import com.android.server.am.ActivityStack.ActivityState; 84import com.android.server.firewall.IntentFirewall; 85import com.android.server.pm.Installer; 86import com.android.server.pm.UserManagerService; 87import com.android.server.statusbar.StatusBarManagerInternal; 88import com.android.server.wm.AppTransition; 89import com.android.server.wm.WindowManagerService; 90import com.google.android.collect.Lists; 91import com.google.android.collect.Maps; 92 93import libcore.io.IoUtils; 94 95import org.xmlpull.v1.XmlPullParser; 96import org.xmlpull.v1.XmlPullParserException; 97import org.xmlpull.v1.XmlSerializer; 98 99import android.app.Activity; 100import android.app.ActivityManager; 101import android.app.ActivityManager.RunningTaskInfo; 102import android.app.ActivityManager.StackInfo; 103import android.app.ActivityManagerInternal; 104import android.app.ActivityManagerNative; 105import android.app.ActivityOptions; 106import android.app.ActivityThread; 107import android.app.AlertDialog; 108import android.app.AppGlobals; 109import android.app.ApplicationErrorReport; 110import android.app.Dialog; 111import android.app.IActivityController; 112import android.app.IApplicationThread; 113import android.app.IInstrumentationWatcher; 114import android.app.INotificationManager; 115import android.app.IProcessObserver; 116import android.app.IServiceConnection; 117import android.app.IStopUserCallback; 118import android.app.IUiAutomationConnection; 119import android.app.IUserSwitchObserver; 120import android.app.Instrumentation; 121import android.app.Notification; 122import android.app.NotificationManager; 123import android.app.PendingIntent; 124import android.app.backup.IBackupManager; 125import android.content.ActivityNotFoundException; 126import android.content.BroadcastReceiver; 127import android.content.ClipData; 128import android.content.ComponentCallbacks2; 129import android.content.ComponentName; 130import android.content.ContentProvider; 131import android.content.ContentResolver; 132import android.content.Context; 133import android.content.DialogInterface; 134import android.content.IContentProvider; 135import android.content.IIntentReceiver; 136import android.content.IIntentSender; 137import android.content.Intent; 138import android.content.IntentFilter; 139import android.content.IntentSender; 140import android.content.pm.ActivityInfo; 141import android.content.pm.ApplicationInfo; 142import android.content.pm.ConfigurationInfo; 143import android.content.pm.IPackageDataObserver; 144import android.content.pm.IPackageManager; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.PackageInfo; 147import android.content.pm.PackageManager; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.UserInfo; 150import android.content.pm.PackageManager.NameNotFoundException; 151import android.content.pm.PathPermission; 152import android.content.pm.ProviderInfo; 153import android.content.pm.ResolveInfo; 154import android.content.pm.ServiceInfo; 155import android.content.res.CompatibilityInfo; 156import android.content.res.Configuration; 157import android.net.Proxy; 158import android.net.ProxyInfo; 159import android.net.Uri; 160import android.os.Binder; 161import android.os.Build; 162import android.os.Bundle; 163import android.os.Debug; 164import android.os.DropBoxManager; 165import android.os.Environment; 166import android.os.FactoryTest; 167import android.os.FileObserver; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.IPermissionController; 172import android.os.IRemoteCallback; 173import android.os.IUserManager; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.PowerManagerInternal; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.SELinux; 183import android.os.ServiceManager; 184import android.os.StrictMode; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.UpdateLock; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.provider.Settings; 191import android.text.format.DateUtils; 192import android.text.format.Time; 193import android.util.AtomicFile; 194import android.util.EventLog; 195import android.util.Log; 196import android.util.Pair; 197import android.util.PrintWriterPrinter; 198import android.util.Slog; 199import android.util.SparseArray; 200import android.util.TimeUtils; 201import android.util.Xml; 202import android.view.Gravity; 203import android.view.LayoutInflater; 204import android.view.View; 205import android.view.WindowManager; 206 207import dalvik.system.VMRuntime; 208 209import java.io.BufferedInputStream; 210import java.io.BufferedOutputStream; 211import java.io.DataInputStream; 212import java.io.DataOutputStream; 213import java.io.File; 214import java.io.FileDescriptor; 215import java.io.FileInputStream; 216import java.io.FileNotFoundException; 217import java.io.FileOutputStream; 218import java.io.IOException; 219import java.io.InputStreamReader; 220import java.io.PrintWriter; 221import java.io.StringWriter; 222import java.lang.ref.WeakReference; 223import java.util.ArrayList; 224import java.util.Arrays; 225import java.util.Collections; 226import java.util.Comparator; 227import java.util.HashMap; 228import java.util.HashSet; 229import java.util.Iterator; 230import java.util.List; 231import java.util.Locale; 232import java.util.Map; 233import java.util.Set; 234import java.util.concurrent.atomic.AtomicBoolean; 235import java.util.concurrent.atomic.AtomicLong; 236 237public final class ActivityManagerService extends ActivityManagerNative 238 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 239 240 private static final String USER_DATA_DIR = "/data/user/"; 241 // File that stores last updated system version and called preboot receivers 242 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 243 244 static final String TAG = "ActivityManager"; 245 static final String TAG_MU = "ActivityManagerServiceMU"; 246 static final boolean DEBUG = false; 247 static final boolean localLOGV = DEBUG; 248 static final boolean DEBUG_BACKUP = localLOGV || false; 249 static final boolean DEBUG_BROADCAST = localLOGV || false; 250 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_CLEANUP = localLOGV || false; 253 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 254 static final boolean DEBUG_FOCUS = false; 255 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 256 static final boolean DEBUG_MU = localLOGV || false; 257 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 258 static final boolean DEBUG_LRU = localLOGV || false; 259 static final boolean DEBUG_PAUSE = localLOGV || false; 260 static final boolean DEBUG_POWER = localLOGV || false; 261 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 262 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 263 static final boolean DEBUG_PROCESSES = localLOGV || false; 264 static final boolean DEBUG_PROVIDER = localLOGV || false; 265 static final boolean DEBUG_RESULTS = localLOGV || false; 266 static final boolean DEBUG_SERVICE = localLOGV || false; 267 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 268 static final boolean DEBUG_STACK = localLOGV || false; 269 static final boolean DEBUG_SWITCH = localLOGV || false; 270 static final boolean DEBUG_TASKS = localLOGV || false; 271 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 272 static final boolean DEBUG_TRANSITION = localLOGV || false; 273 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 274 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 275 static final boolean DEBUG_VISBILITY = localLOGV || false; 276 static final boolean DEBUG_PSS = localLOGV || false; 277 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 278 static final boolean DEBUG_RECENTS = localLOGV || false; 279 static final boolean VALIDATE_TOKENS = false; 280 static final boolean SHOW_ACTIVITY_START_TIME = true; 281 282 // Control over CPU and battery monitoring. 283 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 284 static final boolean MONITOR_CPU_USAGE = true; 285 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 286 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 287 static final boolean MONITOR_THREAD_CPU_USAGE = false; 288 289 // The flags that are set for all calls we make to the package manager. 290 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 291 292 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 293 294 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 295 296 // Maximum number recent bitmaps to keep in memory. 297 static final int MAX_RECENT_BITMAPS = 3; 298 299 // Amount of time after a call to stopAppSwitches() during which we will 300 // prevent further untrusted switches from happening. 301 static final long APP_SWITCH_DELAY_TIME = 5*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real. 305 static final int PROC_START_TIMEOUT = 10*1000; 306 307 // How long we wait for a launched process to attach to the activity manager 308 // before we decide it's never going to come up for real, when the process was 309 // started with a wrapper for instrumentation (such as Valgrind) because it 310 // could take much longer than usual. 311 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 312 313 // How long to wait after going idle before forcing apps to GC. 314 static final int GC_TIMEOUT = 5*1000; 315 316 // The minimum amount of time between successive GC requests for a process. 317 static final int GC_MIN_INTERVAL = 60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process. 320 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 321 322 // The minimum amount of time between successive PSS requests for a process 323 // when the request is due to the memory state being lowered. 324 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 325 326 // The rate at which we check for apps using excessive power -- 15 mins. 327 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on wake locks to start killing things. 331 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // The minimum sample duration we will allow before deciding we have 334 // enough data on CPU usage to start killing things. 335 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 336 337 // How long we allow a receiver to run before giving up on it. 338 static final int BROADCAST_FG_TIMEOUT = 10*1000; 339 static final int BROADCAST_BG_TIMEOUT = 60*1000; 340 341 // How long we wait until we timeout on key dispatching. 342 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 343 344 // How long we wait until we timeout on key dispatching during instrumentation. 345 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 346 347 // Amount of time we wait for observers to handle a user switch before 348 // giving up on them and unfreezing the screen. 349 static final int USER_SWITCH_TIMEOUT = 2*1000; 350 351 // Maximum number of users we allow to be running at a time. 352 static final int MAX_RUNNING_USERS = 3; 353 354 // How long to wait in getAssistContextExtras for the activity and foreground services 355 // to respond with the result. 356 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 357 358 // Maximum number of persisted Uri grants a package is allowed 359 static final int MAX_PERSISTED_URI_GRANTS = 128; 360 361 static final int MY_PID = Process.myPid(); 362 363 static final String[] EMPTY_STRING_ARRAY = new String[0]; 364 365 // How many bytes to write into the dropbox log before truncating 366 static final int DROPBOX_MAX_SIZE = 256 * 1024; 367 368 // Access modes for handleIncomingUser. 369 static final int ALLOW_NON_FULL = 0; 370 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 371 static final int ALLOW_FULL_ONLY = 2; 372 373 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 374 375 // Delay in notifying task stack change listeners (in millis) 376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 377 378 /** All system services */ 379 SystemServiceManager mSystemServiceManager; 380 381 private Installer mInstaller; 382 383 /** Run all ActivityStacks through this */ 384 ActivityStackSupervisor mStackSupervisor; 385 386 /** Task stack change listeners. */ 387 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 388 new RemoteCallbackList<ITaskStackListener>(); 389 390 public IntentFirewall mIntentFirewall; 391 392 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 393 // default actuion automatically. Important for devices without direct input 394 // devices. 395 private boolean mShowDialogs = true; 396 397 BroadcastQueue mFgBroadcastQueue; 398 BroadcastQueue mBgBroadcastQueue; 399 // Convenient for easy iteration over the queues. Foreground is first 400 // so that dispatch of foreground broadcasts gets precedence. 401 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 402 403 BroadcastQueue broadcastQueueForIntent(Intent intent) { 404 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 405 if (DEBUG_BACKGROUND_BROADCAST) { 406 Slog.i(TAG, "Broadcast intent " + intent + " on " 407 + (isFg ? "foreground" : "background") 408 + " queue"); 409 } 410 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 411 } 412 413 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 414 for (BroadcastQueue queue : mBroadcastQueues) { 415 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 416 if (r != null) { 417 return r; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Activity we have told the window manager to have key focus. 425 */ 426 ActivityRecord mFocusedActivity = null; 427 428 /** 429 * List of intents that were used to start the most recent tasks. 430 */ 431 ArrayList<TaskRecord> mRecentTasks; 432 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 433 434 /** 435 * For addAppTask: cached of the last activity component that was added. 436 */ 437 ComponentName mLastAddedTaskComponent; 438 439 /** 440 * For addAppTask: cached of the last activity uid that was added. 441 */ 442 int mLastAddedTaskUid; 443 444 /** 445 * For addAppTask: cached of the last ActivityInfo that was added. 446 */ 447 ActivityInfo mLastAddedTaskActivity; 448 449 public class PendingAssistExtras extends Binder implements Runnable { 450 public final ActivityRecord activity; 451 public final Bundle extras; 452 public final Intent intent; 453 public final String hint; 454 public final int userHandle; 455 public boolean haveResult = false; 456 public Bundle result = null; 457 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 458 String _hint, int _userHandle) { 459 activity = _activity; 460 extras = _extras; 461 intent = _intent; 462 hint = _hint; 463 userHandle = _userHandle; 464 } 465 @Override 466 public void run() { 467 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 468 synchronized (this) { 469 haveResult = true; 470 notifyAll(); 471 } 472 } 473 } 474 475 final ArrayList<PendingAssistExtras> mPendingAssistExtras 476 = new ArrayList<PendingAssistExtras>(); 477 478 /** 479 * Process management. 480 */ 481 final ProcessList mProcessList = new ProcessList(); 482 483 /** 484 * All of the applications we currently have running organized by name. 485 * The keys are strings of the application package name (as 486 * returned by the package manager), and the keys are ApplicationRecord 487 * objects. 488 */ 489 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 490 491 /** 492 * Tracking long-term execution of processes to look for abuse and other 493 * bad app behavior. 494 */ 495 final ProcessStatsService mProcessStats; 496 497 /** 498 * The currently running isolated processes. 499 */ 500 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 501 502 /** 503 * Counter for assigning isolated process uids, to avoid frequently reusing the 504 * same ones. 505 */ 506 int mNextIsolatedProcessUid = 0; 507 508 /** 509 * The currently running heavy-weight process, if any. 510 */ 511 ProcessRecord mHeavyWeightProcess = null; 512 513 /** 514 * The last time that various processes have crashed. 515 */ 516 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 517 518 /** 519 * Information about a process that is currently marked as bad. 520 */ 521 static final class BadProcessInfo { 522 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 523 this.time = time; 524 this.shortMsg = shortMsg; 525 this.longMsg = longMsg; 526 this.stack = stack; 527 } 528 529 final long time; 530 final String shortMsg; 531 final String longMsg; 532 final String stack; 533 } 534 535 /** 536 * Set of applications that we consider to be bad, and will reject 537 * incoming broadcasts from (which the user has no control over). 538 * Processes are added to this set when they have crashed twice within 539 * a minimum amount of time; they are removed from it when they are 540 * later restarted (hopefully due to some user action). The value is the 541 * time it was added to the list. 542 */ 543 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 544 545 /** 546 * All of the processes we currently have running organized by pid. 547 * The keys are the pid running the application. 548 * 549 * <p>NOTE: This object is protected by its own lock, NOT the global 550 * activity manager lock! 551 */ 552 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 553 554 /** 555 * All of the processes that have been forced to be foreground. The key 556 * is the pid of the caller who requested it (we hold a death 557 * link on it). 558 */ 559 abstract class ForegroundToken implements IBinder.DeathRecipient { 560 int pid; 561 IBinder token; 562 } 563 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 564 565 /** 566 * List of records for processes that someone had tried to start before the 567 * system was ready. We don't start them at that point, but ensure they 568 * are started by the time booting is complete. 569 */ 570 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of persistent applications that are in the process 574 * of being started. 575 */ 576 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes that are being forcibly torn down. 580 */ 581 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * List of running applications, sorted by recent usage. 585 * The first entry in the list is the least recently used. 586 */ 587 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Where in mLruProcesses that the processes hosting activities start. 591 */ 592 int mLruProcessActivityStart = 0; 593 594 /** 595 * Where in mLruProcesses that the processes hosting services start. 596 * This is after (lower index) than mLruProcessesActivityStart. 597 */ 598 int mLruProcessServiceStart = 0; 599 600 /** 601 * List of processes that should gc as soon as things are idle. 602 */ 603 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 604 605 /** 606 * Processes we want to collect PSS data from. 607 */ 608 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 609 610 /** 611 * Last time we requested PSS data of all processes. 612 */ 613 long mLastFullPssTime = SystemClock.uptimeMillis(); 614 615 /** 616 * If set, the next time we collect PSS data we should do a full collection 617 * with data from native processes and the kernel. 618 */ 619 boolean mFullPssPending = false; 620 621 /** 622 * This is the process holding what we currently consider to be 623 * the "home" activity. 624 */ 625 ProcessRecord mHomeProcess; 626 627 /** 628 * This is the process holding the activity the user last visited that 629 * is in a different process from the one they are currently in. 630 */ 631 ProcessRecord mPreviousProcess; 632 633 /** 634 * The time at which the previous process was last visible. 635 */ 636 long mPreviousProcessVisibleTime; 637 638 /** 639 * Which uses have been started, so are allowed to run code. 640 */ 641 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 642 643 /** 644 * LRU list of history of current users. Most recently current is at the end. 645 */ 646 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 647 648 /** 649 * Constant array of the users that are currently started. 650 */ 651 int[] mStartedUserArray = new int[] { 0 }; 652 653 /** 654 * Registered observers of the user switching mechanics. 655 */ 656 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 657 = new RemoteCallbackList<IUserSwitchObserver>(); 658 659 /** 660 * Currently active user switch. 661 */ 662 Object mCurUserSwitchCallback; 663 664 /** 665 * Packages that the user has asked to have run in screen size 666 * compatibility mode instead of filling the screen. 667 */ 668 final CompatModePackages mCompatModePackages; 669 670 /** 671 * Set of IntentSenderRecord objects that are currently active. 672 */ 673 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 674 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 675 676 /** 677 * Fingerprints (hashCode()) of stack traces that we've 678 * already logged DropBox entries for. Guarded by itself. If 679 * something (rogue user app) forces this over 680 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 681 */ 682 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 683 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 684 685 /** 686 * Strict Mode background batched logging state. 687 * 688 * The string buffer is guarded by itself, and its lock is also 689 * used to determine if another batched write is already 690 * in-flight. 691 */ 692 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 693 694 /** 695 * Keeps track of all IIntentReceivers that have been registered for 696 * broadcasts. Hash keys are the receiver IBinder, hash value is 697 * a ReceiverList. 698 */ 699 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 700 new HashMap<IBinder, ReceiverList>(); 701 702 /** 703 * Resolver for broadcast intents to registered receivers. 704 * Holds BroadcastFilter (subclass of IntentFilter). 705 */ 706 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 707 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 708 @Override 709 protected boolean allowFilterResult( 710 BroadcastFilter filter, List<BroadcastFilter> dest) { 711 IBinder target = filter.receiverList.receiver.asBinder(); 712 for (int i=dest.size()-1; i>=0; i--) { 713 if (dest.get(i).receiverList.receiver.asBinder() == target) { 714 return false; 715 } 716 } 717 return true; 718 } 719 720 @Override 721 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 722 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 723 || userId == filter.owningUserId) { 724 return super.newResult(filter, match, userId); 725 } 726 return null; 727 } 728 729 @Override 730 protected BroadcastFilter[] newArray(int size) { 731 return new BroadcastFilter[size]; 732 } 733 734 @Override 735 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 736 return packageName.equals(filter.packageName); 737 } 738 }; 739 740 /** 741 * State of all active sticky broadcasts per user. Keys are the action of the 742 * sticky Intent, values are an ArrayList of all broadcasted intents with 743 * that action (which should usually be one). The SparseArray is keyed 744 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 745 * for stickies that are sent to all users. 746 */ 747 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 748 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 749 750 final ActiveServices mServices; 751 752 final static class Association { 753 final int mSourceUid; 754 final String mSourceProcess; 755 final int mTargetUid; 756 final ComponentName mTargetComponent; 757 final String mTargetProcess; 758 759 int mCount; 760 long mTime; 761 762 int mNesting; 763 long mStartTime; 764 765 Association(int sourceUid, String sourceProcess, int targetUid, 766 ComponentName targetComponent, String targetProcess) { 767 mSourceUid = sourceUid; 768 mSourceProcess = sourceProcess; 769 mTargetUid = targetUid; 770 mTargetComponent = targetComponent; 771 mTargetProcess = targetProcess; 772 } 773 } 774 775 /** 776 * When service association tracking is enabled, this is all of the associations we 777 * have seen. Mapping is target uid -> target component -> source uid -> source process name 778 * -> association data. 779 */ 780 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 781 mAssociations = new SparseArray<>(); 782 boolean mTrackingAssociations; 783 784 /** 785 * Backup/restore process management 786 */ 787 String mBackupAppName = null; 788 BackupRecord mBackupTarget = null; 789 790 final ProviderMap mProviderMap; 791 792 /** 793 * List of content providers who have clients waiting for them. The 794 * application is currently being launched and the provider will be 795 * removed from this list once it is published. 796 */ 797 final ArrayList<ContentProviderRecord> mLaunchingProviders 798 = new ArrayList<ContentProviderRecord>(); 799 800 /** 801 * File storing persisted {@link #mGrantedUriPermissions}. 802 */ 803 private final AtomicFile mGrantFile; 804 805 /** XML constants used in {@link #mGrantFile} */ 806 private static final String TAG_URI_GRANTS = "uri-grants"; 807 private static final String TAG_URI_GRANT = "uri-grant"; 808 private static final String ATTR_USER_HANDLE = "userHandle"; 809 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 810 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 811 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 812 private static final String ATTR_TARGET_PKG = "targetPkg"; 813 private static final String ATTR_URI = "uri"; 814 private static final String ATTR_MODE_FLAGS = "modeFlags"; 815 private static final String ATTR_CREATED_TIME = "createdTime"; 816 private static final String ATTR_PREFIX = "prefix"; 817 818 /** 819 * Global set of specific {@link Uri} permissions that have been granted. 820 * This optimized lookup structure maps from {@link UriPermission#targetUid} 821 * to {@link UriPermission#uri} to {@link UriPermission}. 822 */ 823 @GuardedBy("this") 824 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 825 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 826 827 public static class GrantUri { 828 public final int sourceUserId; 829 public final Uri uri; 830 public boolean prefix; 831 832 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 833 this.sourceUserId = sourceUserId; 834 this.uri = uri; 835 this.prefix = prefix; 836 } 837 838 @Override 839 public int hashCode() { 840 int hashCode = 1; 841 hashCode = 31 * hashCode + sourceUserId; 842 hashCode = 31 * hashCode + uri.hashCode(); 843 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 844 return hashCode; 845 } 846 847 @Override 848 public boolean equals(Object o) { 849 if (o instanceof GrantUri) { 850 GrantUri other = (GrantUri) o; 851 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 852 && prefix == other.prefix; 853 } 854 return false; 855 } 856 857 @Override 858 public String toString() { 859 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 860 if (prefix) result += " [prefix]"; 861 return result; 862 } 863 864 public String toSafeString() { 865 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 866 if (prefix) result += " [prefix]"; 867 return result; 868 } 869 870 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 871 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 872 ContentProvider.getUriWithoutUserId(uri), false); 873 } 874 } 875 876 CoreSettingsObserver mCoreSettingsObserver; 877 878 /** 879 * Thread-local storage used to carry caller permissions over through 880 * indirect content-provider access. 881 */ 882 private class Identity { 883 public final IBinder token; 884 public final int pid; 885 public final int uid; 886 887 Identity(IBinder _token, int _pid, int _uid) { 888 token = _token; 889 pid = _pid; 890 uid = _uid; 891 } 892 } 893 894 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 895 896 /** 897 * All information we have collected about the runtime performance of 898 * any user id that can impact battery performance. 899 */ 900 final BatteryStatsService mBatteryStatsService; 901 902 /** 903 * Information about component usage 904 */ 905 UsageStatsManagerInternal mUsageStatsService; 906 907 /** 908 * Information about and control over application operations 909 */ 910 final AppOpsService mAppOpsService; 911 912 /** 913 * Save recent tasks information across reboots. 914 */ 915 final TaskPersister mTaskPersister; 916 917 /** 918 * Current configuration information. HistoryRecord objects are given 919 * a reference to this object to indicate which configuration they are 920 * currently running in, so this object must be kept immutable. 921 */ 922 Configuration mConfiguration = new Configuration(); 923 924 /** 925 * Current sequencing integer of the configuration, for skipping old 926 * configurations. 927 */ 928 int mConfigurationSeq = 0; 929 930 /** 931 * Hardware-reported OpenGLES version. 932 */ 933 final int GL_ES_VERSION; 934 935 /** 936 * List of initialization arguments to pass to all processes when binding applications to them. 937 * For example, references to the commonly used services. 938 */ 939 HashMap<String, IBinder> mAppBindArgs; 940 941 /** 942 * Temporary to avoid allocations. Protected by main lock. 943 */ 944 final StringBuilder mStringBuilder = new StringBuilder(256); 945 946 /** 947 * Used to control how we initialize the service. 948 */ 949 ComponentName mTopComponent; 950 String mTopAction = Intent.ACTION_MAIN; 951 String mTopData; 952 boolean mProcessesReady = false; 953 boolean mSystemReady = false; 954 boolean mBooting = false; 955 boolean mCallFinishBooting = false; 956 boolean mBootAnimationComplete = false; 957 boolean mWaitingUpdate = false; 958 boolean mDidUpdate = false; 959 boolean mOnBattery = false; 960 boolean mLaunchWarningShown = false; 961 962 Context mContext; 963 964 int mFactoryTest; 965 966 boolean mCheckedForSetup; 967 968 /** 969 * The time at which we will allow normal application switches again, 970 * after a call to {@link #stopAppSwitches()}. 971 */ 972 long mAppSwitchesAllowedTime; 973 974 /** 975 * This is set to true after the first switch after mAppSwitchesAllowedTime 976 * is set; any switches after that will clear the time. 977 */ 978 boolean mDidAppSwitch; 979 980 /** 981 * Last time (in realtime) at which we checked for power usage. 982 */ 983 long mLastPowerCheckRealtime; 984 985 /** 986 * Last time (in uptime) at which we checked for power usage. 987 */ 988 long mLastPowerCheckUptime; 989 990 /** 991 * Set while we are wanting to sleep, to prevent any 992 * activities from being started/resumed. 993 */ 994 private boolean mSleeping = false; 995 996 /** 997 * Set while we are running a voice interaction. This overrides 998 * sleeping while it is active. 999 */ 1000 private boolean mRunningVoice = false; 1001 1002 /** 1003 * State of external calls telling us if the device is awake or asleep. 1004 */ 1005 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 1006 1007 static final int LOCK_SCREEN_HIDDEN = 0; 1008 static final int LOCK_SCREEN_LEAVING = 1; 1009 static final int LOCK_SCREEN_SHOWN = 2; 1010 /** 1011 * State of external call telling us if the lock screen is shown. 1012 */ 1013 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 1014 1015 /** 1016 * Set if we are shutting down the system, similar to sleeping. 1017 */ 1018 boolean mShuttingDown = false; 1019 1020 /** 1021 * Current sequence id for oom_adj computation traversal. 1022 */ 1023 int mAdjSeq = 0; 1024 1025 /** 1026 * Current sequence id for process LRU updating. 1027 */ 1028 int mLruSeq = 0; 1029 1030 /** 1031 * Keep track of the non-cached/empty process we last found, to help 1032 * determine how to distribute cached/empty processes next time. 1033 */ 1034 int mNumNonCachedProcs = 0; 1035 1036 /** 1037 * Keep track of the number of cached hidden procs, to balance oom adj 1038 * distribution between those and empty procs. 1039 */ 1040 int mNumCachedHiddenProcs = 0; 1041 1042 /** 1043 * Keep track of the number of service processes we last found, to 1044 * determine on the next iteration which should be B services. 1045 */ 1046 int mNumServiceProcs = 0; 1047 int mNewNumAServiceProcs = 0; 1048 int mNewNumServiceProcs = 0; 1049 1050 /** 1051 * Allow the current computed overall memory level of the system to go down? 1052 * This is set to false when we are killing processes for reasons other than 1053 * memory management, so that the now smaller process list will not be taken as 1054 * an indication that memory is tighter. 1055 */ 1056 boolean mAllowLowerMemLevel = false; 1057 1058 /** 1059 * The last computed memory level, for holding when we are in a state that 1060 * processes are going away for other reasons. 1061 */ 1062 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1063 1064 /** 1065 * The last total number of process we have, to determine if changes actually look 1066 * like a shrinking number of process due to lower RAM. 1067 */ 1068 int mLastNumProcesses; 1069 1070 /** 1071 * The uptime of the last time we performed idle maintenance. 1072 */ 1073 long mLastIdleTime = SystemClock.uptimeMillis(); 1074 1075 /** 1076 * Total time spent with RAM that has been added in the past since the last idle time. 1077 */ 1078 long mLowRamTimeSinceLastIdle = 0; 1079 1080 /** 1081 * If RAM is currently low, when that horrible situation started. 1082 */ 1083 long mLowRamStartTime = 0; 1084 1085 /** 1086 * For reporting to battery stats the current top application. 1087 */ 1088 private String mCurResumedPackage = null; 1089 private int mCurResumedUid = -1; 1090 1091 /** 1092 * For reporting to battery stats the apps currently running foreground 1093 * service. The ProcessMap is package/uid tuples; each of these contain 1094 * an array of the currently foreground processes. 1095 */ 1096 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1097 = new ProcessMap<ArrayList<ProcessRecord>>(); 1098 1099 /** 1100 * This is set if we had to do a delayed dexopt of an app before launching 1101 * it, to increase the ANR timeouts in that case. 1102 */ 1103 boolean mDidDexOpt; 1104 1105 /** 1106 * Set if the systemServer made a call to enterSafeMode. 1107 */ 1108 boolean mSafeMode; 1109 1110 /** 1111 * If true, we are running under a test environment so will sample PSS from processes 1112 * much more rapidly to try to collect better data when the tests are rapidly 1113 * running through apps. 1114 */ 1115 boolean mTestPssMode = false; 1116 1117 String mDebugApp = null; 1118 boolean mWaitForDebugger = false; 1119 boolean mDebugTransient = false; 1120 String mOrigDebugApp = null; 1121 boolean mOrigWaitForDebugger = false; 1122 boolean mAlwaysFinishActivities = false; 1123 IActivityController mController = null; 1124 String mProfileApp = null; 1125 ProcessRecord mProfileProc = null; 1126 String mProfileFile; 1127 ParcelFileDescriptor mProfileFd; 1128 int mSamplingInterval = 0; 1129 boolean mAutoStopProfiler = false; 1130 int mProfileType = 0; 1131 String mOpenGlTraceApp = null; 1132 1133 final long[] mTmpLong = new long[1]; 1134 1135 static class ProcessChangeItem { 1136 static final int CHANGE_ACTIVITIES = 1<<0; 1137 static final int CHANGE_PROCESS_STATE = 1<<1; 1138 int changes; 1139 int uid; 1140 int pid; 1141 int processState; 1142 boolean foregroundActivities; 1143 } 1144 1145 final RemoteCallbackList<IProcessObserver> mProcessObservers 1146 = new RemoteCallbackList<IProcessObserver>(); 1147 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1148 1149 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1150 = new ArrayList<ProcessChangeItem>(); 1151 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1152 = new ArrayList<ProcessChangeItem>(); 1153 1154 /** 1155 * Runtime CPU use collection thread. This object's lock is used to 1156 * perform synchronization with the thread (notifying it to run). 1157 */ 1158 final Thread mProcessCpuThread; 1159 1160 /** 1161 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1162 * Must acquire this object's lock when accessing it. 1163 * NOTE: this lock will be held while doing long operations (trawling 1164 * through all processes in /proc), so it should never be acquired by 1165 * any critical paths such as when holding the main activity manager lock. 1166 */ 1167 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1168 MONITOR_THREAD_CPU_USAGE); 1169 final AtomicLong mLastCpuTime = new AtomicLong(0); 1170 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1171 1172 long mLastWriteTime = 0; 1173 1174 /** 1175 * Used to retain an update lock when the foreground activity is in 1176 * immersive mode. 1177 */ 1178 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1179 1180 /** 1181 * Set to true after the system has finished booting. 1182 */ 1183 boolean mBooted = false; 1184 1185 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1186 int mProcessLimitOverride = -1; 1187 1188 WindowManagerService mWindowManager; 1189 1190 final ActivityThread mSystemThread; 1191 1192 // Holds the current foreground user's id 1193 int mCurrentUserId = 0; 1194 // Holds the target user's id during a user switch 1195 int mTargetUserId = UserHandle.USER_NULL; 1196 // If there are multiple profiles for the current user, their ids are here 1197 // Currently only the primary user can have managed profiles 1198 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1199 1200 /** 1201 * Mapping from each known user ID to the profile group ID it is associated with. 1202 */ 1203 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1204 1205 private UserManagerService mUserManager; 1206 1207 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1208 final ProcessRecord mApp; 1209 final int mPid; 1210 final IApplicationThread mAppThread; 1211 1212 AppDeathRecipient(ProcessRecord app, int pid, 1213 IApplicationThread thread) { 1214 if (localLOGV) Slog.v( 1215 TAG, "New death recipient " + this 1216 + " for thread " + thread.asBinder()); 1217 mApp = app; 1218 mPid = pid; 1219 mAppThread = thread; 1220 } 1221 1222 @Override 1223 public void binderDied() { 1224 if (localLOGV) Slog.v( 1225 TAG, "Death received in " + this 1226 + " for thread " + mAppThread.asBinder()); 1227 synchronized(ActivityManagerService.this) { 1228 appDiedLocked(mApp, mPid, mAppThread); 1229 } 1230 } 1231 } 1232 1233 static final int SHOW_ERROR_MSG = 1; 1234 static final int SHOW_NOT_RESPONDING_MSG = 2; 1235 static final int SHOW_FACTORY_ERROR_MSG = 3; 1236 static final int UPDATE_CONFIGURATION_MSG = 4; 1237 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1238 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1239 static final int SERVICE_TIMEOUT_MSG = 12; 1240 static final int UPDATE_TIME_ZONE = 13; 1241 static final int SHOW_UID_ERROR_MSG = 14; 1242 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1243 static final int PROC_START_TIMEOUT_MSG = 20; 1244 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1245 static final int KILL_APPLICATION_MSG = 22; 1246 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1247 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1248 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1249 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1250 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1251 static final int CLEAR_DNS_CACHE_MSG = 28; 1252 static final int UPDATE_HTTP_PROXY_MSG = 29; 1253 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1254 static final int DISPATCH_PROCESSES_CHANGED = 31; 1255 static final int DISPATCH_PROCESS_DIED = 32; 1256 static final int REPORT_MEM_USAGE_MSG = 33; 1257 static final int REPORT_USER_SWITCH_MSG = 34; 1258 static final int CONTINUE_USER_SWITCH_MSG = 35; 1259 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1260 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1261 static final int PERSIST_URI_GRANTS_MSG = 38; 1262 static final int REQUEST_ALL_PSS_MSG = 39; 1263 static final int START_PROFILES_MSG = 40; 1264 static final int UPDATE_TIME = 41; 1265 static final int SYSTEM_USER_START_MSG = 42; 1266 static final int SYSTEM_USER_CURRENT_MSG = 43; 1267 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1268 static final int FINISH_BOOTING_MSG = 45; 1269 static final int START_USER_SWITCH_MSG = 46; 1270 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1271 static final int DISMISS_DIALOG_MSG = 48; 1272 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1273 1274 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1275 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1276 static final int FIRST_COMPAT_MODE_MSG = 300; 1277 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1278 1279 CompatModeDialog mCompatModeDialog; 1280 long mLastMemUsageReportTime = 0; 1281 1282 /** 1283 * Flag whether the current user is a "monkey", i.e. whether 1284 * the UI is driven by a UI automation tool. 1285 */ 1286 private boolean mUserIsMonkey; 1287 1288 /** Flag whether the device has a Recents UI */ 1289 boolean mHasRecents; 1290 1291 /** The dimensions of the thumbnails in the Recents UI. */ 1292 int mThumbnailWidth; 1293 int mThumbnailHeight; 1294 1295 final ServiceThread mHandlerThread; 1296 final MainHandler mHandler; 1297 1298 final class MainHandler extends Handler { 1299 public MainHandler(Looper looper) { 1300 super(looper, null, true); 1301 } 1302 1303 @Override 1304 public void handleMessage(Message msg) { 1305 switch (msg.what) { 1306 case SHOW_ERROR_MSG: { 1307 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1308 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1309 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1310 synchronized (ActivityManagerService.this) { 1311 ProcessRecord proc = (ProcessRecord)data.get("app"); 1312 AppErrorResult res = (AppErrorResult) data.get("result"); 1313 if (proc != null && proc.crashDialog != null) { 1314 Slog.e(TAG, "App already has crash dialog: " + proc); 1315 if (res != null) { 1316 res.set(0); 1317 } 1318 return; 1319 } 1320 boolean isBackground = (UserHandle.getAppId(proc.uid) 1321 >= Process.FIRST_APPLICATION_UID 1322 && proc.pid != MY_PID); 1323 for (int userId : mCurrentProfileIds) { 1324 isBackground &= (proc.userId != userId); 1325 } 1326 if (isBackground && !showBackground) { 1327 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1328 if (res != null) { 1329 res.set(0); 1330 } 1331 return; 1332 } 1333 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1334 Dialog d = new AppErrorDialog(mContext, 1335 ActivityManagerService.this, res, proc); 1336 d.show(); 1337 proc.crashDialog = d; 1338 } else { 1339 // The device is asleep, so just pretend that the user 1340 // saw a crash dialog and hit "force quit". 1341 if (res != null) { 1342 res.set(0); 1343 } 1344 } 1345 } 1346 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_NOT_RESPONDING_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1352 ProcessRecord proc = (ProcessRecord)data.get("app"); 1353 if (proc != null && proc.anrDialog != null) { 1354 Slog.e(TAG, "App already has anr dialog: " + proc); 1355 return; 1356 } 1357 1358 Intent intent = new Intent("android.intent.action.ANR"); 1359 if (!mProcessesReady) { 1360 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1361 | Intent.FLAG_RECEIVER_FOREGROUND); 1362 } 1363 broadcastIntentLocked(null, null, intent, 1364 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1365 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1366 1367 if (mShowDialogs) { 1368 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1369 mContext, proc, (ActivityRecord)data.get("activity"), 1370 msg.arg1 != 0); 1371 d.show(); 1372 proc.anrDialog = d; 1373 } else { 1374 // Just kill the app if there is no dialog to be shown. 1375 killAppAtUsersRequest(proc, null); 1376 } 1377 } 1378 1379 ensureBootCompleted(); 1380 } break; 1381 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1382 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1383 synchronized (ActivityManagerService.this) { 1384 ProcessRecord proc = (ProcessRecord) data.get("app"); 1385 if (proc == null) { 1386 Slog.e(TAG, "App not found when showing strict mode dialog."); 1387 break; 1388 } 1389 if (proc.crashDialog != null) { 1390 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1391 return; 1392 } 1393 AppErrorResult res = (AppErrorResult) data.get("result"); 1394 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1395 Dialog d = new StrictModeViolationDialog(mContext, 1396 ActivityManagerService.this, res, proc); 1397 d.show(); 1398 proc.crashDialog = d; 1399 } else { 1400 // The device is asleep, so just pretend that the user 1401 // saw a crash dialog and hit "force quit". 1402 res.set(0); 1403 } 1404 } 1405 ensureBootCompleted(); 1406 } break; 1407 case SHOW_FACTORY_ERROR_MSG: { 1408 Dialog d = new FactoryErrorDialog( 1409 mContext, msg.getData().getCharSequence("msg")); 1410 d.show(); 1411 ensureBootCompleted(); 1412 } break; 1413 case UPDATE_CONFIGURATION_MSG: { 1414 final ContentResolver resolver = mContext.getContentResolver(); 1415 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1416 } break; 1417 case GC_BACKGROUND_PROCESSES_MSG: { 1418 synchronized (ActivityManagerService.this) { 1419 performAppGcsIfAppropriateLocked(); 1420 } 1421 } break; 1422 case WAIT_FOR_DEBUGGER_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 ProcessRecord app = (ProcessRecord)msg.obj; 1425 if (msg.arg1 != 0) { 1426 if (!app.waitedForDebugger) { 1427 Dialog d = new AppWaitingForDebuggerDialog( 1428 ActivityManagerService.this, 1429 mContext, app); 1430 app.waitDialog = d; 1431 app.waitedForDebugger = true; 1432 d.show(); 1433 } 1434 } else { 1435 if (app.waitDialog != null) { 1436 app.waitDialog.dismiss(); 1437 app.waitDialog = null; 1438 } 1439 } 1440 } 1441 } break; 1442 case SERVICE_TIMEOUT_MSG: { 1443 if (mDidDexOpt) { 1444 mDidDexOpt = false; 1445 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1446 nmsg.obj = msg.obj; 1447 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1448 return; 1449 } 1450 mServices.serviceTimeout((ProcessRecord)msg.obj); 1451 } break; 1452 case UPDATE_TIME_ZONE: { 1453 synchronized (ActivityManagerService.this) { 1454 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1455 ProcessRecord r = mLruProcesses.get(i); 1456 if (r.thread != null) { 1457 try { 1458 r.thread.updateTimeZone(); 1459 } catch (RemoteException ex) { 1460 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1461 } 1462 } 1463 } 1464 } 1465 } break; 1466 case CLEAR_DNS_CACHE_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1469 ProcessRecord r = mLruProcesses.get(i); 1470 if (r.thread != null) { 1471 try { 1472 r.thread.clearDnsCache(); 1473 } catch (RemoteException ex) { 1474 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1475 } 1476 } 1477 } 1478 } 1479 } break; 1480 case UPDATE_HTTP_PROXY_MSG: { 1481 ProxyInfo proxy = (ProxyInfo)msg.obj; 1482 String host = ""; 1483 String port = ""; 1484 String exclList = ""; 1485 Uri pacFileUrl = Uri.EMPTY; 1486 if (proxy != null) { 1487 host = proxy.getHost(); 1488 port = Integer.toString(proxy.getPort()); 1489 exclList = proxy.getExclusionListAsString(); 1490 pacFileUrl = proxy.getPacFileUrl(); 1491 } 1492 synchronized (ActivityManagerService.this) { 1493 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1494 ProcessRecord r = mLruProcesses.get(i); 1495 if (r.thread != null) { 1496 try { 1497 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1498 } catch (RemoteException ex) { 1499 Slog.w(TAG, "Failed to update http proxy for: " + 1500 r.info.processName); 1501 } 1502 } 1503 } 1504 } 1505 } break; 1506 case SHOW_UID_ERROR_MSG: { 1507 if (mShowDialogs) { 1508 AlertDialog d = new BaseErrorDialog(mContext); 1509 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1510 d.setCancelable(false); 1511 d.setTitle(mContext.getText(R.string.android_system_label)); 1512 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1513 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1514 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1515 d.show(); 1516 } 1517 } break; 1518 case SHOW_FINGERPRINT_ERROR_MSG: { 1519 if (mShowDialogs) { 1520 AlertDialog d = new BaseErrorDialog(mContext); 1521 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1522 d.setCancelable(false); 1523 d.setTitle(mContext.getText(R.string.android_system_label)); 1524 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1525 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1526 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1527 d.show(); 1528 } 1529 } break; 1530 case PROC_START_TIMEOUT_MSG: { 1531 if (mDidDexOpt) { 1532 mDidDexOpt = false; 1533 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1534 nmsg.obj = msg.obj; 1535 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1536 return; 1537 } 1538 ProcessRecord app = (ProcessRecord)msg.obj; 1539 synchronized (ActivityManagerService.this) { 1540 processStartTimedOutLocked(app); 1541 } 1542 } break; 1543 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1544 synchronized (ActivityManagerService.this) { 1545 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1546 } 1547 } break; 1548 case KILL_APPLICATION_MSG: { 1549 synchronized (ActivityManagerService.this) { 1550 int appid = msg.arg1; 1551 boolean restart = (msg.arg2 == 1); 1552 Bundle bundle = (Bundle)msg.obj; 1553 String pkg = bundle.getString("pkg"); 1554 String reason = bundle.getString("reason"); 1555 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1556 false, UserHandle.USER_ALL, reason); 1557 } 1558 } break; 1559 case FINALIZE_PENDING_INTENT_MSG: { 1560 ((PendingIntentRecord)msg.obj).completeFinalize(); 1561 } break; 1562 case POST_HEAVY_NOTIFICATION_MSG: { 1563 INotificationManager inm = NotificationManager.getService(); 1564 if (inm == null) { 1565 return; 1566 } 1567 1568 ActivityRecord root = (ActivityRecord)msg.obj; 1569 ProcessRecord process = root.app; 1570 if (process == null) { 1571 return; 1572 } 1573 1574 try { 1575 Context context = mContext.createPackageContext(process.info.packageName, 0); 1576 String text = mContext.getString(R.string.heavy_weight_notification, 1577 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1578 Notification notification = new Notification(); 1579 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1580 notification.when = 0; 1581 notification.flags = Notification.FLAG_ONGOING_EVENT; 1582 notification.tickerText = text; 1583 notification.defaults = 0; // please be quiet 1584 notification.sound = null; 1585 notification.vibrate = null; 1586 notification.color = mContext.getResources().getColor( 1587 com.android.internal.R.color.system_notification_accent_color); 1588 notification.setLatestEventInfo(context, text, 1589 mContext.getText(R.string.heavy_weight_notification_detail), 1590 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1591 PendingIntent.FLAG_CANCEL_CURRENT, null, 1592 new UserHandle(root.userId))); 1593 1594 try { 1595 int[] outId = new int[1]; 1596 inm.enqueueNotificationWithTag("android", "android", null, 1597 R.string.heavy_weight_notification, 1598 notification, outId, root.userId); 1599 } catch (RuntimeException e) { 1600 Slog.w(ActivityManagerService.TAG, 1601 "Error showing notification for heavy-weight app", e); 1602 } catch (RemoteException e) { 1603 } 1604 } catch (NameNotFoundException e) { 1605 Slog.w(TAG, "Unable to create context for heavy notification", e); 1606 } 1607 } break; 1608 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1609 INotificationManager inm = NotificationManager.getService(); 1610 if (inm == null) { 1611 return; 1612 } 1613 try { 1614 inm.cancelNotificationWithTag("android", null, 1615 R.string.heavy_weight_notification, msg.arg1); 1616 } catch (RuntimeException e) { 1617 Slog.w(ActivityManagerService.TAG, 1618 "Error canceling notification for service", e); 1619 } catch (RemoteException e) { 1620 } 1621 } break; 1622 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1623 synchronized (ActivityManagerService.this) { 1624 checkExcessivePowerUsageLocked(true); 1625 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1626 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1627 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1628 } 1629 } break; 1630 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1631 synchronized (ActivityManagerService.this) { 1632 ActivityRecord ar = (ActivityRecord)msg.obj; 1633 if (mCompatModeDialog != null) { 1634 if (mCompatModeDialog.mAppInfo.packageName.equals( 1635 ar.info.applicationInfo.packageName)) { 1636 return; 1637 } 1638 mCompatModeDialog.dismiss(); 1639 mCompatModeDialog = null; 1640 } 1641 if (ar != null && false) { 1642 if (mCompatModePackages.getPackageAskCompatModeLocked( 1643 ar.packageName)) { 1644 int mode = mCompatModePackages.computeCompatModeLocked( 1645 ar.info.applicationInfo); 1646 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1647 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1648 mCompatModeDialog = new CompatModeDialog( 1649 ActivityManagerService.this, mContext, 1650 ar.info.applicationInfo); 1651 mCompatModeDialog.show(); 1652 } 1653 } 1654 } 1655 } 1656 break; 1657 } 1658 case DISPATCH_PROCESSES_CHANGED: { 1659 dispatchProcessesChanged(); 1660 break; 1661 } 1662 case DISPATCH_PROCESS_DIED: { 1663 final int pid = msg.arg1; 1664 final int uid = msg.arg2; 1665 dispatchProcessDied(pid, uid); 1666 break; 1667 } 1668 case REPORT_MEM_USAGE_MSG: { 1669 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1670 Thread thread = new Thread() { 1671 @Override public void run() { 1672 reportMemUsage(memInfos); 1673 } 1674 }; 1675 thread.start(); 1676 break; 1677 } 1678 case START_USER_SWITCH_MSG: { 1679 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1680 break; 1681 } 1682 case REPORT_USER_SWITCH_MSG: { 1683 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1684 break; 1685 } 1686 case CONTINUE_USER_SWITCH_MSG: { 1687 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1688 break; 1689 } 1690 case USER_SWITCH_TIMEOUT_MSG: { 1691 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1692 break; 1693 } 1694 case IMMERSIVE_MODE_LOCK_MSG: { 1695 final boolean nextState = (msg.arg1 != 0); 1696 if (mUpdateLock.isHeld() != nextState) { 1697 if (DEBUG_IMMERSIVE) { 1698 final ActivityRecord r = (ActivityRecord) msg.obj; 1699 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1700 } 1701 if (nextState) { 1702 mUpdateLock.acquire(); 1703 } else { 1704 mUpdateLock.release(); 1705 } 1706 } 1707 break; 1708 } 1709 case PERSIST_URI_GRANTS_MSG: { 1710 writeGrantedUriPermissions(); 1711 break; 1712 } 1713 case REQUEST_ALL_PSS_MSG: { 1714 synchronized (ActivityManagerService.this) { 1715 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1716 } 1717 break; 1718 } 1719 case START_PROFILES_MSG: { 1720 synchronized (ActivityManagerService.this) { 1721 startProfilesLocked(); 1722 } 1723 break; 1724 } 1725 case UPDATE_TIME: { 1726 synchronized (ActivityManagerService.this) { 1727 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1728 ProcessRecord r = mLruProcesses.get(i); 1729 if (r.thread != null) { 1730 try { 1731 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1732 } catch (RemoteException ex) { 1733 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1734 } 1735 } 1736 } 1737 } 1738 break; 1739 } 1740 case SYSTEM_USER_START_MSG: { 1741 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1742 Integer.toString(msg.arg1), msg.arg1); 1743 mSystemServiceManager.startUser(msg.arg1); 1744 break; 1745 } 1746 case SYSTEM_USER_CURRENT_MSG: { 1747 mBatteryStatsService.noteEvent( 1748 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1749 Integer.toString(msg.arg2), msg.arg2); 1750 mBatteryStatsService.noteEvent( 1751 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1752 Integer.toString(msg.arg1), msg.arg1); 1753 mSystemServiceManager.switchUser(msg.arg1); 1754 break; 1755 } 1756 case ENTER_ANIMATION_COMPLETE_MSG: { 1757 synchronized (ActivityManagerService.this) { 1758 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1759 if (r != null && r.app != null && r.app.thread != null) { 1760 try { 1761 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1762 } catch (RemoteException e) { 1763 } 1764 } 1765 } 1766 break; 1767 } 1768 case FINISH_BOOTING_MSG: { 1769 if (msg.arg1 != 0) { 1770 finishBooting(); 1771 } 1772 if (msg.arg2 != 0) { 1773 enableScreenAfterBoot(); 1774 } 1775 break; 1776 } 1777 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1778 try { 1779 Locale l = (Locale) msg.obj; 1780 IBinder service = ServiceManager.getService("mount"); 1781 IMountService mountService = IMountService.Stub.asInterface(service); 1782 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1783 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1784 } catch (RemoteException e) { 1785 Log.e(TAG, "Error storing locale for decryption UI", e); 1786 } 1787 break; 1788 } 1789 case DISMISS_DIALOG_MSG: { 1790 final Dialog d = (Dialog) msg.obj; 1791 d.dismiss(); 1792 break; 1793 } 1794 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1795 synchronized (ActivityManagerService.this) { 1796 int i = mTaskStackListeners.beginBroadcast(); 1797 while (i > 0) { 1798 i--; 1799 try { 1800 // Make a one-way callback to the listener 1801 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1802 } catch (RemoteException e){ 1803 // Handled by the RemoteCallbackList 1804 } 1805 } 1806 mTaskStackListeners.finishBroadcast(); 1807 } 1808 break; 1809 } 1810 } 1811 } 1812 }; 1813 1814 static final int COLLECT_PSS_BG_MSG = 1; 1815 1816 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1817 @Override 1818 public void handleMessage(Message msg) { 1819 switch (msg.what) { 1820 case COLLECT_PSS_BG_MSG: { 1821 long start = SystemClock.uptimeMillis(); 1822 MemInfoReader memInfo = null; 1823 synchronized (ActivityManagerService.this) { 1824 if (mFullPssPending) { 1825 mFullPssPending = false; 1826 memInfo = new MemInfoReader(); 1827 } 1828 } 1829 if (memInfo != null) { 1830 updateCpuStatsNow(); 1831 long nativeTotalPss = 0; 1832 synchronized (mProcessCpuTracker) { 1833 final int N = mProcessCpuTracker.countStats(); 1834 for (int j=0; j<N; j++) { 1835 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1836 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1837 // This is definitely an application process; skip it. 1838 continue; 1839 } 1840 synchronized (mPidsSelfLocked) { 1841 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1842 // This is one of our own processes; skip it. 1843 continue; 1844 } 1845 } 1846 nativeTotalPss += Debug.getPss(st.pid, null, null); 1847 } 1848 } 1849 memInfo.readMemInfo(); 1850 synchronized (ActivityManagerService.this) { 1851 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1852 + (SystemClock.uptimeMillis()-start) + "ms"); 1853 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1854 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1855 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1856 } 1857 } 1858 1859 int num = 0; 1860 long[] tmp = new long[1]; 1861 do { 1862 ProcessRecord proc; 1863 int procState; 1864 int pid; 1865 long lastPssTime; 1866 synchronized (ActivityManagerService.this) { 1867 if (mPendingPssProcesses.size() <= 0) { 1868 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1869 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1870 mPendingPssProcesses.clear(); 1871 return; 1872 } 1873 proc = mPendingPssProcesses.remove(0); 1874 procState = proc.pssProcState; 1875 lastPssTime = proc.lastPssTime; 1876 if (proc.thread != null && procState == proc.setProcState 1877 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1878 < SystemClock.uptimeMillis()) { 1879 pid = proc.pid; 1880 } else { 1881 proc = null; 1882 pid = 0; 1883 } 1884 } 1885 if (proc != null) { 1886 long pss = Debug.getPss(pid, tmp, null); 1887 synchronized (ActivityManagerService.this) { 1888 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1889 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1890 num++; 1891 recordPssSample(proc, procState, pss, tmp[0], 1892 SystemClock.uptimeMillis()); 1893 } 1894 } 1895 } 1896 } while (true); 1897 } 1898 } 1899 } 1900 }; 1901 1902 public void setSystemProcess() { 1903 try { 1904 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1905 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1906 ServiceManager.addService("meminfo", new MemBinder(this)); 1907 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1908 ServiceManager.addService("dbinfo", new DbBinder(this)); 1909 if (MONITOR_CPU_USAGE) { 1910 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1911 } 1912 ServiceManager.addService("permission", new PermissionController(this)); 1913 1914 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1915 "android", STOCK_PM_FLAGS); 1916 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1917 1918 synchronized (this) { 1919 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1920 app.persistent = true; 1921 app.pid = MY_PID; 1922 app.maxAdj = ProcessList.SYSTEM_ADJ; 1923 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1924 mProcessNames.put(app.processName, app.uid, app); 1925 synchronized (mPidsSelfLocked) { 1926 mPidsSelfLocked.put(app.pid, app); 1927 } 1928 updateLruProcessLocked(app, false, null); 1929 updateOomAdjLocked(); 1930 } 1931 } catch (PackageManager.NameNotFoundException e) { 1932 throw new RuntimeException( 1933 "Unable to find android system package", e); 1934 } 1935 } 1936 1937 public void setWindowManager(WindowManagerService wm) { 1938 mWindowManager = wm; 1939 mStackSupervisor.setWindowManager(wm); 1940 } 1941 1942 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1943 mUsageStatsService = usageStatsManager; 1944 } 1945 1946 public void startObservingNativeCrashes() { 1947 final NativeCrashListener ncl = new NativeCrashListener(this); 1948 ncl.start(); 1949 } 1950 1951 public IAppOpsService getAppOpsService() { 1952 return mAppOpsService; 1953 } 1954 1955 static class MemBinder extends Binder { 1956 ActivityManagerService mActivityManagerService; 1957 MemBinder(ActivityManagerService activityManagerService) { 1958 mActivityManagerService = activityManagerService; 1959 } 1960 1961 @Override 1962 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1963 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1964 != PackageManager.PERMISSION_GRANTED) { 1965 pw.println("Permission Denial: can't dump meminfo from from pid=" 1966 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1967 + " without permission " + android.Manifest.permission.DUMP); 1968 return; 1969 } 1970 1971 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1972 } 1973 } 1974 1975 static class GraphicsBinder extends Binder { 1976 ActivityManagerService mActivityManagerService; 1977 GraphicsBinder(ActivityManagerService activityManagerService) { 1978 mActivityManagerService = activityManagerService; 1979 } 1980 1981 @Override 1982 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1983 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1984 != PackageManager.PERMISSION_GRANTED) { 1985 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1986 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1987 + " without permission " + android.Manifest.permission.DUMP); 1988 return; 1989 } 1990 1991 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1992 } 1993 } 1994 1995 static class DbBinder extends Binder { 1996 ActivityManagerService mActivityManagerService; 1997 DbBinder(ActivityManagerService activityManagerService) { 1998 mActivityManagerService = activityManagerService; 1999 } 2000 2001 @Override 2002 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2003 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2004 != PackageManager.PERMISSION_GRANTED) { 2005 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2006 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2007 + " without permission " + android.Manifest.permission.DUMP); 2008 return; 2009 } 2010 2011 mActivityManagerService.dumpDbInfo(fd, pw, args); 2012 } 2013 } 2014 2015 static class CpuBinder extends Binder { 2016 ActivityManagerService mActivityManagerService; 2017 CpuBinder(ActivityManagerService activityManagerService) { 2018 mActivityManagerService = activityManagerService; 2019 } 2020 2021 @Override 2022 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2023 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2024 != PackageManager.PERMISSION_GRANTED) { 2025 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2026 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2027 + " without permission " + android.Manifest.permission.DUMP); 2028 return; 2029 } 2030 2031 synchronized (mActivityManagerService.mProcessCpuTracker) { 2032 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2033 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2034 SystemClock.uptimeMillis())); 2035 } 2036 } 2037 } 2038 2039 public static final class Lifecycle extends SystemService { 2040 private final ActivityManagerService mService; 2041 2042 public Lifecycle(Context context) { 2043 super(context); 2044 mService = new ActivityManagerService(context); 2045 } 2046 2047 @Override 2048 public void onStart() { 2049 mService.start(); 2050 } 2051 2052 public ActivityManagerService getService() { 2053 return mService; 2054 } 2055 } 2056 2057 // Note: This method is invoked on the main thread but may need to attach various 2058 // handlers to other threads. So take care to be explicit about the looper. 2059 public ActivityManagerService(Context systemContext) { 2060 mContext = systemContext; 2061 mFactoryTest = FactoryTest.getMode(); 2062 mSystemThread = ActivityThread.currentActivityThread(); 2063 2064 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2065 2066 mHandlerThread = new ServiceThread(TAG, 2067 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2068 mHandlerThread.start(); 2069 mHandler = new MainHandler(mHandlerThread.getLooper()); 2070 2071 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2072 "foreground", BROADCAST_FG_TIMEOUT, false); 2073 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2074 "background", BROADCAST_BG_TIMEOUT, true); 2075 mBroadcastQueues[0] = mFgBroadcastQueue; 2076 mBroadcastQueues[1] = mBgBroadcastQueue; 2077 2078 mServices = new ActiveServices(this); 2079 mProviderMap = new ProviderMap(this); 2080 2081 // TODO: Move creation of battery stats service outside of activity manager service. 2082 File dataDir = Environment.getDataDirectory(); 2083 File systemDir = new File(dataDir, "system"); 2084 systemDir.mkdirs(); 2085 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2086 mBatteryStatsService.getActiveStatistics().readLocked(); 2087 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2088 mOnBattery = DEBUG_POWER ? true 2089 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2090 mBatteryStatsService.getActiveStatistics().setCallback(this); 2091 2092 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2093 2094 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2095 2096 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2097 2098 // User 0 is the first and only user that runs at boot. 2099 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2100 mUserLru.add(Integer.valueOf(0)); 2101 updateStartedUserArrayLocked(); 2102 2103 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2104 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2105 2106 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2107 2108 mConfiguration.setToDefaults(); 2109 mConfiguration.locale = Locale.getDefault(); 2110 2111 mConfigurationSeq = mConfiguration.seq = 1; 2112 mProcessCpuTracker.init(); 2113 2114 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2115 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2116 mStackSupervisor = new ActivityStackSupervisor(this); 2117 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2118 2119 mProcessCpuThread = new Thread("CpuTracker") { 2120 @Override 2121 public void run() { 2122 while (true) { 2123 try { 2124 try { 2125 synchronized(this) { 2126 final long now = SystemClock.uptimeMillis(); 2127 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2128 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2129 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2130 // + ", write delay=" + nextWriteDelay); 2131 if (nextWriteDelay < nextCpuDelay) { 2132 nextCpuDelay = nextWriteDelay; 2133 } 2134 if (nextCpuDelay > 0) { 2135 mProcessCpuMutexFree.set(true); 2136 this.wait(nextCpuDelay); 2137 } 2138 } 2139 } catch (InterruptedException e) { 2140 } 2141 updateCpuStatsNow(); 2142 } catch (Exception e) { 2143 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2144 } 2145 } 2146 } 2147 }; 2148 2149 Watchdog.getInstance().addMonitor(this); 2150 Watchdog.getInstance().addThread(mHandler); 2151 } 2152 2153 public void setSystemServiceManager(SystemServiceManager mgr) { 2154 mSystemServiceManager = mgr; 2155 } 2156 2157 public void setInstaller(Installer installer) { 2158 mInstaller = installer; 2159 } 2160 2161 private void start() { 2162 Process.removeAllProcessGroups(); 2163 mProcessCpuThread.start(); 2164 2165 mBatteryStatsService.publish(mContext); 2166 mAppOpsService.publish(mContext); 2167 Slog.d("AppOps", "AppOpsService published"); 2168 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2169 } 2170 2171 public void initPowerManagement() { 2172 mStackSupervisor.initPowerManagement(); 2173 mBatteryStatsService.initPowerManagement(); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuTracker) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<>(); 2347 2348 // Isolated processes won't get this optimization, so that we don't 2349 // violate the rules about which services they have access to. 2350 if (!isolated) { 2351 // Setup the application init args 2352 mAppBindArgs.put("package", ServiceManager.getService("package")); 2353 mAppBindArgs.put("window", ServiceManager.getService("window")); 2354 mAppBindArgs.put(Context.ALARM_SERVICE, 2355 ServiceManager.getService(Context.ALARM_SERVICE)); 2356 } 2357 } 2358 return mAppBindArgs; 2359 } 2360 2361 final void setFocusedActivityLocked(ActivityRecord r, String reason) { 2362 if (mFocusedActivity != r) { 2363 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2364 mFocusedActivity = r; 2365 if (r.task != null && r.task.voiceInteractor != null) { 2366 startRunningVoiceLocked(); 2367 } else { 2368 finishRunningVoiceLocked(); 2369 } 2370 mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity"); 2371 if (r != null) { 2372 mWindowManager.setFocusedApp(r.appToken, true); 2373 } 2374 applyUpdateLockStateLocked(r); 2375 } 2376 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId, 2377 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName); 2378 } 2379 2380 final void clearFocusedActivity(ActivityRecord r) { 2381 if (mFocusedActivity == r) { 2382 mFocusedActivity = null; 2383 } 2384 } 2385 2386 @Override 2387 public void setFocusedStack(int stackId) { 2388 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2389 synchronized (ActivityManagerService.this) { 2390 ActivityStack stack = mStackSupervisor.getStack(stackId); 2391 if (stack != null) { 2392 ActivityRecord r = stack.topRunningActivityLocked(null); 2393 if (r != null) { 2394 setFocusedActivityLocked(r, "setFocusedStack"); 2395 } 2396 } 2397 } 2398 } 2399 2400 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2401 @Override 2402 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2403 synchronized (ActivityManagerService.this) { 2404 if (listener != null) { 2405 mTaskStackListeners.register(listener); 2406 } 2407 } 2408 } 2409 2410 @Override 2411 public void notifyActivityDrawn(IBinder token) { 2412 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2413 synchronized (this) { 2414 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2415 if (r != null) { 2416 r.task.stack.notifyActivityDrawnLocked(r); 2417 } 2418 } 2419 } 2420 2421 final void applyUpdateLockStateLocked(ActivityRecord r) { 2422 // Modifications to the UpdateLock state are done on our handler, outside 2423 // the activity manager's locks. The new state is determined based on the 2424 // state *now* of the relevant activity record. The object is passed to 2425 // the handler solely for logging detail, not to be consulted/modified. 2426 final boolean nextState = r != null && r.immersive; 2427 mHandler.sendMessage( 2428 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2429 } 2430 2431 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2432 Message msg = Message.obtain(); 2433 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2434 msg.obj = r.task.askedCompatMode ? null : r; 2435 mHandler.sendMessage(msg); 2436 } 2437 2438 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2439 String what, Object obj, ProcessRecord srcApp) { 2440 app.lastActivityTime = now; 2441 2442 if (app.activities.size() > 0) { 2443 // Don't want to touch dependent processes that are hosting activities. 2444 return index; 2445 } 2446 2447 int lrui = mLruProcesses.lastIndexOf(app); 2448 if (lrui < 0) { 2449 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2450 + what + " " + obj + " from " + srcApp); 2451 return index; 2452 } 2453 2454 if (lrui >= index) { 2455 // Don't want to cause this to move dependent processes *back* in the 2456 // list as if they were less frequently used. 2457 return index; 2458 } 2459 2460 if (lrui >= mLruProcessActivityStart) { 2461 // Don't want to touch dependent processes that are hosting activities. 2462 return index; 2463 } 2464 2465 mLruProcesses.remove(lrui); 2466 if (index > 0) { 2467 index--; 2468 } 2469 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2470 + " in LRU list: " + app); 2471 mLruProcesses.add(index, app); 2472 return index; 2473 } 2474 2475 final void removeLruProcessLocked(ProcessRecord app) { 2476 int lrui = mLruProcesses.lastIndexOf(app); 2477 if (lrui >= 0) { 2478 if (!app.killed) { 2479 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2480 Process.killProcessQuiet(app.pid); 2481 Process.killProcessGroup(app.info.uid, app.pid); 2482 } 2483 if (lrui <= mLruProcessActivityStart) { 2484 mLruProcessActivityStart--; 2485 } 2486 if (lrui <= mLruProcessServiceStart) { 2487 mLruProcessServiceStart--; 2488 } 2489 mLruProcesses.remove(lrui); 2490 } 2491 } 2492 2493 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2494 ProcessRecord client) { 2495 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2496 || app.treatLikeActivity; 2497 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2498 if (!activityChange && hasActivity) { 2499 // The process has activities, so we are only allowing activity-based adjustments 2500 // to move it. It should be kept in the front of the list with other 2501 // processes that have activities, and we don't want those to change their 2502 // order except due to activity operations. 2503 return; 2504 } 2505 2506 mLruSeq++; 2507 final long now = SystemClock.uptimeMillis(); 2508 app.lastActivityTime = now; 2509 2510 // First a quick reject: if the app is already at the position we will 2511 // put it, then there is nothing to do. 2512 if (hasActivity) { 2513 final int N = mLruProcesses.size(); 2514 if (N > 0 && mLruProcesses.get(N-1) == app) { 2515 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2516 return; 2517 } 2518 } else { 2519 if (mLruProcessServiceStart > 0 2520 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2521 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2522 return; 2523 } 2524 } 2525 2526 int lrui = mLruProcesses.lastIndexOf(app); 2527 2528 if (app.persistent && lrui >= 0) { 2529 // We don't care about the position of persistent processes, as long as 2530 // they are in the list. 2531 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2532 return; 2533 } 2534 2535 /* In progress: compute new position first, so we can avoid doing work 2536 if the process is not actually going to move. Not yet working. 2537 int addIndex; 2538 int nextIndex; 2539 boolean inActivity = false, inService = false; 2540 if (hasActivity) { 2541 // Process has activities, put it at the very tipsy-top. 2542 addIndex = mLruProcesses.size(); 2543 nextIndex = mLruProcessServiceStart; 2544 inActivity = true; 2545 } else if (hasService) { 2546 // Process has services, put it at the top of the service list. 2547 addIndex = mLruProcessActivityStart; 2548 nextIndex = mLruProcessServiceStart; 2549 inActivity = true; 2550 inService = true; 2551 } else { 2552 // Process not otherwise of interest, it goes to the top of the non-service area. 2553 addIndex = mLruProcessServiceStart; 2554 if (client != null) { 2555 int clientIndex = mLruProcesses.lastIndexOf(client); 2556 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2557 + app); 2558 if (clientIndex >= 0 && addIndex > clientIndex) { 2559 addIndex = clientIndex; 2560 } 2561 } 2562 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2563 } 2564 2565 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2566 + mLruProcessActivityStart + "): " + app); 2567 */ 2568 2569 if (lrui >= 0) { 2570 if (lrui < mLruProcessActivityStart) { 2571 mLruProcessActivityStart--; 2572 } 2573 if (lrui < mLruProcessServiceStart) { 2574 mLruProcessServiceStart--; 2575 } 2576 /* 2577 if (addIndex > lrui) { 2578 addIndex--; 2579 } 2580 if (nextIndex > lrui) { 2581 nextIndex--; 2582 } 2583 */ 2584 mLruProcesses.remove(lrui); 2585 } 2586 2587 /* 2588 mLruProcesses.add(addIndex, app); 2589 if (inActivity) { 2590 mLruProcessActivityStart++; 2591 } 2592 if (inService) { 2593 mLruProcessActivityStart++; 2594 } 2595 */ 2596 2597 int nextIndex; 2598 if (hasActivity) { 2599 final int N = mLruProcesses.size(); 2600 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2601 // Process doesn't have activities, but has clients with 2602 // activities... move it up, but one below the top (the top 2603 // should always have a real activity). 2604 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2605 mLruProcesses.add(N-1, app); 2606 // To keep it from spamming the LRU list (by making a bunch of clients), 2607 // we will push down any other entries owned by the app. 2608 final int uid = app.info.uid; 2609 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2610 ProcessRecord subProc = mLruProcesses.get(i); 2611 if (subProc.info.uid == uid) { 2612 // We want to push this one down the list. If the process after 2613 // it is for the same uid, however, don't do so, because we don't 2614 // want them internally to be re-ordered. 2615 if (mLruProcesses.get(i-1).info.uid != uid) { 2616 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2617 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2618 ProcessRecord tmp = mLruProcesses.get(i); 2619 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2620 mLruProcesses.set(i-1, tmp); 2621 i--; 2622 } 2623 } else { 2624 // A gap, we can stop here. 2625 break; 2626 } 2627 } 2628 } else { 2629 // Process has activities, put it at the very tipsy-top. 2630 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2631 mLruProcesses.add(app); 2632 } 2633 nextIndex = mLruProcessServiceStart; 2634 } else if (hasService) { 2635 // Process has services, put it at the top of the service list. 2636 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2637 mLruProcesses.add(mLruProcessActivityStart, app); 2638 nextIndex = mLruProcessServiceStart; 2639 mLruProcessActivityStart++; 2640 } else { 2641 // Process not otherwise of interest, it goes to the top of the non-service area. 2642 int index = mLruProcessServiceStart; 2643 if (client != null) { 2644 // If there is a client, don't allow the process to be moved up higher 2645 // in the list than that client. 2646 int clientIndex = mLruProcesses.lastIndexOf(client); 2647 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2648 + " when updating " + app); 2649 if (clientIndex <= lrui) { 2650 // Don't allow the client index restriction to push it down farther in the 2651 // list than it already is. 2652 clientIndex = lrui; 2653 } 2654 if (clientIndex >= 0 && index > clientIndex) { 2655 index = clientIndex; 2656 } 2657 } 2658 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2659 mLruProcesses.add(index, app); 2660 nextIndex = index-1; 2661 mLruProcessActivityStart++; 2662 mLruProcessServiceStart++; 2663 } 2664 2665 // If the app is currently using a content provider or service, 2666 // bump those processes as well. 2667 for (int j=app.connections.size()-1; j>=0; j--) { 2668 ConnectionRecord cr = app.connections.valueAt(j); 2669 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2670 && cr.binding.service.app != null 2671 && cr.binding.service.app.lruSeq != mLruSeq 2672 && !cr.binding.service.app.persistent) { 2673 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2674 "service connection", cr, app); 2675 } 2676 } 2677 for (int j=app.conProviders.size()-1; j>=0; j--) { 2678 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2679 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2680 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2681 "provider reference", cpr, app); 2682 } 2683 } 2684 } 2685 2686 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2687 if (uid == Process.SYSTEM_UID) { 2688 // The system gets to run in any process. If there are multiple 2689 // processes with the same uid, just pick the first (this 2690 // should never happen). 2691 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2692 if (procs == null) return null; 2693 final int N = procs.size(); 2694 for (int i = 0; i < N; i++) { 2695 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2696 } 2697 } 2698 ProcessRecord proc = mProcessNames.get(processName, uid); 2699 if (false && proc != null && !keepIfLarge 2700 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2701 && proc.lastCachedPss >= 4000) { 2702 // Turn this condition on to cause killing to happen regularly, for testing. 2703 if (proc.baseProcessTracker != null) { 2704 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2705 } 2706 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2707 } else if (proc != null && !keepIfLarge 2708 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2709 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2710 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2711 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2712 if (proc.baseProcessTracker != null) { 2713 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2714 } 2715 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2716 } 2717 } 2718 return proc; 2719 } 2720 2721 void ensurePackageDexOpt(String packageName) { 2722 IPackageManager pm = AppGlobals.getPackageManager(); 2723 try { 2724 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2725 mDidDexOpt = true; 2726 } 2727 } catch (RemoteException e) { 2728 } 2729 } 2730 2731 boolean isNextTransitionForward() { 2732 int transit = mWindowManager.getPendingAppTransition(); 2733 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2734 || transit == AppTransition.TRANSIT_TASK_OPEN 2735 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2736 } 2737 2738 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2739 String processName, String abiOverride, int uid, Runnable crashHandler) { 2740 synchronized(this) { 2741 ApplicationInfo info = new ApplicationInfo(); 2742 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2743 // For isolated processes, the former contains the parent's uid and the latter the 2744 // actual uid of the isolated process. 2745 // In the special case introduced by this method (which is, starting an isolated 2746 // process directly from the SystemServer without an actual parent app process) the 2747 // closest thing to a parent's uid is SYSTEM_UID. 2748 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2749 // the |isolated| logic in the ProcessRecord constructor. 2750 info.uid = Process.SYSTEM_UID; 2751 info.processName = processName; 2752 info.className = entryPoint; 2753 info.packageName = "android"; 2754 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2755 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2756 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2757 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2758 crashHandler); 2759 return proc != null ? proc.pid : 0; 2760 } 2761 } 2762 2763 final ProcessRecord startProcessLocked(String processName, 2764 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2765 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2766 boolean isolated, boolean keepIfLarge) { 2767 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2768 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2769 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2770 null /* crashHandler */); 2771 } 2772 2773 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2774 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2775 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2776 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2777 long startTime = SystemClock.elapsedRealtime(); 2778 ProcessRecord app; 2779 if (!isolated) { 2780 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2781 checkTime(startTime, "startProcess: after getProcessRecord"); 2782 } else { 2783 // If this is an isolated process, it can't re-use an existing process. 2784 app = null; 2785 } 2786 // We don't have to do anything more if: 2787 // (1) There is an existing application record; and 2788 // (2) The caller doesn't think it is dead, OR there is no thread 2789 // object attached to it so we know it couldn't have crashed; and 2790 // (3) There is a pid assigned to it, so it is either starting or 2791 // already running. 2792 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2793 + " app=" + app + " knownToBeDead=" + knownToBeDead 2794 + " thread=" + (app != null ? app.thread : null) 2795 + " pid=" + (app != null ? app.pid : -1)); 2796 if (app != null && app.pid > 0) { 2797 if (!knownToBeDead || app.thread == null) { 2798 // We already have the app running, or are waiting for it to 2799 // come up (we have a pid but not yet its thread), so keep it. 2800 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2801 // If this is a new package in the process, add the package to the list 2802 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2803 checkTime(startTime, "startProcess: done, added package to proc"); 2804 return app; 2805 } 2806 2807 // An application record is attached to a previous process, 2808 // clean it up now. 2809 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2810 checkTime(startTime, "startProcess: bad proc running, killing"); 2811 Process.killProcessGroup(app.info.uid, app.pid); 2812 handleAppDiedLocked(app, true, true); 2813 checkTime(startTime, "startProcess: done killing old proc"); 2814 } 2815 2816 String hostingNameStr = hostingName != null 2817 ? hostingName.flattenToShortString() : null; 2818 2819 if (!isolated) { 2820 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2821 // If we are in the background, then check to see if this process 2822 // is bad. If so, we will just silently fail. 2823 if (mBadProcesses.get(info.processName, info.uid) != null) { 2824 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2825 + "/" + info.processName); 2826 return null; 2827 } 2828 } else { 2829 // When the user is explicitly starting a process, then clear its 2830 // crash count so that we won't make it bad until they see at 2831 // least one crash dialog again, and make the process good again 2832 // if it had been bad. 2833 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2834 + "/" + info.processName); 2835 mProcessCrashTimes.remove(info.processName, info.uid); 2836 if (mBadProcesses.get(info.processName, info.uid) != null) { 2837 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2838 UserHandle.getUserId(info.uid), info.uid, 2839 info.processName); 2840 mBadProcesses.remove(info.processName, info.uid); 2841 if (app != null) { 2842 app.bad = false; 2843 } 2844 } 2845 } 2846 } 2847 2848 if (app == null) { 2849 checkTime(startTime, "startProcess: creating new process record"); 2850 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2851 if (app == null) { 2852 Slog.w(TAG, "Failed making new process record for " 2853 + processName + "/" + info.uid + " isolated=" + isolated); 2854 return null; 2855 } 2856 app.crashHandler = crashHandler; 2857 mProcessNames.put(processName, app.uid, app); 2858 if (isolated) { 2859 mIsolatedProcesses.put(app.uid, app); 2860 } 2861 checkTime(startTime, "startProcess: done creating new process record"); 2862 } else { 2863 // If this is a new package in the process, add the package to the list 2864 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2865 checkTime(startTime, "startProcess: added package to existing proc"); 2866 } 2867 2868 // If the system is not ready yet, then hold off on starting this 2869 // process until it is. 2870 if (!mProcessesReady 2871 && !isAllowedWhileBooting(info) 2872 && !allowWhileBooting) { 2873 if (!mProcessesOnHold.contains(app)) { 2874 mProcessesOnHold.add(app); 2875 } 2876 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2877 checkTime(startTime, "startProcess: returning with proc on hold"); 2878 return app; 2879 } 2880 2881 checkTime(startTime, "startProcess: stepping in to startProcess"); 2882 startProcessLocked( 2883 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2884 checkTime(startTime, "startProcess: done starting proc!"); 2885 return (app.pid != 0) ? app : null; 2886 } 2887 2888 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2889 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2890 } 2891 2892 private final void startProcessLocked(ProcessRecord app, 2893 String hostingType, String hostingNameStr) { 2894 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2895 null /* entryPoint */, null /* entryPointArgs */); 2896 } 2897 2898 private final void startProcessLocked(ProcessRecord app, String hostingType, 2899 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2900 long startTime = SystemClock.elapsedRealtime(); 2901 if (app.pid > 0 && app.pid != MY_PID) { 2902 checkTime(startTime, "startProcess: removing from pids map"); 2903 synchronized (mPidsSelfLocked) { 2904 mPidsSelfLocked.remove(app.pid); 2905 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2906 } 2907 checkTime(startTime, "startProcess: done removing from pids map"); 2908 app.setPid(0); 2909 } 2910 2911 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2912 "startProcessLocked removing on hold: " + app); 2913 mProcessesOnHold.remove(app); 2914 2915 checkTime(startTime, "startProcess: starting to update cpu stats"); 2916 updateCpuStats(); 2917 checkTime(startTime, "startProcess: done updating cpu stats"); 2918 2919 try { 2920 int uid = app.uid; 2921 2922 int[] gids = null; 2923 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2924 if (!app.isolated) { 2925 int[] permGids = null; 2926 try { 2927 checkTime(startTime, "startProcess: getting gids from package manager"); 2928 final PackageManager pm = mContext.getPackageManager(); 2929 permGids = pm.getPackageGids(app.info.packageName); 2930 2931 if (Environment.isExternalStorageEmulated()) { 2932 checkTime(startTime, "startProcess: checking external storage perm"); 2933 if (pm.checkPermission( 2934 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2935 app.info.packageName) == PERMISSION_GRANTED) { 2936 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2937 } else { 2938 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2939 } 2940 } 2941 } catch (PackageManager.NameNotFoundException e) { 2942 Slog.w(TAG, "Unable to retrieve gids", e); 2943 } 2944 2945 /* 2946 * Add shared application and profile GIDs so applications can share some 2947 * resources like shared libraries and access user-wide resources 2948 */ 2949 if (permGids == null) { 2950 gids = new int[2]; 2951 } else { 2952 gids = new int[permGids.length + 2]; 2953 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2954 } 2955 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2956 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2957 } 2958 checkTime(startTime, "startProcess: building args"); 2959 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2960 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2961 && mTopComponent != null 2962 && app.processName.equals(mTopComponent.getPackageName())) { 2963 uid = 0; 2964 } 2965 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2966 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2967 uid = 0; 2968 } 2969 } 2970 int debugFlags = 0; 2971 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2972 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2973 // Also turn on CheckJNI for debuggable apps. It's quite 2974 // awkward to turn on otherwise. 2975 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2976 } 2977 // Run the app in safe mode if its manifest requests so or the 2978 // system is booted in safe mode. 2979 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2980 mSafeMode == true) { 2981 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2982 } 2983 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2984 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2985 } 2986 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2987 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2988 } 2989 if ("1".equals(SystemProperties.get("debug.assert"))) { 2990 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2991 } 2992 2993 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2994 if (requiredAbi == null) { 2995 requiredAbi = Build.SUPPORTED_ABIS[0]; 2996 } 2997 2998 String instructionSet = null; 2999 if (app.info.primaryCpuAbi != null) { 3000 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3001 } 3002 3003 app.gids = gids; 3004 app.requiredAbi = requiredAbi; 3005 app.instructionSet = instructionSet; 3006 3007 // Start the process. It will either succeed and return a result containing 3008 // the PID of the new process, or else throw a RuntimeException. 3009 boolean isActivityProcess = (entryPoint == null); 3010 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3011 checkTime(startTime, "startProcess: asking zygote to start proc"); 3012 Process.ProcessStartResult startResult = Process.start(entryPoint, 3013 app.processName, uid, uid, gids, debugFlags, mountExternal, 3014 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3015 app.info.dataDir, entryPointArgs); 3016 checkTime(startTime, "startProcess: returned from zygote!"); 3017 3018 if (app.isolated) { 3019 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3020 } 3021 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3022 checkTime(startTime, "startProcess: done updating battery stats"); 3023 3024 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3025 UserHandle.getUserId(uid), startResult.pid, uid, 3026 app.processName, hostingType, 3027 hostingNameStr != null ? hostingNameStr : ""); 3028 3029 if (app.persistent) { 3030 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3031 } 3032 3033 checkTime(startTime, "startProcess: building log message"); 3034 StringBuilder buf = mStringBuilder; 3035 buf.setLength(0); 3036 buf.append("Start proc "); 3037 buf.append(startResult.pid); 3038 buf.append(':'); 3039 buf.append(app.processName); 3040 buf.append('/'); 3041 UserHandle.formatUid(buf, uid); 3042 if (!isActivityProcess) { 3043 buf.append(" ["); 3044 buf.append(entryPoint); 3045 buf.append("]"); 3046 } 3047 buf.append(" for "); 3048 buf.append(hostingType); 3049 if (hostingNameStr != null) { 3050 buf.append(" "); 3051 buf.append(hostingNameStr); 3052 } 3053 Slog.i(TAG, buf.toString()); 3054 app.setPid(startResult.pid); 3055 app.usingWrapper = startResult.usingWrapper; 3056 app.removed = false; 3057 app.killed = false; 3058 app.killedByAm = false; 3059 checkTime(startTime, "startProcess: starting to update pids map"); 3060 synchronized (mPidsSelfLocked) { 3061 this.mPidsSelfLocked.put(startResult.pid, app); 3062 if (isActivityProcess) { 3063 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3064 msg.obj = app; 3065 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3066 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3067 } 3068 } 3069 checkTime(startTime, "startProcess: done updating pids map"); 3070 } catch (RuntimeException e) { 3071 // XXX do better error recovery. 3072 app.setPid(0); 3073 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3074 if (app.isolated) { 3075 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3076 } 3077 Slog.e(TAG, "Failure starting process " + app.processName, e); 3078 } 3079 } 3080 3081 void updateUsageStats(ActivityRecord component, boolean resumed) { 3082 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3083 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3084 if (resumed) { 3085 if (mUsageStatsService != null) { 3086 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3087 UsageEvents.Event.MOVE_TO_FOREGROUND); 3088 } 3089 synchronized (stats) { 3090 stats.noteActivityResumedLocked(component.app.uid); 3091 } 3092 } else { 3093 if (mUsageStatsService != null) { 3094 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3095 UsageEvents.Event.MOVE_TO_BACKGROUND); 3096 } 3097 synchronized (stats) { 3098 stats.noteActivityPausedLocked(component.app.uid); 3099 } 3100 } 3101 } 3102 3103 Intent getHomeIntent() { 3104 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3105 intent.setComponent(mTopComponent); 3106 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3107 intent.addCategory(Intent.CATEGORY_HOME); 3108 } 3109 return intent; 3110 } 3111 3112 boolean startHomeActivityLocked(int userId, String reason) { 3113 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3114 && mTopAction == null) { 3115 // We are running in factory test mode, but unable to find 3116 // the factory test app, so just sit around displaying the 3117 // error message and don't try to start anything. 3118 return false; 3119 } 3120 Intent intent = getHomeIntent(); 3121 ActivityInfo aInfo = 3122 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3123 if (aInfo != null) { 3124 intent.setComponent(new ComponentName( 3125 aInfo.applicationInfo.packageName, aInfo.name)); 3126 // Don't do this if the home app is currently being 3127 // instrumented. 3128 aInfo = new ActivityInfo(aInfo); 3129 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3130 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3131 aInfo.applicationInfo.uid, true); 3132 if (app == null || app.instrumentationClass == null) { 3133 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3134 mStackSupervisor.startHomeActivity(intent, aInfo, reason); 3135 } 3136 } 3137 3138 return true; 3139 } 3140 3141 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3142 ActivityInfo ai = null; 3143 ComponentName comp = intent.getComponent(); 3144 try { 3145 if (comp != null) { 3146 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3147 } else { 3148 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3149 intent, 3150 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3151 flags, userId); 3152 3153 if (info != null) { 3154 ai = info.activityInfo; 3155 } 3156 } 3157 } catch (RemoteException e) { 3158 // ignore 3159 } 3160 3161 return ai; 3162 } 3163 3164 /** 3165 * Starts the "new version setup screen" if appropriate. 3166 */ 3167 void startSetupActivityLocked() { 3168 // Only do this once per boot. 3169 if (mCheckedForSetup) { 3170 return; 3171 } 3172 3173 // We will show this screen if the current one is a different 3174 // version than the last one shown, and we are not running in 3175 // low-level factory test mode. 3176 final ContentResolver resolver = mContext.getContentResolver(); 3177 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3178 Settings.Global.getInt(resolver, 3179 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3180 mCheckedForSetup = true; 3181 3182 // See if we should be showing the platform update setup UI. 3183 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3184 List<ResolveInfo> ris = mContext.getPackageManager() 3185 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3186 3187 // We don't allow third party apps to replace this. 3188 ResolveInfo ri = null; 3189 for (int i=0; ris != null && i<ris.size(); i++) { 3190 if ((ris.get(i).activityInfo.applicationInfo.flags 3191 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3192 ri = ris.get(i); 3193 break; 3194 } 3195 } 3196 3197 if (ri != null) { 3198 String vers = ri.activityInfo.metaData != null 3199 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3200 : null; 3201 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3202 vers = ri.activityInfo.applicationInfo.metaData.getString( 3203 Intent.METADATA_SETUP_VERSION); 3204 } 3205 String lastVers = Settings.Secure.getString( 3206 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3207 if (vers != null && !vers.equals(lastVers)) { 3208 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3209 intent.setComponent(new ComponentName( 3210 ri.activityInfo.packageName, ri.activityInfo.name)); 3211 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3212 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3213 null); 3214 } 3215 } 3216 } 3217 } 3218 3219 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3220 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3221 } 3222 3223 void enforceNotIsolatedCaller(String caller) { 3224 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3225 throw new SecurityException("Isolated process not allowed to call " + caller); 3226 } 3227 } 3228 3229 void enforceShellRestriction(String restriction, int userHandle) { 3230 if (Binder.getCallingUid() == Process.SHELL_UID) { 3231 if (userHandle < 0 3232 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3233 throw new SecurityException("Shell does not have permission to access user " 3234 + userHandle); 3235 } 3236 } 3237 } 3238 3239 @Override 3240 public int getFrontActivityScreenCompatMode() { 3241 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3242 synchronized (this) { 3243 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3244 } 3245 } 3246 3247 @Override 3248 public void setFrontActivityScreenCompatMode(int mode) { 3249 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3250 "setFrontActivityScreenCompatMode"); 3251 synchronized (this) { 3252 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3253 } 3254 } 3255 3256 @Override 3257 public int getPackageScreenCompatMode(String packageName) { 3258 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3259 synchronized (this) { 3260 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3261 } 3262 } 3263 3264 @Override 3265 public void setPackageScreenCompatMode(String packageName, int mode) { 3266 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3267 "setPackageScreenCompatMode"); 3268 synchronized (this) { 3269 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3270 } 3271 } 3272 3273 @Override 3274 public boolean getPackageAskScreenCompat(String packageName) { 3275 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3276 synchronized (this) { 3277 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3278 } 3279 } 3280 3281 @Override 3282 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3283 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3284 "setPackageAskScreenCompat"); 3285 synchronized (this) { 3286 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3287 } 3288 } 3289 3290 private void dispatchProcessesChanged() { 3291 int N; 3292 synchronized (this) { 3293 N = mPendingProcessChanges.size(); 3294 if (mActiveProcessChanges.length < N) { 3295 mActiveProcessChanges = new ProcessChangeItem[N]; 3296 } 3297 mPendingProcessChanges.toArray(mActiveProcessChanges); 3298 mAvailProcessChanges.addAll(mPendingProcessChanges); 3299 mPendingProcessChanges.clear(); 3300 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3301 } 3302 3303 int i = mProcessObservers.beginBroadcast(); 3304 while (i > 0) { 3305 i--; 3306 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3307 if (observer != null) { 3308 try { 3309 for (int j=0; j<N; j++) { 3310 ProcessChangeItem item = mActiveProcessChanges[j]; 3311 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3312 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3313 + item.pid + " uid=" + item.uid + ": " 3314 + item.foregroundActivities); 3315 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3316 item.foregroundActivities); 3317 } 3318 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3320 + item.pid + " uid=" + item.uid + ": " + item.processState); 3321 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3322 } 3323 } 3324 } catch (RemoteException e) { 3325 } 3326 } 3327 } 3328 mProcessObservers.finishBroadcast(); 3329 } 3330 3331 private void dispatchProcessDied(int pid, int uid) { 3332 int i = mProcessObservers.beginBroadcast(); 3333 while (i > 0) { 3334 i--; 3335 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3336 if (observer != null) { 3337 try { 3338 observer.onProcessDied(pid, uid); 3339 } catch (RemoteException e) { 3340 } 3341 } 3342 } 3343 mProcessObservers.finishBroadcast(); 3344 } 3345 3346 @Override 3347 public final int startActivity(IApplicationThread caller, String callingPackage, 3348 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3349 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3350 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3351 resultWho, requestCode, startFlags, profilerInfo, options, 3352 UserHandle.getCallingUserId()); 3353 } 3354 3355 @Override 3356 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3357 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3358 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3359 enforceNotIsolatedCaller("startActivity"); 3360 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3361 false, ALLOW_FULL_ONLY, "startActivity", null); 3362 // TODO: Switch to user app stacks here. 3363 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3364 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3365 profilerInfo, null, null, options, userId, null, null); 3366 } 3367 3368 @Override 3369 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3370 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3371 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3372 3373 // This is very dangerous -- it allows you to perform a start activity (including 3374 // permission grants) as any app that may launch one of your own activities. So 3375 // we will only allow this to be done from activities that are part of the core framework, 3376 // and then only when they are running as the system. 3377 final ActivityRecord sourceRecord; 3378 final int targetUid; 3379 final String targetPackage; 3380 synchronized (this) { 3381 if (resultTo == null) { 3382 throw new SecurityException("Must be called from an activity"); 3383 } 3384 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3385 if (sourceRecord == null) { 3386 throw new SecurityException("Called with bad activity token: " + resultTo); 3387 } 3388 if (!sourceRecord.info.packageName.equals("android")) { 3389 throw new SecurityException( 3390 "Must be called from an activity that is declared in the android package"); 3391 } 3392 if (sourceRecord.app == null) { 3393 throw new SecurityException("Called without a process attached to activity"); 3394 } 3395 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3396 // This is still okay, as long as this activity is running under the 3397 // uid of the original calling activity. 3398 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3399 throw new SecurityException( 3400 "Calling activity in uid " + sourceRecord.app.uid 3401 + " must be system uid or original calling uid " 3402 + sourceRecord.launchedFromUid); 3403 } 3404 } 3405 targetUid = sourceRecord.launchedFromUid; 3406 targetPackage = sourceRecord.launchedFromPackage; 3407 } 3408 3409 if (userId == UserHandle.USER_NULL) { 3410 userId = UserHandle.getUserId(sourceRecord.app.uid); 3411 } 3412 3413 // TODO: Switch to user app stacks here. 3414 try { 3415 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3416 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3417 null, null, options, userId, null, null); 3418 return ret; 3419 } catch (SecurityException e) { 3420 // XXX need to figure out how to propagate to original app. 3421 // A SecurityException here is generally actually a fault of the original 3422 // calling activity (such as a fairly granting permissions), so propagate it 3423 // back to them. 3424 /* 3425 StringBuilder msg = new StringBuilder(); 3426 msg.append("While launching"); 3427 msg.append(intent.toString()); 3428 msg.append(": "); 3429 msg.append(e.getMessage()); 3430 */ 3431 throw e; 3432 } 3433 } 3434 3435 @Override 3436 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3437 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3438 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3439 enforceNotIsolatedCaller("startActivityAndWait"); 3440 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3441 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3442 WaitResult res = new WaitResult(); 3443 // TODO: Switch to user app stacks here. 3444 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3445 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3446 options, userId, null, null); 3447 return res; 3448 } 3449 3450 @Override 3451 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3452 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3453 int startFlags, Configuration config, Bundle options, int userId) { 3454 enforceNotIsolatedCaller("startActivityWithConfig"); 3455 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3456 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3457 // TODO: Switch to user app stacks here. 3458 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3459 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3460 null, null, config, options, userId, null, null); 3461 return ret; 3462 } 3463 3464 @Override 3465 public int startActivityIntentSender(IApplicationThread caller, 3466 IntentSender intent, Intent fillInIntent, String resolvedType, 3467 IBinder resultTo, String resultWho, int requestCode, 3468 int flagsMask, int flagsValues, Bundle options) { 3469 enforceNotIsolatedCaller("startActivityIntentSender"); 3470 // Refuse possible leaked file descriptors 3471 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3472 throw new IllegalArgumentException("File descriptors passed in Intent"); 3473 } 3474 3475 IIntentSender sender = intent.getTarget(); 3476 if (!(sender instanceof PendingIntentRecord)) { 3477 throw new IllegalArgumentException("Bad PendingIntent object"); 3478 } 3479 3480 PendingIntentRecord pir = (PendingIntentRecord)sender; 3481 3482 synchronized (this) { 3483 // If this is coming from the currently resumed activity, it is 3484 // effectively saying that app switches are allowed at this point. 3485 final ActivityStack stack = getFocusedStack(); 3486 if (stack.mResumedActivity != null && 3487 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3488 mAppSwitchesAllowedTime = 0; 3489 } 3490 } 3491 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3492 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3493 return ret; 3494 } 3495 3496 @Override 3497 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3498 Intent intent, String resolvedType, IVoiceInteractionSession session, 3499 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3500 Bundle options, int userId) { 3501 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3502 != PackageManager.PERMISSION_GRANTED) { 3503 String msg = "Permission Denial: startVoiceActivity() from pid=" 3504 + Binder.getCallingPid() 3505 + ", uid=" + Binder.getCallingUid() 3506 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3507 Slog.w(TAG, msg); 3508 throw new SecurityException(msg); 3509 } 3510 if (session == null || interactor == null) { 3511 throw new NullPointerException("null session or interactor"); 3512 } 3513 userId = handleIncomingUser(callingPid, callingUid, userId, 3514 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3515 // TODO: Switch to user app stacks here. 3516 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3517 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3518 null, options, userId, null, null); 3519 } 3520 3521 @Override 3522 public boolean startNextMatchingActivity(IBinder callingActivity, 3523 Intent intent, Bundle options) { 3524 // Refuse possible leaked file descriptors 3525 if (intent != null && intent.hasFileDescriptors() == true) { 3526 throw new IllegalArgumentException("File descriptors passed in Intent"); 3527 } 3528 3529 synchronized (this) { 3530 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3531 if (r == null) { 3532 ActivityOptions.abort(options); 3533 return false; 3534 } 3535 if (r.app == null || r.app.thread == null) { 3536 // The caller is not running... d'oh! 3537 ActivityOptions.abort(options); 3538 return false; 3539 } 3540 intent = new Intent(intent); 3541 // The caller is not allowed to change the data. 3542 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3543 // And we are resetting to find the next component... 3544 intent.setComponent(null); 3545 3546 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3547 3548 ActivityInfo aInfo = null; 3549 try { 3550 List<ResolveInfo> resolves = 3551 AppGlobals.getPackageManager().queryIntentActivities( 3552 intent, r.resolvedType, 3553 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3554 UserHandle.getCallingUserId()); 3555 3556 // Look for the original activity in the list... 3557 final int N = resolves != null ? resolves.size() : 0; 3558 for (int i=0; i<N; i++) { 3559 ResolveInfo rInfo = resolves.get(i); 3560 if (rInfo.activityInfo.packageName.equals(r.packageName) 3561 && rInfo.activityInfo.name.equals(r.info.name)) { 3562 // We found the current one... the next matching is 3563 // after it. 3564 i++; 3565 if (i<N) { 3566 aInfo = resolves.get(i).activityInfo; 3567 } 3568 if (debug) { 3569 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3570 + "/" + r.info.name); 3571 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3572 + "/" + aInfo.name); 3573 } 3574 break; 3575 } 3576 } 3577 } catch (RemoteException e) { 3578 } 3579 3580 if (aInfo == null) { 3581 // Nobody who is next! 3582 ActivityOptions.abort(options); 3583 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3584 return false; 3585 } 3586 3587 intent.setComponent(new ComponentName( 3588 aInfo.applicationInfo.packageName, aInfo.name)); 3589 intent.setFlags(intent.getFlags()&~( 3590 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3591 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3592 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3593 Intent.FLAG_ACTIVITY_NEW_TASK)); 3594 3595 // Okay now we need to start the new activity, replacing the 3596 // currently running activity. This is a little tricky because 3597 // we want to start the new one as if the current one is finished, 3598 // but not finish the current one first so that there is no flicker. 3599 // And thus... 3600 final boolean wasFinishing = r.finishing; 3601 r.finishing = true; 3602 3603 // Propagate reply information over to the new activity. 3604 final ActivityRecord resultTo = r.resultTo; 3605 final String resultWho = r.resultWho; 3606 final int requestCode = r.requestCode; 3607 r.resultTo = null; 3608 if (resultTo != null) { 3609 resultTo.removeResultsLocked(r, resultWho, requestCode); 3610 } 3611 3612 final long origId = Binder.clearCallingIdentity(); 3613 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3614 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3615 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3616 -1, r.launchedFromUid, 0, options, false, null, null, null); 3617 Binder.restoreCallingIdentity(origId); 3618 3619 r.finishing = wasFinishing; 3620 if (res != ActivityManager.START_SUCCESS) { 3621 return false; 3622 } 3623 return true; 3624 } 3625 } 3626 3627 @Override 3628 public final int startActivityFromRecents(int taskId, Bundle options) { 3629 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3630 String msg = "Permission Denial: startActivityFromRecents called without " + 3631 START_TASKS_FROM_RECENTS; 3632 Slog.w(TAG, msg); 3633 throw new SecurityException(msg); 3634 } 3635 return startActivityFromRecentsInner(taskId, options); 3636 } 3637 3638 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3639 final TaskRecord task; 3640 final int callingUid; 3641 final String callingPackage; 3642 final Intent intent; 3643 final int userId; 3644 synchronized (this) { 3645 task = recentTaskForIdLocked(taskId); 3646 if (task == null) { 3647 throw new IllegalArgumentException("Task " + taskId + " not found."); 3648 } 3649 if (task.getRootActivity() != null) { 3650 moveTaskToFrontLocked(task.taskId, 0, null); 3651 return ActivityManager.START_TASK_TO_FRONT; 3652 } 3653 callingUid = task.mCallingUid; 3654 callingPackage = task.mCallingPackage; 3655 intent = task.intent; 3656 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3657 userId = task.userId; 3658 } 3659 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3660 options, userId, null, task); 3661 } 3662 3663 final int startActivityInPackage(int uid, String callingPackage, 3664 Intent intent, String resolvedType, IBinder resultTo, 3665 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3666 IActivityContainer container, TaskRecord inTask) { 3667 3668 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3669 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3670 3671 // TODO: Switch to user app stacks here. 3672 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3673 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3674 null, null, null, options, userId, container, inTask); 3675 return ret; 3676 } 3677 3678 @Override 3679 public final int startActivities(IApplicationThread caller, String callingPackage, 3680 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3681 int userId) { 3682 enforceNotIsolatedCaller("startActivities"); 3683 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3684 false, ALLOW_FULL_ONLY, "startActivity", null); 3685 // TODO: Switch to user app stacks here. 3686 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3687 resolvedTypes, resultTo, options, userId); 3688 return ret; 3689 } 3690 3691 final int startActivitiesInPackage(int uid, String callingPackage, 3692 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3693 Bundle options, int userId) { 3694 3695 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3696 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3697 // TODO: Switch to user app stacks here. 3698 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3699 resultTo, options, userId); 3700 return ret; 3701 } 3702 3703 //explicitly remove thd old information in mRecentTasks when removing existing user. 3704 private void removeRecentTasksForUserLocked(int userId) { 3705 if(userId <= 0) { 3706 Slog.i(TAG, "Can't remove recent task on user " + userId); 3707 return; 3708 } 3709 3710 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3711 TaskRecord tr = mRecentTasks.get(i); 3712 if (tr.userId == userId) { 3713 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3714 + " when finishing user" + userId); 3715 mRecentTasks.remove(i); 3716 tr.removedFromRecents(); 3717 } 3718 } 3719 3720 // Remove tasks from persistent storage. 3721 notifyTaskPersisterLocked(null, true); 3722 } 3723 3724 // Sort by taskId 3725 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3726 @Override 3727 public int compare(TaskRecord lhs, TaskRecord rhs) { 3728 return rhs.taskId - lhs.taskId; 3729 } 3730 }; 3731 3732 // Extract the affiliates of the chain containing mRecentTasks[start]. 3733 private int processNextAffiliateChainLocked(int start) { 3734 final TaskRecord startTask = mRecentTasks.get(start); 3735 final int affiliateId = startTask.mAffiliatedTaskId; 3736 3737 // Quick identification of isolated tasks. I.e. those not launched behind. 3738 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3739 startTask.mNextAffiliate == null) { 3740 // There is still a slim chance that there are other tasks that point to this task 3741 // and that the chain is so messed up that this task no longer points to them but 3742 // the gain of this optimization outweighs the risk. 3743 startTask.inRecents = true; 3744 return start + 1; 3745 } 3746 3747 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3748 mTmpRecents.clear(); 3749 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3750 final TaskRecord task = mRecentTasks.get(i); 3751 if (task.mAffiliatedTaskId == affiliateId) { 3752 mRecentTasks.remove(i); 3753 mTmpRecents.add(task); 3754 } 3755 } 3756 3757 // Sort them all by taskId. That is the order they were create in and that order will 3758 // always be correct. 3759 Collections.sort(mTmpRecents, mTaskRecordComparator); 3760 3761 // Go through and fix up the linked list. 3762 // The first one is the end of the chain and has no next. 3763 final TaskRecord first = mTmpRecents.get(0); 3764 first.inRecents = true; 3765 if (first.mNextAffiliate != null) { 3766 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3767 first.setNextAffiliate(null); 3768 notifyTaskPersisterLocked(first, false); 3769 } 3770 // Everything in the middle is doubly linked from next to prev. 3771 final int tmpSize = mTmpRecents.size(); 3772 for (int i = 0; i < tmpSize - 1; ++i) { 3773 final TaskRecord next = mTmpRecents.get(i); 3774 final TaskRecord prev = mTmpRecents.get(i + 1); 3775 if (next.mPrevAffiliate != prev) { 3776 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3777 " setting prev=" + prev); 3778 next.setPrevAffiliate(prev); 3779 notifyTaskPersisterLocked(next, false); 3780 } 3781 if (prev.mNextAffiliate != next) { 3782 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3783 " setting next=" + next); 3784 prev.setNextAffiliate(next); 3785 notifyTaskPersisterLocked(prev, false); 3786 } 3787 prev.inRecents = true; 3788 } 3789 // The last one is the beginning of the list and has no prev. 3790 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3791 if (last.mPrevAffiliate != null) { 3792 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3793 last.setPrevAffiliate(null); 3794 notifyTaskPersisterLocked(last, false); 3795 } 3796 3797 // Insert the group back into mRecentTasks at start. 3798 mRecentTasks.addAll(start, mTmpRecents); 3799 3800 // Let the caller know where we left off. 3801 return start + tmpSize; 3802 } 3803 3804 /** 3805 * Update the recent tasks lists: make sure tasks should still be here (their 3806 * applications / activities still exist), update their availability, fixup ordering 3807 * of affiliations. 3808 */ 3809 void cleanupRecentTasksLocked(int userId) { 3810 if (mRecentTasks == null) { 3811 // Happens when called from the packagemanager broadcast before boot. 3812 return; 3813 } 3814 3815 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3816 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3817 final IPackageManager pm = AppGlobals.getPackageManager(); 3818 final ActivityInfo dummyAct = new ActivityInfo(); 3819 final ApplicationInfo dummyApp = new ApplicationInfo(); 3820 3821 int N = mRecentTasks.size(); 3822 3823 int[] users = userId == UserHandle.USER_ALL 3824 ? getUsersLocked() : new int[] { userId }; 3825 for (int user : users) { 3826 for (int i = 0; i < N; i++) { 3827 TaskRecord task = mRecentTasks.get(i); 3828 if (task.userId != user) { 3829 // Only look at tasks for the user ID of interest. 3830 continue; 3831 } 3832 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3833 // This situation is broken, and we should just get rid of it now. 3834 mRecentTasks.remove(i); 3835 task.removedFromRecents(); 3836 i--; 3837 N--; 3838 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3839 continue; 3840 } 3841 // Check whether this activity is currently available. 3842 if (task.realActivity != null) { 3843 ActivityInfo ai = availActCache.get(task.realActivity); 3844 if (ai == null) { 3845 try { 3846 ai = pm.getActivityInfo(task.realActivity, 3847 PackageManager.GET_UNINSTALLED_PACKAGES 3848 | PackageManager.GET_DISABLED_COMPONENTS, user); 3849 } catch (RemoteException e) { 3850 // Will never happen. 3851 continue; 3852 } 3853 if (ai == null) { 3854 ai = dummyAct; 3855 } 3856 availActCache.put(task.realActivity, ai); 3857 } 3858 if (ai == dummyAct) { 3859 // This could be either because the activity no longer exists, or the 3860 // app is temporarily gone. For the former we want to remove the recents 3861 // entry; for the latter we want to mark it as unavailable. 3862 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3863 if (app == null) { 3864 try { 3865 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3866 PackageManager.GET_UNINSTALLED_PACKAGES 3867 | PackageManager.GET_DISABLED_COMPONENTS, user); 3868 } catch (RemoteException e) { 3869 // Will never happen. 3870 continue; 3871 } 3872 if (app == null) { 3873 app = dummyApp; 3874 } 3875 availAppCache.put(task.realActivity.getPackageName(), app); 3876 } 3877 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3878 // Doesn't exist any more! Good-bye. 3879 mRecentTasks.remove(i); 3880 task.removedFromRecents(); 3881 i--; 3882 N--; 3883 Slog.w(TAG, "Removing no longer valid recent: " + task); 3884 continue; 3885 } else { 3886 // Otherwise just not available for now. 3887 if (task.isAvailable) { 3888 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3889 + task); 3890 } 3891 task.isAvailable = false; 3892 } 3893 } else { 3894 if (!ai.enabled || !ai.applicationInfo.enabled 3895 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3896 if (task.isAvailable) { 3897 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3898 + task + " (enabled=" + ai.enabled + "/" 3899 + ai.applicationInfo.enabled + " flags=" 3900 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3901 } 3902 task.isAvailable = false; 3903 } else { 3904 if (!task.isAvailable) { 3905 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3906 + task); 3907 } 3908 task.isAvailable = true; 3909 } 3910 } 3911 } 3912 } 3913 } 3914 3915 // Verify the affiliate chain for each task. 3916 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3917 } 3918 3919 mTmpRecents.clear(); 3920 // mRecentTasks is now in sorted, affiliated order. 3921 } 3922 3923 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3924 int N = mRecentTasks.size(); 3925 TaskRecord top = task; 3926 int topIndex = taskIndex; 3927 while (top.mNextAffiliate != null && topIndex > 0) { 3928 top = top.mNextAffiliate; 3929 topIndex--; 3930 } 3931 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3932 + topIndex + " from intial " + taskIndex); 3933 // Find the end of the chain, doing a sanity check along the way. 3934 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3935 int endIndex = topIndex; 3936 TaskRecord prev = top; 3937 while (endIndex < N) { 3938 TaskRecord cur = mRecentTasks.get(endIndex); 3939 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3940 + endIndex + " " + cur); 3941 if (cur == top) { 3942 // Verify start of the chain. 3943 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3944 Slog.wtf(TAG, "Bad chain @" + endIndex 3945 + ": first task has next affiliate: " + prev); 3946 sane = false; 3947 break; 3948 } 3949 } else { 3950 // Verify middle of the chain's next points back to the one before. 3951 if (cur.mNextAffiliate != prev 3952 || cur.mNextAffiliateTaskId != prev.taskId) { 3953 Slog.wtf(TAG, "Bad chain @" + endIndex 3954 + ": middle task " + cur + " @" + endIndex 3955 + " has bad next affiliate " 3956 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3957 + ", expected " + prev); 3958 sane = false; 3959 break; 3960 } 3961 } 3962 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3963 // Chain ends here. 3964 if (cur.mPrevAffiliate != null) { 3965 Slog.wtf(TAG, "Bad chain @" + endIndex 3966 + ": last task " + cur + " has previous affiliate " 3967 + cur.mPrevAffiliate); 3968 sane = false; 3969 } 3970 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3971 break; 3972 } else { 3973 // Verify middle of the chain's prev points to a valid item. 3974 if (cur.mPrevAffiliate == null) { 3975 Slog.wtf(TAG, "Bad chain @" + endIndex 3976 + ": task " + cur + " has previous affiliate " 3977 + cur.mPrevAffiliate + " but should be id " 3978 + cur.mPrevAffiliate); 3979 sane = false; 3980 break; 3981 } 3982 } 3983 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3984 Slog.wtf(TAG, "Bad chain @" + endIndex 3985 + ": task " + cur + " has affiliated id " 3986 + cur.mAffiliatedTaskId + " but should be " 3987 + task.mAffiliatedTaskId); 3988 sane = false; 3989 break; 3990 } 3991 prev = cur; 3992 endIndex++; 3993 if (endIndex >= N) { 3994 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3995 + ": last task " + prev); 3996 sane = false; 3997 break; 3998 } 3999 } 4000 if (sane) { 4001 if (endIndex < taskIndex) { 4002 Slog.wtf(TAG, "Bad chain @" + endIndex 4003 + ": did not extend to task " + task + " @" + taskIndex); 4004 sane = false; 4005 } 4006 } 4007 if (sane) { 4008 // All looks good, we can just move all of the affiliated tasks 4009 // to the top. 4010 for (int i=topIndex; i<=endIndex; i++) { 4011 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4012 + " from " + i + " to " + (i-topIndex)); 4013 TaskRecord cur = mRecentTasks.remove(i); 4014 mRecentTasks.add(i-topIndex, cur); 4015 } 4016 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4017 + " to " + endIndex); 4018 return true; 4019 } 4020 4021 // Whoops, couldn't do it. 4022 return false; 4023 } 4024 4025 final void addRecentTaskLocked(TaskRecord task) { 4026 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4027 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4028 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4029 4030 int N = mRecentTasks.size(); 4031 // Quick case: check if the top-most recent task is the same. 4032 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4033 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4034 return; 4035 } 4036 // Another quick case: check if this is part of a set of affiliated 4037 // tasks that are at the top. 4038 if (isAffiliated && N > 0 && task.inRecents 4039 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4040 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4041 + " at top when adding " + task); 4042 return; 4043 } 4044 // Another quick case: never add voice sessions. 4045 if (task.voiceSession != null) { 4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4047 return; 4048 } 4049 4050 boolean needAffiliationFix = false; 4051 4052 // Slightly less quick case: the task is already in recents, so all we need 4053 // to do is move it. 4054 if (task.inRecents) { 4055 int taskIndex = mRecentTasks.indexOf(task); 4056 if (taskIndex >= 0) { 4057 if (!isAffiliated) { 4058 // Simple case: this is not an affiliated task, so we just move it to the front. 4059 mRecentTasks.remove(taskIndex); 4060 mRecentTasks.add(0, task); 4061 notifyTaskPersisterLocked(task, false); 4062 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4063 + " from " + taskIndex); 4064 return; 4065 } else { 4066 // More complicated: need to keep all affiliated tasks together. 4067 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4068 // All went well. 4069 return; 4070 } 4071 4072 // Uh oh... something bad in the affiliation chain, try to rebuild 4073 // everything and then go through our general path of adding a new task. 4074 needAffiliationFix = true; 4075 } 4076 } else { 4077 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4078 needAffiliationFix = true; 4079 } 4080 } 4081 4082 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4083 trimRecentsForTaskLocked(task, true); 4084 4085 N = mRecentTasks.size(); 4086 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4087 final TaskRecord tr = mRecentTasks.remove(N - 1); 4088 tr.removedFromRecents(); 4089 N--; 4090 } 4091 task.inRecents = true; 4092 if (!isAffiliated || needAffiliationFix) { 4093 // If this is a simple non-affiliated task, or we had some failure trying to 4094 // handle it as part of an affilated task, then just place it at the top. 4095 mRecentTasks.add(0, task); 4096 } else if (isAffiliated) { 4097 // If this is a new affiliated task, then move all of the affiliated tasks 4098 // to the front and insert this new one. 4099 TaskRecord other = task.mNextAffiliate; 4100 if (other == null) { 4101 other = task.mPrevAffiliate; 4102 } 4103 if (other != null) { 4104 int otherIndex = mRecentTasks.indexOf(other); 4105 if (otherIndex >= 0) { 4106 // Insert new task at appropriate location. 4107 int taskIndex; 4108 if (other == task.mNextAffiliate) { 4109 // We found the index of our next affiliation, which is who is 4110 // before us in the list, so add after that point. 4111 taskIndex = otherIndex+1; 4112 } else { 4113 // We found the index of our previous affiliation, which is who is 4114 // after us in the list, so add at their position. 4115 taskIndex = otherIndex; 4116 } 4117 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4118 + taskIndex + ": " + task); 4119 mRecentTasks.add(taskIndex, task); 4120 4121 // Now move everything to the front. 4122 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4123 // All went well. 4124 return; 4125 } 4126 4127 // Uh oh... something bad in the affiliation chain, try to rebuild 4128 // everything and then go through our general path of adding a new task. 4129 needAffiliationFix = true; 4130 } else { 4131 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4132 + other); 4133 needAffiliationFix = true; 4134 } 4135 } else { 4136 if (DEBUG_RECENTS) Slog.d(TAG, 4137 "addRecent: adding affiliated task without next/prev:" + task); 4138 needAffiliationFix = true; 4139 } 4140 } 4141 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4142 4143 if (needAffiliationFix) { 4144 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4145 cleanupRecentTasksLocked(task.userId); 4146 } 4147 } 4148 4149 /** 4150 * If needed, remove oldest existing entries in recents that are for the same kind 4151 * of task as the given one. 4152 */ 4153 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4154 int N = mRecentTasks.size(); 4155 final Intent intent = task.intent; 4156 final boolean document = intent != null && intent.isDocument(); 4157 4158 int maxRecents = task.maxRecents - 1; 4159 for (int i=0; i<N; i++) { 4160 final TaskRecord tr = mRecentTasks.get(i); 4161 if (task != tr) { 4162 if (task.userId != tr.userId) { 4163 continue; 4164 } 4165 if (i > MAX_RECENT_BITMAPS) { 4166 tr.freeLastThumbnail(); 4167 } 4168 final Intent trIntent = tr.intent; 4169 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4170 (intent == null || !intent.filterEquals(trIntent))) { 4171 continue; 4172 } 4173 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4174 if (document && trIsDocument) { 4175 // These are the same document activity (not necessarily the same doc). 4176 if (maxRecents > 0) { 4177 --maxRecents; 4178 continue; 4179 } 4180 // Hit the maximum number of documents for this task. Fall through 4181 // and remove this document from recents. 4182 } else if (document || trIsDocument) { 4183 // Only one of these is a document. Not the droid we're looking for. 4184 continue; 4185 } 4186 } 4187 4188 if (!doTrim) { 4189 // If the caller is not actually asking for a trim, just tell them we reached 4190 // a point where the trim would happen. 4191 return i; 4192 } 4193 4194 // Either task and tr are the same or, their affinities match or their intents match 4195 // and neither of them is a document, or they are documents using the same activity 4196 // and their maxRecents has been reached. 4197 tr.disposeThumbnail(); 4198 mRecentTasks.remove(i); 4199 if (task != tr) { 4200 tr.removedFromRecents(); 4201 } 4202 i--; 4203 N--; 4204 if (task.intent == null) { 4205 // If the new recent task we are adding is not fully 4206 // specified, then replace it with the existing recent task. 4207 task = tr; 4208 } 4209 notifyTaskPersisterLocked(tr, false); 4210 } 4211 4212 return -1; 4213 } 4214 4215 @Override 4216 public void reportActivityFullyDrawn(IBinder token) { 4217 synchronized (this) { 4218 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4219 if (r == null) { 4220 return; 4221 } 4222 r.reportFullyDrawnLocked(); 4223 } 4224 } 4225 4226 @Override 4227 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4228 synchronized (this) { 4229 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4230 if (r == null) { 4231 return; 4232 } 4233 final long origId = Binder.clearCallingIdentity(); 4234 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4235 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4236 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4237 if (config != null) { 4238 r.frozenBeforeDestroy = true; 4239 if (!updateConfigurationLocked(config, r, false, false)) { 4240 mStackSupervisor.resumeTopActivitiesLocked(); 4241 } 4242 } 4243 Binder.restoreCallingIdentity(origId); 4244 } 4245 } 4246 4247 @Override 4248 public int getRequestedOrientation(IBinder token) { 4249 synchronized (this) { 4250 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4251 if (r == null) { 4252 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4253 } 4254 return mWindowManager.getAppOrientation(r.appToken); 4255 } 4256 } 4257 4258 /** 4259 * This is the internal entry point for handling Activity.finish(). 4260 * 4261 * @param token The Binder token referencing the Activity we want to finish. 4262 * @param resultCode Result code, if any, from this Activity. 4263 * @param resultData Result data (Intent), if any, from this Activity. 4264 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4265 * the root Activity in the task. 4266 * 4267 * @return Returns true if the activity successfully finished, or false if it is still running. 4268 */ 4269 @Override 4270 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4271 boolean finishTask) { 4272 // Refuse possible leaked file descriptors 4273 if (resultData != null && resultData.hasFileDescriptors() == true) { 4274 throw new IllegalArgumentException("File descriptors passed in Intent"); 4275 } 4276 4277 synchronized(this) { 4278 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4279 if (r == null) { 4280 return true; 4281 } 4282 // Keep track of the root activity of the task before we finish it 4283 TaskRecord tr = r.task; 4284 ActivityRecord rootR = tr.getRootActivity(); 4285 if (rootR == null) { 4286 Slog.w(TAG, "Finishing task with all activities already finished"); 4287 } 4288 // Do not allow task to finish in Lock Task mode. 4289 if (tr == mStackSupervisor.mLockTaskModeTask) { 4290 if (rootR == r) { 4291 Slog.i(TAG, "Not finishing task in lock task mode"); 4292 mStackSupervisor.showLockTaskToast(); 4293 return false; 4294 } 4295 } 4296 if (mController != null) { 4297 // Find the first activity that is not finishing. 4298 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4299 if (next != null) { 4300 // ask watcher if this is allowed 4301 boolean resumeOK = true; 4302 try { 4303 resumeOK = mController.activityResuming(next.packageName); 4304 } catch (RemoteException e) { 4305 mController = null; 4306 Watchdog.getInstance().setActivityController(null); 4307 } 4308 4309 if (!resumeOK) { 4310 Slog.i(TAG, "Not finishing activity because controller resumed"); 4311 return false; 4312 } 4313 } 4314 } 4315 final long origId = Binder.clearCallingIdentity(); 4316 try { 4317 boolean res; 4318 if (finishTask && r == rootR) { 4319 // If requested, remove the task that is associated to this activity only if it 4320 // was the root activity in the task. The result code and data is ignored 4321 // because we don't support returning them across task boundaries. 4322 res = removeTaskByIdLocked(tr.taskId, false); 4323 if (!res) { 4324 Slog.i(TAG, "Removing task failed to finish activity"); 4325 } 4326 } else { 4327 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4328 resultData, "app-request", true); 4329 if (!res) { 4330 Slog.i(TAG, "Failed to finish by app-request"); 4331 } 4332 } 4333 return res; 4334 } finally { 4335 Binder.restoreCallingIdentity(origId); 4336 } 4337 } 4338 } 4339 4340 @Override 4341 public final void finishHeavyWeightApp() { 4342 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4343 != PackageManager.PERMISSION_GRANTED) { 4344 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4345 + Binder.getCallingPid() 4346 + ", uid=" + Binder.getCallingUid() 4347 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4348 Slog.w(TAG, msg); 4349 throw new SecurityException(msg); 4350 } 4351 4352 synchronized(this) { 4353 if (mHeavyWeightProcess == null) { 4354 return; 4355 } 4356 4357 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4358 mHeavyWeightProcess.activities); 4359 for (int i=0; i<activities.size(); i++) { 4360 ActivityRecord r = activities.get(i); 4361 if (!r.finishing) { 4362 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4363 null, "finish-heavy", true); 4364 } 4365 } 4366 4367 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4368 mHeavyWeightProcess.userId, 0)); 4369 mHeavyWeightProcess = null; 4370 } 4371 } 4372 4373 @Override 4374 public void crashApplication(int uid, int initialPid, String packageName, 4375 String message) { 4376 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4377 != PackageManager.PERMISSION_GRANTED) { 4378 String msg = "Permission Denial: crashApplication() from pid=" 4379 + Binder.getCallingPid() 4380 + ", uid=" + Binder.getCallingUid() 4381 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4382 Slog.w(TAG, msg); 4383 throw new SecurityException(msg); 4384 } 4385 4386 synchronized(this) { 4387 ProcessRecord proc = null; 4388 4389 // Figure out which process to kill. We don't trust that initialPid 4390 // still has any relation to current pids, so must scan through the 4391 // list. 4392 synchronized (mPidsSelfLocked) { 4393 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4394 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4395 if (p.uid != uid) { 4396 continue; 4397 } 4398 if (p.pid == initialPid) { 4399 proc = p; 4400 break; 4401 } 4402 if (p.pkgList.containsKey(packageName)) { 4403 proc = p; 4404 } 4405 } 4406 } 4407 4408 if (proc == null) { 4409 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4410 + " initialPid=" + initialPid 4411 + " packageName=" + packageName); 4412 return; 4413 } 4414 4415 if (proc.thread != null) { 4416 if (proc.pid == Process.myPid()) { 4417 Log.w(TAG, "crashApplication: trying to crash self!"); 4418 return; 4419 } 4420 long ident = Binder.clearCallingIdentity(); 4421 try { 4422 proc.thread.scheduleCrash(message); 4423 } catch (RemoteException e) { 4424 } 4425 Binder.restoreCallingIdentity(ident); 4426 } 4427 } 4428 } 4429 4430 @Override 4431 public final void finishSubActivity(IBinder token, String resultWho, 4432 int requestCode) { 4433 synchronized(this) { 4434 final long origId = Binder.clearCallingIdentity(); 4435 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4436 if (r != null) { 4437 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4438 } 4439 Binder.restoreCallingIdentity(origId); 4440 } 4441 } 4442 4443 @Override 4444 public boolean finishActivityAffinity(IBinder token) { 4445 synchronized(this) { 4446 final long origId = Binder.clearCallingIdentity(); 4447 try { 4448 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4449 4450 ActivityRecord rootR = r.task.getRootActivity(); 4451 // Do not allow task to finish in Lock Task mode. 4452 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4453 if (rootR == r) { 4454 mStackSupervisor.showLockTaskToast(); 4455 return false; 4456 } 4457 } 4458 boolean res = false; 4459 if (r != null) { 4460 res = r.task.stack.finishActivityAffinityLocked(r); 4461 } 4462 return res; 4463 } finally { 4464 Binder.restoreCallingIdentity(origId); 4465 } 4466 } 4467 } 4468 4469 @Override 4470 public void finishVoiceTask(IVoiceInteractionSession session) { 4471 synchronized(this) { 4472 final long origId = Binder.clearCallingIdentity(); 4473 try { 4474 mStackSupervisor.finishVoiceTask(session); 4475 } finally { 4476 Binder.restoreCallingIdentity(origId); 4477 } 4478 } 4479 4480 } 4481 4482 @Override 4483 public boolean releaseActivityInstance(IBinder token) { 4484 synchronized(this) { 4485 final long origId = Binder.clearCallingIdentity(); 4486 try { 4487 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4488 if (r.task == null || r.task.stack == null) { 4489 return false; 4490 } 4491 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4492 } finally { 4493 Binder.restoreCallingIdentity(origId); 4494 } 4495 } 4496 } 4497 4498 @Override 4499 public void releaseSomeActivities(IApplicationThread appInt) { 4500 synchronized(this) { 4501 final long origId = Binder.clearCallingIdentity(); 4502 try { 4503 ProcessRecord app = getRecordForAppLocked(appInt); 4504 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4505 } finally { 4506 Binder.restoreCallingIdentity(origId); 4507 } 4508 } 4509 } 4510 4511 @Override 4512 public boolean willActivityBeVisible(IBinder token) { 4513 synchronized(this) { 4514 ActivityStack stack = ActivityRecord.getStackLocked(token); 4515 if (stack != null) { 4516 return stack.willActivityBeVisibleLocked(token); 4517 } 4518 return false; 4519 } 4520 } 4521 4522 @Override 4523 public void overridePendingTransition(IBinder token, String packageName, 4524 int enterAnim, int exitAnim) { 4525 synchronized(this) { 4526 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4527 if (self == null) { 4528 return; 4529 } 4530 4531 final long origId = Binder.clearCallingIdentity(); 4532 4533 if (self.state == ActivityState.RESUMED 4534 || self.state == ActivityState.PAUSING) { 4535 mWindowManager.overridePendingAppTransition(packageName, 4536 enterAnim, exitAnim, null); 4537 } 4538 4539 Binder.restoreCallingIdentity(origId); 4540 } 4541 } 4542 4543 /** 4544 * Main function for removing an existing process from the activity manager 4545 * as a result of that process going away. Clears out all connections 4546 * to the process. 4547 */ 4548 private final void handleAppDiedLocked(ProcessRecord app, 4549 boolean restarting, boolean allowRestart) { 4550 int pid = app.pid; 4551 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4552 if (!kept && !restarting) { 4553 removeLruProcessLocked(app); 4554 if (pid > 0) { 4555 ProcessList.remove(pid); 4556 } 4557 } 4558 4559 if (mProfileProc == app) { 4560 clearProfilerLocked(); 4561 } 4562 4563 // Remove this application's activities from active lists. 4564 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4565 4566 app.activities.clear(); 4567 4568 if (app.instrumentationClass != null) { 4569 Slog.w(TAG, "Crash of app " + app.processName 4570 + " running instrumentation " + app.instrumentationClass); 4571 Bundle info = new Bundle(); 4572 info.putString("shortMsg", "Process crashed."); 4573 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4574 } 4575 4576 if (!restarting) { 4577 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4578 // If there was nothing to resume, and we are not already 4579 // restarting this process, but there is a visible activity that 4580 // is hosted by the process... then make sure all visible 4581 // activities are running, taking care of restarting this 4582 // process. 4583 if (hasVisibleActivities) { 4584 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4585 } 4586 } 4587 } 4588 } 4589 4590 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4591 IBinder threadBinder = thread.asBinder(); 4592 // Find the application record. 4593 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4594 ProcessRecord rec = mLruProcesses.get(i); 4595 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4596 return i; 4597 } 4598 } 4599 return -1; 4600 } 4601 4602 final ProcessRecord getRecordForAppLocked( 4603 IApplicationThread thread) { 4604 if (thread == null) { 4605 return null; 4606 } 4607 4608 int appIndex = getLRURecordIndexForAppLocked(thread); 4609 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4610 } 4611 4612 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4613 // If there are no longer any background processes running, 4614 // and the app that died was not running instrumentation, 4615 // then tell everyone we are now low on memory. 4616 boolean haveBg = false; 4617 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4618 ProcessRecord rec = mLruProcesses.get(i); 4619 if (rec.thread != null 4620 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4621 haveBg = true; 4622 break; 4623 } 4624 } 4625 4626 if (!haveBg) { 4627 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4628 if (doReport) { 4629 long now = SystemClock.uptimeMillis(); 4630 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4631 doReport = false; 4632 } else { 4633 mLastMemUsageReportTime = now; 4634 } 4635 } 4636 final ArrayList<ProcessMemInfo> memInfos 4637 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4638 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4639 long now = SystemClock.uptimeMillis(); 4640 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4641 ProcessRecord rec = mLruProcesses.get(i); 4642 if (rec == dyingProc || rec.thread == null) { 4643 continue; 4644 } 4645 if (doReport) { 4646 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4647 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4648 } 4649 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4650 // The low memory report is overriding any current 4651 // state for a GC request. Make sure to do 4652 // heavy/important/visible/foreground processes first. 4653 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4654 rec.lastRequestedGc = 0; 4655 } else { 4656 rec.lastRequestedGc = rec.lastLowMemory; 4657 } 4658 rec.reportLowMemory = true; 4659 rec.lastLowMemory = now; 4660 mProcessesToGc.remove(rec); 4661 addProcessToGcListLocked(rec); 4662 } 4663 } 4664 if (doReport) { 4665 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4666 mHandler.sendMessage(msg); 4667 } 4668 scheduleAppGcsLocked(); 4669 } 4670 } 4671 4672 final void appDiedLocked(ProcessRecord app) { 4673 appDiedLocked(app, app.pid, app.thread); 4674 } 4675 4676 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4677 // First check if this ProcessRecord is actually active for the pid. 4678 synchronized (mPidsSelfLocked) { 4679 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4680 if (curProc != app) { 4681 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4682 return; 4683 } 4684 } 4685 4686 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4687 synchronized (stats) { 4688 stats.noteProcessDiedLocked(app.info.uid, pid); 4689 } 4690 4691 if (!app.killed) { 4692 Process.killProcessQuiet(pid); 4693 Process.killProcessGroup(app.info.uid, pid); 4694 app.killed = true; 4695 } 4696 4697 // Clean up already done if the process has been re-started. 4698 if (app.pid == pid && app.thread != null && 4699 app.thread.asBinder() == thread.asBinder()) { 4700 boolean doLowMem = app.instrumentationClass == null; 4701 boolean doOomAdj = doLowMem; 4702 if (!app.killedByAm) { 4703 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4704 + ") has died"); 4705 mAllowLowerMemLevel = true; 4706 } else { 4707 // Note that we always want to do oom adj to update our state with the 4708 // new number of procs. 4709 mAllowLowerMemLevel = false; 4710 doLowMem = false; 4711 } 4712 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4713 if (DEBUG_CLEANUP) Slog.v( 4714 TAG, "Dying app: " + app + ", pid: " + pid 4715 + ", thread: " + thread.asBinder()); 4716 handleAppDiedLocked(app, false, true); 4717 4718 if (doOomAdj) { 4719 updateOomAdjLocked(); 4720 } 4721 if (doLowMem) { 4722 doLowMemReportIfNeededLocked(app); 4723 } 4724 } else if (app.pid != pid) { 4725 // A new process has already been started. 4726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4727 + ") has died and restarted (pid " + app.pid + ")."); 4728 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4729 } else if (DEBUG_PROCESSES) { 4730 Slog.d(TAG, "Received spurious death notification for thread " 4731 + thread.asBinder()); 4732 } 4733 } 4734 4735 /** 4736 * If a stack trace dump file is configured, dump process stack traces. 4737 * @param clearTraces causes the dump file to be erased prior to the new 4738 * traces being written, if true; when false, the new traces will be 4739 * appended to any existing file content. 4740 * @param firstPids of dalvik VM processes to dump stack traces for first 4741 * @param lastPids of dalvik VM processes to dump stack traces for last 4742 * @param nativeProcs optional list of native process names to dump stack crawls 4743 * @return file containing stack traces, or null if no dump file is configured 4744 */ 4745 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4746 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4747 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4748 if (tracesPath == null || tracesPath.length() == 0) { 4749 return null; 4750 } 4751 4752 File tracesFile = new File(tracesPath); 4753 try { 4754 File tracesDir = tracesFile.getParentFile(); 4755 if (!tracesDir.exists()) { 4756 tracesDir.mkdirs(); 4757 if (!SELinux.restorecon(tracesDir)) { 4758 return null; 4759 } 4760 } 4761 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4762 4763 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4764 tracesFile.createNewFile(); 4765 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4766 } catch (IOException e) { 4767 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4768 return null; 4769 } 4770 4771 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4772 return tracesFile; 4773 } 4774 4775 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4776 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4777 // Use a FileObserver to detect when traces finish writing. 4778 // The order of traces is considered important to maintain for legibility. 4779 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4780 @Override 4781 public synchronized void onEvent(int event, String path) { notify(); } 4782 }; 4783 4784 try { 4785 observer.startWatching(); 4786 4787 // First collect all of the stacks of the most important pids. 4788 if (firstPids != null) { 4789 try { 4790 int num = firstPids.size(); 4791 for (int i = 0; i < num; i++) { 4792 synchronized (observer) { 4793 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4794 observer.wait(200); // Wait for write-close, give up after 200msec 4795 } 4796 } 4797 } catch (InterruptedException e) { 4798 Slog.wtf(TAG, e); 4799 } 4800 } 4801 4802 // Next collect the stacks of the native pids 4803 if (nativeProcs != null) { 4804 int[] pids = Process.getPidsForCommands(nativeProcs); 4805 if (pids != null) { 4806 for (int pid : pids) { 4807 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4808 } 4809 } 4810 } 4811 4812 // Lastly, measure CPU usage. 4813 if (processCpuTracker != null) { 4814 processCpuTracker.init(); 4815 System.gc(); 4816 processCpuTracker.update(); 4817 try { 4818 synchronized (processCpuTracker) { 4819 processCpuTracker.wait(500); // measure over 1/2 second. 4820 } 4821 } catch (InterruptedException e) { 4822 } 4823 processCpuTracker.update(); 4824 4825 // We'll take the stack crawls of just the top apps using CPU. 4826 final int N = processCpuTracker.countWorkingStats(); 4827 int numProcs = 0; 4828 for (int i=0; i<N && numProcs<5; i++) { 4829 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4830 if (lastPids.indexOfKey(stats.pid) >= 0) { 4831 numProcs++; 4832 try { 4833 synchronized (observer) { 4834 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4835 observer.wait(200); // Wait for write-close, give up after 200msec 4836 } 4837 } catch (InterruptedException e) { 4838 Slog.wtf(TAG, e); 4839 } 4840 4841 } 4842 } 4843 } 4844 } finally { 4845 observer.stopWatching(); 4846 } 4847 } 4848 4849 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4850 if (true || IS_USER_BUILD) { 4851 return; 4852 } 4853 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4854 if (tracesPath == null || tracesPath.length() == 0) { 4855 return; 4856 } 4857 4858 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4859 StrictMode.allowThreadDiskWrites(); 4860 try { 4861 final File tracesFile = new File(tracesPath); 4862 final File tracesDir = tracesFile.getParentFile(); 4863 final File tracesTmp = new File(tracesDir, "__tmp__"); 4864 try { 4865 if (!tracesDir.exists()) { 4866 tracesDir.mkdirs(); 4867 if (!SELinux.restorecon(tracesDir.getPath())) { 4868 return; 4869 } 4870 } 4871 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4872 4873 if (tracesFile.exists()) { 4874 tracesTmp.delete(); 4875 tracesFile.renameTo(tracesTmp); 4876 } 4877 StringBuilder sb = new StringBuilder(); 4878 Time tobj = new Time(); 4879 tobj.set(System.currentTimeMillis()); 4880 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4881 sb.append(": "); 4882 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4883 sb.append(" since "); 4884 sb.append(msg); 4885 FileOutputStream fos = new FileOutputStream(tracesFile); 4886 fos.write(sb.toString().getBytes()); 4887 if (app == null) { 4888 fos.write("\n*** No application process!".getBytes()); 4889 } 4890 fos.close(); 4891 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4892 } catch (IOException e) { 4893 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4894 return; 4895 } 4896 4897 if (app != null) { 4898 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4899 firstPids.add(app.pid); 4900 dumpStackTraces(tracesPath, firstPids, null, null, null); 4901 } 4902 4903 File lastTracesFile = null; 4904 File curTracesFile = null; 4905 for (int i=9; i>=0; i--) { 4906 String name = String.format(Locale.US, "slow%02d.txt", i); 4907 curTracesFile = new File(tracesDir, name); 4908 if (curTracesFile.exists()) { 4909 if (lastTracesFile != null) { 4910 curTracesFile.renameTo(lastTracesFile); 4911 } else { 4912 curTracesFile.delete(); 4913 } 4914 } 4915 lastTracesFile = curTracesFile; 4916 } 4917 tracesFile.renameTo(curTracesFile); 4918 if (tracesTmp.exists()) { 4919 tracesTmp.renameTo(tracesFile); 4920 } 4921 } finally { 4922 StrictMode.setThreadPolicy(oldPolicy); 4923 } 4924 } 4925 4926 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4927 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4928 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4929 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4930 4931 if (mController != null) { 4932 try { 4933 // 0 == continue, -1 = kill process immediately 4934 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4935 if (res < 0 && app.pid != MY_PID) { 4936 app.kill("anr", true); 4937 } 4938 } catch (RemoteException e) { 4939 mController = null; 4940 Watchdog.getInstance().setActivityController(null); 4941 } 4942 } 4943 4944 long anrTime = SystemClock.uptimeMillis(); 4945 if (MONITOR_CPU_USAGE) { 4946 updateCpuStatsNow(); 4947 } 4948 4949 synchronized (this) { 4950 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4951 if (mShuttingDown) { 4952 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4953 return; 4954 } else if (app.notResponding) { 4955 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4956 return; 4957 } else if (app.crashing) { 4958 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4959 return; 4960 } 4961 4962 // In case we come through here for the same app before completing 4963 // this one, mark as anring now so we will bail out. 4964 app.notResponding = true; 4965 4966 // Log the ANR to the event log. 4967 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4968 app.processName, app.info.flags, annotation); 4969 4970 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4971 firstPids.add(app.pid); 4972 4973 int parentPid = app.pid; 4974 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4975 if (parentPid != app.pid) firstPids.add(parentPid); 4976 4977 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4978 4979 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4980 ProcessRecord r = mLruProcesses.get(i); 4981 if (r != null && r.thread != null) { 4982 int pid = r.pid; 4983 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4984 if (r.persistent) { 4985 firstPids.add(pid); 4986 } else { 4987 lastPids.put(pid, Boolean.TRUE); 4988 } 4989 } 4990 } 4991 } 4992 } 4993 4994 // Log the ANR to the main log. 4995 StringBuilder info = new StringBuilder(); 4996 info.setLength(0); 4997 info.append("ANR in ").append(app.processName); 4998 if (activity != null && activity.shortComponentName != null) { 4999 info.append(" (").append(activity.shortComponentName).append(")"); 5000 } 5001 info.append("\n"); 5002 info.append("PID: ").append(app.pid).append("\n"); 5003 if (annotation != null) { 5004 info.append("Reason: ").append(annotation).append("\n"); 5005 } 5006 if (parent != null && parent != activity) { 5007 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5008 } 5009 5010 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5011 5012 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5013 NATIVE_STACKS_OF_INTEREST); 5014 5015 String cpuInfo = null; 5016 if (MONITOR_CPU_USAGE) { 5017 updateCpuStatsNow(); 5018 synchronized (mProcessCpuTracker) { 5019 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5020 } 5021 info.append(processCpuTracker.printCurrentLoad()); 5022 info.append(cpuInfo); 5023 } 5024 5025 info.append(processCpuTracker.printCurrentState(anrTime)); 5026 5027 Slog.e(TAG, info.toString()); 5028 if (tracesFile == null) { 5029 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5030 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5031 } 5032 5033 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5034 cpuInfo, tracesFile, null); 5035 5036 if (mController != null) { 5037 try { 5038 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5039 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5040 if (res != 0) { 5041 if (res < 0 && app.pid != MY_PID) { 5042 app.kill("anr", true); 5043 } else { 5044 synchronized (this) { 5045 mServices.scheduleServiceTimeoutLocked(app); 5046 } 5047 } 5048 return; 5049 } 5050 } catch (RemoteException e) { 5051 mController = null; 5052 Watchdog.getInstance().setActivityController(null); 5053 } 5054 } 5055 5056 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5057 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5058 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5059 5060 synchronized (this) { 5061 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5062 5063 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5064 app.kill("bg anr", true); 5065 return; 5066 } 5067 5068 // Set the app's notResponding state, and look up the errorReportReceiver 5069 makeAppNotRespondingLocked(app, 5070 activity != null ? activity.shortComponentName : null, 5071 annotation != null ? "ANR " + annotation : "ANR", 5072 info.toString()); 5073 5074 // Bring up the infamous App Not Responding dialog 5075 Message msg = Message.obtain(); 5076 HashMap<String, Object> map = new HashMap<String, Object>(); 5077 msg.what = SHOW_NOT_RESPONDING_MSG; 5078 msg.obj = map; 5079 msg.arg1 = aboveSystem ? 1 : 0; 5080 map.put("app", app); 5081 if (activity != null) { 5082 map.put("activity", activity); 5083 } 5084 5085 mHandler.sendMessage(msg); 5086 } 5087 } 5088 5089 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5090 if (!mLaunchWarningShown) { 5091 mLaunchWarningShown = true; 5092 mHandler.post(new Runnable() { 5093 @Override 5094 public void run() { 5095 synchronized (ActivityManagerService.this) { 5096 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5097 d.show(); 5098 mHandler.postDelayed(new Runnable() { 5099 @Override 5100 public void run() { 5101 synchronized (ActivityManagerService.this) { 5102 d.dismiss(); 5103 mLaunchWarningShown = false; 5104 } 5105 } 5106 }, 4000); 5107 } 5108 } 5109 }); 5110 } 5111 } 5112 5113 @Override 5114 public boolean clearApplicationUserData(final String packageName, 5115 final IPackageDataObserver observer, int userId) { 5116 enforceNotIsolatedCaller("clearApplicationUserData"); 5117 int uid = Binder.getCallingUid(); 5118 int pid = Binder.getCallingPid(); 5119 userId = handleIncomingUser(pid, uid, 5120 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5121 long callingId = Binder.clearCallingIdentity(); 5122 try { 5123 IPackageManager pm = AppGlobals.getPackageManager(); 5124 int pkgUid = -1; 5125 synchronized(this) { 5126 try { 5127 pkgUid = pm.getPackageUid(packageName, userId); 5128 } catch (RemoteException e) { 5129 } 5130 if (pkgUid == -1) { 5131 Slog.w(TAG, "Invalid packageName: " + packageName); 5132 if (observer != null) { 5133 try { 5134 observer.onRemoveCompleted(packageName, false); 5135 } catch (RemoteException e) { 5136 Slog.i(TAG, "Observer no longer exists."); 5137 } 5138 } 5139 return false; 5140 } 5141 if (uid == pkgUid || checkComponentPermission( 5142 android.Manifest.permission.CLEAR_APP_USER_DATA, 5143 pid, uid, -1, true) 5144 == PackageManager.PERMISSION_GRANTED) { 5145 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5146 } else { 5147 throw new SecurityException("PID " + pid + " does not have permission " 5148 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5149 + " of package " + packageName); 5150 } 5151 5152 // Remove all tasks match the cleared application package and user 5153 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5154 final TaskRecord tr = mRecentTasks.get(i); 5155 final String taskPackageName = 5156 tr.getBaseIntent().getComponent().getPackageName(); 5157 if (tr.userId != userId) continue; 5158 if (!taskPackageName.equals(packageName)) continue; 5159 removeTaskByIdLocked(tr.taskId, false); 5160 } 5161 } 5162 5163 try { 5164 // Clear application user data 5165 pm.clearApplicationUserData(packageName, observer, userId); 5166 5167 synchronized(this) { 5168 // Remove all permissions granted from/to this package 5169 removeUriPermissionsForPackageLocked(packageName, userId, true); 5170 } 5171 5172 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5173 Uri.fromParts("package", packageName, null)); 5174 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5175 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5176 null, null, 0, null, null, null, false, false, userId); 5177 } catch (RemoteException e) { 5178 } 5179 } finally { 5180 Binder.restoreCallingIdentity(callingId); 5181 } 5182 return true; 5183 } 5184 5185 @Override 5186 public void killBackgroundProcesses(final String packageName, int userId) { 5187 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5188 != PackageManager.PERMISSION_GRANTED && 5189 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5190 != PackageManager.PERMISSION_GRANTED) { 5191 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5192 + Binder.getCallingPid() 5193 + ", uid=" + Binder.getCallingUid() 5194 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5195 Slog.w(TAG, msg); 5196 throw new SecurityException(msg); 5197 } 5198 5199 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5200 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5201 long callingId = Binder.clearCallingIdentity(); 5202 try { 5203 IPackageManager pm = AppGlobals.getPackageManager(); 5204 synchronized(this) { 5205 int appId = -1; 5206 try { 5207 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5208 } catch (RemoteException e) { 5209 } 5210 if (appId == -1) { 5211 Slog.w(TAG, "Invalid packageName: " + packageName); 5212 return; 5213 } 5214 killPackageProcessesLocked(packageName, appId, userId, 5215 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5216 } 5217 } finally { 5218 Binder.restoreCallingIdentity(callingId); 5219 } 5220 } 5221 5222 @Override 5223 public void killAllBackgroundProcesses() { 5224 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5225 != PackageManager.PERMISSION_GRANTED) { 5226 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5227 + Binder.getCallingPid() 5228 + ", uid=" + Binder.getCallingUid() 5229 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5230 Slog.w(TAG, msg); 5231 throw new SecurityException(msg); 5232 } 5233 5234 long callingId = Binder.clearCallingIdentity(); 5235 try { 5236 synchronized(this) { 5237 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5238 final int NP = mProcessNames.getMap().size(); 5239 for (int ip=0; ip<NP; ip++) { 5240 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5241 final int NA = apps.size(); 5242 for (int ia=0; ia<NA; ia++) { 5243 ProcessRecord app = apps.valueAt(ia); 5244 if (app.persistent) { 5245 // we don't kill persistent processes 5246 continue; 5247 } 5248 if (app.removed) { 5249 procs.add(app); 5250 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5251 app.removed = true; 5252 procs.add(app); 5253 } 5254 } 5255 } 5256 5257 int N = procs.size(); 5258 for (int i=0; i<N; i++) { 5259 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5260 } 5261 mAllowLowerMemLevel = true; 5262 updateOomAdjLocked(); 5263 doLowMemReportIfNeededLocked(null); 5264 } 5265 } finally { 5266 Binder.restoreCallingIdentity(callingId); 5267 } 5268 } 5269 5270 @Override 5271 public void forceStopPackage(final String packageName, int userId) { 5272 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5273 != PackageManager.PERMISSION_GRANTED) { 5274 String msg = "Permission Denial: forceStopPackage() from pid=" 5275 + Binder.getCallingPid() 5276 + ", uid=" + Binder.getCallingUid() 5277 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5278 Slog.w(TAG, msg); 5279 throw new SecurityException(msg); 5280 } 5281 final int callingPid = Binder.getCallingPid(); 5282 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5283 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5284 long callingId = Binder.clearCallingIdentity(); 5285 try { 5286 IPackageManager pm = AppGlobals.getPackageManager(); 5287 synchronized(this) { 5288 int[] users = userId == UserHandle.USER_ALL 5289 ? getUsersLocked() : new int[] { userId }; 5290 for (int user : users) { 5291 int pkgUid = -1; 5292 try { 5293 pkgUid = pm.getPackageUid(packageName, user); 5294 } catch (RemoteException e) { 5295 } 5296 if (pkgUid == -1) { 5297 Slog.w(TAG, "Invalid packageName: " + packageName); 5298 continue; 5299 } 5300 try { 5301 pm.setPackageStoppedState(packageName, true, user); 5302 } catch (RemoteException e) { 5303 } catch (IllegalArgumentException e) { 5304 Slog.w(TAG, "Failed trying to unstop package " 5305 + packageName + ": " + e); 5306 } 5307 if (isUserRunningLocked(user, false)) { 5308 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5309 } 5310 } 5311 } 5312 } finally { 5313 Binder.restoreCallingIdentity(callingId); 5314 } 5315 } 5316 5317 @Override 5318 public void addPackageDependency(String packageName) { 5319 synchronized (this) { 5320 int callingPid = Binder.getCallingPid(); 5321 if (callingPid == Process.myPid()) { 5322 // Yeah, um, no. 5323 return; 5324 } 5325 ProcessRecord proc; 5326 synchronized (mPidsSelfLocked) { 5327 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5328 } 5329 if (proc != null) { 5330 if (proc.pkgDeps == null) { 5331 proc.pkgDeps = new ArraySet<String>(1); 5332 } 5333 proc.pkgDeps.add(packageName); 5334 } 5335 } 5336 } 5337 5338 /* 5339 * The pkg name and app id have to be specified. 5340 */ 5341 @Override 5342 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5343 if (pkg == null) { 5344 return; 5345 } 5346 // Make sure the uid is valid. 5347 if (appid < 0) { 5348 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5349 return; 5350 } 5351 int callerUid = Binder.getCallingUid(); 5352 // Only the system server can kill an application 5353 if (callerUid == Process.SYSTEM_UID) { 5354 // Post an aysnc message to kill the application 5355 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5356 msg.arg1 = appid; 5357 msg.arg2 = 0; 5358 Bundle bundle = new Bundle(); 5359 bundle.putString("pkg", pkg); 5360 bundle.putString("reason", reason); 5361 msg.obj = bundle; 5362 mHandler.sendMessage(msg); 5363 } else { 5364 throw new SecurityException(callerUid + " cannot kill pkg: " + 5365 pkg); 5366 } 5367 } 5368 5369 @Override 5370 public void closeSystemDialogs(String reason) { 5371 enforceNotIsolatedCaller("closeSystemDialogs"); 5372 5373 final int pid = Binder.getCallingPid(); 5374 final int uid = Binder.getCallingUid(); 5375 final long origId = Binder.clearCallingIdentity(); 5376 try { 5377 synchronized (this) { 5378 // Only allow this from foreground processes, so that background 5379 // applications can't abuse it to prevent system UI from being shown. 5380 if (uid >= Process.FIRST_APPLICATION_UID) { 5381 ProcessRecord proc; 5382 synchronized (mPidsSelfLocked) { 5383 proc = mPidsSelfLocked.get(pid); 5384 } 5385 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5386 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5387 + " from background process " + proc); 5388 return; 5389 } 5390 } 5391 closeSystemDialogsLocked(reason); 5392 } 5393 } finally { 5394 Binder.restoreCallingIdentity(origId); 5395 } 5396 } 5397 5398 void closeSystemDialogsLocked(String reason) { 5399 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5400 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5401 | Intent.FLAG_RECEIVER_FOREGROUND); 5402 if (reason != null) { 5403 intent.putExtra("reason", reason); 5404 } 5405 mWindowManager.closeSystemDialogs(reason); 5406 5407 mStackSupervisor.closeSystemDialogsLocked(); 5408 5409 broadcastIntentLocked(null, null, intent, null, 5410 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5411 Process.SYSTEM_UID, UserHandle.USER_ALL); 5412 } 5413 5414 @Override 5415 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5416 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5417 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5418 for (int i=pids.length-1; i>=0; i--) { 5419 ProcessRecord proc; 5420 int oomAdj; 5421 synchronized (this) { 5422 synchronized (mPidsSelfLocked) { 5423 proc = mPidsSelfLocked.get(pids[i]); 5424 oomAdj = proc != null ? proc.setAdj : 0; 5425 } 5426 } 5427 infos[i] = new Debug.MemoryInfo(); 5428 Debug.getMemoryInfo(pids[i], infos[i]); 5429 if (proc != null) { 5430 synchronized (this) { 5431 if (proc.thread != null && proc.setAdj == oomAdj) { 5432 // Record this for posterity if the process has been stable. 5433 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5434 infos[i].getTotalUss(), false, proc.pkgList); 5435 } 5436 } 5437 } 5438 } 5439 return infos; 5440 } 5441 5442 @Override 5443 public long[] getProcessPss(int[] pids) { 5444 enforceNotIsolatedCaller("getProcessPss"); 5445 long[] pss = new long[pids.length]; 5446 for (int i=pids.length-1; i>=0; i--) { 5447 ProcessRecord proc; 5448 int oomAdj; 5449 synchronized (this) { 5450 synchronized (mPidsSelfLocked) { 5451 proc = mPidsSelfLocked.get(pids[i]); 5452 oomAdj = proc != null ? proc.setAdj : 0; 5453 } 5454 } 5455 long[] tmpUss = new long[1]; 5456 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5457 if (proc != null) { 5458 synchronized (this) { 5459 if (proc.thread != null && proc.setAdj == oomAdj) { 5460 // Record this for posterity if the process has been stable. 5461 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5462 } 5463 } 5464 } 5465 } 5466 return pss; 5467 } 5468 5469 @Override 5470 public void killApplicationProcess(String processName, int uid) { 5471 if (processName == null) { 5472 return; 5473 } 5474 5475 int callerUid = Binder.getCallingUid(); 5476 // Only the system server can kill an application 5477 if (callerUid == Process.SYSTEM_UID) { 5478 synchronized (this) { 5479 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5480 if (app != null && app.thread != null) { 5481 try { 5482 app.thread.scheduleSuicide(); 5483 } catch (RemoteException e) { 5484 // If the other end already died, then our work here is done. 5485 } 5486 } else { 5487 Slog.w(TAG, "Process/uid not found attempting kill of " 5488 + processName + " / " + uid); 5489 } 5490 } 5491 } else { 5492 throw new SecurityException(callerUid + " cannot kill app process: " + 5493 processName); 5494 } 5495 } 5496 5497 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5498 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5499 false, true, false, false, UserHandle.getUserId(uid), reason); 5500 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5501 Uri.fromParts("package", packageName, null)); 5502 if (!mProcessesReady) { 5503 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5504 | Intent.FLAG_RECEIVER_FOREGROUND); 5505 } 5506 intent.putExtra(Intent.EXTRA_UID, uid); 5507 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5508 broadcastIntentLocked(null, null, intent, 5509 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5510 false, false, 5511 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5512 } 5513 5514 private void forceStopUserLocked(int userId, String reason) { 5515 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5516 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5517 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5518 | Intent.FLAG_RECEIVER_FOREGROUND); 5519 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5520 broadcastIntentLocked(null, null, intent, 5521 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5522 false, false, 5523 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5524 } 5525 5526 private final boolean killPackageProcessesLocked(String packageName, int appId, 5527 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5528 boolean doit, boolean evenPersistent, String reason) { 5529 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5530 5531 // Remove all processes this package may have touched: all with the 5532 // same UID (except for the system or root user), and all whose name 5533 // matches the package name. 5534 final int NP = mProcessNames.getMap().size(); 5535 for (int ip=0; ip<NP; ip++) { 5536 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5537 final int NA = apps.size(); 5538 for (int ia=0; ia<NA; ia++) { 5539 ProcessRecord app = apps.valueAt(ia); 5540 if (app.persistent && !evenPersistent) { 5541 // we don't kill persistent processes 5542 continue; 5543 } 5544 if (app.removed) { 5545 if (doit) { 5546 procs.add(app); 5547 } 5548 continue; 5549 } 5550 5551 // Skip process if it doesn't meet our oom adj requirement. 5552 if (app.setAdj < minOomAdj) { 5553 continue; 5554 } 5555 5556 // If no package is specified, we call all processes under the 5557 // give user id. 5558 if (packageName == null) { 5559 if (app.userId != userId) { 5560 continue; 5561 } 5562 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5563 continue; 5564 } 5565 // Package has been specified, we want to hit all processes 5566 // that match it. We need to qualify this by the processes 5567 // that are running under the specified app and user ID. 5568 } else { 5569 final boolean isDep = app.pkgDeps != null 5570 && app.pkgDeps.contains(packageName); 5571 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5572 continue; 5573 } 5574 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5575 continue; 5576 } 5577 if (!app.pkgList.containsKey(packageName) && !isDep) { 5578 continue; 5579 } 5580 } 5581 5582 // Process has passed all conditions, kill it! 5583 if (!doit) { 5584 return true; 5585 } 5586 app.removed = true; 5587 procs.add(app); 5588 } 5589 } 5590 5591 int N = procs.size(); 5592 for (int i=0; i<N; i++) { 5593 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5594 } 5595 updateOomAdjLocked(); 5596 return N > 0; 5597 } 5598 5599 private final boolean forceStopPackageLocked(String name, int appId, 5600 boolean callerWillRestart, boolean purgeCache, boolean doit, 5601 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5602 int i; 5603 int N; 5604 5605 if (userId == UserHandle.USER_ALL && name == null) { 5606 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5607 } 5608 5609 if (appId < 0 && name != null) { 5610 try { 5611 appId = UserHandle.getAppId( 5612 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5613 } catch (RemoteException e) { 5614 } 5615 } 5616 5617 if (doit) { 5618 if (name != null) { 5619 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5620 + " user=" + userId + ": " + reason); 5621 } else { 5622 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5623 } 5624 5625 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5626 for (int ip=pmap.size()-1; ip>=0; ip--) { 5627 SparseArray<Long> ba = pmap.valueAt(ip); 5628 for (i=ba.size()-1; i>=0; i--) { 5629 boolean remove = false; 5630 final int entUid = ba.keyAt(i); 5631 if (name != null) { 5632 if (userId == UserHandle.USER_ALL) { 5633 if (UserHandle.getAppId(entUid) == appId) { 5634 remove = true; 5635 } 5636 } else { 5637 if (entUid == UserHandle.getUid(userId, appId)) { 5638 remove = true; 5639 } 5640 } 5641 } else if (UserHandle.getUserId(entUid) == userId) { 5642 remove = true; 5643 } 5644 if (remove) { 5645 ba.removeAt(i); 5646 } 5647 } 5648 if (ba.size() == 0) { 5649 pmap.removeAt(ip); 5650 } 5651 } 5652 } 5653 5654 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5655 -100, callerWillRestart, true, doit, evenPersistent, 5656 name == null ? ("stop user " + userId) : ("stop " + name)); 5657 5658 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5659 if (!doit) { 5660 return true; 5661 } 5662 didSomething = true; 5663 } 5664 5665 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5666 if (!doit) { 5667 return true; 5668 } 5669 didSomething = true; 5670 } 5671 5672 if (name == null) { 5673 // Remove all sticky broadcasts from this user. 5674 mStickyBroadcasts.remove(userId); 5675 } 5676 5677 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5678 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5679 userId, providers)) { 5680 if (!doit) { 5681 return true; 5682 } 5683 didSomething = true; 5684 } 5685 N = providers.size(); 5686 for (i=0; i<N; i++) { 5687 removeDyingProviderLocked(null, providers.get(i), true); 5688 } 5689 5690 // Remove transient permissions granted from/to this package/user 5691 removeUriPermissionsForPackageLocked(name, userId, false); 5692 5693 if (name == null || uninstalling) { 5694 // Remove pending intents. For now we only do this when force 5695 // stopping users, because we have some problems when doing this 5696 // for packages -- app widgets are not currently cleaned up for 5697 // such packages, so they can be left with bad pending intents. 5698 if (mIntentSenderRecords.size() > 0) { 5699 Iterator<WeakReference<PendingIntentRecord>> it 5700 = mIntentSenderRecords.values().iterator(); 5701 while (it.hasNext()) { 5702 WeakReference<PendingIntentRecord> wpir = it.next(); 5703 if (wpir == null) { 5704 it.remove(); 5705 continue; 5706 } 5707 PendingIntentRecord pir = wpir.get(); 5708 if (pir == null) { 5709 it.remove(); 5710 continue; 5711 } 5712 if (name == null) { 5713 // Stopping user, remove all objects for the user. 5714 if (pir.key.userId != userId) { 5715 // Not the same user, skip it. 5716 continue; 5717 } 5718 } else { 5719 if (UserHandle.getAppId(pir.uid) != appId) { 5720 // Different app id, skip it. 5721 continue; 5722 } 5723 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5724 // Different user, skip it. 5725 continue; 5726 } 5727 if (!pir.key.packageName.equals(name)) { 5728 // Different package, skip it. 5729 continue; 5730 } 5731 } 5732 if (!doit) { 5733 return true; 5734 } 5735 didSomething = true; 5736 it.remove(); 5737 pir.canceled = true; 5738 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5739 pir.key.activity.pendingResults.remove(pir.ref); 5740 } 5741 } 5742 } 5743 } 5744 5745 if (doit) { 5746 if (purgeCache && name != null) { 5747 AttributeCache ac = AttributeCache.instance(); 5748 if (ac != null) { 5749 ac.removePackage(name); 5750 } 5751 } 5752 if (mBooted) { 5753 mStackSupervisor.resumeTopActivitiesLocked(); 5754 mStackSupervisor.scheduleIdleLocked(); 5755 } 5756 } 5757 5758 return didSomething; 5759 } 5760 5761 private final boolean removeProcessLocked(ProcessRecord app, 5762 boolean callerWillRestart, boolean allowRestart, String reason) { 5763 final String name = app.processName; 5764 final int uid = app.uid; 5765 if (DEBUG_PROCESSES) Slog.d( 5766 TAG, "Force removing proc " + app.toShortString() + " (" + name 5767 + "/" + uid + ")"); 5768 5769 mProcessNames.remove(name, uid); 5770 mIsolatedProcesses.remove(app.uid); 5771 if (mHeavyWeightProcess == app) { 5772 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5773 mHeavyWeightProcess.userId, 0)); 5774 mHeavyWeightProcess = null; 5775 } 5776 boolean needRestart = false; 5777 if (app.pid > 0 && app.pid != MY_PID) { 5778 int pid = app.pid; 5779 synchronized (mPidsSelfLocked) { 5780 mPidsSelfLocked.remove(pid); 5781 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5782 } 5783 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5784 if (app.isolated) { 5785 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5786 } 5787 app.kill(reason, true); 5788 handleAppDiedLocked(app, true, allowRestart); 5789 removeLruProcessLocked(app); 5790 5791 if (app.persistent && !app.isolated) { 5792 if (!callerWillRestart) { 5793 addAppLocked(app.info, false, null /* ABI override */); 5794 } else { 5795 needRestart = true; 5796 } 5797 } 5798 } else { 5799 mRemovedProcesses.add(app); 5800 } 5801 5802 return needRestart; 5803 } 5804 5805 private final void processStartTimedOutLocked(ProcessRecord app) { 5806 final int pid = app.pid; 5807 boolean gone = false; 5808 synchronized (mPidsSelfLocked) { 5809 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5810 if (knownApp != null && knownApp.thread == null) { 5811 mPidsSelfLocked.remove(pid); 5812 gone = true; 5813 } 5814 } 5815 5816 if (gone) { 5817 Slog.w(TAG, "Process " + app + " failed to attach"); 5818 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5819 pid, app.uid, app.processName); 5820 mProcessNames.remove(app.processName, app.uid); 5821 mIsolatedProcesses.remove(app.uid); 5822 if (mHeavyWeightProcess == app) { 5823 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5824 mHeavyWeightProcess.userId, 0)); 5825 mHeavyWeightProcess = null; 5826 } 5827 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5828 if (app.isolated) { 5829 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5830 } 5831 // Take care of any launching providers waiting for this process. 5832 checkAppInLaunchingProvidersLocked(app, true); 5833 // Take care of any services that are waiting for the process. 5834 mServices.processStartTimedOutLocked(app); 5835 app.kill("start timeout", true); 5836 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5837 Slog.w(TAG, "Unattached app died before backup, skipping"); 5838 try { 5839 IBackupManager bm = IBackupManager.Stub.asInterface( 5840 ServiceManager.getService(Context.BACKUP_SERVICE)); 5841 bm.agentDisconnected(app.info.packageName); 5842 } catch (RemoteException e) { 5843 // Can't happen; the backup manager is local 5844 } 5845 } 5846 if (isPendingBroadcastProcessLocked(pid)) { 5847 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5848 skipPendingBroadcastLocked(pid); 5849 } 5850 } else { 5851 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5852 } 5853 } 5854 5855 private final boolean attachApplicationLocked(IApplicationThread thread, 5856 int pid) { 5857 5858 // Find the application record that is being attached... either via 5859 // the pid if we are running in multiple processes, or just pull the 5860 // next app record if we are emulating process with anonymous threads. 5861 ProcessRecord app; 5862 if (pid != MY_PID && pid >= 0) { 5863 synchronized (mPidsSelfLocked) { 5864 app = mPidsSelfLocked.get(pid); 5865 } 5866 } else { 5867 app = null; 5868 } 5869 5870 if (app == null) { 5871 Slog.w(TAG, "No pending application record for pid " + pid 5872 + " (IApplicationThread " + thread + "); dropping process"); 5873 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5874 if (pid > 0 && pid != MY_PID) { 5875 Process.killProcessQuiet(pid); 5876 //TODO: Process.killProcessGroup(app.info.uid, pid); 5877 } else { 5878 try { 5879 thread.scheduleExit(); 5880 } catch (Exception e) { 5881 // Ignore exceptions. 5882 } 5883 } 5884 return false; 5885 } 5886 5887 // If this application record is still attached to a previous 5888 // process, clean it up now. 5889 if (app.thread != null) { 5890 handleAppDiedLocked(app, true, true); 5891 } 5892 5893 // Tell the process all about itself. 5894 5895 if (localLOGV) Slog.v( 5896 TAG, "Binding process pid " + pid + " to record " + app); 5897 5898 final String processName = app.processName; 5899 try { 5900 AppDeathRecipient adr = new AppDeathRecipient( 5901 app, pid, thread); 5902 thread.asBinder().linkToDeath(adr, 0); 5903 app.deathRecipient = adr; 5904 } catch (RemoteException e) { 5905 app.resetPackageList(mProcessStats); 5906 startProcessLocked(app, "link fail", processName); 5907 return false; 5908 } 5909 5910 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5911 5912 app.makeActive(thread, mProcessStats); 5913 app.curAdj = app.setAdj = -100; 5914 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5915 app.forcingToForeground = null; 5916 updateProcessForegroundLocked(app, false, false); 5917 app.hasShownUi = false; 5918 app.debugging = false; 5919 app.cached = false; 5920 app.killedByAm = false; 5921 5922 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5923 5924 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5925 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5926 5927 if (!normalMode) { 5928 Slog.i(TAG, "Launching preboot mode app: " + app); 5929 } 5930 5931 if (localLOGV) Slog.v( 5932 TAG, "New app record " + app 5933 + " thread=" + thread.asBinder() + " pid=" + pid); 5934 try { 5935 int testMode = IApplicationThread.DEBUG_OFF; 5936 if (mDebugApp != null && mDebugApp.equals(processName)) { 5937 testMode = mWaitForDebugger 5938 ? IApplicationThread.DEBUG_WAIT 5939 : IApplicationThread.DEBUG_ON; 5940 app.debugging = true; 5941 if (mDebugTransient) { 5942 mDebugApp = mOrigDebugApp; 5943 mWaitForDebugger = mOrigWaitForDebugger; 5944 } 5945 } 5946 String profileFile = app.instrumentationProfileFile; 5947 ParcelFileDescriptor profileFd = null; 5948 int samplingInterval = 0; 5949 boolean profileAutoStop = false; 5950 if (mProfileApp != null && mProfileApp.equals(processName)) { 5951 mProfileProc = app; 5952 profileFile = mProfileFile; 5953 profileFd = mProfileFd; 5954 samplingInterval = mSamplingInterval; 5955 profileAutoStop = mAutoStopProfiler; 5956 } 5957 boolean enableOpenGlTrace = false; 5958 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5959 enableOpenGlTrace = true; 5960 mOpenGlTraceApp = null; 5961 } 5962 5963 // If the app is being launched for restore or full backup, set it up specially 5964 boolean isRestrictedBackupMode = false; 5965 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5966 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5967 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5968 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5969 } 5970 5971 ensurePackageDexOpt(app.instrumentationInfo != null 5972 ? app.instrumentationInfo.packageName 5973 : app.info.packageName); 5974 if (app.instrumentationClass != null) { 5975 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5976 } 5977 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5978 + processName + " with config " + mConfiguration); 5979 ApplicationInfo appInfo = app.instrumentationInfo != null 5980 ? app.instrumentationInfo : app.info; 5981 app.compat = compatibilityInfoForPackageLocked(appInfo); 5982 if (profileFd != null) { 5983 profileFd = profileFd.dup(); 5984 } 5985 ProfilerInfo profilerInfo = profileFile == null ? null 5986 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5987 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5988 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5989 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5990 isRestrictedBackupMode || !normalMode, app.persistent, 5991 new Configuration(mConfiguration), app.compat, 5992 getCommonServicesLocked(app.isolated), 5993 mCoreSettingsObserver.getCoreSettingsLocked()); 5994 updateLruProcessLocked(app, false, null); 5995 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5996 } catch (Exception e) { 5997 // todo: Yikes! What should we do? For now we will try to 5998 // start another process, but that could easily get us in 5999 // an infinite loop of restarting processes... 6000 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6001 6002 app.resetPackageList(mProcessStats); 6003 app.unlinkDeathRecipient(); 6004 startProcessLocked(app, "bind fail", processName); 6005 return false; 6006 } 6007 6008 // Remove this record from the list of starting applications. 6009 mPersistentStartingProcesses.remove(app); 6010 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6011 "Attach application locked removing on hold: " + app); 6012 mProcessesOnHold.remove(app); 6013 6014 boolean badApp = false; 6015 boolean didSomething = false; 6016 6017 // See if the top visible activity is waiting to run in this process... 6018 if (normalMode) { 6019 try { 6020 if (mStackSupervisor.attachApplicationLocked(app)) { 6021 didSomething = true; 6022 } 6023 } catch (Exception e) { 6024 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6025 badApp = true; 6026 } 6027 } 6028 6029 // Find any services that should be running in this process... 6030 if (!badApp) { 6031 try { 6032 didSomething |= mServices.attachApplicationLocked(app, processName); 6033 } catch (Exception e) { 6034 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6035 badApp = true; 6036 } 6037 } 6038 6039 // Check if a next-broadcast receiver is in this process... 6040 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6041 try { 6042 didSomething |= sendPendingBroadcastsLocked(app); 6043 } catch (Exception e) { 6044 // If the app died trying to launch the receiver we declare it 'bad' 6045 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6046 badApp = true; 6047 } 6048 } 6049 6050 // Check whether the next backup agent is in this process... 6051 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6052 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6053 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6054 try { 6055 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6056 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6057 mBackupTarget.backupMode); 6058 } catch (Exception e) { 6059 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6060 badApp = true; 6061 } 6062 } 6063 6064 if (badApp) { 6065 app.kill("error during init", true); 6066 handleAppDiedLocked(app, false, true); 6067 return false; 6068 } 6069 6070 if (!didSomething) { 6071 updateOomAdjLocked(); 6072 } 6073 6074 return true; 6075 } 6076 6077 @Override 6078 public final void attachApplication(IApplicationThread thread) { 6079 synchronized (this) { 6080 int callingPid = Binder.getCallingPid(); 6081 final long origId = Binder.clearCallingIdentity(); 6082 attachApplicationLocked(thread, callingPid); 6083 Binder.restoreCallingIdentity(origId); 6084 } 6085 } 6086 6087 @Override 6088 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6089 final long origId = Binder.clearCallingIdentity(); 6090 synchronized (this) { 6091 ActivityStack stack = ActivityRecord.getStackLocked(token); 6092 if (stack != null) { 6093 ActivityRecord r = 6094 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6095 if (stopProfiling) { 6096 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6097 try { 6098 mProfileFd.close(); 6099 } catch (IOException e) { 6100 } 6101 clearProfilerLocked(); 6102 } 6103 } 6104 } 6105 } 6106 Binder.restoreCallingIdentity(origId); 6107 } 6108 6109 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6110 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6111 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6112 } 6113 6114 void enableScreenAfterBoot() { 6115 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6116 SystemClock.uptimeMillis()); 6117 mWindowManager.enableScreenAfterBoot(); 6118 6119 synchronized (this) { 6120 updateEventDispatchingLocked(); 6121 } 6122 } 6123 6124 @Override 6125 public void showBootMessage(final CharSequence msg, final boolean always) { 6126 enforceNotIsolatedCaller("showBootMessage"); 6127 mWindowManager.showBootMessage(msg, always); 6128 } 6129 6130 @Override 6131 public void keyguardWaitingForActivityDrawn() { 6132 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6133 final long token = Binder.clearCallingIdentity(); 6134 try { 6135 synchronized (this) { 6136 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6137 mWindowManager.keyguardWaitingForActivityDrawn(); 6138 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6139 mLockScreenShown = LOCK_SCREEN_LEAVING; 6140 updateSleepIfNeededLocked(); 6141 } 6142 } 6143 } finally { 6144 Binder.restoreCallingIdentity(token); 6145 } 6146 } 6147 6148 final void finishBooting() { 6149 synchronized (this) { 6150 if (!mBootAnimationComplete) { 6151 mCallFinishBooting = true; 6152 return; 6153 } 6154 mCallFinishBooting = false; 6155 } 6156 6157 ArraySet<String> completedIsas = new ArraySet<String>(); 6158 for (String abi : Build.SUPPORTED_ABIS) { 6159 Process.establishZygoteConnectionForAbi(abi); 6160 final String instructionSet = VMRuntime.getInstructionSet(abi); 6161 if (!completedIsas.contains(instructionSet)) { 6162 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6163 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6164 } 6165 completedIsas.add(instructionSet); 6166 } 6167 } 6168 6169 IntentFilter pkgFilter = new IntentFilter(); 6170 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6171 pkgFilter.addDataScheme("package"); 6172 mContext.registerReceiver(new BroadcastReceiver() { 6173 @Override 6174 public void onReceive(Context context, Intent intent) { 6175 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6176 if (pkgs != null) { 6177 for (String pkg : pkgs) { 6178 synchronized (ActivityManagerService.this) { 6179 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6180 0, "finished booting")) { 6181 setResultCode(Activity.RESULT_OK); 6182 return; 6183 } 6184 } 6185 } 6186 } 6187 } 6188 }, pkgFilter); 6189 6190 // Let system services know. 6191 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6192 6193 synchronized (this) { 6194 // Ensure that any processes we had put on hold are now started 6195 // up. 6196 final int NP = mProcessesOnHold.size(); 6197 if (NP > 0) { 6198 ArrayList<ProcessRecord> procs = 6199 new ArrayList<ProcessRecord>(mProcessesOnHold); 6200 for (int ip=0; ip<NP; ip++) { 6201 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6202 + procs.get(ip)); 6203 startProcessLocked(procs.get(ip), "on-hold", null); 6204 } 6205 } 6206 6207 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6208 // Start looking for apps that are abusing wake locks. 6209 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6210 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6211 // Tell anyone interested that we are done booting! 6212 SystemProperties.set("sys.boot_completed", "1"); 6213 6214 // And trigger dev.bootcomplete if we are not showing encryption progress 6215 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6216 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6217 SystemProperties.set("dev.bootcomplete", "1"); 6218 } 6219 for (int i=0; i<mStartedUsers.size(); i++) { 6220 UserStartedState uss = mStartedUsers.valueAt(i); 6221 if (uss.mState == UserStartedState.STATE_BOOTING) { 6222 uss.mState = UserStartedState.STATE_RUNNING; 6223 final int userId = mStartedUsers.keyAt(i); 6224 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6225 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6226 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6227 broadcastIntentLocked(null, null, intent, null, 6228 new IIntentReceiver.Stub() { 6229 @Override 6230 public void performReceive(Intent intent, int resultCode, 6231 String data, Bundle extras, boolean ordered, 6232 boolean sticky, int sendingUser) { 6233 synchronized (ActivityManagerService.this) { 6234 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6235 true, false); 6236 } 6237 } 6238 }, 6239 0, null, null, 6240 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6241 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6242 userId); 6243 } 6244 } 6245 scheduleStartProfilesLocked(); 6246 } 6247 } 6248 } 6249 6250 @Override 6251 public void bootAnimationComplete() { 6252 final boolean callFinishBooting; 6253 synchronized (this) { 6254 callFinishBooting = mCallFinishBooting; 6255 mBootAnimationComplete = true; 6256 } 6257 if (callFinishBooting) { 6258 finishBooting(); 6259 } 6260 } 6261 6262 @Override 6263 public void systemBackupRestored() { 6264 synchronized (this) { 6265 if (mSystemReady) { 6266 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6267 } else { 6268 Slog.w(TAG, "System backup restored before system is ready"); 6269 } 6270 } 6271 } 6272 6273 final void ensureBootCompleted() { 6274 boolean booting; 6275 boolean enableScreen; 6276 synchronized (this) { 6277 booting = mBooting; 6278 mBooting = false; 6279 enableScreen = !mBooted; 6280 mBooted = true; 6281 } 6282 6283 if (booting) { 6284 finishBooting(); 6285 } 6286 6287 if (enableScreen) { 6288 enableScreenAfterBoot(); 6289 } 6290 } 6291 6292 @Override 6293 public final void activityResumed(IBinder token) { 6294 final long origId = Binder.clearCallingIdentity(); 6295 synchronized(this) { 6296 ActivityStack stack = ActivityRecord.getStackLocked(token); 6297 if (stack != null) { 6298 ActivityRecord.activityResumedLocked(token); 6299 } 6300 } 6301 Binder.restoreCallingIdentity(origId); 6302 } 6303 6304 @Override 6305 public final void activityPaused(IBinder token) { 6306 final long origId = Binder.clearCallingIdentity(); 6307 synchronized(this) { 6308 ActivityStack stack = ActivityRecord.getStackLocked(token); 6309 if (stack != null) { 6310 stack.activityPausedLocked(token, false); 6311 } 6312 } 6313 Binder.restoreCallingIdentity(origId); 6314 } 6315 6316 @Override 6317 public final void activityStopped(IBinder token, Bundle icicle, 6318 PersistableBundle persistentState, CharSequence description) { 6319 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6320 6321 // Refuse possible leaked file descriptors 6322 if (icicle != null && icicle.hasFileDescriptors()) { 6323 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6324 } 6325 6326 final long origId = Binder.clearCallingIdentity(); 6327 6328 synchronized (this) { 6329 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6330 if (r != null) { 6331 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6332 } 6333 } 6334 6335 trimApplications(); 6336 6337 Binder.restoreCallingIdentity(origId); 6338 } 6339 6340 @Override 6341 public final void activityDestroyed(IBinder token) { 6342 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6343 synchronized (this) { 6344 ActivityStack stack = ActivityRecord.getStackLocked(token); 6345 if (stack != null) { 6346 stack.activityDestroyedLocked(token, "activityDestroyed"); 6347 } 6348 } 6349 } 6350 6351 @Override 6352 public final void backgroundResourcesReleased(IBinder token) { 6353 final long origId = Binder.clearCallingIdentity(); 6354 try { 6355 synchronized (this) { 6356 ActivityStack stack = ActivityRecord.getStackLocked(token); 6357 if (stack != null) { 6358 stack.backgroundResourcesReleased(); 6359 } 6360 } 6361 } finally { 6362 Binder.restoreCallingIdentity(origId); 6363 } 6364 } 6365 6366 @Override 6367 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6368 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6369 } 6370 6371 @Override 6372 public final void notifyEnterAnimationComplete(IBinder token) { 6373 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6374 } 6375 6376 @Override 6377 public String getCallingPackage(IBinder token) { 6378 synchronized (this) { 6379 ActivityRecord r = getCallingRecordLocked(token); 6380 return r != null ? r.info.packageName : null; 6381 } 6382 } 6383 6384 @Override 6385 public ComponentName getCallingActivity(IBinder token) { 6386 synchronized (this) { 6387 ActivityRecord r = getCallingRecordLocked(token); 6388 return r != null ? r.intent.getComponent() : null; 6389 } 6390 } 6391 6392 private ActivityRecord getCallingRecordLocked(IBinder token) { 6393 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6394 if (r == null) { 6395 return null; 6396 } 6397 return r.resultTo; 6398 } 6399 6400 @Override 6401 public ComponentName getActivityClassForToken(IBinder token) { 6402 synchronized(this) { 6403 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6404 if (r == null) { 6405 return null; 6406 } 6407 return r.intent.getComponent(); 6408 } 6409 } 6410 6411 @Override 6412 public String getPackageForToken(IBinder token) { 6413 synchronized(this) { 6414 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6415 if (r == null) { 6416 return null; 6417 } 6418 return r.packageName; 6419 } 6420 } 6421 6422 @Override 6423 public IIntentSender getIntentSender(int type, 6424 String packageName, IBinder token, String resultWho, 6425 int requestCode, Intent[] intents, String[] resolvedTypes, 6426 int flags, Bundle options, int userId) { 6427 enforceNotIsolatedCaller("getIntentSender"); 6428 // Refuse possible leaked file descriptors 6429 if (intents != null) { 6430 if (intents.length < 1) { 6431 throw new IllegalArgumentException("Intents array length must be >= 1"); 6432 } 6433 for (int i=0; i<intents.length; i++) { 6434 Intent intent = intents[i]; 6435 if (intent != null) { 6436 if (intent.hasFileDescriptors()) { 6437 throw new IllegalArgumentException("File descriptors passed in Intent"); 6438 } 6439 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6440 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6441 throw new IllegalArgumentException( 6442 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6443 } 6444 intents[i] = new Intent(intent); 6445 } 6446 } 6447 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6448 throw new IllegalArgumentException( 6449 "Intent array length does not match resolvedTypes length"); 6450 } 6451 } 6452 if (options != null) { 6453 if (options.hasFileDescriptors()) { 6454 throw new IllegalArgumentException("File descriptors passed in options"); 6455 } 6456 } 6457 6458 synchronized(this) { 6459 int callingUid = Binder.getCallingUid(); 6460 int origUserId = userId; 6461 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6462 type == ActivityManager.INTENT_SENDER_BROADCAST, 6463 ALLOW_NON_FULL, "getIntentSender", null); 6464 if (origUserId == UserHandle.USER_CURRENT) { 6465 // We don't want to evaluate this until the pending intent is 6466 // actually executed. However, we do want to always do the 6467 // security checking for it above. 6468 userId = UserHandle.USER_CURRENT; 6469 } 6470 try { 6471 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6472 int uid = AppGlobals.getPackageManager() 6473 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6474 if (!UserHandle.isSameApp(callingUid, uid)) { 6475 String msg = "Permission Denial: getIntentSender() from pid=" 6476 + Binder.getCallingPid() 6477 + ", uid=" + Binder.getCallingUid() 6478 + ", (need uid=" + uid + ")" 6479 + " is not allowed to send as package " + packageName; 6480 Slog.w(TAG, msg); 6481 throw new SecurityException(msg); 6482 } 6483 } 6484 6485 return getIntentSenderLocked(type, packageName, callingUid, userId, 6486 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6487 6488 } catch (RemoteException e) { 6489 throw new SecurityException(e); 6490 } 6491 } 6492 } 6493 6494 IIntentSender getIntentSenderLocked(int type, String packageName, 6495 int callingUid, int userId, IBinder token, String resultWho, 6496 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6497 Bundle options) { 6498 if (DEBUG_MU) 6499 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6500 ActivityRecord activity = null; 6501 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6502 activity = ActivityRecord.isInStackLocked(token); 6503 if (activity == null) { 6504 return null; 6505 } 6506 if (activity.finishing) { 6507 return null; 6508 } 6509 } 6510 6511 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6512 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6513 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6514 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6515 |PendingIntent.FLAG_UPDATE_CURRENT); 6516 6517 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6518 type, packageName, activity, resultWho, 6519 requestCode, intents, resolvedTypes, flags, options, userId); 6520 WeakReference<PendingIntentRecord> ref; 6521 ref = mIntentSenderRecords.get(key); 6522 PendingIntentRecord rec = ref != null ? ref.get() : null; 6523 if (rec != null) { 6524 if (!cancelCurrent) { 6525 if (updateCurrent) { 6526 if (rec.key.requestIntent != null) { 6527 rec.key.requestIntent.replaceExtras(intents != null ? 6528 intents[intents.length - 1] : null); 6529 } 6530 if (intents != null) { 6531 intents[intents.length-1] = rec.key.requestIntent; 6532 rec.key.allIntents = intents; 6533 rec.key.allResolvedTypes = resolvedTypes; 6534 } else { 6535 rec.key.allIntents = null; 6536 rec.key.allResolvedTypes = null; 6537 } 6538 } 6539 return rec; 6540 } 6541 rec.canceled = true; 6542 mIntentSenderRecords.remove(key); 6543 } 6544 if (noCreate) { 6545 return rec; 6546 } 6547 rec = new PendingIntentRecord(this, key, callingUid); 6548 mIntentSenderRecords.put(key, rec.ref); 6549 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6550 if (activity.pendingResults == null) { 6551 activity.pendingResults 6552 = new HashSet<WeakReference<PendingIntentRecord>>(); 6553 } 6554 activity.pendingResults.add(rec.ref); 6555 } 6556 return rec; 6557 } 6558 6559 @Override 6560 public void cancelIntentSender(IIntentSender sender) { 6561 if (!(sender instanceof PendingIntentRecord)) { 6562 return; 6563 } 6564 synchronized(this) { 6565 PendingIntentRecord rec = (PendingIntentRecord)sender; 6566 try { 6567 int uid = AppGlobals.getPackageManager() 6568 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6569 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6570 String msg = "Permission Denial: cancelIntentSender() from pid=" 6571 + Binder.getCallingPid() 6572 + ", uid=" + Binder.getCallingUid() 6573 + " is not allowed to cancel packges " 6574 + rec.key.packageName; 6575 Slog.w(TAG, msg); 6576 throw new SecurityException(msg); 6577 } 6578 } catch (RemoteException e) { 6579 throw new SecurityException(e); 6580 } 6581 cancelIntentSenderLocked(rec, true); 6582 } 6583 } 6584 6585 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6586 rec.canceled = true; 6587 mIntentSenderRecords.remove(rec.key); 6588 if (cleanActivity && rec.key.activity != null) { 6589 rec.key.activity.pendingResults.remove(rec.ref); 6590 } 6591 } 6592 6593 @Override 6594 public String getPackageForIntentSender(IIntentSender pendingResult) { 6595 if (!(pendingResult instanceof PendingIntentRecord)) { 6596 return null; 6597 } 6598 try { 6599 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6600 return res.key.packageName; 6601 } catch (ClassCastException e) { 6602 } 6603 return null; 6604 } 6605 6606 @Override 6607 public int getUidForIntentSender(IIntentSender sender) { 6608 if (sender instanceof PendingIntentRecord) { 6609 try { 6610 PendingIntentRecord res = (PendingIntentRecord)sender; 6611 return res.uid; 6612 } catch (ClassCastException e) { 6613 } 6614 } 6615 return -1; 6616 } 6617 6618 @Override 6619 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6620 if (!(pendingResult instanceof PendingIntentRecord)) { 6621 return false; 6622 } 6623 try { 6624 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6625 if (res.key.allIntents == null) { 6626 return false; 6627 } 6628 for (int i=0; i<res.key.allIntents.length; i++) { 6629 Intent intent = res.key.allIntents[i]; 6630 if (intent.getPackage() != null && intent.getComponent() != null) { 6631 return false; 6632 } 6633 } 6634 return true; 6635 } catch (ClassCastException e) { 6636 } 6637 return false; 6638 } 6639 6640 @Override 6641 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6642 if (!(pendingResult instanceof PendingIntentRecord)) { 6643 return false; 6644 } 6645 try { 6646 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6647 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6648 return true; 6649 } 6650 return false; 6651 } catch (ClassCastException e) { 6652 } 6653 return false; 6654 } 6655 6656 @Override 6657 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6658 if (!(pendingResult instanceof PendingIntentRecord)) { 6659 return null; 6660 } 6661 try { 6662 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6663 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6664 } catch (ClassCastException e) { 6665 } 6666 return null; 6667 } 6668 6669 @Override 6670 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6671 if (!(pendingResult instanceof PendingIntentRecord)) { 6672 return null; 6673 } 6674 try { 6675 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6676 Intent intent = res.key.requestIntent; 6677 if (intent != null) { 6678 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6679 || res.lastTagPrefix.equals(prefix))) { 6680 return res.lastTag; 6681 } 6682 res.lastTagPrefix = prefix; 6683 StringBuilder sb = new StringBuilder(128); 6684 if (prefix != null) { 6685 sb.append(prefix); 6686 } 6687 if (intent.getAction() != null) { 6688 sb.append(intent.getAction()); 6689 } else if (intent.getComponent() != null) { 6690 intent.getComponent().appendShortString(sb); 6691 } else { 6692 sb.append("?"); 6693 } 6694 return res.lastTag = sb.toString(); 6695 } 6696 } catch (ClassCastException e) { 6697 } 6698 return null; 6699 } 6700 6701 @Override 6702 public void setProcessLimit(int max) { 6703 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6704 "setProcessLimit()"); 6705 synchronized (this) { 6706 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6707 mProcessLimitOverride = max; 6708 } 6709 trimApplications(); 6710 } 6711 6712 @Override 6713 public int getProcessLimit() { 6714 synchronized (this) { 6715 return mProcessLimitOverride; 6716 } 6717 } 6718 6719 void foregroundTokenDied(ForegroundToken token) { 6720 synchronized (ActivityManagerService.this) { 6721 synchronized (mPidsSelfLocked) { 6722 ForegroundToken cur 6723 = mForegroundProcesses.get(token.pid); 6724 if (cur != token) { 6725 return; 6726 } 6727 mForegroundProcesses.remove(token.pid); 6728 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6729 if (pr == null) { 6730 return; 6731 } 6732 pr.forcingToForeground = null; 6733 updateProcessForegroundLocked(pr, false, false); 6734 } 6735 updateOomAdjLocked(); 6736 } 6737 } 6738 6739 @Override 6740 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6741 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6742 "setProcessForeground()"); 6743 synchronized(this) { 6744 boolean changed = false; 6745 6746 synchronized (mPidsSelfLocked) { 6747 ProcessRecord pr = mPidsSelfLocked.get(pid); 6748 if (pr == null && isForeground) { 6749 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6750 return; 6751 } 6752 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6753 if (oldToken != null) { 6754 oldToken.token.unlinkToDeath(oldToken, 0); 6755 mForegroundProcesses.remove(pid); 6756 if (pr != null) { 6757 pr.forcingToForeground = null; 6758 } 6759 changed = true; 6760 } 6761 if (isForeground && token != null) { 6762 ForegroundToken newToken = new ForegroundToken() { 6763 @Override 6764 public void binderDied() { 6765 foregroundTokenDied(this); 6766 } 6767 }; 6768 newToken.pid = pid; 6769 newToken.token = token; 6770 try { 6771 token.linkToDeath(newToken, 0); 6772 mForegroundProcesses.put(pid, newToken); 6773 pr.forcingToForeground = token; 6774 changed = true; 6775 } catch (RemoteException e) { 6776 // If the process died while doing this, we will later 6777 // do the cleanup with the process death link. 6778 } 6779 } 6780 } 6781 6782 if (changed) { 6783 updateOomAdjLocked(); 6784 } 6785 } 6786 } 6787 6788 // ========================================================= 6789 // PERMISSIONS 6790 // ========================================================= 6791 6792 static class PermissionController extends IPermissionController.Stub { 6793 ActivityManagerService mActivityManagerService; 6794 PermissionController(ActivityManagerService activityManagerService) { 6795 mActivityManagerService = activityManagerService; 6796 } 6797 6798 @Override 6799 public boolean checkPermission(String permission, int pid, int uid) { 6800 return mActivityManagerService.checkPermission(permission, pid, 6801 uid) == PackageManager.PERMISSION_GRANTED; 6802 } 6803 } 6804 6805 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6806 @Override 6807 public int checkComponentPermission(String permission, int pid, int uid, 6808 int owningUid, boolean exported) { 6809 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6810 owningUid, exported); 6811 } 6812 6813 @Override 6814 public Object getAMSLock() { 6815 return ActivityManagerService.this; 6816 } 6817 } 6818 6819 /** 6820 * This can be called with or without the global lock held. 6821 */ 6822 int checkComponentPermission(String permission, int pid, int uid, 6823 int owningUid, boolean exported) { 6824 if (pid == MY_PID) { 6825 return PackageManager.PERMISSION_GRANTED; 6826 } 6827 return ActivityManager.checkComponentPermission(permission, uid, 6828 owningUid, exported); 6829 } 6830 6831 /** 6832 * As the only public entry point for permissions checking, this method 6833 * can enforce the semantic that requesting a check on a null global 6834 * permission is automatically denied. (Internally a null permission 6835 * string is used when calling {@link #checkComponentPermission} in cases 6836 * when only uid-based security is needed.) 6837 * 6838 * This can be called with or without the global lock held. 6839 */ 6840 @Override 6841 public int checkPermission(String permission, int pid, int uid) { 6842 if (permission == null) { 6843 return PackageManager.PERMISSION_DENIED; 6844 } 6845 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6846 } 6847 6848 @Override 6849 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6850 if (permission == null) { 6851 return PackageManager.PERMISSION_DENIED; 6852 } 6853 6854 // We might be performing an operation on behalf of an indirect binder 6855 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6856 // client identity accordingly before proceeding. 6857 Identity tlsIdentity = sCallerIdentity.get(); 6858 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6859 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6860 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6861 uid = tlsIdentity.uid; 6862 pid = tlsIdentity.pid; 6863 } 6864 6865 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6866 } 6867 6868 /** 6869 * Binder IPC calls go through the public entry point. 6870 * This can be called with or without the global lock held. 6871 */ 6872 int checkCallingPermission(String permission) { 6873 return checkPermission(permission, 6874 Binder.getCallingPid(), 6875 UserHandle.getAppId(Binder.getCallingUid())); 6876 } 6877 6878 /** 6879 * This can be called with or without the global lock held. 6880 */ 6881 void enforceCallingPermission(String permission, String func) { 6882 if (checkCallingPermission(permission) 6883 == PackageManager.PERMISSION_GRANTED) { 6884 return; 6885 } 6886 6887 String msg = "Permission Denial: " + func + " from pid=" 6888 + Binder.getCallingPid() 6889 + ", uid=" + Binder.getCallingUid() 6890 + " requires " + permission; 6891 Slog.w(TAG, msg); 6892 throw new SecurityException(msg); 6893 } 6894 6895 /** 6896 * Determine if UID is holding permissions required to access {@link Uri} in 6897 * the given {@link ProviderInfo}. Final permission checking is always done 6898 * in {@link ContentProvider}. 6899 */ 6900 private final boolean checkHoldingPermissionsLocked( 6901 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6902 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6903 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6904 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6905 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6906 != PERMISSION_GRANTED) { 6907 return false; 6908 } 6909 } 6910 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6911 } 6912 6913 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6914 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6915 if (pi.applicationInfo.uid == uid) { 6916 return true; 6917 } else if (!pi.exported) { 6918 return false; 6919 } 6920 6921 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6922 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6923 try { 6924 // check if target holds top-level <provider> permissions 6925 if (!readMet && pi.readPermission != null && considerUidPermissions 6926 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6927 readMet = true; 6928 } 6929 if (!writeMet && pi.writePermission != null && considerUidPermissions 6930 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6931 writeMet = true; 6932 } 6933 6934 // track if unprotected read/write is allowed; any denied 6935 // <path-permission> below removes this ability 6936 boolean allowDefaultRead = pi.readPermission == null; 6937 boolean allowDefaultWrite = pi.writePermission == null; 6938 6939 // check if target holds any <path-permission> that match uri 6940 final PathPermission[] pps = pi.pathPermissions; 6941 if (pps != null) { 6942 final String path = grantUri.uri.getPath(); 6943 int i = pps.length; 6944 while (i > 0 && (!readMet || !writeMet)) { 6945 i--; 6946 PathPermission pp = pps[i]; 6947 if (pp.match(path)) { 6948 if (!readMet) { 6949 final String pprperm = pp.getReadPermission(); 6950 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6951 + pprperm + " for " + pp.getPath() 6952 + ": match=" + pp.match(path) 6953 + " check=" + pm.checkUidPermission(pprperm, uid)); 6954 if (pprperm != null) { 6955 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6956 == PERMISSION_GRANTED) { 6957 readMet = true; 6958 } else { 6959 allowDefaultRead = false; 6960 } 6961 } 6962 } 6963 if (!writeMet) { 6964 final String ppwperm = pp.getWritePermission(); 6965 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6966 + ppwperm + " for " + pp.getPath() 6967 + ": match=" + pp.match(path) 6968 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6969 if (ppwperm != null) { 6970 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6971 == PERMISSION_GRANTED) { 6972 writeMet = true; 6973 } else { 6974 allowDefaultWrite = false; 6975 } 6976 } 6977 } 6978 } 6979 } 6980 } 6981 6982 // grant unprotected <provider> read/write, if not blocked by 6983 // <path-permission> above 6984 if (allowDefaultRead) readMet = true; 6985 if (allowDefaultWrite) writeMet = true; 6986 6987 } catch (RemoteException e) { 6988 return false; 6989 } 6990 6991 return readMet && writeMet; 6992 } 6993 6994 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6995 ProviderInfo pi = null; 6996 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6997 if (cpr != null) { 6998 pi = cpr.info; 6999 } else { 7000 try { 7001 pi = AppGlobals.getPackageManager().resolveContentProvider( 7002 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7003 } catch (RemoteException ex) { 7004 } 7005 } 7006 return pi; 7007 } 7008 7009 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7010 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7011 if (targetUris != null) { 7012 return targetUris.get(grantUri); 7013 } 7014 return null; 7015 } 7016 7017 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7018 String targetPkg, int targetUid, GrantUri grantUri) { 7019 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7020 if (targetUris == null) { 7021 targetUris = Maps.newArrayMap(); 7022 mGrantedUriPermissions.put(targetUid, targetUris); 7023 } 7024 7025 UriPermission perm = targetUris.get(grantUri); 7026 if (perm == null) { 7027 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7028 targetUris.put(grantUri, perm); 7029 } 7030 7031 return perm; 7032 } 7033 7034 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7035 final int modeFlags) { 7036 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7037 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7038 : UriPermission.STRENGTH_OWNED; 7039 7040 // Root gets to do everything. 7041 if (uid == 0) { 7042 return true; 7043 } 7044 7045 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7046 if (perms == null) return false; 7047 7048 // First look for exact match 7049 final UriPermission exactPerm = perms.get(grantUri); 7050 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7051 return true; 7052 } 7053 7054 // No exact match, look for prefixes 7055 final int N = perms.size(); 7056 for (int i = 0; i < N; i++) { 7057 final UriPermission perm = perms.valueAt(i); 7058 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7059 && perm.getStrength(modeFlags) >= minStrength) { 7060 return true; 7061 } 7062 } 7063 7064 return false; 7065 } 7066 7067 /** 7068 * @param uri This uri must NOT contain an embedded userId. 7069 * @param userId The userId in which the uri is to be resolved. 7070 */ 7071 @Override 7072 public int checkUriPermission(Uri uri, int pid, int uid, 7073 final int modeFlags, int userId, IBinder callerToken) { 7074 enforceNotIsolatedCaller("checkUriPermission"); 7075 7076 // Another redirected-binder-call permissions check as in 7077 // {@link checkPermissionWithToken}. 7078 Identity tlsIdentity = sCallerIdentity.get(); 7079 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7080 uid = tlsIdentity.uid; 7081 pid = tlsIdentity.pid; 7082 } 7083 7084 // Our own process gets to do everything. 7085 if (pid == MY_PID) { 7086 return PackageManager.PERMISSION_GRANTED; 7087 } 7088 synchronized (this) { 7089 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7090 ? PackageManager.PERMISSION_GRANTED 7091 : PackageManager.PERMISSION_DENIED; 7092 } 7093 } 7094 7095 /** 7096 * Check if the targetPkg can be granted permission to access uri by 7097 * the callingUid using the given modeFlags. Throws a security exception 7098 * if callingUid is not allowed to do this. Returns the uid of the target 7099 * if the URI permission grant should be performed; returns -1 if it is not 7100 * needed (for example targetPkg already has permission to access the URI). 7101 * If you already know the uid of the target, you can supply it in 7102 * lastTargetUid else set that to -1. 7103 */ 7104 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7105 final int modeFlags, int lastTargetUid) { 7106 if (!Intent.isAccessUriMode(modeFlags)) { 7107 return -1; 7108 } 7109 7110 if (targetPkg != null) { 7111 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7112 "Checking grant " + targetPkg + " permission to " + grantUri); 7113 } 7114 7115 final IPackageManager pm = AppGlobals.getPackageManager(); 7116 7117 // If this is not a content: uri, we can't do anything with it. 7118 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7119 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7120 "Can't grant URI permission for non-content URI: " + grantUri); 7121 return -1; 7122 } 7123 7124 final String authority = grantUri.uri.getAuthority(); 7125 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7126 if (pi == null) { 7127 Slog.w(TAG, "No content provider found for permission check: " + 7128 grantUri.uri.toSafeString()); 7129 return -1; 7130 } 7131 7132 int targetUid = lastTargetUid; 7133 if (targetUid < 0 && targetPkg != null) { 7134 try { 7135 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7136 if (targetUid < 0) { 7137 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7138 "Can't grant URI permission no uid for: " + targetPkg); 7139 return -1; 7140 } 7141 } catch (RemoteException ex) { 7142 return -1; 7143 } 7144 } 7145 7146 if (targetUid >= 0) { 7147 // First... does the target actually need this permission? 7148 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7149 // No need to grant the target this permission. 7150 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7151 "Target " + targetPkg + " already has full permission to " + grantUri); 7152 return -1; 7153 } 7154 } else { 7155 // First... there is no target package, so can anyone access it? 7156 boolean allowed = pi.exported; 7157 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7158 if (pi.readPermission != null) { 7159 allowed = false; 7160 } 7161 } 7162 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7163 if (pi.writePermission != null) { 7164 allowed = false; 7165 } 7166 } 7167 if (allowed) { 7168 return -1; 7169 } 7170 } 7171 7172 /* There is a special cross user grant if: 7173 * - The target is on another user. 7174 * - Apps on the current user can access the uri without any uid permissions. 7175 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7176 * grant uri permissions. 7177 */ 7178 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7179 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7180 modeFlags, false /*without considering the uid permissions*/); 7181 7182 // Second... is the provider allowing granting of URI permissions? 7183 if (!specialCrossUserGrant) { 7184 if (!pi.grantUriPermissions) { 7185 throw new SecurityException("Provider " + pi.packageName 7186 + "/" + pi.name 7187 + " does not allow granting of Uri permissions (uri " 7188 + grantUri + ")"); 7189 } 7190 if (pi.uriPermissionPatterns != null) { 7191 final int N = pi.uriPermissionPatterns.length; 7192 boolean allowed = false; 7193 for (int i=0; i<N; i++) { 7194 if (pi.uriPermissionPatterns[i] != null 7195 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7196 allowed = true; 7197 break; 7198 } 7199 } 7200 if (!allowed) { 7201 throw new SecurityException("Provider " + pi.packageName 7202 + "/" + pi.name 7203 + " does not allow granting of permission to path of Uri " 7204 + grantUri); 7205 } 7206 } 7207 } 7208 7209 // Third... does the caller itself have permission to access 7210 // this uri? 7211 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7212 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7213 // Require they hold a strong enough Uri permission 7214 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7215 throw new SecurityException("Uid " + callingUid 7216 + " does not have permission to uri " + grantUri); 7217 } 7218 } 7219 } 7220 return targetUid; 7221 } 7222 7223 /** 7224 * @param uri This uri must NOT contain an embedded userId. 7225 * @param userId The userId in which the uri is to be resolved. 7226 */ 7227 @Override 7228 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7229 final int modeFlags, int userId) { 7230 enforceNotIsolatedCaller("checkGrantUriPermission"); 7231 synchronized(this) { 7232 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7233 new GrantUri(userId, uri, false), modeFlags, -1); 7234 } 7235 } 7236 7237 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7238 final int modeFlags, UriPermissionOwner owner) { 7239 if (!Intent.isAccessUriMode(modeFlags)) { 7240 return; 7241 } 7242 7243 // So here we are: the caller has the assumed permission 7244 // to the uri, and the target doesn't. Let's now give this to 7245 // the target. 7246 7247 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7248 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7249 7250 final String authority = grantUri.uri.getAuthority(); 7251 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7252 if (pi == null) { 7253 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7254 return; 7255 } 7256 7257 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7258 grantUri.prefix = true; 7259 } 7260 final UriPermission perm = findOrCreateUriPermissionLocked( 7261 pi.packageName, targetPkg, targetUid, grantUri); 7262 perm.grantModes(modeFlags, owner); 7263 } 7264 7265 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7266 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7267 if (targetPkg == null) { 7268 throw new NullPointerException("targetPkg"); 7269 } 7270 int targetUid; 7271 final IPackageManager pm = AppGlobals.getPackageManager(); 7272 try { 7273 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7274 } catch (RemoteException ex) { 7275 return; 7276 } 7277 7278 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7279 targetUid); 7280 if (targetUid < 0) { 7281 return; 7282 } 7283 7284 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7285 owner); 7286 } 7287 7288 static class NeededUriGrants extends ArrayList<GrantUri> { 7289 final String targetPkg; 7290 final int targetUid; 7291 final int flags; 7292 7293 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7294 this.targetPkg = targetPkg; 7295 this.targetUid = targetUid; 7296 this.flags = flags; 7297 } 7298 } 7299 7300 /** 7301 * Like checkGrantUriPermissionLocked, but takes an Intent. 7302 */ 7303 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7304 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7305 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7306 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7307 + " clip=" + (intent != null ? intent.getClipData() : null) 7308 + " from " + intent + "; flags=0x" 7309 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7310 7311 if (targetPkg == null) { 7312 throw new NullPointerException("targetPkg"); 7313 } 7314 7315 if (intent == null) { 7316 return null; 7317 } 7318 Uri data = intent.getData(); 7319 ClipData clip = intent.getClipData(); 7320 if (data == null && clip == null) { 7321 return null; 7322 } 7323 // Default userId for uris in the intent (if they don't specify it themselves) 7324 int contentUserHint = intent.getContentUserHint(); 7325 if (contentUserHint == UserHandle.USER_CURRENT) { 7326 contentUserHint = UserHandle.getUserId(callingUid); 7327 } 7328 final IPackageManager pm = AppGlobals.getPackageManager(); 7329 int targetUid; 7330 if (needed != null) { 7331 targetUid = needed.targetUid; 7332 } else { 7333 try { 7334 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7335 } catch (RemoteException ex) { 7336 return null; 7337 } 7338 if (targetUid < 0) { 7339 if (DEBUG_URI_PERMISSION) { 7340 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7341 + " on user " + targetUserId); 7342 } 7343 return null; 7344 } 7345 } 7346 if (data != null) { 7347 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7348 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7349 targetUid); 7350 if (targetUid > 0) { 7351 if (needed == null) { 7352 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7353 } 7354 needed.add(grantUri); 7355 } 7356 } 7357 if (clip != null) { 7358 for (int i=0; i<clip.getItemCount(); i++) { 7359 Uri uri = clip.getItemAt(i).getUri(); 7360 if (uri != null) { 7361 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7362 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7363 targetUid); 7364 if (targetUid > 0) { 7365 if (needed == null) { 7366 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7367 } 7368 needed.add(grantUri); 7369 } 7370 } else { 7371 Intent clipIntent = clip.getItemAt(i).getIntent(); 7372 if (clipIntent != null) { 7373 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7374 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7375 if (newNeeded != null) { 7376 needed = newNeeded; 7377 } 7378 } 7379 } 7380 } 7381 } 7382 7383 return needed; 7384 } 7385 7386 /** 7387 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7388 */ 7389 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7390 UriPermissionOwner owner) { 7391 if (needed != null) { 7392 for (int i=0; i<needed.size(); i++) { 7393 GrantUri grantUri = needed.get(i); 7394 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7395 grantUri, needed.flags, owner); 7396 } 7397 } 7398 } 7399 7400 void grantUriPermissionFromIntentLocked(int callingUid, 7401 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7402 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7403 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7404 if (needed == null) { 7405 return; 7406 } 7407 7408 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7409 } 7410 7411 /** 7412 * @param uri This uri must NOT contain an embedded userId. 7413 * @param userId The userId in which the uri is to be resolved. 7414 */ 7415 @Override 7416 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7417 final int modeFlags, int userId) { 7418 enforceNotIsolatedCaller("grantUriPermission"); 7419 GrantUri grantUri = new GrantUri(userId, uri, false); 7420 synchronized(this) { 7421 final ProcessRecord r = getRecordForAppLocked(caller); 7422 if (r == null) { 7423 throw new SecurityException("Unable to find app for caller " 7424 + caller 7425 + " when granting permission to uri " + grantUri); 7426 } 7427 if (targetPkg == null) { 7428 throw new IllegalArgumentException("null target"); 7429 } 7430 if (grantUri == null) { 7431 throw new IllegalArgumentException("null uri"); 7432 } 7433 7434 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7435 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7436 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7437 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7438 7439 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7440 UserHandle.getUserId(r.uid)); 7441 } 7442 } 7443 7444 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7445 if (perm.modeFlags == 0) { 7446 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7447 perm.targetUid); 7448 if (perms != null) { 7449 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7450 "Removing " + perm.targetUid + " permission to " + perm.uri); 7451 7452 perms.remove(perm.uri); 7453 if (perms.isEmpty()) { 7454 mGrantedUriPermissions.remove(perm.targetUid); 7455 } 7456 } 7457 } 7458 } 7459 7460 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7461 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7462 7463 final IPackageManager pm = AppGlobals.getPackageManager(); 7464 final String authority = grantUri.uri.getAuthority(); 7465 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7466 if (pi == null) { 7467 Slog.w(TAG, "No content provider found for permission revoke: " 7468 + grantUri.toSafeString()); 7469 return; 7470 } 7471 7472 // Does the caller have this permission on the URI? 7473 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7474 // If they don't have direct access to the URI, then revoke any 7475 // ownerless URI permissions that have been granted to them. 7476 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7477 if (perms != null) { 7478 boolean persistChanged = false; 7479 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7480 final UriPermission perm = it.next(); 7481 if (perm.uri.sourceUserId == grantUri.sourceUserId 7482 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7483 if (DEBUG_URI_PERMISSION) 7484 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7485 " permission to " + perm.uri); 7486 persistChanged |= perm.revokeModes( 7487 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7488 if (perm.modeFlags == 0) { 7489 it.remove(); 7490 } 7491 } 7492 } 7493 if (perms.isEmpty()) { 7494 mGrantedUriPermissions.remove(callingUid); 7495 } 7496 if (persistChanged) { 7497 schedulePersistUriGrants(); 7498 } 7499 } 7500 return; 7501 } 7502 7503 boolean persistChanged = false; 7504 7505 // Go through all of the permissions and remove any that match. 7506 int N = mGrantedUriPermissions.size(); 7507 for (int i = 0; i < N; i++) { 7508 final int targetUid = mGrantedUriPermissions.keyAt(i); 7509 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7510 7511 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7512 final UriPermission perm = it.next(); 7513 if (perm.uri.sourceUserId == grantUri.sourceUserId 7514 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7515 if (DEBUG_URI_PERMISSION) 7516 Slog.v(TAG, 7517 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7518 persistChanged |= perm.revokeModes( 7519 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7520 if (perm.modeFlags == 0) { 7521 it.remove(); 7522 } 7523 } 7524 } 7525 7526 if (perms.isEmpty()) { 7527 mGrantedUriPermissions.remove(targetUid); 7528 N--; 7529 i--; 7530 } 7531 } 7532 7533 if (persistChanged) { 7534 schedulePersistUriGrants(); 7535 } 7536 } 7537 7538 /** 7539 * @param uri This uri must NOT contain an embedded userId. 7540 * @param userId The userId in which the uri is to be resolved. 7541 */ 7542 @Override 7543 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7544 int userId) { 7545 enforceNotIsolatedCaller("revokeUriPermission"); 7546 synchronized(this) { 7547 final ProcessRecord r = getRecordForAppLocked(caller); 7548 if (r == null) { 7549 throw new SecurityException("Unable to find app for caller " 7550 + caller 7551 + " when revoking permission to uri " + uri); 7552 } 7553 if (uri == null) { 7554 Slog.w(TAG, "revokeUriPermission: null uri"); 7555 return; 7556 } 7557 7558 if (!Intent.isAccessUriMode(modeFlags)) { 7559 return; 7560 } 7561 7562 final IPackageManager pm = AppGlobals.getPackageManager(); 7563 final String authority = uri.getAuthority(); 7564 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7565 if (pi == null) { 7566 Slog.w(TAG, "No content provider found for permission revoke: " 7567 + uri.toSafeString()); 7568 return; 7569 } 7570 7571 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7572 } 7573 } 7574 7575 /** 7576 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7577 * given package. 7578 * 7579 * @param packageName Package name to match, or {@code null} to apply to all 7580 * packages. 7581 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7582 * to all users. 7583 * @param persistable If persistable grants should be removed. 7584 */ 7585 private void removeUriPermissionsForPackageLocked( 7586 String packageName, int userHandle, boolean persistable) { 7587 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7588 throw new IllegalArgumentException("Must narrow by either package or user"); 7589 } 7590 7591 boolean persistChanged = false; 7592 7593 int N = mGrantedUriPermissions.size(); 7594 for (int i = 0; i < N; i++) { 7595 final int targetUid = mGrantedUriPermissions.keyAt(i); 7596 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7597 7598 // Only inspect grants matching user 7599 if (userHandle == UserHandle.USER_ALL 7600 || userHandle == UserHandle.getUserId(targetUid)) { 7601 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7602 final UriPermission perm = it.next(); 7603 7604 // Only inspect grants matching package 7605 if (packageName == null || perm.sourcePkg.equals(packageName) 7606 || perm.targetPkg.equals(packageName)) { 7607 persistChanged |= perm.revokeModes(persistable 7608 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7609 7610 // Only remove when no modes remain; any persisted grants 7611 // will keep this alive. 7612 if (perm.modeFlags == 0) { 7613 it.remove(); 7614 } 7615 } 7616 } 7617 7618 if (perms.isEmpty()) { 7619 mGrantedUriPermissions.remove(targetUid); 7620 N--; 7621 i--; 7622 } 7623 } 7624 } 7625 7626 if (persistChanged) { 7627 schedulePersistUriGrants(); 7628 } 7629 } 7630 7631 @Override 7632 public IBinder newUriPermissionOwner(String name) { 7633 enforceNotIsolatedCaller("newUriPermissionOwner"); 7634 synchronized(this) { 7635 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7636 return owner.getExternalTokenLocked(); 7637 } 7638 } 7639 7640 /** 7641 * @param uri This uri must NOT contain an embedded userId. 7642 * @param sourceUserId The userId in which the uri is to be resolved. 7643 * @param targetUserId The userId of the app that receives the grant. 7644 */ 7645 @Override 7646 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7647 final int modeFlags, int sourceUserId, int targetUserId) { 7648 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7649 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7650 synchronized(this) { 7651 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7652 if (owner == null) { 7653 throw new IllegalArgumentException("Unknown owner: " + token); 7654 } 7655 if (fromUid != Binder.getCallingUid()) { 7656 if (Binder.getCallingUid() != Process.myUid()) { 7657 // Only system code can grant URI permissions on behalf 7658 // of other users. 7659 throw new SecurityException("nice try"); 7660 } 7661 } 7662 if (targetPkg == null) { 7663 throw new IllegalArgumentException("null target"); 7664 } 7665 if (uri == null) { 7666 throw new IllegalArgumentException("null uri"); 7667 } 7668 7669 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7670 modeFlags, owner, targetUserId); 7671 } 7672 } 7673 7674 /** 7675 * @param uri This uri must NOT contain an embedded userId. 7676 * @param userId The userId in which the uri is to be resolved. 7677 */ 7678 @Override 7679 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7680 synchronized(this) { 7681 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7682 if (owner == null) { 7683 throw new IllegalArgumentException("Unknown owner: " + token); 7684 } 7685 7686 if (uri == null) { 7687 owner.removeUriPermissionsLocked(mode); 7688 } else { 7689 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7690 } 7691 } 7692 } 7693 7694 private void schedulePersistUriGrants() { 7695 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7696 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7697 10 * DateUtils.SECOND_IN_MILLIS); 7698 } 7699 } 7700 7701 private void writeGrantedUriPermissions() { 7702 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7703 7704 // Snapshot permissions so we can persist without lock 7705 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7706 synchronized (this) { 7707 final int size = mGrantedUriPermissions.size(); 7708 for (int i = 0; i < size; i++) { 7709 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7710 for (UriPermission perm : perms.values()) { 7711 if (perm.persistedModeFlags != 0) { 7712 persist.add(perm.snapshot()); 7713 } 7714 } 7715 } 7716 } 7717 7718 FileOutputStream fos = null; 7719 try { 7720 fos = mGrantFile.startWrite(); 7721 7722 XmlSerializer out = new FastXmlSerializer(); 7723 out.setOutput(fos, "utf-8"); 7724 out.startDocument(null, true); 7725 out.startTag(null, TAG_URI_GRANTS); 7726 for (UriPermission.Snapshot perm : persist) { 7727 out.startTag(null, TAG_URI_GRANT); 7728 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7729 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7730 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7731 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7732 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7733 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7734 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7735 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7736 out.endTag(null, TAG_URI_GRANT); 7737 } 7738 out.endTag(null, TAG_URI_GRANTS); 7739 out.endDocument(); 7740 7741 mGrantFile.finishWrite(fos); 7742 } catch (IOException e) { 7743 if (fos != null) { 7744 mGrantFile.failWrite(fos); 7745 } 7746 } 7747 } 7748 7749 private void readGrantedUriPermissionsLocked() { 7750 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7751 7752 final long now = System.currentTimeMillis(); 7753 7754 FileInputStream fis = null; 7755 try { 7756 fis = mGrantFile.openRead(); 7757 final XmlPullParser in = Xml.newPullParser(); 7758 in.setInput(fis, null); 7759 7760 int type; 7761 while ((type = in.next()) != END_DOCUMENT) { 7762 final String tag = in.getName(); 7763 if (type == START_TAG) { 7764 if (TAG_URI_GRANT.equals(tag)) { 7765 final int sourceUserId; 7766 final int targetUserId; 7767 final int userHandle = readIntAttribute(in, 7768 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7769 if (userHandle != UserHandle.USER_NULL) { 7770 // For backwards compatibility. 7771 sourceUserId = userHandle; 7772 targetUserId = userHandle; 7773 } else { 7774 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7775 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7776 } 7777 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7778 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7779 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7780 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7781 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7782 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7783 7784 // Sanity check that provider still belongs to source package 7785 final ProviderInfo pi = getProviderInfoLocked( 7786 uri.getAuthority(), sourceUserId); 7787 if (pi != null && sourcePkg.equals(pi.packageName)) { 7788 int targetUid = -1; 7789 try { 7790 targetUid = AppGlobals.getPackageManager() 7791 .getPackageUid(targetPkg, targetUserId); 7792 } catch (RemoteException e) { 7793 } 7794 if (targetUid != -1) { 7795 final UriPermission perm = findOrCreateUriPermissionLocked( 7796 sourcePkg, targetPkg, targetUid, 7797 new GrantUri(sourceUserId, uri, prefix)); 7798 perm.initPersistedModes(modeFlags, createdTime); 7799 } 7800 } else { 7801 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7802 + " but instead found " + pi); 7803 } 7804 } 7805 } 7806 } 7807 } catch (FileNotFoundException e) { 7808 // Missing grants is okay 7809 } catch (IOException e) { 7810 Slog.wtf(TAG, "Failed reading Uri grants", e); 7811 } catch (XmlPullParserException e) { 7812 Slog.wtf(TAG, "Failed reading Uri grants", e); 7813 } finally { 7814 IoUtils.closeQuietly(fis); 7815 } 7816 } 7817 7818 /** 7819 * @param uri This uri must NOT contain an embedded userId. 7820 * @param userId The userId in which the uri is to be resolved. 7821 */ 7822 @Override 7823 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7824 enforceNotIsolatedCaller("takePersistableUriPermission"); 7825 7826 Preconditions.checkFlagsArgument(modeFlags, 7827 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7828 7829 synchronized (this) { 7830 final int callingUid = Binder.getCallingUid(); 7831 boolean persistChanged = false; 7832 GrantUri grantUri = new GrantUri(userId, uri, false); 7833 7834 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7835 new GrantUri(userId, uri, false)); 7836 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7837 new GrantUri(userId, uri, true)); 7838 7839 final boolean exactValid = (exactPerm != null) 7840 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7841 final boolean prefixValid = (prefixPerm != null) 7842 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7843 7844 if (!(exactValid || prefixValid)) { 7845 throw new SecurityException("No persistable permission grants found for UID " 7846 + callingUid + " and Uri " + grantUri.toSafeString()); 7847 } 7848 7849 if (exactValid) { 7850 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7851 } 7852 if (prefixValid) { 7853 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7854 } 7855 7856 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7857 7858 if (persistChanged) { 7859 schedulePersistUriGrants(); 7860 } 7861 } 7862 } 7863 7864 /** 7865 * @param uri This uri must NOT contain an embedded userId. 7866 * @param userId The userId in which the uri is to be resolved. 7867 */ 7868 @Override 7869 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7870 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7871 7872 Preconditions.checkFlagsArgument(modeFlags, 7873 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7874 7875 synchronized (this) { 7876 final int callingUid = Binder.getCallingUid(); 7877 boolean persistChanged = false; 7878 7879 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7880 new GrantUri(userId, uri, false)); 7881 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7882 new GrantUri(userId, uri, true)); 7883 if (exactPerm == null && prefixPerm == null) { 7884 throw new SecurityException("No permission grants found for UID " + callingUid 7885 + " and Uri " + uri.toSafeString()); 7886 } 7887 7888 if (exactPerm != null) { 7889 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7890 removeUriPermissionIfNeededLocked(exactPerm); 7891 } 7892 if (prefixPerm != null) { 7893 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7894 removeUriPermissionIfNeededLocked(prefixPerm); 7895 } 7896 7897 if (persistChanged) { 7898 schedulePersistUriGrants(); 7899 } 7900 } 7901 } 7902 7903 /** 7904 * Prune any older {@link UriPermission} for the given UID until outstanding 7905 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7906 * 7907 * @return if any mutations occured that require persisting. 7908 */ 7909 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7910 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7911 if (perms == null) return false; 7912 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7913 7914 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7915 for (UriPermission perm : perms.values()) { 7916 if (perm.persistedModeFlags != 0) { 7917 persisted.add(perm); 7918 } 7919 } 7920 7921 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7922 if (trimCount <= 0) return false; 7923 7924 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7925 for (int i = 0; i < trimCount; i++) { 7926 final UriPermission perm = persisted.get(i); 7927 7928 if (DEBUG_URI_PERMISSION) { 7929 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7930 } 7931 7932 perm.releasePersistableModes(~0); 7933 removeUriPermissionIfNeededLocked(perm); 7934 } 7935 7936 return true; 7937 } 7938 7939 @Override 7940 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7941 String packageName, boolean incoming) { 7942 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7943 Preconditions.checkNotNull(packageName, "packageName"); 7944 7945 final int callingUid = Binder.getCallingUid(); 7946 final IPackageManager pm = AppGlobals.getPackageManager(); 7947 try { 7948 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7949 if (packageUid != callingUid) { 7950 throw new SecurityException( 7951 "Package " + packageName + " does not belong to calling UID " + callingUid); 7952 } 7953 } catch (RemoteException e) { 7954 throw new SecurityException("Failed to verify package name ownership"); 7955 } 7956 7957 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7958 synchronized (this) { 7959 if (incoming) { 7960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7961 callingUid); 7962 if (perms == null) { 7963 Slog.w(TAG, "No permission grants found for " + packageName); 7964 } else { 7965 for (UriPermission perm : perms.values()) { 7966 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7967 result.add(perm.buildPersistedPublicApiObject()); 7968 } 7969 } 7970 } 7971 } else { 7972 final int size = mGrantedUriPermissions.size(); 7973 for (int i = 0; i < size; i++) { 7974 final ArrayMap<GrantUri, UriPermission> perms = 7975 mGrantedUriPermissions.valueAt(i); 7976 for (UriPermission perm : perms.values()) { 7977 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7978 result.add(perm.buildPersistedPublicApiObject()); 7979 } 7980 } 7981 } 7982 } 7983 } 7984 return new ParceledListSlice<android.content.UriPermission>(result); 7985 } 7986 7987 @Override 7988 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7989 synchronized (this) { 7990 ProcessRecord app = 7991 who != null ? getRecordForAppLocked(who) : null; 7992 if (app == null) return; 7993 7994 Message msg = Message.obtain(); 7995 msg.what = WAIT_FOR_DEBUGGER_MSG; 7996 msg.obj = app; 7997 msg.arg1 = waiting ? 1 : 0; 7998 mHandler.sendMessage(msg); 7999 } 8000 } 8001 8002 @Override 8003 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8004 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8005 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8006 outInfo.availMem = Process.getFreeMemory(); 8007 outInfo.totalMem = Process.getTotalMemory(); 8008 outInfo.threshold = homeAppMem; 8009 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8010 outInfo.hiddenAppThreshold = cachedAppMem; 8011 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8012 ProcessList.SERVICE_ADJ); 8013 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8014 ProcessList.VISIBLE_APP_ADJ); 8015 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8016 ProcessList.FOREGROUND_APP_ADJ); 8017 } 8018 8019 // ========================================================= 8020 // TASK MANAGEMENT 8021 // ========================================================= 8022 8023 @Override 8024 public List<IAppTask> getAppTasks(String callingPackage) { 8025 int callingUid = Binder.getCallingUid(); 8026 long ident = Binder.clearCallingIdentity(); 8027 8028 synchronized(this) { 8029 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8030 try { 8031 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8032 8033 final int N = mRecentTasks.size(); 8034 for (int i = 0; i < N; i++) { 8035 TaskRecord tr = mRecentTasks.get(i); 8036 // Skip tasks that do not match the caller. We don't need to verify 8037 // callingPackage, because we are also limiting to callingUid and know 8038 // that will limit to the correct security sandbox. 8039 if (tr.effectiveUid != callingUid) { 8040 continue; 8041 } 8042 Intent intent = tr.getBaseIntent(); 8043 if (intent == null || 8044 !callingPackage.equals(intent.getComponent().getPackageName())) { 8045 continue; 8046 } 8047 ActivityManager.RecentTaskInfo taskInfo = 8048 createRecentTaskInfoFromTaskRecord(tr); 8049 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8050 list.add(taskImpl); 8051 } 8052 } finally { 8053 Binder.restoreCallingIdentity(ident); 8054 } 8055 return list; 8056 } 8057 } 8058 8059 @Override 8060 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8061 final int callingUid = Binder.getCallingUid(); 8062 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8063 8064 synchronized(this) { 8065 if (localLOGV) Slog.v( 8066 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8067 8068 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8069 callingUid); 8070 8071 // TODO: Improve with MRU list from all ActivityStacks. 8072 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8073 } 8074 8075 return list; 8076 } 8077 8078 /** 8079 * Creates a new RecentTaskInfo from a TaskRecord. 8080 */ 8081 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8082 // Update the task description to reflect any changes in the task stack 8083 tr.updateTaskDescription(); 8084 8085 // Compose the recent task info 8086 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8087 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8088 rti.persistentId = tr.taskId; 8089 rti.baseIntent = new Intent(tr.getBaseIntent()); 8090 rti.origActivity = tr.origActivity; 8091 rti.description = tr.lastDescription; 8092 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8093 rti.userId = tr.userId; 8094 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8095 rti.firstActiveTime = tr.firstActiveTime; 8096 rti.lastActiveTime = tr.lastActiveTime; 8097 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8098 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8099 return rti; 8100 } 8101 8102 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8103 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8104 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8105 if (!allowed) { 8106 if (checkPermission(android.Manifest.permission.GET_TASKS, 8107 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8108 // Temporary compatibility: some existing apps on the system image may 8109 // still be requesting the old permission and not switched to the new 8110 // one; if so, we'll still allow them full access. This means we need 8111 // to see if they are holding the old permission and are a system app. 8112 try { 8113 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8114 allowed = true; 8115 Slog.w(TAG, caller + ": caller " + callingUid 8116 + " is using old GET_TASKS but privileged; allowing"); 8117 } 8118 } catch (RemoteException e) { 8119 } 8120 } 8121 } 8122 if (!allowed) { 8123 Slog.w(TAG, caller + ": caller " + callingUid 8124 + " does not hold GET_TASKS; limiting output"); 8125 } 8126 return allowed; 8127 } 8128 8129 @Override 8130 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8131 final int callingUid = Binder.getCallingUid(); 8132 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8133 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8134 8135 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8136 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8137 synchronized (this) { 8138 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8139 callingUid); 8140 final boolean detailed = checkCallingPermission( 8141 android.Manifest.permission.GET_DETAILED_TASKS) 8142 == PackageManager.PERMISSION_GRANTED; 8143 8144 final int N = mRecentTasks.size(); 8145 ArrayList<ActivityManager.RecentTaskInfo> res 8146 = new ArrayList<ActivityManager.RecentTaskInfo>( 8147 maxNum < N ? maxNum : N); 8148 8149 final Set<Integer> includedUsers; 8150 if (includeProfiles) { 8151 includedUsers = getProfileIdsLocked(userId); 8152 } else { 8153 includedUsers = new HashSet<Integer>(); 8154 } 8155 includedUsers.add(Integer.valueOf(userId)); 8156 8157 for (int i=0; i<N && maxNum > 0; i++) { 8158 TaskRecord tr = mRecentTasks.get(i); 8159 // Only add calling user or related users recent tasks 8160 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8161 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8162 continue; 8163 } 8164 8165 // Return the entry if desired by the caller. We always return 8166 // the first entry, because callers always expect this to be the 8167 // foreground app. We may filter others if the caller has 8168 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8169 // we should exclude the entry. 8170 8171 if (i == 0 8172 || withExcluded 8173 || (tr.intent == null) 8174 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8175 == 0)) { 8176 if (!allowed) { 8177 // If the caller doesn't have the GET_TASKS permission, then only 8178 // allow them to see a small subset of tasks -- their own and home. 8179 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8180 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8181 continue; 8182 } 8183 } 8184 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8185 if (tr.stack != null && tr.stack.isHomeStack()) { 8186 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8187 continue; 8188 } 8189 } 8190 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8191 // Don't include auto remove tasks that are finished or finishing. 8192 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8193 + tr); 8194 continue; 8195 } 8196 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8197 && !tr.isAvailable) { 8198 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8199 continue; 8200 } 8201 8202 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8203 if (!detailed) { 8204 rti.baseIntent.replaceExtras((Bundle)null); 8205 } 8206 8207 res.add(rti); 8208 maxNum--; 8209 } 8210 } 8211 return res; 8212 } 8213 } 8214 8215 TaskRecord recentTaskForIdLocked(int id) { 8216 final int N = mRecentTasks.size(); 8217 for (int i=0; i<N; i++) { 8218 TaskRecord tr = mRecentTasks.get(i); 8219 if (tr.taskId == id) { 8220 return tr; 8221 } 8222 } 8223 return null; 8224 } 8225 8226 @Override 8227 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8228 synchronized (this) { 8229 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8230 "getTaskThumbnail()"); 8231 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8232 if (tr != null) { 8233 return tr.getTaskThumbnailLocked(); 8234 } 8235 } 8236 return null; 8237 } 8238 8239 @Override 8240 public int addAppTask(IBinder activityToken, Intent intent, 8241 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8242 final int callingUid = Binder.getCallingUid(); 8243 final long callingIdent = Binder.clearCallingIdentity(); 8244 8245 try { 8246 synchronized (this) { 8247 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8248 if (r == null) { 8249 throw new IllegalArgumentException("Activity does not exist; token=" 8250 + activityToken); 8251 } 8252 ComponentName comp = intent.getComponent(); 8253 if (comp == null) { 8254 throw new IllegalArgumentException("Intent " + intent 8255 + " must specify explicit component"); 8256 } 8257 if (thumbnail.getWidth() != mThumbnailWidth 8258 || thumbnail.getHeight() != mThumbnailHeight) { 8259 throw new IllegalArgumentException("Bad thumbnail size: got " 8260 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8261 + mThumbnailWidth + "x" + mThumbnailHeight); 8262 } 8263 if (intent.getSelector() != null) { 8264 intent.setSelector(null); 8265 } 8266 if (intent.getSourceBounds() != null) { 8267 intent.setSourceBounds(null); 8268 } 8269 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8270 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8271 // The caller has added this as an auto-remove task... that makes no 8272 // sense, so turn off auto-remove. 8273 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8274 } 8275 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8276 // Must be a new task. 8277 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8278 } 8279 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8280 mLastAddedTaskActivity = null; 8281 } 8282 ActivityInfo ainfo = mLastAddedTaskActivity; 8283 if (ainfo == null) { 8284 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8285 comp, 0, UserHandle.getUserId(callingUid)); 8286 if (ainfo.applicationInfo.uid != callingUid) { 8287 throw new SecurityException( 8288 "Can't add task for another application: target uid=" 8289 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8290 } 8291 } 8292 8293 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8294 intent, description); 8295 8296 int trimIdx = trimRecentsForTaskLocked(task, false); 8297 if (trimIdx >= 0) { 8298 // If this would have caused a trim, then we'll abort because that 8299 // means it would be added at the end of the list but then just removed. 8300 return INVALID_TASK_ID; 8301 } 8302 8303 final int N = mRecentTasks.size(); 8304 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8305 final TaskRecord tr = mRecentTasks.remove(N - 1); 8306 tr.removedFromRecents(); 8307 } 8308 8309 task.inRecents = true; 8310 mRecentTasks.add(task); 8311 r.task.stack.addTask(task, false, false); 8312 8313 task.setLastThumbnail(thumbnail); 8314 task.freeLastThumbnail(); 8315 8316 return task.taskId; 8317 } 8318 } finally { 8319 Binder.restoreCallingIdentity(callingIdent); 8320 } 8321 } 8322 8323 @Override 8324 public Point getAppTaskThumbnailSize() { 8325 synchronized (this) { 8326 return new Point(mThumbnailWidth, mThumbnailHeight); 8327 } 8328 } 8329 8330 @Override 8331 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8332 synchronized (this) { 8333 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8334 if (r != null) { 8335 r.setTaskDescription(td); 8336 r.task.updateTaskDescription(); 8337 } 8338 } 8339 } 8340 8341 @Override 8342 public Bitmap getTaskDescriptionIcon(String filename) { 8343 if (!FileUtils.isValidExtFilename(filename) 8344 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8345 throw new IllegalArgumentException("Bad filename: " + filename); 8346 } 8347 return mTaskPersister.getTaskDescriptionIcon(filename); 8348 } 8349 8350 @Override 8351 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8352 throws RemoteException { 8353 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8354 opts.getCustomInPlaceResId() == 0) { 8355 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8356 "with valid animation"); 8357 } 8358 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8359 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8360 opts.getCustomInPlaceResId()); 8361 mWindowManager.executeAppTransition(); 8362 } 8363 8364 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8365 mRecentTasks.remove(tr); 8366 tr.removedFromRecents(); 8367 ComponentName component = tr.getBaseIntent().getComponent(); 8368 if (component == null) { 8369 Slog.w(TAG, "No component for base intent of task: " + tr); 8370 return; 8371 } 8372 8373 if (!killProcess) { 8374 return; 8375 } 8376 8377 // Determine if the process(es) for this task should be killed. 8378 final String pkg = component.getPackageName(); 8379 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8380 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8381 for (int i = 0; i < pmap.size(); i++) { 8382 8383 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8384 for (int j = 0; j < uids.size(); j++) { 8385 ProcessRecord proc = uids.valueAt(j); 8386 if (proc.userId != tr.userId) { 8387 // Don't kill process for a different user. 8388 continue; 8389 } 8390 if (proc == mHomeProcess) { 8391 // Don't kill the home process along with tasks from the same package. 8392 continue; 8393 } 8394 if (!proc.pkgList.containsKey(pkg)) { 8395 // Don't kill process that is not associated with this task. 8396 continue; 8397 } 8398 8399 for (int k = 0; k < proc.activities.size(); k++) { 8400 TaskRecord otherTask = proc.activities.get(k).task; 8401 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8402 // Don't kill process(es) that has an activity in a different task that is 8403 // also in recents. 8404 return; 8405 } 8406 } 8407 8408 // Add process to kill list. 8409 procsToKill.add(proc); 8410 } 8411 } 8412 8413 // Find any running services associated with this app and stop if needed. 8414 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8415 8416 // Kill the running processes. 8417 for (int i = 0; i < procsToKill.size(); i++) { 8418 ProcessRecord pr = procsToKill.get(i); 8419 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8420 pr.kill("remove task", true); 8421 } else { 8422 pr.waitingToKill = "remove task"; 8423 } 8424 } 8425 } 8426 8427 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8428 // Remove all tasks with activities in the specified package from the list of recent tasks 8429 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8430 TaskRecord tr = mRecentTasks.get(i); 8431 if (tr.userId != userId) continue; 8432 8433 ComponentName cn = tr.intent.getComponent(); 8434 if (cn != null && cn.getPackageName().equals(packageName)) { 8435 // If the package name matches, remove the task. 8436 removeTaskByIdLocked(tr.taskId, true); 8437 } 8438 } 8439 } 8440 8441 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8442 final IPackageManager pm = AppGlobals.getPackageManager(); 8443 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8444 8445 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8446 TaskRecord tr = mRecentTasks.get(i); 8447 if (tr.userId != userId) continue; 8448 8449 ComponentName cn = tr.intent.getComponent(); 8450 if (cn != null && cn.getPackageName().equals(packageName)) { 8451 // Skip if component still exists in the package. 8452 if (componentsKnownToExist.contains(cn)) continue; 8453 8454 try { 8455 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8456 if (info != null) { 8457 componentsKnownToExist.add(cn); 8458 } else { 8459 removeTaskByIdLocked(tr.taskId, false); 8460 } 8461 } catch (RemoteException e) { 8462 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8463 } 8464 } 8465 } 8466 } 8467 8468 /** 8469 * Removes the task with the specified task id. 8470 * 8471 * @param taskId Identifier of the task to be removed. 8472 * @param killProcess Kill any process associated with the task if possible. 8473 * @return Returns true if the given task was found and removed. 8474 */ 8475 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8476 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8477 if (tr != null) { 8478 tr.removeTaskActivitiesLocked(); 8479 cleanUpRemovedTaskLocked(tr, killProcess); 8480 if (tr.isPersistable) { 8481 notifyTaskPersisterLocked(null, true); 8482 } 8483 return true; 8484 } 8485 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8486 return false; 8487 } 8488 8489 @Override 8490 public boolean removeTask(int taskId) { 8491 synchronized (this) { 8492 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8493 "removeTask()"); 8494 long ident = Binder.clearCallingIdentity(); 8495 try { 8496 return removeTaskByIdLocked(taskId, true); 8497 } finally { 8498 Binder.restoreCallingIdentity(ident); 8499 } 8500 } 8501 } 8502 8503 /** 8504 * TODO: Add mController hook 8505 */ 8506 @Override 8507 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8508 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8509 "moveTaskToFront()"); 8510 8511 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8512 synchronized(this) { 8513 moveTaskToFrontLocked(taskId, flags, options); 8514 } 8515 } 8516 8517 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8518 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8519 Binder.getCallingUid(), -1, -1, "Task to front")) { 8520 ActivityOptions.abort(options); 8521 return; 8522 } 8523 final long origId = Binder.clearCallingIdentity(); 8524 try { 8525 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8526 if (task == null) { 8527 Slog.d(TAG, "Could not find task for id: "+ taskId); 8528 return; 8529 } 8530 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8531 mStackSupervisor.showLockTaskToast(); 8532 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8533 return; 8534 } 8535 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8536 if (prev != null && prev.isRecentsActivity()) { 8537 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8538 } 8539 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront"); 8540 } finally { 8541 Binder.restoreCallingIdentity(origId); 8542 } 8543 ActivityOptions.abort(options); 8544 } 8545 8546 @Override 8547 public void moveTaskToBack(int taskId) { 8548 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8549 "moveTaskToBack()"); 8550 8551 synchronized(this) { 8552 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8553 if (tr != null) { 8554 if (tr == mStackSupervisor.mLockTaskModeTask) { 8555 mStackSupervisor.showLockTaskToast(); 8556 return; 8557 } 8558 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8559 ActivityStack stack = tr.stack; 8560 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8561 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8562 Binder.getCallingUid(), -1, -1, "Task to back")) { 8563 return; 8564 } 8565 } 8566 final long origId = Binder.clearCallingIdentity(); 8567 try { 8568 stack.moveTaskToBackLocked(taskId); 8569 } finally { 8570 Binder.restoreCallingIdentity(origId); 8571 } 8572 } 8573 } 8574 } 8575 8576 /** 8577 * Moves an activity, and all of the other activities within the same task, to the bottom 8578 * of the history stack. The activity's order within the task is unchanged. 8579 * 8580 * @param token A reference to the activity we wish to move 8581 * @param nonRoot If false then this only works if the activity is the root 8582 * of a task; if true it will work for any activity in a task. 8583 * @return Returns true if the move completed, false if not. 8584 */ 8585 @Override 8586 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8587 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8588 synchronized(this) { 8589 final long origId = Binder.clearCallingIdentity(); 8590 try { 8591 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8592 if (taskId >= 0) { 8593 if ((mStackSupervisor.mLockTaskModeTask != null) 8594 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8595 mStackSupervisor.showLockTaskToast(); 8596 return false; 8597 } 8598 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 8599 } 8600 } finally { 8601 Binder.restoreCallingIdentity(origId); 8602 } 8603 } 8604 return false; 8605 } 8606 8607 @Override 8608 public void moveTaskBackwards(int task) { 8609 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8610 "moveTaskBackwards()"); 8611 8612 synchronized(this) { 8613 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8614 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8615 return; 8616 } 8617 final long origId = Binder.clearCallingIdentity(); 8618 moveTaskBackwardsLocked(task); 8619 Binder.restoreCallingIdentity(origId); 8620 } 8621 } 8622 8623 private final void moveTaskBackwardsLocked(int task) { 8624 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8625 } 8626 8627 @Override 8628 public IBinder getHomeActivityToken() throws RemoteException { 8629 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8630 "getHomeActivityToken()"); 8631 synchronized (this) { 8632 return mStackSupervisor.getHomeActivityToken(); 8633 } 8634 } 8635 8636 @Override 8637 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8638 IActivityContainerCallback callback) throws RemoteException { 8639 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8640 "createActivityContainer()"); 8641 synchronized (this) { 8642 if (parentActivityToken == null) { 8643 throw new IllegalArgumentException("parent token must not be null"); 8644 } 8645 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8646 if (r == null) { 8647 return null; 8648 } 8649 if (callback == null) { 8650 throw new IllegalArgumentException("callback must not be null"); 8651 } 8652 return mStackSupervisor.createActivityContainer(r, callback); 8653 } 8654 } 8655 8656 @Override 8657 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8658 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8659 "deleteActivityContainer()"); 8660 synchronized (this) { 8661 mStackSupervisor.deleteActivityContainer(container); 8662 } 8663 } 8664 8665 @Override 8666 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8667 throws RemoteException { 8668 synchronized (this) { 8669 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8670 if (stack != null) { 8671 return stack.mActivityContainer; 8672 } 8673 return null; 8674 } 8675 } 8676 8677 @Override 8678 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8679 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8680 "moveTaskToStack()"); 8681 if (stackId == HOME_STACK_ID) { 8682 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8683 new RuntimeException("here").fillInStackTrace()); 8684 } 8685 synchronized (this) { 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8689 + stackId + " toTop=" + toTop); 8690 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop); 8691 } finally { 8692 Binder.restoreCallingIdentity(ident); 8693 } 8694 } 8695 } 8696 8697 @Override 8698 public void resizeStack(int stackBoxId, Rect bounds) { 8699 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8700 "resizeStackBox()"); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 mWindowManager.resizeStack(stackBoxId, bounds); 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public List<StackInfo> getAllStackInfos() { 8711 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8712 "getAllStackInfos()"); 8713 long ident = Binder.clearCallingIdentity(); 8714 try { 8715 synchronized (this) { 8716 return mStackSupervisor.getAllStackInfosLocked(); 8717 } 8718 } finally { 8719 Binder.restoreCallingIdentity(ident); 8720 } 8721 } 8722 8723 @Override 8724 public StackInfo getStackInfo(int stackId) { 8725 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8726 "getStackInfo()"); 8727 long ident = Binder.clearCallingIdentity(); 8728 try { 8729 synchronized (this) { 8730 return mStackSupervisor.getStackInfoLocked(stackId); 8731 } 8732 } finally { 8733 Binder.restoreCallingIdentity(ident); 8734 } 8735 } 8736 8737 @Override 8738 public boolean isInHomeStack(int taskId) { 8739 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8740 "getStackInfo()"); 8741 long ident = Binder.clearCallingIdentity(); 8742 try { 8743 synchronized (this) { 8744 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8745 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8746 } 8747 } finally { 8748 Binder.restoreCallingIdentity(ident); 8749 } 8750 } 8751 8752 @Override 8753 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8754 synchronized(this) { 8755 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8756 } 8757 } 8758 8759 private boolean isLockTaskAuthorized(String pkg) { 8760 final DevicePolicyManager dpm = (DevicePolicyManager) 8761 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8762 try { 8763 int uid = mContext.getPackageManager().getPackageUid(pkg, 8764 Binder.getCallingUserHandle().getIdentifier()); 8765 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8766 } catch (NameNotFoundException e) { 8767 return false; 8768 } 8769 } 8770 8771 void startLockTaskMode(TaskRecord task) { 8772 final String pkg; 8773 synchronized (this) { 8774 pkg = task.intent.getComponent().getPackageName(); 8775 } 8776 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8777 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8778 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8779 StatusBarManagerInternal.class); 8780 if (statusBarManager != null) { 8781 statusBarManager.showScreenPinningRequest(); 8782 } 8783 return; 8784 } 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 // Since we lost lock on task, make sure it is still there. 8789 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8790 if (task != null) { 8791 if (!isSystemInitiated 8792 && ((mStackSupervisor.getFocusedStack() == null) 8793 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8794 throw new IllegalArgumentException("Invalid task, not in foreground"); 8795 } 8796 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated, 8797 "startLockTask"); 8798 } 8799 } 8800 } finally { 8801 Binder.restoreCallingIdentity(ident); 8802 } 8803 } 8804 8805 @Override 8806 public void startLockTaskMode(int taskId) { 8807 final TaskRecord task; 8808 long ident = Binder.clearCallingIdentity(); 8809 try { 8810 synchronized (this) { 8811 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8812 } 8813 } finally { 8814 Binder.restoreCallingIdentity(ident); 8815 } 8816 if (task != null) { 8817 startLockTaskMode(task); 8818 } 8819 } 8820 8821 @Override 8822 public void startLockTaskMode(IBinder token) { 8823 final TaskRecord task; 8824 long ident = Binder.clearCallingIdentity(); 8825 try { 8826 synchronized (this) { 8827 final ActivityRecord r = ActivityRecord.forToken(token); 8828 if (r == null) { 8829 return; 8830 } 8831 task = r.task; 8832 } 8833 } finally { 8834 Binder.restoreCallingIdentity(ident); 8835 } 8836 if (task != null) { 8837 startLockTaskMode(task); 8838 } 8839 } 8840 8841 @Override 8842 public void startLockTaskModeOnCurrent() throws RemoteException { 8843 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8844 "startLockTaskModeOnCurrent"); 8845 long ident = Binder.clearCallingIdentity(); 8846 try { 8847 ActivityRecord r = null; 8848 synchronized (this) { 8849 r = mStackSupervisor.topRunningActivityLocked(); 8850 } 8851 startLockTaskMode(r.task); 8852 } finally { 8853 Binder.restoreCallingIdentity(ident); 8854 } 8855 } 8856 8857 @Override 8858 public void stopLockTaskMode() { 8859 // Verify that the user matches the package of the intent for the TaskRecord 8860 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8861 // and stopLockTaskMode. 8862 final int callingUid = Binder.getCallingUid(); 8863 if (callingUid != Process.SYSTEM_UID) { 8864 try { 8865 String pkg = 8866 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8867 int uid = mContext.getPackageManager().getPackageUid(pkg, 8868 Binder.getCallingUserHandle().getIdentifier()); 8869 if (uid != callingUid) { 8870 throw new SecurityException("Invalid uid, expected " + uid); 8871 } 8872 } catch (NameNotFoundException e) { 8873 Log.d(TAG, "stopLockTaskMode " + e); 8874 return; 8875 } 8876 } 8877 long ident = Binder.clearCallingIdentity(); 8878 try { 8879 Log.d(TAG, "stopLockTaskMode"); 8880 // Stop lock task 8881 synchronized (this) { 8882 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask"); 8883 } 8884 } finally { 8885 Binder.restoreCallingIdentity(ident); 8886 } 8887 } 8888 8889 @Override 8890 public void stopLockTaskModeOnCurrent() throws RemoteException { 8891 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8892 "stopLockTaskModeOnCurrent"); 8893 long ident = Binder.clearCallingIdentity(); 8894 try { 8895 stopLockTaskMode(); 8896 } finally { 8897 Binder.restoreCallingIdentity(ident); 8898 } 8899 } 8900 8901 @Override 8902 public boolean isInLockTaskMode() { 8903 synchronized (this) { 8904 return mStackSupervisor.isInLockTaskMode(); 8905 } 8906 } 8907 8908 // ========================================================= 8909 // CONTENT PROVIDERS 8910 // ========================================================= 8911 8912 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8913 List<ProviderInfo> providers = null; 8914 try { 8915 providers = AppGlobals.getPackageManager(). 8916 queryContentProviders(app.processName, app.uid, 8917 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8918 } catch (RemoteException ex) { 8919 } 8920 if (DEBUG_MU) 8921 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8922 int userId = app.userId; 8923 if (providers != null) { 8924 int N = providers.size(); 8925 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8926 for (int i=0; i<N; i++) { 8927 ProviderInfo cpi = 8928 (ProviderInfo)providers.get(i); 8929 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8930 cpi.name, cpi.flags); 8931 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8932 // This is a singleton provider, but a user besides the 8933 // default user is asking to initialize a process it runs 8934 // in... well, no, it doesn't actually run in this process, 8935 // it runs in the process of the default user. Get rid of it. 8936 providers.remove(i); 8937 N--; 8938 i--; 8939 continue; 8940 } 8941 8942 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8943 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8944 if (cpr == null) { 8945 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8946 mProviderMap.putProviderByClass(comp, cpr); 8947 } 8948 if (DEBUG_MU) 8949 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8950 app.pubProviders.put(cpi.name, cpr); 8951 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8952 // Don't add this if it is a platform component that is marked 8953 // to run in multiple processes, because this is actually 8954 // part of the framework so doesn't make sense to track as a 8955 // separate apk in the process. 8956 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8957 mProcessStats); 8958 } 8959 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8960 } 8961 } 8962 return providers; 8963 } 8964 8965 /** 8966 * Check if {@link ProcessRecord} has a possible chance at accessing the 8967 * given {@link ProviderInfo}. Final permission checking is always done 8968 * in {@link ContentProvider}. 8969 */ 8970 private final String checkContentProviderPermissionLocked( 8971 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8972 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8973 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8974 boolean checkedGrants = false; 8975 if (checkUser) { 8976 // Looking for cross-user grants before enforcing the typical cross-users permissions 8977 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8978 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8979 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8980 return null; 8981 } 8982 checkedGrants = true; 8983 } 8984 userId = handleIncomingUser(callingPid, callingUid, userId, 8985 false, ALLOW_NON_FULL, 8986 "checkContentProviderPermissionLocked " + cpi.authority, null); 8987 if (userId != tmpTargetUserId) { 8988 // When we actually went to determine the final targer user ID, this ended 8989 // up different than our initial check for the authority. This is because 8990 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8991 // SELF. So we need to re-check the grants again. 8992 checkedGrants = false; 8993 } 8994 } 8995 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8996 cpi.applicationInfo.uid, cpi.exported) 8997 == PackageManager.PERMISSION_GRANTED) { 8998 return null; 8999 } 9000 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9001 cpi.applicationInfo.uid, cpi.exported) 9002 == PackageManager.PERMISSION_GRANTED) { 9003 return null; 9004 } 9005 9006 PathPermission[] pps = cpi.pathPermissions; 9007 if (pps != null) { 9008 int i = pps.length; 9009 while (i > 0) { 9010 i--; 9011 PathPermission pp = pps[i]; 9012 String pprperm = pp.getReadPermission(); 9013 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9014 cpi.applicationInfo.uid, cpi.exported) 9015 == PackageManager.PERMISSION_GRANTED) { 9016 return null; 9017 } 9018 String ppwperm = pp.getWritePermission(); 9019 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9020 cpi.applicationInfo.uid, cpi.exported) 9021 == PackageManager.PERMISSION_GRANTED) { 9022 return null; 9023 } 9024 } 9025 } 9026 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9027 return null; 9028 } 9029 9030 String msg; 9031 if (!cpi.exported) { 9032 msg = "Permission Denial: opening provider " + cpi.name 9033 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9034 + ", uid=" + callingUid + ") that is not exported from uid " 9035 + cpi.applicationInfo.uid; 9036 } else { 9037 msg = "Permission Denial: opening provider " + cpi.name 9038 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9039 + ", uid=" + callingUid + ") requires " 9040 + cpi.readPermission + " or " + cpi.writePermission; 9041 } 9042 Slog.w(TAG, msg); 9043 return msg; 9044 } 9045 9046 /** 9047 * Returns if the ContentProvider has granted a uri to callingUid 9048 */ 9049 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9050 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9051 if (perms != null) { 9052 for (int i=perms.size()-1; i>=0; i--) { 9053 GrantUri grantUri = perms.keyAt(i); 9054 if (grantUri.sourceUserId == userId || !checkUser) { 9055 if (matchesProvider(grantUri.uri, cpi)) { 9056 return true; 9057 } 9058 } 9059 } 9060 } 9061 return false; 9062 } 9063 9064 /** 9065 * Returns true if the uri authority is one of the authorities specified in the provider. 9066 */ 9067 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9068 String uriAuth = uri.getAuthority(); 9069 String cpiAuth = cpi.authority; 9070 if (cpiAuth.indexOf(';') == -1) { 9071 return cpiAuth.equals(uriAuth); 9072 } 9073 String[] cpiAuths = cpiAuth.split(";"); 9074 int length = cpiAuths.length; 9075 for (int i = 0; i < length; i++) { 9076 if (cpiAuths[i].equals(uriAuth)) return true; 9077 } 9078 return false; 9079 } 9080 9081 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9082 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9083 if (r != null) { 9084 for (int i=0; i<r.conProviders.size(); i++) { 9085 ContentProviderConnection conn = r.conProviders.get(i); 9086 if (conn.provider == cpr) { 9087 if (DEBUG_PROVIDER) Slog.v(TAG, 9088 "Adding provider requested by " 9089 + r.processName + " from process " 9090 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9091 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9092 if (stable) { 9093 conn.stableCount++; 9094 conn.numStableIncs++; 9095 } else { 9096 conn.unstableCount++; 9097 conn.numUnstableIncs++; 9098 } 9099 return conn; 9100 } 9101 } 9102 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9103 if (stable) { 9104 conn.stableCount = 1; 9105 conn.numStableIncs = 1; 9106 } else { 9107 conn.unstableCount = 1; 9108 conn.numUnstableIncs = 1; 9109 } 9110 cpr.connections.add(conn); 9111 r.conProviders.add(conn); 9112 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9113 return conn; 9114 } 9115 cpr.addExternalProcessHandleLocked(externalProcessToken); 9116 return null; 9117 } 9118 9119 boolean decProviderCountLocked(ContentProviderConnection conn, 9120 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9121 if (conn != null) { 9122 cpr = conn.provider; 9123 if (DEBUG_PROVIDER) Slog.v(TAG, 9124 "Removing provider requested by " 9125 + conn.client.processName + " from process " 9126 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9127 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9128 if (stable) { 9129 conn.stableCount--; 9130 } else { 9131 conn.unstableCount--; 9132 } 9133 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9134 cpr.connections.remove(conn); 9135 conn.client.conProviders.remove(conn); 9136 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9137 return true; 9138 } 9139 return false; 9140 } 9141 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9142 return false; 9143 } 9144 9145 private void checkTime(long startTime, String where) { 9146 long now = SystemClock.elapsedRealtime(); 9147 if ((now-startTime) > 1000) { 9148 // If we are taking more than a second, log about it. 9149 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9150 } 9151 } 9152 9153 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9154 String name, IBinder token, boolean stable, int userId) { 9155 ContentProviderRecord cpr; 9156 ContentProviderConnection conn = null; 9157 ProviderInfo cpi = null; 9158 9159 synchronized(this) { 9160 long startTime = SystemClock.elapsedRealtime(); 9161 9162 ProcessRecord r = null; 9163 if (caller != null) { 9164 r = getRecordForAppLocked(caller); 9165 if (r == null) { 9166 throw new SecurityException( 9167 "Unable to find app for caller " + caller 9168 + " (pid=" + Binder.getCallingPid() 9169 + ") when getting content provider " + name); 9170 } 9171 } 9172 9173 boolean checkCrossUser = true; 9174 9175 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9176 9177 // First check if this content provider has been published... 9178 cpr = mProviderMap.getProviderByName(name, userId); 9179 // If that didn't work, check if it exists for user 0 and then 9180 // verify that it's a singleton provider before using it. 9181 if (cpr == null && userId != UserHandle.USER_OWNER) { 9182 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9183 if (cpr != null) { 9184 cpi = cpr.info; 9185 if (isSingleton(cpi.processName, cpi.applicationInfo, 9186 cpi.name, cpi.flags) 9187 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9188 userId = UserHandle.USER_OWNER; 9189 checkCrossUser = false; 9190 } else { 9191 cpr = null; 9192 cpi = null; 9193 } 9194 } 9195 } 9196 9197 boolean providerRunning = cpr != null; 9198 if (providerRunning) { 9199 cpi = cpr.info; 9200 String msg; 9201 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9202 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9203 != null) { 9204 throw new SecurityException(msg); 9205 } 9206 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9207 9208 if (r != null && cpr.canRunHere(r)) { 9209 // This provider has been published or is in the process 9210 // of being published... but it is also allowed to run 9211 // in the caller's process, so don't make a connection 9212 // and just let the caller instantiate its own instance. 9213 ContentProviderHolder holder = cpr.newHolder(null); 9214 // don't give caller the provider object, it needs 9215 // to make its own. 9216 holder.provider = null; 9217 return holder; 9218 } 9219 9220 final long origId = Binder.clearCallingIdentity(); 9221 9222 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9223 9224 // In this case the provider instance already exists, so we can 9225 // return it right away. 9226 conn = incProviderCountLocked(r, cpr, token, stable); 9227 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9228 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9229 // If this is a perceptible app accessing the provider, 9230 // make sure to count it as being accessed and thus 9231 // back up on the LRU list. This is good because 9232 // content providers are often expensive to start. 9233 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9234 updateLruProcessLocked(cpr.proc, false, null); 9235 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9236 } 9237 } 9238 9239 if (cpr.proc != null) { 9240 if (false) { 9241 if (cpr.name.flattenToShortString().equals( 9242 "com.android.providers.calendar/.CalendarProvider2")) { 9243 Slog.v(TAG, "****************** KILLING " 9244 + cpr.name.flattenToShortString()); 9245 Process.killProcess(cpr.proc.pid); 9246 } 9247 } 9248 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9249 boolean success = updateOomAdjLocked(cpr.proc); 9250 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9251 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9252 // NOTE: there is still a race here where a signal could be 9253 // pending on the process even though we managed to update its 9254 // adj level. Not sure what to do about this, but at least 9255 // the race is now smaller. 9256 if (!success) { 9257 // Uh oh... it looks like the provider's process 9258 // has been killed on us. We need to wait for a new 9259 // process to be started, and make sure its death 9260 // doesn't kill our process. 9261 Slog.i(TAG, 9262 "Existing provider " + cpr.name.flattenToShortString() 9263 + " is crashing; detaching " + r); 9264 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9265 checkTime(startTime, "getContentProviderImpl: before appDied"); 9266 appDiedLocked(cpr.proc); 9267 checkTime(startTime, "getContentProviderImpl: after appDied"); 9268 if (!lastRef) { 9269 // This wasn't the last ref our process had on 9270 // the provider... we have now been killed, bail. 9271 return null; 9272 } 9273 providerRunning = false; 9274 conn = null; 9275 } 9276 } 9277 9278 Binder.restoreCallingIdentity(origId); 9279 } 9280 9281 boolean singleton; 9282 if (!providerRunning) { 9283 try { 9284 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9285 cpi = AppGlobals.getPackageManager(). 9286 resolveContentProvider(name, 9287 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9288 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9289 } catch (RemoteException ex) { 9290 } 9291 if (cpi == null) { 9292 return null; 9293 } 9294 // If the provider is a singleton AND 9295 // (it's a call within the same user || the provider is a 9296 // privileged app) 9297 // Then allow connecting to the singleton provider 9298 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9299 cpi.name, cpi.flags) 9300 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9301 if (singleton) { 9302 userId = UserHandle.USER_OWNER; 9303 } 9304 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9305 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9306 9307 String msg; 9308 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9309 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9310 != null) { 9311 throw new SecurityException(msg); 9312 } 9313 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9314 9315 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9316 && !cpi.processName.equals("system")) { 9317 // If this content provider does not run in the system 9318 // process, and the system is not yet ready to run other 9319 // processes, then fail fast instead of hanging. 9320 throw new IllegalArgumentException( 9321 "Attempt to launch content provider before system ready"); 9322 } 9323 9324 // Make sure that the user who owns this provider is running. If not, 9325 // we don't want to allow it to run. 9326 if (!isUserRunningLocked(userId, false)) { 9327 Slog.w(TAG, "Unable to launch app " 9328 + cpi.applicationInfo.packageName + "/" 9329 + cpi.applicationInfo.uid + " for provider " 9330 + name + ": user " + userId + " is stopped"); 9331 return null; 9332 } 9333 9334 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9335 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9336 cpr = mProviderMap.getProviderByClass(comp, userId); 9337 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9338 final boolean firstClass = cpr == null; 9339 if (firstClass) { 9340 final long ident = Binder.clearCallingIdentity(); 9341 try { 9342 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9343 ApplicationInfo ai = 9344 AppGlobals.getPackageManager(). 9345 getApplicationInfo( 9346 cpi.applicationInfo.packageName, 9347 STOCK_PM_FLAGS, userId); 9348 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9349 if (ai == null) { 9350 Slog.w(TAG, "No package info for content provider " 9351 + cpi.name); 9352 return null; 9353 } 9354 ai = getAppInfoForUser(ai, userId); 9355 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9356 } catch (RemoteException ex) { 9357 // pm is in same process, this will never happen. 9358 } finally { 9359 Binder.restoreCallingIdentity(ident); 9360 } 9361 } 9362 9363 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9364 9365 if (r != null && cpr.canRunHere(r)) { 9366 // If this is a multiprocess provider, then just return its 9367 // info and allow the caller to instantiate it. Only do 9368 // this if the provider is the same user as the caller's 9369 // process, or can run as root (so can be in any process). 9370 return cpr.newHolder(null); 9371 } 9372 9373 if (DEBUG_PROVIDER) { 9374 RuntimeException e = new RuntimeException("here"); 9375 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9376 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9377 } 9378 9379 // This is single process, and our app is now connecting to it. 9380 // See if we are already in the process of launching this 9381 // provider. 9382 final int N = mLaunchingProviders.size(); 9383 int i; 9384 for (i=0; i<N; i++) { 9385 if (mLaunchingProviders.get(i) == cpr) { 9386 break; 9387 } 9388 } 9389 9390 // If the provider is not already being launched, then get it 9391 // started. 9392 if (i >= N) { 9393 final long origId = Binder.clearCallingIdentity(); 9394 9395 try { 9396 // Content provider is now in use, its package can't be stopped. 9397 try { 9398 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9399 AppGlobals.getPackageManager().setPackageStoppedState( 9400 cpr.appInfo.packageName, false, userId); 9401 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9402 } catch (RemoteException e) { 9403 } catch (IllegalArgumentException e) { 9404 Slog.w(TAG, "Failed trying to unstop package " 9405 + cpr.appInfo.packageName + ": " + e); 9406 } 9407 9408 // Use existing process if already started 9409 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9410 ProcessRecord proc = getProcessRecordLocked( 9411 cpi.processName, cpr.appInfo.uid, false); 9412 if (proc != null && proc.thread != null) { 9413 if (DEBUG_PROVIDER) { 9414 Slog.d(TAG, "Installing in existing process " + proc); 9415 } 9416 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9417 proc.pubProviders.put(cpi.name, cpr); 9418 try { 9419 proc.thread.scheduleInstallProvider(cpi); 9420 } catch (RemoteException e) { 9421 } 9422 } else { 9423 checkTime(startTime, "getContentProviderImpl: before start process"); 9424 proc = startProcessLocked(cpi.processName, 9425 cpr.appInfo, false, 0, "content provider", 9426 new ComponentName(cpi.applicationInfo.packageName, 9427 cpi.name), false, false, false); 9428 checkTime(startTime, "getContentProviderImpl: after start process"); 9429 if (proc == null) { 9430 Slog.w(TAG, "Unable to launch app " 9431 + cpi.applicationInfo.packageName + "/" 9432 + cpi.applicationInfo.uid + " for provider " 9433 + name + ": process is bad"); 9434 return null; 9435 } 9436 } 9437 cpr.launchingApp = proc; 9438 mLaunchingProviders.add(cpr); 9439 } finally { 9440 Binder.restoreCallingIdentity(origId); 9441 } 9442 } 9443 9444 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9445 9446 // Make sure the provider is published (the same provider class 9447 // may be published under multiple names). 9448 if (firstClass) { 9449 mProviderMap.putProviderByClass(comp, cpr); 9450 } 9451 9452 mProviderMap.putProviderByName(name, cpr); 9453 conn = incProviderCountLocked(r, cpr, token, stable); 9454 if (conn != null) { 9455 conn.waiting = true; 9456 } 9457 } 9458 checkTime(startTime, "getContentProviderImpl: done!"); 9459 } 9460 9461 // Wait for the provider to be published... 9462 synchronized (cpr) { 9463 while (cpr.provider == null) { 9464 if (cpr.launchingApp == null) { 9465 Slog.w(TAG, "Unable to launch app " 9466 + cpi.applicationInfo.packageName + "/" 9467 + cpi.applicationInfo.uid + " for provider " 9468 + name + ": launching app became null"); 9469 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9470 UserHandle.getUserId(cpi.applicationInfo.uid), 9471 cpi.applicationInfo.packageName, 9472 cpi.applicationInfo.uid, name); 9473 return null; 9474 } 9475 try { 9476 if (DEBUG_MU) { 9477 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9478 + cpr.launchingApp); 9479 } 9480 if (conn != null) { 9481 conn.waiting = true; 9482 } 9483 cpr.wait(); 9484 } catch (InterruptedException ex) { 9485 } finally { 9486 if (conn != null) { 9487 conn.waiting = false; 9488 } 9489 } 9490 } 9491 } 9492 return cpr != null ? cpr.newHolder(conn) : null; 9493 } 9494 9495 @Override 9496 public final ContentProviderHolder getContentProvider( 9497 IApplicationThread caller, String name, int userId, boolean stable) { 9498 enforceNotIsolatedCaller("getContentProvider"); 9499 if (caller == null) { 9500 String msg = "null IApplicationThread when getting content provider " 9501 + name; 9502 Slog.w(TAG, msg); 9503 throw new SecurityException(msg); 9504 } 9505 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9506 // with cross-user grant. 9507 return getContentProviderImpl(caller, name, null, stable, userId); 9508 } 9509 9510 public ContentProviderHolder getContentProviderExternal( 9511 String name, int userId, IBinder token) { 9512 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9513 "Do not have permission in call getContentProviderExternal()"); 9514 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9515 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9516 return getContentProviderExternalUnchecked(name, token, userId); 9517 } 9518 9519 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9520 IBinder token, int userId) { 9521 return getContentProviderImpl(null, name, token, true, userId); 9522 } 9523 9524 /** 9525 * Drop a content provider from a ProcessRecord's bookkeeping 9526 */ 9527 public void removeContentProvider(IBinder connection, boolean stable) { 9528 enforceNotIsolatedCaller("removeContentProvider"); 9529 long ident = Binder.clearCallingIdentity(); 9530 try { 9531 synchronized (this) { 9532 ContentProviderConnection conn; 9533 try { 9534 conn = (ContentProviderConnection)connection; 9535 } catch (ClassCastException e) { 9536 String msg ="removeContentProvider: " + connection 9537 + " not a ContentProviderConnection"; 9538 Slog.w(TAG, msg); 9539 throw new IllegalArgumentException(msg); 9540 } 9541 if (conn == null) { 9542 throw new NullPointerException("connection is null"); 9543 } 9544 if (decProviderCountLocked(conn, null, null, stable)) { 9545 updateOomAdjLocked(); 9546 } 9547 } 9548 } finally { 9549 Binder.restoreCallingIdentity(ident); 9550 } 9551 } 9552 9553 public void removeContentProviderExternal(String name, IBinder token) { 9554 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9555 "Do not have permission in call removeContentProviderExternal()"); 9556 int userId = UserHandle.getCallingUserId(); 9557 long ident = Binder.clearCallingIdentity(); 9558 try { 9559 removeContentProviderExternalUnchecked(name, token, userId); 9560 } finally { 9561 Binder.restoreCallingIdentity(ident); 9562 } 9563 } 9564 9565 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9566 synchronized (this) { 9567 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9568 if(cpr == null) { 9569 //remove from mProvidersByClass 9570 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9571 return; 9572 } 9573 9574 //update content provider record entry info 9575 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9576 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9577 if (localCpr.hasExternalProcessHandles()) { 9578 if (localCpr.removeExternalProcessHandleLocked(token)) { 9579 updateOomAdjLocked(); 9580 } else { 9581 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9582 + " with no external reference for token: " 9583 + token + "."); 9584 } 9585 } else { 9586 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9587 + " with no external references."); 9588 } 9589 } 9590 } 9591 9592 public final void publishContentProviders(IApplicationThread caller, 9593 List<ContentProviderHolder> providers) { 9594 if (providers == null) { 9595 return; 9596 } 9597 9598 enforceNotIsolatedCaller("publishContentProviders"); 9599 synchronized (this) { 9600 final ProcessRecord r = getRecordForAppLocked(caller); 9601 if (DEBUG_MU) 9602 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9603 if (r == null) { 9604 throw new SecurityException( 9605 "Unable to find app for caller " + caller 9606 + " (pid=" + Binder.getCallingPid() 9607 + ") when publishing content providers"); 9608 } 9609 9610 final long origId = Binder.clearCallingIdentity(); 9611 9612 final int N = providers.size(); 9613 for (int i=0; i<N; i++) { 9614 ContentProviderHolder src = providers.get(i); 9615 if (src == null || src.info == null || src.provider == null) { 9616 continue; 9617 } 9618 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9619 if (DEBUG_MU) 9620 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9621 if (dst != null) { 9622 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9623 mProviderMap.putProviderByClass(comp, dst); 9624 String names[] = dst.info.authority.split(";"); 9625 for (int j = 0; j < names.length; j++) { 9626 mProviderMap.putProviderByName(names[j], dst); 9627 } 9628 9629 int NL = mLaunchingProviders.size(); 9630 int j; 9631 for (j=0; j<NL; j++) { 9632 if (mLaunchingProviders.get(j) == dst) { 9633 mLaunchingProviders.remove(j); 9634 j--; 9635 NL--; 9636 } 9637 } 9638 synchronized (dst) { 9639 dst.provider = src.provider; 9640 dst.proc = r; 9641 dst.notifyAll(); 9642 } 9643 updateOomAdjLocked(r); 9644 } 9645 } 9646 9647 Binder.restoreCallingIdentity(origId); 9648 } 9649 } 9650 9651 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9652 ContentProviderConnection conn; 9653 try { 9654 conn = (ContentProviderConnection)connection; 9655 } catch (ClassCastException e) { 9656 String msg ="refContentProvider: " + connection 9657 + " not a ContentProviderConnection"; 9658 Slog.w(TAG, msg); 9659 throw new IllegalArgumentException(msg); 9660 } 9661 if (conn == null) { 9662 throw new NullPointerException("connection is null"); 9663 } 9664 9665 synchronized (this) { 9666 if (stable > 0) { 9667 conn.numStableIncs += stable; 9668 } 9669 stable = conn.stableCount + stable; 9670 if (stable < 0) { 9671 throw new IllegalStateException("stableCount < 0: " + stable); 9672 } 9673 9674 if (unstable > 0) { 9675 conn.numUnstableIncs += unstable; 9676 } 9677 unstable = conn.unstableCount + unstable; 9678 if (unstable < 0) { 9679 throw new IllegalStateException("unstableCount < 0: " + unstable); 9680 } 9681 9682 if ((stable+unstable) <= 0) { 9683 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9684 + stable + " unstable=" + unstable); 9685 } 9686 conn.stableCount = stable; 9687 conn.unstableCount = unstable; 9688 return !conn.dead; 9689 } 9690 } 9691 9692 public void unstableProviderDied(IBinder connection) { 9693 ContentProviderConnection conn; 9694 try { 9695 conn = (ContentProviderConnection)connection; 9696 } catch (ClassCastException e) { 9697 String msg ="refContentProvider: " + connection 9698 + " not a ContentProviderConnection"; 9699 Slog.w(TAG, msg); 9700 throw new IllegalArgumentException(msg); 9701 } 9702 if (conn == null) { 9703 throw new NullPointerException("connection is null"); 9704 } 9705 9706 // Safely retrieve the content provider associated with the connection. 9707 IContentProvider provider; 9708 synchronized (this) { 9709 provider = conn.provider.provider; 9710 } 9711 9712 if (provider == null) { 9713 // Um, yeah, we're way ahead of you. 9714 return; 9715 } 9716 9717 // Make sure the caller is being honest with us. 9718 if (provider.asBinder().pingBinder()) { 9719 // Er, no, still looks good to us. 9720 synchronized (this) { 9721 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9722 + " says " + conn + " died, but we don't agree"); 9723 return; 9724 } 9725 } 9726 9727 // Well look at that! It's dead! 9728 synchronized (this) { 9729 if (conn.provider.provider != provider) { 9730 // But something changed... good enough. 9731 return; 9732 } 9733 9734 ProcessRecord proc = conn.provider.proc; 9735 if (proc == null || proc.thread == null) { 9736 // Seems like the process is already cleaned up. 9737 return; 9738 } 9739 9740 // As far as we're concerned, this is just like receiving a 9741 // death notification... just a bit prematurely. 9742 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9743 + ") early provider death"); 9744 final long ident = Binder.clearCallingIdentity(); 9745 try { 9746 appDiedLocked(proc); 9747 } finally { 9748 Binder.restoreCallingIdentity(ident); 9749 } 9750 } 9751 } 9752 9753 @Override 9754 public void appNotRespondingViaProvider(IBinder connection) { 9755 enforceCallingPermission( 9756 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9757 9758 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9759 if (conn == null) { 9760 Slog.w(TAG, "ContentProviderConnection is null"); 9761 return; 9762 } 9763 9764 final ProcessRecord host = conn.provider.proc; 9765 if (host == null) { 9766 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9767 return; 9768 } 9769 9770 final long token = Binder.clearCallingIdentity(); 9771 try { 9772 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9773 } finally { 9774 Binder.restoreCallingIdentity(token); 9775 } 9776 } 9777 9778 public final void installSystemProviders() { 9779 List<ProviderInfo> providers; 9780 synchronized (this) { 9781 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9782 providers = generateApplicationProvidersLocked(app); 9783 if (providers != null) { 9784 for (int i=providers.size()-1; i>=0; i--) { 9785 ProviderInfo pi = (ProviderInfo)providers.get(i); 9786 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9787 Slog.w(TAG, "Not installing system proc provider " + pi.name 9788 + ": not system .apk"); 9789 providers.remove(i); 9790 } 9791 } 9792 } 9793 } 9794 if (providers != null) { 9795 mSystemThread.installSystemProviders(providers); 9796 } 9797 9798 mCoreSettingsObserver = new CoreSettingsObserver(this); 9799 9800 //mUsageStatsService.monitorPackages(); 9801 } 9802 9803 /** 9804 * Allows apps to retrieve the MIME type of a URI. 9805 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9806 * users, then it does not need permission to access the ContentProvider. 9807 * Either, it needs cross-user uri grants. 9808 * 9809 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9810 * 9811 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9812 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9813 */ 9814 public String getProviderMimeType(Uri uri, int userId) { 9815 enforceNotIsolatedCaller("getProviderMimeType"); 9816 final String name = uri.getAuthority(); 9817 int callingUid = Binder.getCallingUid(); 9818 int callingPid = Binder.getCallingPid(); 9819 long ident = 0; 9820 boolean clearedIdentity = false; 9821 userId = unsafeConvertIncomingUser(userId); 9822 if (canClearIdentity(callingPid, callingUid, userId)) { 9823 clearedIdentity = true; 9824 ident = Binder.clearCallingIdentity(); 9825 } 9826 ContentProviderHolder holder = null; 9827 try { 9828 holder = getContentProviderExternalUnchecked(name, null, userId); 9829 if (holder != null) { 9830 return holder.provider.getType(uri); 9831 } 9832 } catch (RemoteException e) { 9833 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9834 return null; 9835 } finally { 9836 // We need to clear the identity to call removeContentProviderExternalUnchecked 9837 if (!clearedIdentity) { 9838 ident = Binder.clearCallingIdentity(); 9839 } 9840 try { 9841 if (holder != null) { 9842 removeContentProviderExternalUnchecked(name, null, userId); 9843 } 9844 } finally { 9845 Binder.restoreCallingIdentity(ident); 9846 } 9847 } 9848 9849 return null; 9850 } 9851 9852 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9853 if (UserHandle.getUserId(callingUid) == userId) { 9854 return true; 9855 } 9856 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9857 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9858 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9859 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9860 return true; 9861 } 9862 return false; 9863 } 9864 9865 // ========================================================= 9866 // GLOBAL MANAGEMENT 9867 // ========================================================= 9868 9869 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9870 boolean isolated, int isolatedUid) { 9871 String proc = customProcess != null ? customProcess : info.processName; 9872 BatteryStatsImpl.Uid.Proc ps = null; 9873 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9874 int uid = info.uid; 9875 if (isolated) { 9876 if (isolatedUid == 0) { 9877 int userId = UserHandle.getUserId(uid); 9878 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9879 while (true) { 9880 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9881 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9882 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9883 } 9884 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9885 mNextIsolatedProcessUid++; 9886 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9887 // No process for this uid, use it. 9888 break; 9889 } 9890 stepsLeft--; 9891 if (stepsLeft <= 0) { 9892 return null; 9893 } 9894 } 9895 } else { 9896 // Special case for startIsolatedProcess (internal only), where 9897 // the uid of the isolated process is specified by the caller. 9898 uid = isolatedUid; 9899 } 9900 } 9901 return new ProcessRecord(stats, info, proc, uid); 9902 } 9903 9904 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9905 String abiOverride) { 9906 ProcessRecord app; 9907 if (!isolated) { 9908 app = getProcessRecordLocked(info.processName, info.uid, true); 9909 } else { 9910 app = null; 9911 } 9912 9913 if (app == null) { 9914 app = newProcessRecordLocked(info, null, isolated, 0); 9915 mProcessNames.put(info.processName, app.uid, app); 9916 if (isolated) { 9917 mIsolatedProcesses.put(app.uid, app); 9918 } 9919 updateLruProcessLocked(app, false, null); 9920 updateOomAdjLocked(); 9921 } 9922 9923 // This package really, really can not be stopped. 9924 try { 9925 AppGlobals.getPackageManager().setPackageStoppedState( 9926 info.packageName, false, UserHandle.getUserId(app.uid)); 9927 } catch (RemoteException e) { 9928 } catch (IllegalArgumentException e) { 9929 Slog.w(TAG, "Failed trying to unstop package " 9930 + info.packageName + ": " + e); 9931 } 9932 9933 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9934 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9935 app.persistent = true; 9936 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9937 } 9938 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9939 mPersistentStartingProcesses.add(app); 9940 startProcessLocked(app, "added application", app.processName, abiOverride, 9941 null /* entryPoint */, null /* entryPointArgs */); 9942 } 9943 9944 return app; 9945 } 9946 9947 public void unhandledBack() { 9948 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9949 "unhandledBack()"); 9950 9951 synchronized(this) { 9952 final long origId = Binder.clearCallingIdentity(); 9953 try { 9954 getFocusedStack().unhandledBackLocked(); 9955 } finally { 9956 Binder.restoreCallingIdentity(origId); 9957 } 9958 } 9959 } 9960 9961 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9962 enforceNotIsolatedCaller("openContentUri"); 9963 final int userId = UserHandle.getCallingUserId(); 9964 String name = uri.getAuthority(); 9965 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9966 ParcelFileDescriptor pfd = null; 9967 if (cph != null) { 9968 // We record the binder invoker's uid in thread-local storage before 9969 // going to the content provider to open the file. Later, in the code 9970 // that handles all permissions checks, we look for this uid and use 9971 // that rather than the Activity Manager's own uid. The effect is that 9972 // we do the check against the caller's permissions even though it looks 9973 // to the content provider like the Activity Manager itself is making 9974 // the request. 9975 Binder token = new Binder(); 9976 sCallerIdentity.set(new Identity( 9977 token, Binder.getCallingPid(), Binder.getCallingUid())); 9978 try { 9979 pfd = cph.provider.openFile(null, uri, "r", null, token); 9980 } catch (FileNotFoundException e) { 9981 // do nothing; pfd will be returned null 9982 } finally { 9983 // Ensure that whatever happens, we clean up the identity state 9984 sCallerIdentity.remove(); 9985 } 9986 9987 // We've got the fd now, so we're done with the provider. 9988 removeContentProviderExternalUnchecked(name, null, userId); 9989 } else { 9990 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9991 } 9992 return pfd; 9993 } 9994 9995 // Actually is sleeping or shutting down or whatever else in the future 9996 // is an inactive state. 9997 public boolean isSleepingOrShuttingDown() { 9998 return isSleeping() || mShuttingDown; 9999 } 10000 10001 public boolean isSleeping() { 10002 return mSleeping; 10003 } 10004 10005 void onWakefulnessChanged(int wakefulness) { 10006 synchronized(this) { 10007 mWakefulness = wakefulness; 10008 updateSleepIfNeededLocked(); 10009 } 10010 } 10011 10012 void finishRunningVoiceLocked() { 10013 if (mRunningVoice) { 10014 mRunningVoice = false; 10015 updateSleepIfNeededLocked(); 10016 } 10017 } 10018 10019 void updateSleepIfNeededLocked() { 10020 if (mSleeping && !shouldSleepLocked()) { 10021 mSleeping = false; 10022 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10023 } else if (!mSleeping && shouldSleepLocked()) { 10024 mSleeping = true; 10025 mStackSupervisor.goingToSleepLocked(); 10026 10027 // Initialize the wake times of all processes. 10028 checkExcessivePowerUsageLocked(false); 10029 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10030 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10031 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10032 } 10033 } 10034 10035 private boolean shouldSleepLocked() { 10036 // Resume applications while running a voice interactor. 10037 if (mRunningVoice) { 10038 return false; 10039 } 10040 10041 switch (mWakefulness) { 10042 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10043 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10044 // If we're interactive but applications are already paused then defer 10045 // resuming them until the lock screen is hidden. 10046 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10047 case PowerManagerInternal.WAKEFULNESS_DOZING: 10048 // If we're dozing then pause applications whenever the lock screen is shown. 10049 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10050 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10051 default: 10052 // If we're asleep then pause applications unconditionally. 10053 return true; 10054 } 10055 } 10056 10057 /** Pokes the task persister. */ 10058 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10059 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10060 // Never persist the home stack. 10061 return; 10062 } 10063 mTaskPersister.wakeup(task, flush); 10064 } 10065 10066 /** Notifies all listeners when the task stack has changed. */ 10067 void notifyTaskStackChangedLocked() { 10068 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10069 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10070 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10071 } 10072 10073 @Override 10074 public boolean shutdown(int timeout) { 10075 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10076 != PackageManager.PERMISSION_GRANTED) { 10077 throw new SecurityException("Requires permission " 10078 + android.Manifest.permission.SHUTDOWN); 10079 } 10080 10081 boolean timedout = false; 10082 10083 synchronized(this) { 10084 mShuttingDown = true; 10085 updateEventDispatchingLocked(); 10086 timedout = mStackSupervisor.shutdownLocked(timeout); 10087 } 10088 10089 mAppOpsService.shutdown(); 10090 if (mUsageStatsService != null) { 10091 mUsageStatsService.prepareShutdown(); 10092 } 10093 mBatteryStatsService.shutdown(); 10094 synchronized (this) { 10095 mProcessStats.shutdownLocked(); 10096 notifyTaskPersisterLocked(null, true); 10097 } 10098 10099 return timedout; 10100 } 10101 10102 public final void activitySlept(IBinder token) { 10103 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10104 10105 final long origId = Binder.clearCallingIdentity(); 10106 10107 synchronized (this) { 10108 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10109 if (r != null) { 10110 mStackSupervisor.activitySleptLocked(r); 10111 } 10112 } 10113 10114 Binder.restoreCallingIdentity(origId); 10115 } 10116 10117 private String lockScreenShownToString() { 10118 switch (mLockScreenShown) { 10119 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10120 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10121 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10122 default: return "Unknown=" + mLockScreenShown; 10123 } 10124 } 10125 10126 void logLockScreen(String msg) { 10127 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10128 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10129 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10130 + " mSleeping=" + mSleeping); 10131 } 10132 10133 void startRunningVoiceLocked() { 10134 if (!mRunningVoice) { 10135 mRunningVoice = true; 10136 updateSleepIfNeededLocked(); 10137 } 10138 } 10139 10140 private void updateEventDispatchingLocked() { 10141 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10142 } 10143 10144 public void setLockScreenShown(boolean shown) { 10145 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10146 != PackageManager.PERMISSION_GRANTED) { 10147 throw new SecurityException("Requires permission " 10148 + android.Manifest.permission.DEVICE_POWER); 10149 } 10150 10151 synchronized(this) { 10152 long ident = Binder.clearCallingIdentity(); 10153 try { 10154 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10155 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10156 updateSleepIfNeededLocked(); 10157 } finally { 10158 Binder.restoreCallingIdentity(ident); 10159 } 10160 } 10161 } 10162 10163 @Override 10164 public void stopAppSwitches() { 10165 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10166 != PackageManager.PERMISSION_GRANTED) { 10167 throw new SecurityException("Requires permission " 10168 + android.Manifest.permission.STOP_APP_SWITCHES); 10169 } 10170 10171 synchronized(this) { 10172 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10173 + APP_SWITCH_DELAY_TIME; 10174 mDidAppSwitch = false; 10175 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10176 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10177 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10178 } 10179 } 10180 10181 public void resumeAppSwitches() { 10182 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10183 != PackageManager.PERMISSION_GRANTED) { 10184 throw new SecurityException("Requires permission " 10185 + android.Manifest.permission.STOP_APP_SWITCHES); 10186 } 10187 10188 synchronized(this) { 10189 // Note that we don't execute any pending app switches... we will 10190 // let those wait until either the timeout, or the next start 10191 // activity request. 10192 mAppSwitchesAllowedTime = 0; 10193 } 10194 } 10195 10196 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10197 int callingPid, int callingUid, String name) { 10198 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10199 return true; 10200 } 10201 10202 int perm = checkComponentPermission( 10203 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10204 sourceUid, -1, true); 10205 if (perm == PackageManager.PERMISSION_GRANTED) { 10206 return true; 10207 } 10208 10209 // If the actual IPC caller is different from the logical source, then 10210 // also see if they are allowed to control app switches. 10211 if (callingUid != -1 && callingUid != sourceUid) { 10212 perm = checkComponentPermission( 10213 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10214 callingUid, -1, true); 10215 if (perm == PackageManager.PERMISSION_GRANTED) { 10216 return true; 10217 } 10218 } 10219 10220 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10221 return false; 10222 } 10223 10224 public void setDebugApp(String packageName, boolean waitForDebugger, 10225 boolean persistent) { 10226 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10227 "setDebugApp()"); 10228 10229 long ident = Binder.clearCallingIdentity(); 10230 try { 10231 // Note that this is not really thread safe if there are multiple 10232 // callers into it at the same time, but that's not a situation we 10233 // care about. 10234 if (persistent) { 10235 final ContentResolver resolver = mContext.getContentResolver(); 10236 Settings.Global.putString( 10237 resolver, Settings.Global.DEBUG_APP, 10238 packageName); 10239 Settings.Global.putInt( 10240 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10241 waitForDebugger ? 1 : 0); 10242 } 10243 10244 synchronized (this) { 10245 if (!persistent) { 10246 mOrigDebugApp = mDebugApp; 10247 mOrigWaitForDebugger = mWaitForDebugger; 10248 } 10249 mDebugApp = packageName; 10250 mWaitForDebugger = waitForDebugger; 10251 mDebugTransient = !persistent; 10252 if (packageName != null) { 10253 forceStopPackageLocked(packageName, -1, false, false, true, true, 10254 false, UserHandle.USER_ALL, "set debug app"); 10255 } 10256 } 10257 } finally { 10258 Binder.restoreCallingIdentity(ident); 10259 } 10260 } 10261 10262 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10263 synchronized (this) { 10264 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10265 if (!isDebuggable) { 10266 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10267 throw new SecurityException("Process not debuggable: " + app.packageName); 10268 } 10269 } 10270 10271 mOpenGlTraceApp = processName; 10272 } 10273 } 10274 10275 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10276 synchronized (this) { 10277 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10278 if (!isDebuggable) { 10279 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10280 throw new SecurityException("Process not debuggable: " + app.packageName); 10281 } 10282 } 10283 mProfileApp = processName; 10284 mProfileFile = profilerInfo.profileFile; 10285 if (mProfileFd != null) { 10286 try { 10287 mProfileFd.close(); 10288 } catch (IOException e) { 10289 } 10290 mProfileFd = null; 10291 } 10292 mProfileFd = profilerInfo.profileFd; 10293 mSamplingInterval = profilerInfo.samplingInterval; 10294 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10295 mProfileType = 0; 10296 } 10297 } 10298 10299 @Override 10300 public void setAlwaysFinish(boolean enabled) { 10301 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10302 "setAlwaysFinish()"); 10303 10304 Settings.Global.putInt( 10305 mContext.getContentResolver(), 10306 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10307 10308 synchronized (this) { 10309 mAlwaysFinishActivities = enabled; 10310 } 10311 } 10312 10313 @Override 10314 public void setActivityController(IActivityController controller) { 10315 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10316 "setActivityController()"); 10317 synchronized (this) { 10318 mController = controller; 10319 Watchdog.getInstance().setActivityController(controller); 10320 } 10321 } 10322 10323 @Override 10324 public void setUserIsMonkey(boolean userIsMonkey) { 10325 synchronized (this) { 10326 synchronized (mPidsSelfLocked) { 10327 final int callingPid = Binder.getCallingPid(); 10328 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10329 if (precessRecord == null) { 10330 throw new SecurityException("Unknown process: " + callingPid); 10331 } 10332 if (precessRecord.instrumentationUiAutomationConnection == null) { 10333 throw new SecurityException("Only an instrumentation process " 10334 + "with a UiAutomation can call setUserIsMonkey"); 10335 } 10336 } 10337 mUserIsMonkey = userIsMonkey; 10338 } 10339 } 10340 10341 @Override 10342 public boolean isUserAMonkey() { 10343 synchronized (this) { 10344 // If there is a controller also implies the user is a monkey. 10345 return (mUserIsMonkey || mController != null); 10346 } 10347 } 10348 10349 public void requestBugReport() { 10350 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10351 SystemProperties.set("ctl.start", "bugreport"); 10352 } 10353 10354 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10355 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10356 } 10357 10358 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10359 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10360 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10361 } 10362 return KEY_DISPATCHING_TIMEOUT; 10363 } 10364 10365 @Override 10366 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10367 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10368 != PackageManager.PERMISSION_GRANTED) { 10369 throw new SecurityException("Requires permission " 10370 + android.Manifest.permission.FILTER_EVENTS); 10371 } 10372 ProcessRecord proc; 10373 long timeout; 10374 synchronized (this) { 10375 synchronized (mPidsSelfLocked) { 10376 proc = mPidsSelfLocked.get(pid); 10377 } 10378 timeout = getInputDispatchingTimeoutLocked(proc); 10379 } 10380 10381 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10382 return -1; 10383 } 10384 10385 return timeout; 10386 } 10387 10388 /** 10389 * Handle input dispatching timeouts. 10390 * Returns whether input dispatching should be aborted or not. 10391 */ 10392 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10393 final ActivityRecord activity, final ActivityRecord parent, 10394 final boolean aboveSystem, String reason) { 10395 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10396 != PackageManager.PERMISSION_GRANTED) { 10397 throw new SecurityException("Requires permission " 10398 + android.Manifest.permission.FILTER_EVENTS); 10399 } 10400 10401 final String annotation; 10402 if (reason == null) { 10403 annotation = "Input dispatching timed out"; 10404 } else { 10405 annotation = "Input dispatching timed out (" + reason + ")"; 10406 } 10407 10408 if (proc != null) { 10409 synchronized (this) { 10410 if (proc.debugging) { 10411 return false; 10412 } 10413 10414 if (mDidDexOpt) { 10415 // Give more time since we were dexopting. 10416 mDidDexOpt = false; 10417 return false; 10418 } 10419 10420 if (proc.instrumentationClass != null) { 10421 Bundle info = new Bundle(); 10422 info.putString("shortMsg", "keyDispatchingTimedOut"); 10423 info.putString("longMsg", annotation); 10424 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10425 return true; 10426 } 10427 } 10428 mHandler.post(new Runnable() { 10429 @Override 10430 public void run() { 10431 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10432 } 10433 }); 10434 } 10435 10436 return true; 10437 } 10438 10439 public Bundle getAssistContextExtras(int requestType) { 10440 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10441 UserHandle.getCallingUserId()); 10442 if (pae == null) { 10443 return null; 10444 } 10445 synchronized (pae) { 10446 while (!pae.haveResult) { 10447 try { 10448 pae.wait(); 10449 } catch (InterruptedException e) { 10450 } 10451 } 10452 if (pae.result != null) { 10453 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10454 } 10455 } 10456 synchronized (this) { 10457 mPendingAssistExtras.remove(pae); 10458 mHandler.removeCallbacks(pae); 10459 } 10460 return pae.extras; 10461 } 10462 10463 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10464 int userHandle) { 10465 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10466 "getAssistContextExtras()"); 10467 PendingAssistExtras pae; 10468 Bundle extras = new Bundle(); 10469 synchronized (this) { 10470 ActivityRecord activity = getFocusedStack().mResumedActivity; 10471 if (activity == null) { 10472 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10473 return null; 10474 } 10475 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10476 if (activity.app == null || activity.app.thread == null) { 10477 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10478 return null; 10479 } 10480 if (activity.app.pid == Binder.getCallingPid()) { 10481 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10482 return null; 10483 } 10484 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10485 try { 10486 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10487 requestType); 10488 mPendingAssistExtras.add(pae); 10489 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10490 } catch (RemoteException e) { 10491 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10492 return null; 10493 } 10494 return pae; 10495 } 10496 } 10497 10498 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10499 PendingAssistExtras pae = (PendingAssistExtras)token; 10500 synchronized (pae) { 10501 pae.result = extras; 10502 pae.haveResult = true; 10503 pae.notifyAll(); 10504 if (pae.intent == null) { 10505 // Caller is just waiting for the result. 10506 return; 10507 } 10508 } 10509 10510 // We are now ready to launch the assist activity. 10511 synchronized (this) { 10512 boolean exists = mPendingAssistExtras.remove(pae); 10513 mHandler.removeCallbacks(pae); 10514 if (!exists) { 10515 // Timed out. 10516 return; 10517 } 10518 } 10519 pae.intent.replaceExtras(extras); 10520 if (pae.hint != null) { 10521 pae.intent.putExtra(pae.hint, true); 10522 } 10523 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10524 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10525 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10526 closeSystemDialogs("assist"); 10527 try { 10528 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10529 } catch (ActivityNotFoundException e) { 10530 Slog.w(TAG, "No activity to handle assist action.", e); 10531 } 10532 } 10533 10534 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10535 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10536 } 10537 10538 public void registerProcessObserver(IProcessObserver observer) { 10539 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10540 "registerProcessObserver()"); 10541 synchronized (this) { 10542 mProcessObservers.register(observer); 10543 } 10544 } 10545 10546 @Override 10547 public void unregisterProcessObserver(IProcessObserver observer) { 10548 synchronized (this) { 10549 mProcessObservers.unregister(observer); 10550 } 10551 } 10552 10553 @Override 10554 public boolean convertFromTranslucent(IBinder token) { 10555 final long origId = Binder.clearCallingIdentity(); 10556 try { 10557 synchronized (this) { 10558 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10559 if (r == null) { 10560 return false; 10561 } 10562 final boolean translucentChanged = r.changeWindowTranslucency(true); 10563 if (translucentChanged) { 10564 r.task.stack.releaseBackgroundResources(); 10565 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10566 } 10567 mWindowManager.setAppFullscreen(token, true); 10568 return translucentChanged; 10569 } 10570 } finally { 10571 Binder.restoreCallingIdentity(origId); 10572 } 10573 } 10574 10575 @Override 10576 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10577 final long origId = Binder.clearCallingIdentity(); 10578 try { 10579 synchronized (this) { 10580 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10581 if (r == null) { 10582 return false; 10583 } 10584 int index = r.task.mActivities.lastIndexOf(r); 10585 if (index > 0) { 10586 ActivityRecord under = r.task.mActivities.get(index - 1); 10587 under.returningOptions = options; 10588 } 10589 final boolean translucentChanged = r.changeWindowTranslucency(false); 10590 if (translucentChanged) { 10591 r.task.stack.convertToTranslucent(r); 10592 } 10593 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10594 mWindowManager.setAppFullscreen(token, false); 10595 return translucentChanged; 10596 } 10597 } finally { 10598 Binder.restoreCallingIdentity(origId); 10599 } 10600 } 10601 10602 @Override 10603 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10604 final long origId = Binder.clearCallingIdentity(); 10605 try { 10606 synchronized (this) { 10607 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10608 if (r != null) { 10609 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10610 } 10611 } 10612 return false; 10613 } finally { 10614 Binder.restoreCallingIdentity(origId); 10615 } 10616 } 10617 10618 @Override 10619 public boolean isBackgroundVisibleBehind(IBinder token) { 10620 final long origId = Binder.clearCallingIdentity(); 10621 try { 10622 synchronized (this) { 10623 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10624 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10625 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10626 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10627 return visible; 10628 } 10629 } finally { 10630 Binder.restoreCallingIdentity(origId); 10631 } 10632 } 10633 10634 @Override 10635 public ActivityOptions getActivityOptions(IBinder token) { 10636 final long origId = Binder.clearCallingIdentity(); 10637 try { 10638 synchronized (this) { 10639 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10640 if (r != null) { 10641 final ActivityOptions activityOptions = r.pendingOptions; 10642 r.pendingOptions = null; 10643 return activityOptions; 10644 } 10645 return null; 10646 } 10647 } finally { 10648 Binder.restoreCallingIdentity(origId); 10649 } 10650 } 10651 10652 @Override 10653 public void setImmersive(IBinder token, boolean immersive) { 10654 synchronized(this) { 10655 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10656 if (r == null) { 10657 throw new IllegalArgumentException(); 10658 } 10659 r.immersive = immersive; 10660 10661 // update associated state if we're frontmost 10662 if (r == mFocusedActivity) { 10663 if (DEBUG_IMMERSIVE) { 10664 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10665 } 10666 applyUpdateLockStateLocked(r); 10667 } 10668 } 10669 } 10670 10671 @Override 10672 public boolean isImmersive(IBinder token) { 10673 synchronized (this) { 10674 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10675 if (r == null) { 10676 throw new IllegalArgumentException(); 10677 } 10678 return r.immersive; 10679 } 10680 } 10681 10682 public boolean isTopActivityImmersive() { 10683 enforceNotIsolatedCaller("startActivity"); 10684 synchronized (this) { 10685 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10686 return (r != null) ? r.immersive : false; 10687 } 10688 } 10689 10690 @Override 10691 public boolean isTopOfTask(IBinder token) { 10692 synchronized (this) { 10693 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10694 if (r == null) { 10695 throw new IllegalArgumentException(); 10696 } 10697 return r.task.getTopActivity() == r; 10698 } 10699 } 10700 10701 public final void enterSafeMode() { 10702 synchronized(this) { 10703 // It only makes sense to do this before the system is ready 10704 // and started launching other packages. 10705 if (!mSystemReady) { 10706 try { 10707 AppGlobals.getPackageManager().enterSafeMode(); 10708 } catch (RemoteException e) { 10709 } 10710 } 10711 10712 mSafeMode = true; 10713 } 10714 } 10715 10716 public final void showSafeModeOverlay() { 10717 View v = LayoutInflater.from(mContext).inflate( 10718 com.android.internal.R.layout.safe_mode, null); 10719 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10720 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10721 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10722 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10723 lp.gravity = Gravity.BOTTOM | Gravity.START; 10724 lp.format = v.getBackground().getOpacity(); 10725 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10726 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10727 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10728 ((WindowManager)mContext.getSystemService( 10729 Context.WINDOW_SERVICE)).addView(v, lp); 10730 } 10731 10732 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10733 if (!(sender instanceof PendingIntentRecord)) { 10734 return; 10735 } 10736 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10737 synchronized (stats) { 10738 if (mBatteryStatsService.isOnBattery()) { 10739 mBatteryStatsService.enforceCallingPermission(); 10740 PendingIntentRecord rec = (PendingIntentRecord)sender; 10741 int MY_UID = Binder.getCallingUid(); 10742 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10743 BatteryStatsImpl.Uid.Pkg pkg = 10744 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10745 sourcePkg != null ? sourcePkg : rec.key.packageName); 10746 pkg.incWakeupsLocked(); 10747 } 10748 } 10749 } 10750 10751 public boolean killPids(int[] pids, String pReason, boolean secure) { 10752 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10753 throw new SecurityException("killPids only available to the system"); 10754 } 10755 String reason = (pReason == null) ? "Unknown" : pReason; 10756 // XXX Note: don't acquire main activity lock here, because the window 10757 // manager calls in with its locks held. 10758 10759 boolean killed = false; 10760 synchronized (mPidsSelfLocked) { 10761 int[] types = new int[pids.length]; 10762 int worstType = 0; 10763 for (int i=0; i<pids.length; i++) { 10764 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10765 if (proc != null) { 10766 int type = proc.setAdj; 10767 types[i] = type; 10768 if (type > worstType) { 10769 worstType = type; 10770 } 10771 } 10772 } 10773 10774 // If the worst oom_adj is somewhere in the cached proc LRU range, 10775 // then constrain it so we will kill all cached procs. 10776 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10777 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10778 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10779 } 10780 10781 // If this is not a secure call, don't let it kill processes that 10782 // are important. 10783 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10784 worstType = ProcessList.SERVICE_ADJ; 10785 } 10786 10787 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10788 for (int i=0; i<pids.length; i++) { 10789 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10790 if (proc == null) { 10791 continue; 10792 } 10793 int adj = proc.setAdj; 10794 if (adj >= worstType && !proc.killedByAm) { 10795 proc.kill(reason, true); 10796 killed = true; 10797 } 10798 } 10799 } 10800 return killed; 10801 } 10802 10803 @Override 10804 public void killUid(int uid, String reason) { 10805 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10806 throw new SecurityException("killUid only available to the system"); 10807 } 10808 synchronized (this) { 10809 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10810 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10811 reason != null ? reason : "kill uid"); 10812 } 10813 } 10814 10815 @Override 10816 public boolean killProcessesBelowForeground(String reason) { 10817 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10818 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10819 } 10820 10821 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10822 } 10823 10824 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10825 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10826 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10827 } 10828 10829 boolean killed = false; 10830 synchronized (mPidsSelfLocked) { 10831 final int size = mPidsSelfLocked.size(); 10832 for (int i = 0; i < size; i++) { 10833 final int pid = mPidsSelfLocked.keyAt(i); 10834 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10835 if (proc == null) continue; 10836 10837 final int adj = proc.setAdj; 10838 if (adj > belowAdj && !proc.killedByAm) { 10839 proc.kill(reason, true); 10840 killed = true; 10841 } 10842 } 10843 } 10844 return killed; 10845 } 10846 10847 @Override 10848 public void hang(final IBinder who, boolean allowRestart) { 10849 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10850 != PackageManager.PERMISSION_GRANTED) { 10851 throw new SecurityException("Requires permission " 10852 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10853 } 10854 10855 final IBinder.DeathRecipient death = new DeathRecipient() { 10856 @Override 10857 public void binderDied() { 10858 synchronized (this) { 10859 notifyAll(); 10860 } 10861 } 10862 }; 10863 10864 try { 10865 who.linkToDeath(death, 0); 10866 } catch (RemoteException e) { 10867 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10868 return; 10869 } 10870 10871 synchronized (this) { 10872 Watchdog.getInstance().setAllowRestart(allowRestart); 10873 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10874 synchronized (death) { 10875 while (who.isBinderAlive()) { 10876 try { 10877 death.wait(); 10878 } catch (InterruptedException e) { 10879 } 10880 } 10881 } 10882 Watchdog.getInstance().setAllowRestart(true); 10883 } 10884 } 10885 10886 @Override 10887 public void restart() { 10888 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10889 != PackageManager.PERMISSION_GRANTED) { 10890 throw new SecurityException("Requires permission " 10891 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10892 } 10893 10894 Log.i(TAG, "Sending shutdown broadcast..."); 10895 10896 BroadcastReceiver br = new BroadcastReceiver() { 10897 @Override public void onReceive(Context context, Intent intent) { 10898 // Now the broadcast is done, finish up the low-level shutdown. 10899 Log.i(TAG, "Shutting down activity manager..."); 10900 shutdown(10000); 10901 Log.i(TAG, "Shutdown complete, restarting!"); 10902 Process.killProcess(Process.myPid()); 10903 System.exit(10); 10904 } 10905 }; 10906 10907 // First send the high-level shut down broadcast. 10908 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10909 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10910 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10911 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10912 mContext.sendOrderedBroadcastAsUser(intent, 10913 UserHandle.ALL, null, br, mHandler, 0, null, null); 10914 */ 10915 br.onReceive(mContext, intent); 10916 } 10917 10918 private long getLowRamTimeSinceIdle(long now) { 10919 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10920 } 10921 10922 @Override 10923 public void performIdleMaintenance() { 10924 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10925 != PackageManager.PERMISSION_GRANTED) { 10926 throw new SecurityException("Requires permission " 10927 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10928 } 10929 10930 synchronized (this) { 10931 final long now = SystemClock.uptimeMillis(); 10932 final long timeSinceLastIdle = now - mLastIdleTime; 10933 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10934 mLastIdleTime = now; 10935 mLowRamTimeSinceLastIdle = 0; 10936 if (mLowRamStartTime != 0) { 10937 mLowRamStartTime = now; 10938 } 10939 10940 StringBuilder sb = new StringBuilder(128); 10941 sb.append("Idle maintenance over "); 10942 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10943 sb.append(" low RAM for "); 10944 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10945 Slog.i(TAG, sb.toString()); 10946 10947 // If at least 1/3 of our time since the last idle period has been spent 10948 // with RAM low, then we want to kill processes. 10949 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10950 10951 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10952 ProcessRecord proc = mLruProcesses.get(i); 10953 if (proc.notCachedSinceIdle) { 10954 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10955 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10956 if (doKilling && proc.initialIdlePss != 0 10957 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10958 sb = new StringBuilder(128); 10959 sb.append("Kill"); 10960 sb.append(proc.processName); 10961 sb.append(" in idle maint: pss="); 10962 sb.append(proc.lastPss); 10963 sb.append(", initialPss="); 10964 sb.append(proc.initialIdlePss); 10965 sb.append(", period="); 10966 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10967 sb.append(", lowRamPeriod="); 10968 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10969 Slog.wtfQuiet(TAG, sb.toString()); 10970 proc.kill("idle maint (pss " + proc.lastPss 10971 + " from " + proc.initialIdlePss + ")", true); 10972 } 10973 } 10974 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10975 proc.notCachedSinceIdle = true; 10976 proc.initialIdlePss = 0; 10977 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10978 mTestPssMode, isSleeping(), now); 10979 } 10980 } 10981 10982 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10983 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10984 } 10985 } 10986 10987 private void retrieveSettings() { 10988 final ContentResolver resolver = mContext.getContentResolver(); 10989 String debugApp = Settings.Global.getString( 10990 resolver, Settings.Global.DEBUG_APP); 10991 boolean waitForDebugger = Settings.Global.getInt( 10992 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10993 boolean alwaysFinishActivities = Settings.Global.getInt( 10994 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10995 boolean forceRtl = Settings.Global.getInt( 10996 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10997 // Transfer any global setting for forcing RTL layout, into a System Property 10998 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10999 11000 Configuration configuration = new Configuration(); 11001 Settings.System.getConfiguration(resolver, configuration); 11002 if (forceRtl) { 11003 // This will take care of setting the correct layout direction flags 11004 configuration.setLayoutDirection(configuration.locale); 11005 } 11006 11007 synchronized (this) { 11008 mDebugApp = mOrigDebugApp = debugApp; 11009 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11010 mAlwaysFinishActivities = alwaysFinishActivities; 11011 // This happens before any activities are started, so we can 11012 // change mConfiguration in-place. 11013 updateConfigurationLocked(configuration, null, false, true); 11014 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11015 } 11016 } 11017 11018 /** Loads resources after the current configuration has been set. */ 11019 private void loadResourcesOnSystemReady() { 11020 final Resources res = mContext.getResources(); 11021 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11022 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11023 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11024 } 11025 11026 public boolean testIsSystemReady() { 11027 // no need to synchronize(this) just to read & return the value 11028 return mSystemReady; 11029 } 11030 11031 private static File getCalledPreBootReceiversFile() { 11032 File dataDir = Environment.getDataDirectory(); 11033 File systemDir = new File(dataDir, "system"); 11034 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11035 return fname; 11036 } 11037 11038 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11039 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11040 File file = getCalledPreBootReceiversFile(); 11041 FileInputStream fis = null; 11042 try { 11043 fis = new FileInputStream(file); 11044 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11045 int fvers = dis.readInt(); 11046 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11047 String vers = dis.readUTF(); 11048 String codename = dis.readUTF(); 11049 String build = dis.readUTF(); 11050 if (android.os.Build.VERSION.RELEASE.equals(vers) 11051 && android.os.Build.VERSION.CODENAME.equals(codename) 11052 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11053 int num = dis.readInt(); 11054 while (num > 0) { 11055 num--; 11056 String pkg = dis.readUTF(); 11057 String cls = dis.readUTF(); 11058 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11059 } 11060 } 11061 } 11062 } catch (FileNotFoundException e) { 11063 } catch (IOException e) { 11064 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11065 } finally { 11066 if (fis != null) { 11067 try { 11068 fis.close(); 11069 } catch (IOException e) { 11070 } 11071 } 11072 } 11073 return lastDoneReceivers; 11074 } 11075 11076 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11077 File file = getCalledPreBootReceiversFile(); 11078 FileOutputStream fos = null; 11079 DataOutputStream dos = null; 11080 try { 11081 fos = new FileOutputStream(file); 11082 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11083 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11084 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11085 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11086 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11087 dos.writeInt(list.size()); 11088 for (int i=0; i<list.size(); i++) { 11089 dos.writeUTF(list.get(i).getPackageName()); 11090 dos.writeUTF(list.get(i).getClassName()); 11091 } 11092 } catch (IOException e) { 11093 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11094 file.delete(); 11095 } finally { 11096 FileUtils.sync(fos); 11097 if (dos != null) { 11098 try { 11099 dos.close(); 11100 } catch (IOException e) { 11101 // TODO Auto-generated catch block 11102 e.printStackTrace(); 11103 } 11104 } 11105 } 11106 } 11107 11108 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11109 ArrayList<ComponentName> doneReceivers, int userId) { 11110 boolean waitingUpdate = false; 11111 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11112 List<ResolveInfo> ris = null; 11113 try { 11114 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11115 intent, null, 0, userId); 11116 } catch (RemoteException e) { 11117 } 11118 if (ris != null) { 11119 for (int i=ris.size()-1; i>=0; i--) { 11120 if ((ris.get(i).activityInfo.applicationInfo.flags 11121 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11122 ris.remove(i); 11123 } 11124 } 11125 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11126 11127 // For User 0, load the version number. When delivering to a new user, deliver 11128 // to all receivers. 11129 if (userId == UserHandle.USER_OWNER) { 11130 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11131 for (int i=0; i<ris.size(); i++) { 11132 ActivityInfo ai = ris.get(i).activityInfo; 11133 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11134 if (lastDoneReceivers.contains(comp)) { 11135 // We already did the pre boot receiver for this app with the current 11136 // platform version, so don't do it again... 11137 ris.remove(i); 11138 i--; 11139 // ...however, do keep it as one that has been done, so we don't 11140 // forget about it when rewriting the file of last done receivers. 11141 doneReceivers.add(comp); 11142 } 11143 } 11144 } 11145 11146 // If primary user, send broadcast to all available users, else just to userId 11147 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11148 : new int[] { userId }; 11149 for (int i = 0; i < ris.size(); i++) { 11150 ActivityInfo ai = ris.get(i).activityInfo; 11151 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11152 doneReceivers.add(comp); 11153 intent.setComponent(comp); 11154 for (int j=0; j<users.length; j++) { 11155 IIntentReceiver finisher = null; 11156 // On last receiver and user, set up a completion callback 11157 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11158 finisher = new IIntentReceiver.Stub() { 11159 public void performReceive(Intent intent, int resultCode, 11160 String data, Bundle extras, boolean ordered, 11161 boolean sticky, int sendingUser) { 11162 // The raw IIntentReceiver interface is called 11163 // with the AM lock held, so redispatch to 11164 // execute our code without the lock. 11165 mHandler.post(onFinishCallback); 11166 } 11167 }; 11168 } 11169 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11170 + " for user " + users[j]); 11171 broadcastIntentLocked(null, null, intent, null, finisher, 11172 0, null, null, null, AppOpsManager.OP_NONE, 11173 true, false, MY_PID, Process.SYSTEM_UID, 11174 users[j]); 11175 if (finisher != null) { 11176 waitingUpdate = true; 11177 } 11178 } 11179 } 11180 } 11181 11182 return waitingUpdate; 11183 } 11184 11185 public void systemReady(final Runnable goingCallback) { 11186 synchronized(this) { 11187 if (mSystemReady) { 11188 // If we're done calling all the receivers, run the next "boot phase" passed in 11189 // by the SystemServer 11190 if (goingCallback != null) { 11191 goingCallback.run(); 11192 } 11193 return; 11194 } 11195 11196 // Make sure we have the current profile info, since it is needed for 11197 // security checks. 11198 updateCurrentProfileIdsLocked(); 11199 11200 if (mRecentTasks == null) { 11201 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11202 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11203 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11204 mTaskPersister.startPersisting(); 11205 } 11206 11207 // Check to see if there are any update receivers to run. 11208 if (!mDidUpdate) { 11209 if (mWaitingUpdate) { 11210 return; 11211 } 11212 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11213 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11214 public void run() { 11215 synchronized (ActivityManagerService.this) { 11216 mDidUpdate = true; 11217 } 11218 writeLastDonePreBootReceivers(doneReceivers); 11219 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11220 false); 11221 systemReady(goingCallback); 11222 } 11223 }, doneReceivers, UserHandle.USER_OWNER); 11224 11225 if (mWaitingUpdate) { 11226 return; 11227 } 11228 mDidUpdate = true; 11229 } 11230 11231 mAppOpsService.systemReady(); 11232 mSystemReady = true; 11233 } 11234 11235 ArrayList<ProcessRecord> procsToKill = null; 11236 synchronized(mPidsSelfLocked) { 11237 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11238 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11239 if (!isAllowedWhileBooting(proc.info)){ 11240 if (procsToKill == null) { 11241 procsToKill = new ArrayList<ProcessRecord>(); 11242 } 11243 procsToKill.add(proc); 11244 } 11245 } 11246 } 11247 11248 synchronized(this) { 11249 if (procsToKill != null) { 11250 for (int i=procsToKill.size()-1; i>=0; i--) { 11251 ProcessRecord proc = procsToKill.get(i); 11252 Slog.i(TAG, "Removing system update proc: " + proc); 11253 removeProcessLocked(proc, true, false, "system update done"); 11254 } 11255 } 11256 11257 // Now that we have cleaned up any update processes, we 11258 // are ready to start launching real processes and know that 11259 // we won't trample on them any more. 11260 mProcessesReady = true; 11261 } 11262 11263 Slog.i(TAG, "System now ready"); 11264 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11265 SystemClock.uptimeMillis()); 11266 11267 synchronized(this) { 11268 // Make sure we have no pre-ready processes sitting around. 11269 11270 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11271 ResolveInfo ri = mContext.getPackageManager() 11272 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11273 STOCK_PM_FLAGS); 11274 CharSequence errorMsg = null; 11275 if (ri != null) { 11276 ActivityInfo ai = ri.activityInfo; 11277 ApplicationInfo app = ai.applicationInfo; 11278 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11279 mTopAction = Intent.ACTION_FACTORY_TEST; 11280 mTopData = null; 11281 mTopComponent = new ComponentName(app.packageName, 11282 ai.name); 11283 } else { 11284 errorMsg = mContext.getResources().getText( 11285 com.android.internal.R.string.factorytest_not_system); 11286 } 11287 } else { 11288 errorMsg = mContext.getResources().getText( 11289 com.android.internal.R.string.factorytest_no_action); 11290 } 11291 if (errorMsg != null) { 11292 mTopAction = null; 11293 mTopData = null; 11294 mTopComponent = null; 11295 Message msg = Message.obtain(); 11296 msg.what = SHOW_FACTORY_ERROR_MSG; 11297 msg.getData().putCharSequence("msg", errorMsg); 11298 mHandler.sendMessage(msg); 11299 } 11300 } 11301 } 11302 11303 retrieveSettings(); 11304 loadResourcesOnSystemReady(); 11305 11306 synchronized (this) { 11307 readGrantedUriPermissionsLocked(); 11308 } 11309 11310 if (goingCallback != null) goingCallback.run(); 11311 11312 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11313 Integer.toString(mCurrentUserId), mCurrentUserId); 11314 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11315 Integer.toString(mCurrentUserId), mCurrentUserId); 11316 mSystemServiceManager.startUser(mCurrentUserId); 11317 11318 synchronized (this) { 11319 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11320 try { 11321 List apps = AppGlobals.getPackageManager(). 11322 getPersistentApplications(STOCK_PM_FLAGS); 11323 if (apps != null) { 11324 int N = apps.size(); 11325 int i; 11326 for (i=0; i<N; i++) { 11327 ApplicationInfo info 11328 = (ApplicationInfo)apps.get(i); 11329 if (info != null && 11330 !info.packageName.equals("android")) { 11331 addAppLocked(info, false, null /* ABI override */); 11332 } 11333 } 11334 } 11335 } catch (RemoteException ex) { 11336 // pm is in same process, this will never happen. 11337 } 11338 } 11339 11340 // Start up initial activity. 11341 mBooting = true; 11342 startHomeActivityLocked(mCurrentUserId, "systemReady"); 11343 11344 try { 11345 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11346 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11347 + " data partition or your device will be unstable."); 11348 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11349 } 11350 } catch (RemoteException e) { 11351 } 11352 11353 if (!Build.isFingerprintConsistent()) { 11354 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11355 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11356 } 11357 11358 long ident = Binder.clearCallingIdentity(); 11359 try { 11360 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11361 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11362 | Intent.FLAG_RECEIVER_FOREGROUND); 11363 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11364 broadcastIntentLocked(null, null, intent, 11365 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11366 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11367 intent = new Intent(Intent.ACTION_USER_STARTING); 11368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11369 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11370 broadcastIntentLocked(null, null, intent, 11371 null, new IIntentReceiver.Stub() { 11372 @Override 11373 public void performReceive(Intent intent, int resultCode, String data, 11374 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11375 throws RemoteException { 11376 } 11377 }, 0, null, null, 11378 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11379 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11380 } catch (Throwable t) { 11381 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11382 } finally { 11383 Binder.restoreCallingIdentity(ident); 11384 } 11385 mStackSupervisor.resumeTopActivitiesLocked(); 11386 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11387 } 11388 } 11389 11390 private boolean makeAppCrashingLocked(ProcessRecord app, 11391 String shortMsg, String longMsg, String stackTrace) { 11392 app.crashing = true; 11393 app.crashingReport = generateProcessError(app, 11394 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11395 startAppProblemLocked(app); 11396 app.stopFreezingAllLocked(); 11397 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11398 } 11399 11400 private void makeAppNotRespondingLocked(ProcessRecord app, 11401 String activity, String shortMsg, String longMsg) { 11402 app.notResponding = true; 11403 app.notRespondingReport = generateProcessError(app, 11404 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11405 activity, shortMsg, longMsg, null); 11406 startAppProblemLocked(app); 11407 app.stopFreezingAllLocked(); 11408 } 11409 11410 /** 11411 * Generate a process error record, suitable for attachment to a ProcessRecord. 11412 * 11413 * @param app The ProcessRecord in which the error occurred. 11414 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11415 * ActivityManager.AppErrorStateInfo 11416 * @param activity The activity associated with the crash, if known. 11417 * @param shortMsg Short message describing the crash. 11418 * @param longMsg Long message describing the crash. 11419 * @param stackTrace Full crash stack trace, may be null. 11420 * 11421 * @return Returns a fully-formed AppErrorStateInfo record. 11422 */ 11423 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11424 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11425 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11426 11427 report.condition = condition; 11428 report.processName = app.processName; 11429 report.pid = app.pid; 11430 report.uid = app.info.uid; 11431 report.tag = activity; 11432 report.shortMsg = shortMsg; 11433 report.longMsg = longMsg; 11434 report.stackTrace = stackTrace; 11435 11436 return report; 11437 } 11438 11439 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11440 synchronized (this) { 11441 app.crashing = false; 11442 app.crashingReport = null; 11443 app.notResponding = false; 11444 app.notRespondingReport = null; 11445 if (app.anrDialog == fromDialog) { 11446 app.anrDialog = null; 11447 } 11448 if (app.waitDialog == fromDialog) { 11449 app.waitDialog = null; 11450 } 11451 if (app.pid > 0 && app.pid != MY_PID) { 11452 handleAppCrashLocked(app, null, null, null); 11453 app.kill("user request after error", true); 11454 } 11455 } 11456 } 11457 11458 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11459 String stackTrace) { 11460 long now = SystemClock.uptimeMillis(); 11461 11462 Long crashTime; 11463 if (!app.isolated) { 11464 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11465 } else { 11466 crashTime = null; 11467 } 11468 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11469 // This process loses! 11470 Slog.w(TAG, "Process " + app.info.processName 11471 + " has crashed too many times: killing!"); 11472 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11473 app.userId, app.info.processName, app.uid); 11474 mStackSupervisor.handleAppCrashLocked(app); 11475 if (!app.persistent) { 11476 // We don't want to start this process again until the user 11477 // explicitly does so... but for persistent process, we really 11478 // need to keep it running. If a persistent process is actually 11479 // repeatedly crashing, then badness for everyone. 11480 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11481 app.info.processName); 11482 if (!app.isolated) { 11483 // XXX We don't have a way to mark isolated processes 11484 // as bad, since they don't have a peristent identity. 11485 mBadProcesses.put(app.info.processName, app.uid, 11486 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11487 mProcessCrashTimes.remove(app.info.processName, app.uid); 11488 } 11489 app.bad = true; 11490 app.removed = true; 11491 // Don't let services in this process be restarted and potentially 11492 // annoy the user repeatedly. Unless it is persistent, since those 11493 // processes run critical code. 11494 removeProcessLocked(app, false, false, "crash"); 11495 mStackSupervisor.resumeTopActivitiesLocked(); 11496 return false; 11497 } 11498 mStackSupervisor.resumeTopActivitiesLocked(); 11499 } else { 11500 mStackSupervisor.finishTopRunningActivityLocked(app); 11501 } 11502 11503 // Bump up the crash count of any services currently running in the proc. 11504 for (int i=app.services.size()-1; i>=0; i--) { 11505 // Any services running in the application need to be placed 11506 // back in the pending list. 11507 ServiceRecord sr = app.services.valueAt(i); 11508 sr.crashCount++; 11509 } 11510 11511 // If the crashing process is what we consider to be the "home process" and it has been 11512 // replaced by a third-party app, clear the package preferred activities from packages 11513 // with a home activity running in the process to prevent a repeatedly crashing app 11514 // from blocking the user to manually clear the list. 11515 final ArrayList<ActivityRecord> activities = app.activities; 11516 if (app == mHomeProcess && activities.size() > 0 11517 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11518 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11519 final ActivityRecord r = activities.get(activityNdx); 11520 if (r.isHomeActivity()) { 11521 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11522 try { 11523 ActivityThread.getPackageManager() 11524 .clearPackagePreferredActivities(r.packageName); 11525 } catch (RemoteException c) { 11526 // pm is in same process, this will never happen. 11527 } 11528 } 11529 } 11530 } 11531 11532 if (!app.isolated) { 11533 // XXX Can't keep track of crash times for isolated processes, 11534 // because they don't have a perisistent identity. 11535 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11536 } 11537 11538 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11539 return true; 11540 } 11541 11542 void startAppProblemLocked(ProcessRecord app) { 11543 // If this app is not running under the current user, then we 11544 // can't give it a report button because that would require 11545 // launching the report UI under a different user. 11546 app.errorReportReceiver = null; 11547 11548 for (int userId : mCurrentProfileIds) { 11549 if (app.userId == userId) { 11550 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11551 mContext, app.info.packageName, app.info.flags); 11552 } 11553 } 11554 skipCurrentReceiverLocked(app); 11555 } 11556 11557 void skipCurrentReceiverLocked(ProcessRecord app) { 11558 for (BroadcastQueue queue : mBroadcastQueues) { 11559 queue.skipCurrentReceiverLocked(app); 11560 } 11561 } 11562 11563 /** 11564 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11565 * The application process will exit immediately after this call returns. 11566 * @param app object of the crashing app, null for the system server 11567 * @param crashInfo describing the exception 11568 */ 11569 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11570 ProcessRecord r = findAppProcess(app, "Crash"); 11571 final String processName = app == null ? "system_server" 11572 : (r == null ? "unknown" : r.processName); 11573 11574 handleApplicationCrashInner("crash", r, processName, crashInfo); 11575 } 11576 11577 /* Native crash reporting uses this inner version because it needs to be somewhat 11578 * decoupled from the AM-managed cleanup lifecycle 11579 */ 11580 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11581 ApplicationErrorReport.CrashInfo crashInfo) { 11582 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11583 UserHandle.getUserId(Binder.getCallingUid()), processName, 11584 r == null ? -1 : r.info.flags, 11585 crashInfo.exceptionClassName, 11586 crashInfo.exceptionMessage, 11587 crashInfo.throwFileName, 11588 crashInfo.throwLineNumber); 11589 11590 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11591 11592 crashApplication(r, crashInfo); 11593 } 11594 11595 public void handleApplicationStrictModeViolation( 11596 IBinder app, 11597 int violationMask, 11598 StrictMode.ViolationInfo info) { 11599 ProcessRecord r = findAppProcess(app, "StrictMode"); 11600 if (r == null) { 11601 return; 11602 } 11603 11604 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11605 Integer stackFingerprint = info.hashCode(); 11606 boolean logIt = true; 11607 synchronized (mAlreadyLoggedViolatedStacks) { 11608 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11609 logIt = false; 11610 // TODO: sub-sample into EventLog for these, with 11611 // the info.durationMillis? Then we'd get 11612 // the relative pain numbers, without logging all 11613 // the stack traces repeatedly. We'd want to do 11614 // likewise in the client code, which also does 11615 // dup suppression, before the Binder call. 11616 } else { 11617 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11618 mAlreadyLoggedViolatedStacks.clear(); 11619 } 11620 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11621 } 11622 } 11623 if (logIt) { 11624 logStrictModeViolationToDropBox(r, info); 11625 } 11626 } 11627 11628 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11629 AppErrorResult result = new AppErrorResult(); 11630 synchronized (this) { 11631 final long origId = Binder.clearCallingIdentity(); 11632 11633 Message msg = Message.obtain(); 11634 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11635 HashMap<String, Object> data = new HashMap<String, Object>(); 11636 data.put("result", result); 11637 data.put("app", r); 11638 data.put("violationMask", violationMask); 11639 data.put("info", info); 11640 msg.obj = data; 11641 mHandler.sendMessage(msg); 11642 11643 Binder.restoreCallingIdentity(origId); 11644 } 11645 int res = result.get(); 11646 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11647 } 11648 } 11649 11650 // Depending on the policy in effect, there could be a bunch of 11651 // these in quick succession so we try to batch these together to 11652 // minimize disk writes, number of dropbox entries, and maximize 11653 // compression, by having more fewer, larger records. 11654 private void logStrictModeViolationToDropBox( 11655 ProcessRecord process, 11656 StrictMode.ViolationInfo info) { 11657 if (info == null) { 11658 return; 11659 } 11660 final boolean isSystemApp = process == null || 11661 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11662 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11663 final String processName = process == null ? "unknown" : process.processName; 11664 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11665 final DropBoxManager dbox = (DropBoxManager) 11666 mContext.getSystemService(Context.DROPBOX_SERVICE); 11667 11668 // Exit early if the dropbox isn't configured to accept this report type. 11669 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11670 11671 boolean bufferWasEmpty; 11672 boolean needsFlush; 11673 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11674 synchronized (sb) { 11675 bufferWasEmpty = sb.length() == 0; 11676 appendDropBoxProcessHeaders(process, processName, sb); 11677 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11678 sb.append("System-App: ").append(isSystemApp).append("\n"); 11679 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11680 if (info.violationNumThisLoop != 0) { 11681 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11682 } 11683 if (info.numAnimationsRunning != 0) { 11684 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11685 } 11686 if (info.broadcastIntentAction != null) { 11687 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11688 } 11689 if (info.durationMillis != -1) { 11690 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11691 } 11692 if (info.numInstances != -1) { 11693 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11694 } 11695 if (info.tags != null) { 11696 for (String tag : info.tags) { 11697 sb.append("Span-Tag: ").append(tag).append("\n"); 11698 } 11699 } 11700 sb.append("\n"); 11701 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11702 sb.append(info.crashInfo.stackTrace); 11703 } 11704 sb.append("\n"); 11705 11706 // Only buffer up to ~64k. Various logging bits truncate 11707 // things at 128k. 11708 needsFlush = (sb.length() > 64 * 1024); 11709 } 11710 11711 // Flush immediately if the buffer's grown too large, or this 11712 // is a non-system app. Non-system apps are isolated with a 11713 // different tag & policy and not batched. 11714 // 11715 // Batching is useful during internal testing with 11716 // StrictMode settings turned up high. Without batching, 11717 // thousands of separate files could be created on boot. 11718 if (!isSystemApp || needsFlush) { 11719 new Thread("Error dump: " + dropboxTag) { 11720 @Override 11721 public void run() { 11722 String report; 11723 synchronized (sb) { 11724 report = sb.toString(); 11725 sb.delete(0, sb.length()); 11726 sb.trimToSize(); 11727 } 11728 if (report.length() != 0) { 11729 dbox.addText(dropboxTag, report); 11730 } 11731 } 11732 }.start(); 11733 return; 11734 } 11735 11736 // System app batching: 11737 if (!bufferWasEmpty) { 11738 // An existing dropbox-writing thread is outstanding, so 11739 // we don't need to start it up. The existing thread will 11740 // catch the buffer appends we just did. 11741 return; 11742 } 11743 11744 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11745 // (After this point, we shouldn't access AMS internal data structures.) 11746 new Thread("Error dump: " + dropboxTag) { 11747 @Override 11748 public void run() { 11749 // 5 second sleep to let stacks arrive and be batched together 11750 try { 11751 Thread.sleep(5000); // 5 seconds 11752 } catch (InterruptedException e) {} 11753 11754 String errorReport; 11755 synchronized (mStrictModeBuffer) { 11756 errorReport = mStrictModeBuffer.toString(); 11757 if (errorReport.length() == 0) { 11758 return; 11759 } 11760 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11761 mStrictModeBuffer.trimToSize(); 11762 } 11763 dbox.addText(dropboxTag, errorReport); 11764 } 11765 }.start(); 11766 } 11767 11768 /** 11769 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11770 * @param app object of the crashing app, null for the system server 11771 * @param tag reported by the caller 11772 * @param system whether this wtf is coming from the system 11773 * @param crashInfo describing the context of the error 11774 * @return true if the process should exit immediately (WTF is fatal) 11775 */ 11776 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11777 final ApplicationErrorReport.CrashInfo crashInfo) { 11778 final int callingUid = Binder.getCallingUid(); 11779 final int callingPid = Binder.getCallingPid(); 11780 11781 if (system) { 11782 // If this is coming from the system, we could very well have low-level 11783 // system locks held, so we want to do this all asynchronously. And we 11784 // never want this to become fatal, so there is that too. 11785 mHandler.post(new Runnable() { 11786 @Override public void run() { 11787 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11788 } 11789 }); 11790 return false; 11791 } 11792 11793 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11794 crashInfo); 11795 11796 if (r != null && r.pid != Process.myPid() && 11797 Settings.Global.getInt(mContext.getContentResolver(), 11798 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11799 crashApplication(r, crashInfo); 11800 return true; 11801 } else { 11802 return false; 11803 } 11804 } 11805 11806 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11807 final ApplicationErrorReport.CrashInfo crashInfo) { 11808 final ProcessRecord r = findAppProcess(app, "WTF"); 11809 final String processName = app == null ? "system_server" 11810 : (r == null ? "unknown" : r.processName); 11811 11812 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11813 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11814 11815 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11816 11817 return r; 11818 } 11819 11820 /** 11821 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11822 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11823 */ 11824 private ProcessRecord findAppProcess(IBinder app, String reason) { 11825 if (app == null) { 11826 return null; 11827 } 11828 11829 synchronized (this) { 11830 final int NP = mProcessNames.getMap().size(); 11831 for (int ip=0; ip<NP; ip++) { 11832 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11833 final int NA = apps.size(); 11834 for (int ia=0; ia<NA; ia++) { 11835 ProcessRecord p = apps.valueAt(ia); 11836 if (p.thread != null && p.thread.asBinder() == app) { 11837 return p; 11838 } 11839 } 11840 } 11841 11842 Slog.w(TAG, "Can't find mystery application for " + reason 11843 + " from pid=" + Binder.getCallingPid() 11844 + " uid=" + Binder.getCallingUid() + ": " + app); 11845 return null; 11846 } 11847 } 11848 11849 /** 11850 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11851 * to append various headers to the dropbox log text. 11852 */ 11853 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11854 StringBuilder sb) { 11855 // Watchdog thread ends up invoking this function (with 11856 // a null ProcessRecord) to add the stack file to dropbox. 11857 // Do not acquire a lock on this (am) in such cases, as it 11858 // could cause a potential deadlock, if and when watchdog 11859 // is invoked due to unavailability of lock on am and it 11860 // would prevent watchdog from killing system_server. 11861 if (process == null) { 11862 sb.append("Process: ").append(processName).append("\n"); 11863 return; 11864 } 11865 // Note: ProcessRecord 'process' is guarded by the service 11866 // instance. (notably process.pkgList, which could otherwise change 11867 // concurrently during execution of this method) 11868 synchronized (this) { 11869 sb.append("Process: ").append(processName).append("\n"); 11870 int flags = process.info.flags; 11871 IPackageManager pm = AppGlobals.getPackageManager(); 11872 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11873 for (int ip=0; ip<process.pkgList.size(); ip++) { 11874 String pkg = process.pkgList.keyAt(ip); 11875 sb.append("Package: ").append(pkg); 11876 try { 11877 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11878 if (pi != null) { 11879 sb.append(" v").append(pi.versionCode); 11880 if (pi.versionName != null) { 11881 sb.append(" (").append(pi.versionName).append(")"); 11882 } 11883 } 11884 } catch (RemoteException e) { 11885 Slog.e(TAG, "Error getting package info: " + pkg, e); 11886 } 11887 sb.append("\n"); 11888 } 11889 } 11890 } 11891 11892 private static String processClass(ProcessRecord process) { 11893 if (process == null || process.pid == MY_PID) { 11894 return "system_server"; 11895 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11896 return "system_app"; 11897 } else { 11898 return "data_app"; 11899 } 11900 } 11901 11902 /** 11903 * Write a description of an error (crash, WTF, ANR) to the drop box. 11904 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11905 * @param process which caused the error, null means the system server 11906 * @param activity which triggered the error, null if unknown 11907 * @param parent activity related to the error, null if unknown 11908 * @param subject line related to the error, null if absent 11909 * @param report in long form describing the error, null if absent 11910 * @param logFile to include in the report, null if none 11911 * @param crashInfo giving an application stack trace, null if absent 11912 */ 11913 public void addErrorToDropBox(String eventType, 11914 ProcessRecord process, String processName, ActivityRecord activity, 11915 ActivityRecord parent, String subject, 11916 final String report, final File logFile, 11917 final ApplicationErrorReport.CrashInfo crashInfo) { 11918 // NOTE -- this must never acquire the ActivityManagerService lock, 11919 // otherwise the watchdog may be prevented from resetting the system. 11920 11921 final String dropboxTag = processClass(process) + "_" + eventType; 11922 final DropBoxManager dbox = (DropBoxManager) 11923 mContext.getSystemService(Context.DROPBOX_SERVICE); 11924 11925 // Exit early if the dropbox isn't configured to accept this report type. 11926 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11927 11928 final StringBuilder sb = new StringBuilder(1024); 11929 appendDropBoxProcessHeaders(process, processName, sb); 11930 if (activity != null) { 11931 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11932 } 11933 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11934 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11935 } 11936 if (parent != null && parent != activity) { 11937 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11938 } 11939 if (subject != null) { 11940 sb.append("Subject: ").append(subject).append("\n"); 11941 } 11942 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11943 if (Debug.isDebuggerConnected()) { 11944 sb.append("Debugger: Connected\n"); 11945 } 11946 sb.append("\n"); 11947 11948 // Do the rest in a worker thread to avoid blocking the caller on I/O 11949 // (After this point, we shouldn't access AMS internal data structures.) 11950 Thread worker = new Thread("Error dump: " + dropboxTag) { 11951 @Override 11952 public void run() { 11953 if (report != null) { 11954 sb.append(report); 11955 } 11956 if (logFile != null) { 11957 try { 11958 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11959 "\n\n[[TRUNCATED]]")); 11960 } catch (IOException e) { 11961 Slog.e(TAG, "Error reading " + logFile, e); 11962 } 11963 } 11964 if (crashInfo != null && crashInfo.stackTrace != null) { 11965 sb.append(crashInfo.stackTrace); 11966 } 11967 11968 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11969 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11970 if (lines > 0) { 11971 sb.append("\n"); 11972 11973 // Merge several logcat streams, and take the last N lines 11974 InputStreamReader input = null; 11975 try { 11976 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11977 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11978 "-b", "crash", 11979 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11980 11981 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11982 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11983 input = new InputStreamReader(logcat.getInputStream()); 11984 11985 int num; 11986 char[] buf = new char[8192]; 11987 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11988 } catch (IOException e) { 11989 Slog.e(TAG, "Error running logcat", e); 11990 } finally { 11991 if (input != null) try { input.close(); } catch (IOException e) {} 11992 } 11993 } 11994 11995 dbox.addText(dropboxTag, sb.toString()); 11996 } 11997 }; 11998 11999 if (process == null) { 12000 // If process is null, we are being called from some internal code 12001 // and may be about to die -- run this synchronously. 12002 worker.run(); 12003 } else { 12004 worker.start(); 12005 } 12006 } 12007 12008 /** 12009 * Bring up the "unexpected error" dialog box for a crashing app. 12010 * Deal with edge cases (intercepts from instrumented applications, 12011 * ActivityController, error intent receivers, that sort of thing). 12012 * @param r the application crashing 12013 * @param crashInfo describing the failure 12014 */ 12015 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12016 long timeMillis = System.currentTimeMillis(); 12017 String shortMsg = crashInfo.exceptionClassName; 12018 String longMsg = crashInfo.exceptionMessage; 12019 String stackTrace = crashInfo.stackTrace; 12020 if (shortMsg != null && longMsg != null) { 12021 longMsg = shortMsg + ": " + longMsg; 12022 } else if (shortMsg != null) { 12023 longMsg = shortMsg; 12024 } 12025 12026 AppErrorResult result = new AppErrorResult(); 12027 synchronized (this) { 12028 if (mController != null) { 12029 try { 12030 String name = r != null ? r.processName : null; 12031 int pid = r != null ? r.pid : Binder.getCallingPid(); 12032 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12033 if (!mController.appCrashed(name, pid, 12034 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12035 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12036 && "Native crash".equals(crashInfo.exceptionClassName)) { 12037 Slog.w(TAG, "Skip killing native crashed app " + name 12038 + "(" + pid + ") during testing"); 12039 } else { 12040 Slog.w(TAG, "Force-killing crashed app " + name 12041 + " at watcher's request"); 12042 if (r != null) { 12043 r.kill("crash", true); 12044 } else { 12045 // Huh. 12046 Process.killProcess(pid); 12047 Process.killProcessGroup(uid, pid); 12048 } 12049 } 12050 return; 12051 } 12052 } catch (RemoteException e) { 12053 mController = null; 12054 Watchdog.getInstance().setActivityController(null); 12055 } 12056 } 12057 12058 final long origId = Binder.clearCallingIdentity(); 12059 12060 // If this process is running instrumentation, finish it. 12061 if (r != null && r.instrumentationClass != null) { 12062 Slog.w(TAG, "Error in app " + r.processName 12063 + " running instrumentation " + r.instrumentationClass + ":"); 12064 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12065 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12066 Bundle info = new Bundle(); 12067 info.putString("shortMsg", shortMsg); 12068 info.putString("longMsg", longMsg); 12069 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12070 Binder.restoreCallingIdentity(origId); 12071 return; 12072 } 12073 12074 // Log crash in battery stats. 12075 if (r != null) { 12076 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12077 } 12078 12079 // If we can't identify the process or it's already exceeded its crash quota, 12080 // quit right away without showing a crash dialog. 12081 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12082 Binder.restoreCallingIdentity(origId); 12083 return; 12084 } 12085 12086 Message msg = Message.obtain(); 12087 msg.what = SHOW_ERROR_MSG; 12088 HashMap data = new HashMap(); 12089 data.put("result", result); 12090 data.put("app", r); 12091 msg.obj = data; 12092 mHandler.sendMessage(msg); 12093 12094 Binder.restoreCallingIdentity(origId); 12095 } 12096 12097 int res = result.get(); 12098 12099 Intent appErrorIntent = null; 12100 synchronized (this) { 12101 if (r != null && !r.isolated) { 12102 // XXX Can't keep track of crash time for isolated processes, 12103 // since they don't have a persistent identity. 12104 mProcessCrashTimes.put(r.info.processName, r.uid, 12105 SystemClock.uptimeMillis()); 12106 } 12107 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12108 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12109 } 12110 } 12111 12112 if (appErrorIntent != null) { 12113 try { 12114 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12115 } catch (ActivityNotFoundException e) { 12116 Slog.w(TAG, "bug report receiver dissappeared", e); 12117 } 12118 } 12119 } 12120 12121 Intent createAppErrorIntentLocked(ProcessRecord r, 12122 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12123 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12124 if (report == null) { 12125 return null; 12126 } 12127 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12128 result.setComponent(r.errorReportReceiver); 12129 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12130 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12131 return result; 12132 } 12133 12134 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12135 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12136 if (r.errorReportReceiver == null) { 12137 return null; 12138 } 12139 12140 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12141 return null; 12142 } 12143 12144 ApplicationErrorReport report = new ApplicationErrorReport(); 12145 report.packageName = r.info.packageName; 12146 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12147 report.processName = r.processName; 12148 report.time = timeMillis; 12149 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12150 12151 if (r.crashing || r.forceCrashReport) { 12152 report.type = ApplicationErrorReport.TYPE_CRASH; 12153 report.crashInfo = crashInfo; 12154 } else if (r.notResponding) { 12155 report.type = ApplicationErrorReport.TYPE_ANR; 12156 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12157 12158 report.anrInfo.activity = r.notRespondingReport.tag; 12159 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12160 report.anrInfo.info = r.notRespondingReport.longMsg; 12161 } 12162 12163 return report; 12164 } 12165 12166 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12167 enforceNotIsolatedCaller("getProcessesInErrorState"); 12168 // assume our apps are happy - lazy create the list 12169 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12170 12171 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12172 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12173 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12174 12175 synchronized (this) { 12176 12177 // iterate across all processes 12178 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12179 ProcessRecord app = mLruProcesses.get(i); 12180 if (!allUsers && app.userId != userId) { 12181 continue; 12182 } 12183 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12184 // This one's in trouble, so we'll generate a report for it 12185 // crashes are higher priority (in case there's a crash *and* an anr) 12186 ActivityManager.ProcessErrorStateInfo report = null; 12187 if (app.crashing) { 12188 report = app.crashingReport; 12189 } else if (app.notResponding) { 12190 report = app.notRespondingReport; 12191 } 12192 12193 if (report != null) { 12194 if (errList == null) { 12195 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12196 } 12197 errList.add(report); 12198 } else { 12199 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12200 " crashing = " + app.crashing + 12201 " notResponding = " + app.notResponding); 12202 } 12203 } 12204 } 12205 } 12206 12207 return errList; 12208 } 12209 12210 static int procStateToImportance(int procState, int memAdj, 12211 ActivityManager.RunningAppProcessInfo currApp) { 12212 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12213 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12214 currApp.lru = memAdj; 12215 } else { 12216 currApp.lru = 0; 12217 } 12218 return imp; 12219 } 12220 12221 private void fillInProcMemInfo(ProcessRecord app, 12222 ActivityManager.RunningAppProcessInfo outInfo) { 12223 outInfo.pid = app.pid; 12224 outInfo.uid = app.info.uid; 12225 if (mHeavyWeightProcess == app) { 12226 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12227 } 12228 if (app.persistent) { 12229 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12230 } 12231 if (app.activities.size() > 0) { 12232 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12233 } 12234 outInfo.lastTrimLevel = app.trimMemoryLevel; 12235 int adj = app.curAdj; 12236 int procState = app.curProcState; 12237 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12238 outInfo.importanceReasonCode = app.adjTypeCode; 12239 outInfo.processState = app.curProcState; 12240 } 12241 12242 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12243 enforceNotIsolatedCaller("getRunningAppProcesses"); 12244 // Lazy instantiation of list 12245 List<ActivityManager.RunningAppProcessInfo> runList = null; 12246 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12247 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12248 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12249 synchronized (this) { 12250 // Iterate across all processes 12251 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12252 ProcessRecord app = mLruProcesses.get(i); 12253 if (!allUsers && app.userId != userId) { 12254 continue; 12255 } 12256 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12257 // Generate process state info for running application 12258 ActivityManager.RunningAppProcessInfo currApp = 12259 new ActivityManager.RunningAppProcessInfo(app.processName, 12260 app.pid, app.getPackageList()); 12261 fillInProcMemInfo(app, currApp); 12262 if (app.adjSource instanceof ProcessRecord) { 12263 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12264 currApp.importanceReasonImportance = 12265 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12266 app.adjSourceProcState); 12267 } else if (app.adjSource instanceof ActivityRecord) { 12268 ActivityRecord r = (ActivityRecord)app.adjSource; 12269 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12270 } 12271 if (app.adjTarget instanceof ComponentName) { 12272 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12273 } 12274 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12275 // + " lru=" + currApp.lru); 12276 if (runList == null) { 12277 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12278 } 12279 runList.add(currApp); 12280 } 12281 } 12282 } 12283 return runList; 12284 } 12285 12286 public List<ApplicationInfo> getRunningExternalApplications() { 12287 enforceNotIsolatedCaller("getRunningExternalApplications"); 12288 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12289 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12290 if (runningApps != null && runningApps.size() > 0) { 12291 Set<String> extList = new HashSet<String>(); 12292 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12293 if (app.pkgList != null) { 12294 for (String pkg : app.pkgList) { 12295 extList.add(pkg); 12296 } 12297 } 12298 } 12299 IPackageManager pm = AppGlobals.getPackageManager(); 12300 for (String pkg : extList) { 12301 try { 12302 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12303 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12304 retList.add(info); 12305 } 12306 } catch (RemoteException e) { 12307 } 12308 } 12309 } 12310 return retList; 12311 } 12312 12313 @Override 12314 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12315 enforceNotIsolatedCaller("getMyMemoryState"); 12316 synchronized (this) { 12317 ProcessRecord proc; 12318 synchronized (mPidsSelfLocked) { 12319 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12320 } 12321 fillInProcMemInfo(proc, outInfo); 12322 } 12323 } 12324 12325 @Override 12326 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12327 if (checkCallingPermission(android.Manifest.permission.DUMP) 12328 != PackageManager.PERMISSION_GRANTED) { 12329 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12330 + Binder.getCallingPid() 12331 + ", uid=" + Binder.getCallingUid() 12332 + " without permission " 12333 + android.Manifest.permission.DUMP); 12334 return; 12335 } 12336 12337 boolean dumpAll = false; 12338 boolean dumpClient = false; 12339 String dumpPackage = null; 12340 12341 int opti = 0; 12342 while (opti < args.length) { 12343 String opt = args[opti]; 12344 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12345 break; 12346 } 12347 opti++; 12348 if ("-a".equals(opt)) { 12349 dumpAll = true; 12350 } else if ("-c".equals(opt)) { 12351 dumpClient = true; 12352 } else if ("-p".equals(opt)) { 12353 if (opti < args.length) { 12354 dumpPackage = args[opti]; 12355 opti++; 12356 } else { 12357 pw.println("Error: -p option requires package argument"); 12358 return; 12359 } 12360 dumpClient = true; 12361 } else if ("-h".equals(opt)) { 12362 pw.println("Activity manager dump options:"); 12363 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12364 pw.println(" cmd may be one of:"); 12365 pw.println(" a[ctivities]: activity stack state"); 12366 pw.println(" r[recents]: recent activities state"); 12367 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12368 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12369 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12370 pw.println(" o[om]: out of memory management"); 12371 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12372 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12373 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12374 pw.println(" as[sociations]: tracked app associations"); 12375 pw.println(" service [COMP_SPEC]: service client-side state"); 12376 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12377 pw.println(" all: dump all activities"); 12378 pw.println(" top: dump the top activity"); 12379 pw.println(" write: write all pending state to storage"); 12380 pw.println(" track-associations: enable association tracking"); 12381 pw.println(" untrack-associations: disable and clear association tracking"); 12382 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12383 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12384 pw.println(" a partial substring in a component name, a"); 12385 pw.println(" hex object identifier."); 12386 pw.println(" -a: include all available server state."); 12387 pw.println(" -c: include client state."); 12388 pw.println(" -p: limit output to given package."); 12389 return; 12390 } else { 12391 pw.println("Unknown argument: " + opt + "; use -h for help"); 12392 } 12393 } 12394 12395 long origId = Binder.clearCallingIdentity(); 12396 boolean more = false; 12397 // Is the caller requesting to dump a particular piece of data? 12398 if (opti < args.length) { 12399 String cmd = args[opti]; 12400 opti++; 12401 if ("activities".equals(cmd) || "a".equals(cmd)) { 12402 synchronized (this) { 12403 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12404 } 12405 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12406 synchronized (this) { 12407 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12408 } 12409 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12410 String[] newArgs; 12411 String name; 12412 if (opti >= args.length) { 12413 name = null; 12414 newArgs = EMPTY_STRING_ARRAY; 12415 } else { 12416 dumpPackage = args[opti]; 12417 opti++; 12418 newArgs = new String[args.length - opti]; 12419 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12420 args.length - opti); 12421 } 12422 synchronized (this) { 12423 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12424 } 12425 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12426 String[] newArgs; 12427 String name; 12428 if (opti >= args.length) { 12429 name = null; 12430 newArgs = EMPTY_STRING_ARRAY; 12431 } else { 12432 dumpPackage = args[opti]; 12433 opti++; 12434 newArgs = new String[args.length - opti]; 12435 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12436 args.length - opti); 12437 } 12438 synchronized (this) { 12439 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12440 } 12441 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12442 String[] newArgs; 12443 String name; 12444 if (opti >= args.length) { 12445 name = null; 12446 newArgs = EMPTY_STRING_ARRAY; 12447 } else { 12448 dumpPackage = args[opti]; 12449 opti++; 12450 newArgs = new String[args.length - opti]; 12451 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12452 args.length - opti); 12453 } 12454 synchronized (this) { 12455 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12456 } 12457 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12458 synchronized (this) { 12459 dumpOomLocked(fd, pw, args, opti, true); 12460 } 12461 } else if ("provider".equals(cmd)) { 12462 String[] newArgs; 12463 String name; 12464 if (opti >= args.length) { 12465 name = null; 12466 newArgs = EMPTY_STRING_ARRAY; 12467 } else { 12468 name = args[opti]; 12469 opti++; 12470 newArgs = new String[args.length - opti]; 12471 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12472 } 12473 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12474 pw.println("No providers match: " + name); 12475 pw.println("Use -h for help."); 12476 } 12477 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12478 synchronized (this) { 12479 dumpProvidersLocked(fd, pw, args, opti, true, null); 12480 } 12481 } else if ("service".equals(cmd)) { 12482 String[] newArgs; 12483 String name; 12484 if (opti >= args.length) { 12485 name = null; 12486 newArgs = EMPTY_STRING_ARRAY; 12487 } else { 12488 name = args[opti]; 12489 opti++; 12490 newArgs = new String[args.length - opti]; 12491 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12492 args.length - opti); 12493 } 12494 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12495 pw.println("No services match: " + name); 12496 pw.println("Use -h for help."); 12497 } 12498 } else if ("package".equals(cmd)) { 12499 String[] newArgs; 12500 if (opti >= args.length) { 12501 pw.println("package: no package name specified"); 12502 pw.println("Use -h for help."); 12503 } else { 12504 dumpPackage = args[opti]; 12505 opti++; 12506 newArgs = new String[args.length - opti]; 12507 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12508 args.length - opti); 12509 args = newArgs; 12510 opti = 0; 12511 more = true; 12512 } 12513 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12514 synchronized (this) { 12515 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12516 } 12517 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12518 synchronized (this) { 12519 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12520 } 12521 } else if ("write".equals(cmd)) { 12522 mTaskPersister.flush(); 12523 pw.println("All tasks persisted."); 12524 return; 12525 } else if ("track-associations".equals(cmd)) { 12526 synchronized (this) { 12527 if (!mTrackingAssociations) { 12528 mTrackingAssociations = true; 12529 pw.println("Association tracking started."); 12530 } else { 12531 pw.println("Association tracking already enabled."); 12532 } 12533 } 12534 return; 12535 } else if ("untrack-associations".equals(cmd)) { 12536 synchronized (this) { 12537 if (mTrackingAssociations) { 12538 mTrackingAssociations = false; 12539 mAssociations.clear(); 12540 pw.println("Association tracking stopped."); 12541 } else { 12542 pw.println("Association tracking not running."); 12543 } 12544 } 12545 return; 12546 } else { 12547 // Dumping a single activity? 12548 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12549 pw.println("Bad activity command, or no activities match: " + cmd); 12550 pw.println("Use -h for help."); 12551 } 12552 } 12553 if (!more) { 12554 Binder.restoreCallingIdentity(origId); 12555 return; 12556 } 12557 } 12558 12559 // No piece of data specified, dump everything. 12560 synchronized (this) { 12561 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12562 pw.println(); 12563 if (dumpAll) { 12564 pw.println("-------------------------------------------------------------------------------"); 12565 } 12566 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12567 pw.println(); 12568 if (dumpAll) { 12569 pw.println("-------------------------------------------------------------------------------"); 12570 } 12571 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12572 pw.println(); 12573 if (dumpAll) { 12574 pw.println("-------------------------------------------------------------------------------"); 12575 } 12576 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12577 pw.println(); 12578 if (dumpAll) { 12579 pw.println("-------------------------------------------------------------------------------"); 12580 } 12581 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12582 pw.println(); 12583 if (dumpAll) { 12584 pw.println("-------------------------------------------------------------------------------"); 12585 } 12586 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12587 if (mAssociations.size() > 0) { 12588 pw.println(); 12589 if (dumpAll) { 12590 pw.println("-------------------------------------------------------------------------------"); 12591 } 12592 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12593 } 12594 pw.println(); 12595 if (dumpAll) { 12596 pw.println("-------------------------------------------------------------------------------"); 12597 } 12598 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12599 } 12600 Binder.restoreCallingIdentity(origId); 12601 } 12602 12603 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12604 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12605 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12606 12607 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12608 dumpPackage); 12609 boolean needSep = printedAnything; 12610 12611 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12612 dumpPackage, needSep, " mFocusedActivity: "); 12613 if (printed) { 12614 printedAnything = true; 12615 needSep = false; 12616 } 12617 12618 if (dumpPackage == null) { 12619 if (needSep) { 12620 pw.println(); 12621 } 12622 needSep = true; 12623 printedAnything = true; 12624 mStackSupervisor.dump(pw, " "); 12625 } 12626 12627 if (!printedAnything) { 12628 pw.println(" (nothing)"); 12629 } 12630 } 12631 12632 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12633 int opti, boolean dumpAll, String dumpPackage) { 12634 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12635 12636 boolean printedAnything = false; 12637 12638 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12639 boolean printedHeader = false; 12640 12641 final int N = mRecentTasks.size(); 12642 for (int i=0; i<N; i++) { 12643 TaskRecord tr = mRecentTasks.get(i); 12644 if (dumpPackage != null) { 12645 if (tr.realActivity == null || 12646 !dumpPackage.equals(tr.realActivity)) { 12647 continue; 12648 } 12649 } 12650 if (!printedHeader) { 12651 pw.println(" Recent tasks:"); 12652 printedHeader = true; 12653 printedAnything = true; 12654 } 12655 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12656 pw.println(tr); 12657 if (dumpAll) { 12658 mRecentTasks.get(i).dump(pw, " "); 12659 } 12660 } 12661 } 12662 12663 if (!printedAnything) { 12664 pw.println(" (nothing)"); 12665 } 12666 } 12667 12668 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12669 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12670 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12671 12672 int dumpUid = 0; 12673 if (dumpPackage != null) { 12674 IPackageManager pm = AppGlobals.getPackageManager(); 12675 try { 12676 dumpUid = pm.getPackageUid(dumpPackage, 0); 12677 } catch (RemoteException e) { 12678 } 12679 } 12680 12681 boolean printedAnything = false; 12682 12683 final long now = SystemClock.uptimeMillis(); 12684 12685 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12686 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12687 = mAssociations.valueAt(i1); 12688 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12689 SparseArray<ArrayMap<String, Association>> sourceUids 12690 = targetComponents.valueAt(i2); 12691 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12692 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12693 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12694 Association ass = sourceProcesses.valueAt(i4); 12695 if (dumpPackage != null) { 12696 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12697 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12698 continue; 12699 } 12700 } 12701 printedAnything = true; 12702 pw.print(" "); 12703 pw.print(ass.mTargetProcess); 12704 pw.print("/"); 12705 UserHandle.formatUid(pw, ass.mTargetUid); 12706 pw.print(" <- "); 12707 pw.print(ass.mSourceProcess); 12708 pw.print("/"); 12709 UserHandle.formatUid(pw, ass.mSourceUid); 12710 pw.println(); 12711 pw.print(" via "); 12712 pw.print(ass.mTargetComponent.flattenToShortString()); 12713 pw.println(); 12714 pw.print(" "); 12715 long dur = ass.mTime; 12716 if (ass.mNesting > 0) { 12717 dur += now - ass.mStartTime; 12718 } 12719 TimeUtils.formatDuration(dur, pw); 12720 pw.print(" ("); 12721 pw.print(ass.mCount); 12722 pw.println(" times)"); 12723 if (ass.mNesting > 0) { 12724 pw.print(" "); 12725 pw.print(" Currently active: "); 12726 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12727 pw.println(); 12728 } 12729 } 12730 } 12731 } 12732 12733 } 12734 12735 if (!printedAnything) { 12736 pw.println(" (nothing)"); 12737 } 12738 } 12739 12740 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12741 int opti, boolean dumpAll, String dumpPackage) { 12742 boolean needSep = false; 12743 boolean printedAnything = false; 12744 int numPers = 0; 12745 12746 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12747 12748 if (dumpAll) { 12749 final int NP = mProcessNames.getMap().size(); 12750 for (int ip=0; ip<NP; ip++) { 12751 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12752 final int NA = procs.size(); 12753 for (int ia=0; ia<NA; ia++) { 12754 ProcessRecord r = procs.valueAt(ia); 12755 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12756 continue; 12757 } 12758 if (!needSep) { 12759 pw.println(" All known processes:"); 12760 needSep = true; 12761 printedAnything = true; 12762 } 12763 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12764 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12765 pw.print(" "); pw.println(r); 12766 r.dump(pw, " "); 12767 if (r.persistent) { 12768 numPers++; 12769 } 12770 } 12771 } 12772 } 12773 12774 if (mIsolatedProcesses.size() > 0) { 12775 boolean printed = false; 12776 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12777 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12778 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12779 continue; 12780 } 12781 if (!printed) { 12782 if (needSep) { 12783 pw.println(); 12784 } 12785 pw.println(" Isolated process list (sorted by uid):"); 12786 printedAnything = true; 12787 printed = true; 12788 needSep = true; 12789 } 12790 pw.println(String.format("%sIsolated #%2d: %s", 12791 " ", i, r.toString())); 12792 } 12793 } 12794 12795 if (mLruProcesses.size() > 0) { 12796 if (needSep) { 12797 pw.println(); 12798 } 12799 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12800 pw.print(" total, non-act at "); 12801 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12802 pw.print(", non-svc at "); 12803 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12804 pw.println("):"); 12805 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12806 needSep = true; 12807 printedAnything = true; 12808 } 12809 12810 if (dumpAll || dumpPackage != null) { 12811 synchronized (mPidsSelfLocked) { 12812 boolean printed = false; 12813 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12814 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12815 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12816 continue; 12817 } 12818 if (!printed) { 12819 if (needSep) pw.println(); 12820 needSep = true; 12821 pw.println(" PID mappings:"); 12822 printed = true; 12823 printedAnything = true; 12824 } 12825 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12826 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12827 } 12828 } 12829 } 12830 12831 if (mForegroundProcesses.size() > 0) { 12832 synchronized (mPidsSelfLocked) { 12833 boolean printed = false; 12834 for (int i=0; i<mForegroundProcesses.size(); i++) { 12835 ProcessRecord r = mPidsSelfLocked.get( 12836 mForegroundProcesses.valueAt(i).pid); 12837 if (dumpPackage != null && (r == null 12838 || !r.pkgList.containsKey(dumpPackage))) { 12839 continue; 12840 } 12841 if (!printed) { 12842 if (needSep) pw.println(); 12843 needSep = true; 12844 pw.println(" Foreground Processes:"); 12845 printed = true; 12846 printedAnything = true; 12847 } 12848 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12849 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12850 } 12851 } 12852 } 12853 12854 if (mPersistentStartingProcesses.size() > 0) { 12855 if (needSep) pw.println(); 12856 needSep = true; 12857 printedAnything = true; 12858 pw.println(" Persisent processes that are starting:"); 12859 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12860 "Starting Norm", "Restarting PERS", dumpPackage); 12861 } 12862 12863 if (mRemovedProcesses.size() > 0) { 12864 if (needSep) pw.println(); 12865 needSep = true; 12866 printedAnything = true; 12867 pw.println(" Processes that are being removed:"); 12868 dumpProcessList(pw, this, mRemovedProcesses, " ", 12869 "Removed Norm", "Removed PERS", dumpPackage); 12870 } 12871 12872 if (mProcessesOnHold.size() > 0) { 12873 if (needSep) pw.println(); 12874 needSep = true; 12875 printedAnything = true; 12876 pw.println(" Processes that are on old until the system is ready:"); 12877 dumpProcessList(pw, this, mProcessesOnHold, " ", 12878 "OnHold Norm", "OnHold PERS", dumpPackage); 12879 } 12880 12881 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12882 12883 if (mProcessCrashTimes.getMap().size() > 0) { 12884 boolean printed = false; 12885 long now = SystemClock.uptimeMillis(); 12886 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12887 final int NP = pmap.size(); 12888 for (int ip=0; ip<NP; ip++) { 12889 String pname = pmap.keyAt(ip); 12890 SparseArray<Long> uids = pmap.valueAt(ip); 12891 final int N = uids.size(); 12892 for (int i=0; i<N; i++) { 12893 int puid = uids.keyAt(i); 12894 ProcessRecord r = mProcessNames.get(pname, puid); 12895 if (dumpPackage != null && (r == null 12896 || !r.pkgList.containsKey(dumpPackage))) { 12897 continue; 12898 } 12899 if (!printed) { 12900 if (needSep) pw.println(); 12901 needSep = true; 12902 pw.println(" Time since processes crashed:"); 12903 printed = true; 12904 printedAnything = true; 12905 } 12906 pw.print(" Process "); pw.print(pname); 12907 pw.print(" uid "); pw.print(puid); 12908 pw.print(": last crashed "); 12909 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12910 pw.println(" ago"); 12911 } 12912 } 12913 } 12914 12915 if (mBadProcesses.getMap().size() > 0) { 12916 boolean printed = false; 12917 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12918 final int NP = pmap.size(); 12919 for (int ip=0; ip<NP; ip++) { 12920 String pname = pmap.keyAt(ip); 12921 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12922 final int N = uids.size(); 12923 for (int i=0; i<N; i++) { 12924 int puid = uids.keyAt(i); 12925 ProcessRecord r = mProcessNames.get(pname, puid); 12926 if (dumpPackage != null && (r == null 12927 || !r.pkgList.containsKey(dumpPackage))) { 12928 continue; 12929 } 12930 if (!printed) { 12931 if (needSep) pw.println(); 12932 needSep = true; 12933 pw.println(" Bad processes:"); 12934 printedAnything = true; 12935 } 12936 BadProcessInfo info = uids.valueAt(i); 12937 pw.print(" Bad process "); pw.print(pname); 12938 pw.print(" uid "); pw.print(puid); 12939 pw.print(": crashed at time "); pw.println(info.time); 12940 if (info.shortMsg != null) { 12941 pw.print(" Short msg: "); pw.println(info.shortMsg); 12942 } 12943 if (info.longMsg != null) { 12944 pw.print(" Long msg: "); pw.println(info.longMsg); 12945 } 12946 if (info.stack != null) { 12947 pw.println(" Stack:"); 12948 int lastPos = 0; 12949 for (int pos=0; pos<info.stack.length(); pos++) { 12950 if (info.stack.charAt(pos) == '\n') { 12951 pw.print(" "); 12952 pw.write(info.stack, lastPos, pos-lastPos); 12953 pw.println(); 12954 lastPos = pos+1; 12955 } 12956 } 12957 if (lastPos < info.stack.length()) { 12958 pw.print(" "); 12959 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12960 pw.println(); 12961 } 12962 } 12963 } 12964 } 12965 } 12966 12967 if (dumpPackage == null) { 12968 pw.println(); 12969 needSep = false; 12970 pw.println(" mStartedUsers:"); 12971 for (int i=0; i<mStartedUsers.size(); i++) { 12972 UserStartedState uss = mStartedUsers.valueAt(i); 12973 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12974 pw.print(": "); uss.dump("", pw); 12975 } 12976 pw.print(" mStartedUserArray: ["); 12977 for (int i=0; i<mStartedUserArray.length; i++) { 12978 if (i > 0) pw.print(", "); 12979 pw.print(mStartedUserArray[i]); 12980 } 12981 pw.println("]"); 12982 pw.print(" mUserLru: ["); 12983 for (int i=0; i<mUserLru.size(); i++) { 12984 if (i > 0) pw.print(", "); 12985 pw.print(mUserLru.get(i)); 12986 } 12987 pw.println("]"); 12988 if (dumpAll) { 12989 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12990 } 12991 synchronized (mUserProfileGroupIdsSelfLocked) { 12992 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12993 pw.println(" mUserProfileGroupIds:"); 12994 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12995 pw.print(" User #"); 12996 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12997 pw.print(" -> profile #"); 12998 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12999 } 13000 } 13001 } 13002 } 13003 if (mHomeProcess != null && (dumpPackage == null 13004 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13005 if (needSep) { 13006 pw.println(); 13007 needSep = false; 13008 } 13009 pw.println(" mHomeProcess: " + mHomeProcess); 13010 } 13011 if (mPreviousProcess != null && (dumpPackage == null 13012 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13013 if (needSep) { 13014 pw.println(); 13015 needSep = false; 13016 } 13017 pw.println(" mPreviousProcess: " + mPreviousProcess); 13018 } 13019 if (dumpAll) { 13020 StringBuilder sb = new StringBuilder(128); 13021 sb.append(" mPreviousProcessVisibleTime: "); 13022 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13023 pw.println(sb); 13024 } 13025 if (mHeavyWeightProcess != null && (dumpPackage == null 13026 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13027 if (needSep) { 13028 pw.println(); 13029 needSep = false; 13030 } 13031 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13032 } 13033 if (dumpPackage == null) { 13034 pw.println(" mConfiguration: " + mConfiguration); 13035 } 13036 if (dumpAll) { 13037 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13038 if (mCompatModePackages.getPackages().size() > 0) { 13039 boolean printed = false; 13040 for (Map.Entry<String, Integer> entry 13041 : mCompatModePackages.getPackages().entrySet()) { 13042 String pkg = entry.getKey(); 13043 int mode = entry.getValue(); 13044 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13045 continue; 13046 } 13047 if (!printed) { 13048 pw.println(" mScreenCompatPackages:"); 13049 printed = true; 13050 } 13051 pw.print(" "); pw.print(pkg); pw.print(": "); 13052 pw.print(mode); pw.println(); 13053 } 13054 } 13055 } 13056 if (dumpPackage == null) { 13057 pw.println(" mWakefulness=" 13058 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13059 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13060 + lockScreenShownToString()); 13061 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13062 + " mTestPssMode=" + mTestPssMode); 13063 } 13064 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13065 || mOrigWaitForDebugger) { 13066 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13067 || dumpPackage.equals(mOrigDebugApp)) { 13068 if (needSep) { 13069 pw.println(); 13070 needSep = false; 13071 } 13072 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13073 + " mDebugTransient=" + mDebugTransient 13074 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13075 } 13076 } 13077 if (mOpenGlTraceApp != null) { 13078 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13079 if (needSep) { 13080 pw.println(); 13081 needSep = false; 13082 } 13083 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13084 } 13085 } 13086 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13087 || mProfileFd != null) { 13088 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13089 if (needSep) { 13090 pw.println(); 13091 needSep = false; 13092 } 13093 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13094 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13095 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13096 + mAutoStopProfiler); 13097 pw.println(" mProfileType=" + mProfileType); 13098 } 13099 } 13100 if (dumpPackage == null) { 13101 if (mAlwaysFinishActivities || mController != null) { 13102 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13103 + " mController=" + mController); 13104 } 13105 if (dumpAll) { 13106 pw.println(" Total persistent processes: " + numPers); 13107 pw.println(" mProcessesReady=" + mProcessesReady 13108 + " mSystemReady=" + mSystemReady 13109 + " mBooted=" + mBooted 13110 + " mFactoryTest=" + mFactoryTest); 13111 pw.println(" mBooting=" + mBooting 13112 + " mCallFinishBooting=" + mCallFinishBooting 13113 + " mBootAnimationComplete=" + mBootAnimationComplete); 13114 pw.print(" mLastPowerCheckRealtime="); 13115 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13116 pw.println(""); 13117 pw.print(" mLastPowerCheckUptime="); 13118 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13119 pw.println(""); 13120 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13121 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13122 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13123 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13124 + " (" + mLruProcesses.size() + " total)" 13125 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13126 + " mNumServiceProcs=" + mNumServiceProcs 13127 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13128 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13129 + " mLastMemoryLevel" + mLastMemoryLevel 13130 + " mLastNumProcesses" + mLastNumProcesses); 13131 long now = SystemClock.uptimeMillis(); 13132 pw.print(" mLastIdleTime="); 13133 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13134 pw.print(" mLowRamSinceLastIdle="); 13135 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13136 pw.println(); 13137 } 13138 } 13139 13140 if (!printedAnything) { 13141 pw.println(" (nothing)"); 13142 } 13143 } 13144 13145 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13146 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13147 if (mProcessesToGc.size() > 0) { 13148 boolean printed = false; 13149 long now = SystemClock.uptimeMillis(); 13150 for (int i=0; i<mProcessesToGc.size(); i++) { 13151 ProcessRecord proc = mProcessesToGc.get(i); 13152 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13153 continue; 13154 } 13155 if (!printed) { 13156 if (needSep) pw.println(); 13157 needSep = true; 13158 pw.println(" Processes that are waiting to GC:"); 13159 printed = true; 13160 } 13161 pw.print(" Process "); pw.println(proc); 13162 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13163 pw.print(", last gced="); 13164 pw.print(now-proc.lastRequestedGc); 13165 pw.print(" ms ago, last lowMem="); 13166 pw.print(now-proc.lastLowMemory); 13167 pw.println(" ms ago"); 13168 13169 } 13170 } 13171 return needSep; 13172 } 13173 13174 void printOomLevel(PrintWriter pw, String name, int adj) { 13175 pw.print(" "); 13176 if (adj >= 0) { 13177 pw.print(' '); 13178 if (adj < 10) pw.print(' '); 13179 } else { 13180 if (adj > -10) pw.print(' '); 13181 } 13182 pw.print(adj); 13183 pw.print(": "); 13184 pw.print(name); 13185 pw.print(" ("); 13186 pw.print(mProcessList.getMemLevel(adj)/1024); 13187 pw.println(" kB)"); 13188 } 13189 13190 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13191 int opti, boolean dumpAll) { 13192 boolean needSep = false; 13193 13194 if (mLruProcesses.size() > 0) { 13195 if (needSep) pw.println(); 13196 needSep = true; 13197 pw.println(" OOM levels:"); 13198 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13199 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13200 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13201 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13202 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13203 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13204 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13205 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13206 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13207 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13208 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13209 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13210 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13211 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13212 13213 if (needSep) pw.println(); 13214 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13215 pw.print(" total, non-act at "); 13216 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13217 pw.print(", non-svc at "); 13218 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13219 pw.println("):"); 13220 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13221 needSep = true; 13222 } 13223 13224 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13225 13226 pw.println(); 13227 pw.println(" mHomeProcess: " + mHomeProcess); 13228 pw.println(" mPreviousProcess: " + mPreviousProcess); 13229 if (mHeavyWeightProcess != null) { 13230 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13231 } 13232 13233 return true; 13234 } 13235 13236 /** 13237 * There are three ways to call this: 13238 * - no provider specified: dump all the providers 13239 * - a flattened component name that matched an existing provider was specified as the 13240 * first arg: dump that one provider 13241 * - the first arg isn't the flattened component name of an existing provider: 13242 * dump all providers whose component contains the first arg as a substring 13243 */ 13244 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13245 int opti, boolean dumpAll) { 13246 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13247 } 13248 13249 static class ItemMatcher { 13250 ArrayList<ComponentName> components; 13251 ArrayList<String> strings; 13252 ArrayList<Integer> objects; 13253 boolean all; 13254 13255 ItemMatcher() { 13256 all = true; 13257 } 13258 13259 void build(String name) { 13260 ComponentName componentName = ComponentName.unflattenFromString(name); 13261 if (componentName != null) { 13262 if (components == null) { 13263 components = new ArrayList<ComponentName>(); 13264 } 13265 components.add(componentName); 13266 all = false; 13267 } else { 13268 int objectId = 0; 13269 // Not a '/' separated full component name; maybe an object ID? 13270 try { 13271 objectId = Integer.parseInt(name, 16); 13272 if (objects == null) { 13273 objects = new ArrayList<Integer>(); 13274 } 13275 objects.add(objectId); 13276 all = false; 13277 } catch (RuntimeException e) { 13278 // Not an integer; just do string match. 13279 if (strings == null) { 13280 strings = new ArrayList<String>(); 13281 } 13282 strings.add(name); 13283 all = false; 13284 } 13285 } 13286 } 13287 13288 int build(String[] args, int opti) { 13289 for (; opti<args.length; opti++) { 13290 String name = args[opti]; 13291 if ("--".equals(name)) { 13292 return opti+1; 13293 } 13294 build(name); 13295 } 13296 return opti; 13297 } 13298 13299 boolean match(Object object, ComponentName comp) { 13300 if (all) { 13301 return true; 13302 } 13303 if (components != null) { 13304 for (int i=0; i<components.size(); i++) { 13305 if (components.get(i).equals(comp)) { 13306 return true; 13307 } 13308 } 13309 } 13310 if (objects != null) { 13311 for (int i=0; i<objects.size(); i++) { 13312 if (System.identityHashCode(object) == objects.get(i)) { 13313 return true; 13314 } 13315 } 13316 } 13317 if (strings != null) { 13318 String flat = comp.flattenToString(); 13319 for (int i=0; i<strings.size(); i++) { 13320 if (flat.contains(strings.get(i))) { 13321 return true; 13322 } 13323 } 13324 } 13325 return false; 13326 } 13327 } 13328 13329 /** 13330 * There are three things that cmd can be: 13331 * - a flattened component name that matches an existing activity 13332 * - the cmd arg isn't the flattened component name of an existing activity: 13333 * dump all activity whose component contains the cmd as a substring 13334 * - A hex number of the ActivityRecord object instance. 13335 */ 13336 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13337 int opti, boolean dumpAll) { 13338 ArrayList<ActivityRecord> activities; 13339 13340 synchronized (this) { 13341 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13342 } 13343 13344 if (activities.size() <= 0) { 13345 return false; 13346 } 13347 13348 String[] newArgs = new String[args.length - opti]; 13349 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13350 13351 TaskRecord lastTask = null; 13352 boolean needSep = false; 13353 for (int i=activities.size()-1; i>=0; i--) { 13354 ActivityRecord r = activities.get(i); 13355 if (needSep) { 13356 pw.println(); 13357 } 13358 needSep = true; 13359 synchronized (this) { 13360 if (lastTask != r.task) { 13361 lastTask = r.task; 13362 pw.print("TASK "); pw.print(lastTask.affinity); 13363 pw.print(" id="); pw.println(lastTask.taskId); 13364 if (dumpAll) { 13365 lastTask.dump(pw, " "); 13366 } 13367 } 13368 } 13369 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13370 } 13371 return true; 13372 } 13373 13374 /** 13375 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13376 * there is a thread associated with the activity. 13377 */ 13378 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13379 final ActivityRecord r, String[] args, boolean dumpAll) { 13380 String innerPrefix = prefix + " "; 13381 synchronized (this) { 13382 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13383 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13384 pw.print(" pid="); 13385 if (r.app != null) pw.println(r.app.pid); 13386 else pw.println("(not running)"); 13387 if (dumpAll) { 13388 r.dump(pw, innerPrefix); 13389 } 13390 } 13391 if (r.app != null && r.app.thread != null) { 13392 // flush anything that is already in the PrintWriter since the thread is going 13393 // to write to the file descriptor directly 13394 pw.flush(); 13395 try { 13396 TransferPipe tp = new TransferPipe(); 13397 try { 13398 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13399 r.appToken, innerPrefix, args); 13400 tp.go(fd); 13401 } finally { 13402 tp.kill(); 13403 } 13404 } catch (IOException e) { 13405 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13406 } catch (RemoteException e) { 13407 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13408 } 13409 } 13410 } 13411 13412 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13413 int opti, boolean dumpAll, String dumpPackage) { 13414 boolean needSep = false; 13415 boolean onlyHistory = false; 13416 boolean printedAnything = false; 13417 13418 if ("history".equals(dumpPackage)) { 13419 if (opti < args.length && "-s".equals(args[opti])) { 13420 dumpAll = false; 13421 } 13422 onlyHistory = true; 13423 dumpPackage = null; 13424 } 13425 13426 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13427 if (!onlyHistory && dumpAll) { 13428 if (mRegisteredReceivers.size() > 0) { 13429 boolean printed = false; 13430 Iterator it = mRegisteredReceivers.values().iterator(); 13431 while (it.hasNext()) { 13432 ReceiverList r = (ReceiverList)it.next(); 13433 if (dumpPackage != null && (r.app == null || 13434 !dumpPackage.equals(r.app.info.packageName))) { 13435 continue; 13436 } 13437 if (!printed) { 13438 pw.println(" Registered Receivers:"); 13439 needSep = true; 13440 printed = true; 13441 printedAnything = true; 13442 } 13443 pw.print(" * "); pw.println(r); 13444 r.dump(pw, " "); 13445 } 13446 } 13447 13448 if (mReceiverResolver.dump(pw, needSep ? 13449 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13450 " ", dumpPackage, false, false)) { 13451 needSep = true; 13452 printedAnything = true; 13453 } 13454 } 13455 13456 for (BroadcastQueue q : mBroadcastQueues) { 13457 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13458 printedAnything |= needSep; 13459 } 13460 13461 needSep = true; 13462 13463 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13464 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13465 if (needSep) { 13466 pw.println(); 13467 } 13468 needSep = true; 13469 printedAnything = true; 13470 pw.print(" Sticky broadcasts for user "); 13471 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13472 StringBuilder sb = new StringBuilder(128); 13473 for (Map.Entry<String, ArrayList<Intent>> ent 13474 : mStickyBroadcasts.valueAt(user).entrySet()) { 13475 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13476 if (dumpAll) { 13477 pw.println(":"); 13478 ArrayList<Intent> intents = ent.getValue(); 13479 final int N = intents.size(); 13480 for (int i=0; i<N; i++) { 13481 sb.setLength(0); 13482 sb.append(" Intent: "); 13483 intents.get(i).toShortString(sb, false, true, false, false); 13484 pw.println(sb.toString()); 13485 Bundle bundle = intents.get(i).getExtras(); 13486 if (bundle != null) { 13487 pw.print(" "); 13488 pw.println(bundle.toString()); 13489 } 13490 } 13491 } else { 13492 pw.println(""); 13493 } 13494 } 13495 } 13496 } 13497 13498 if (!onlyHistory && dumpAll) { 13499 pw.println(); 13500 for (BroadcastQueue queue : mBroadcastQueues) { 13501 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13502 + queue.mBroadcastsScheduled); 13503 } 13504 pw.println(" mHandler:"); 13505 mHandler.dump(new PrintWriterPrinter(pw), " "); 13506 needSep = true; 13507 printedAnything = true; 13508 } 13509 13510 if (!printedAnything) { 13511 pw.println(" (nothing)"); 13512 } 13513 } 13514 13515 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13516 int opti, boolean dumpAll, String dumpPackage) { 13517 boolean needSep; 13518 boolean printedAnything = false; 13519 13520 ItemMatcher matcher = new ItemMatcher(); 13521 matcher.build(args, opti); 13522 13523 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13524 13525 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13526 printedAnything |= needSep; 13527 13528 if (mLaunchingProviders.size() > 0) { 13529 boolean printed = false; 13530 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13531 ContentProviderRecord r = mLaunchingProviders.get(i); 13532 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13533 continue; 13534 } 13535 if (!printed) { 13536 if (needSep) pw.println(); 13537 needSep = true; 13538 pw.println(" Launching content providers:"); 13539 printed = true; 13540 printedAnything = true; 13541 } 13542 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13543 pw.println(r); 13544 } 13545 } 13546 13547 if (mGrantedUriPermissions.size() > 0) { 13548 boolean printed = false; 13549 int dumpUid = -2; 13550 if (dumpPackage != null) { 13551 try { 13552 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13553 } catch (NameNotFoundException e) { 13554 dumpUid = -1; 13555 } 13556 } 13557 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13558 int uid = mGrantedUriPermissions.keyAt(i); 13559 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13560 continue; 13561 } 13562 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13563 if (!printed) { 13564 if (needSep) pw.println(); 13565 needSep = true; 13566 pw.println(" Granted Uri Permissions:"); 13567 printed = true; 13568 printedAnything = true; 13569 } 13570 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13571 for (UriPermission perm : perms.values()) { 13572 pw.print(" "); pw.println(perm); 13573 if (dumpAll) { 13574 perm.dump(pw, " "); 13575 } 13576 } 13577 } 13578 } 13579 13580 if (!printedAnything) { 13581 pw.println(" (nothing)"); 13582 } 13583 } 13584 13585 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13586 int opti, boolean dumpAll, String dumpPackage) { 13587 boolean printed = false; 13588 13589 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13590 13591 if (mIntentSenderRecords.size() > 0) { 13592 Iterator<WeakReference<PendingIntentRecord>> it 13593 = mIntentSenderRecords.values().iterator(); 13594 while (it.hasNext()) { 13595 WeakReference<PendingIntentRecord> ref = it.next(); 13596 PendingIntentRecord rec = ref != null ? ref.get(): null; 13597 if (dumpPackage != null && (rec == null 13598 || !dumpPackage.equals(rec.key.packageName))) { 13599 continue; 13600 } 13601 printed = true; 13602 if (rec != null) { 13603 pw.print(" * "); pw.println(rec); 13604 if (dumpAll) { 13605 rec.dump(pw, " "); 13606 } 13607 } else { 13608 pw.print(" * "); pw.println(ref); 13609 } 13610 } 13611 } 13612 13613 if (!printed) { 13614 pw.println(" (nothing)"); 13615 } 13616 } 13617 13618 private static final int dumpProcessList(PrintWriter pw, 13619 ActivityManagerService service, List list, 13620 String prefix, String normalLabel, String persistentLabel, 13621 String dumpPackage) { 13622 int numPers = 0; 13623 final int N = list.size()-1; 13624 for (int i=N; i>=0; i--) { 13625 ProcessRecord r = (ProcessRecord)list.get(i); 13626 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13627 continue; 13628 } 13629 pw.println(String.format("%s%s #%2d: %s", 13630 prefix, (r.persistent ? persistentLabel : normalLabel), 13631 i, r.toString())); 13632 if (r.persistent) { 13633 numPers++; 13634 } 13635 } 13636 return numPers; 13637 } 13638 13639 private static final boolean dumpProcessOomList(PrintWriter pw, 13640 ActivityManagerService service, List<ProcessRecord> origList, 13641 String prefix, String normalLabel, String persistentLabel, 13642 boolean inclDetails, String dumpPackage) { 13643 13644 ArrayList<Pair<ProcessRecord, Integer>> list 13645 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13646 for (int i=0; i<origList.size(); i++) { 13647 ProcessRecord r = origList.get(i); 13648 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13649 continue; 13650 } 13651 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13652 } 13653 13654 if (list.size() <= 0) { 13655 return false; 13656 } 13657 13658 Comparator<Pair<ProcessRecord, Integer>> comparator 13659 = new Comparator<Pair<ProcessRecord, Integer>>() { 13660 @Override 13661 public int compare(Pair<ProcessRecord, Integer> object1, 13662 Pair<ProcessRecord, Integer> object2) { 13663 if (object1.first.setAdj != object2.first.setAdj) { 13664 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13665 } 13666 if (object1.second.intValue() != object2.second.intValue()) { 13667 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13668 } 13669 return 0; 13670 } 13671 }; 13672 13673 Collections.sort(list, comparator); 13674 13675 final long curRealtime = SystemClock.elapsedRealtime(); 13676 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13677 final long curUptime = SystemClock.uptimeMillis(); 13678 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13679 13680 for (int i=list.size()-1; i>=0; i--) { 13681 ProcessRecord r = list.get(i).first; 13682 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13683 char schedGroup; 13684 switch (r.setSchedGroup) { 13685 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13686 schedGroup = 'B'; 13687 break; 13688 case Process.THREAD_GROUP_DEFAULT: 13689 schedGroup = 'F'; 13690 break; 13691 default: 13692 schedGroup = '?'; 13693 break; 13694 } 13695 char foreground; 13696 if (r.foregroundActivities) { 13697 foreground = 'A'; 13698 } else if (r.foregroundServices) { 13699 foreground = 'S'; 13700 } else { 13701 foreground = ' '; 13702 } 13703 String procState = ProcessList.makeProcStateString(r.curProcState); 13704 pw.print(prefix); 13705 pw.print(r.persistent ? persistentLabel : normalLabel); 13706 pw.print(" #"); 13707 int num = (origList.size()-1)-list.get(i).second; 13708 if (num < 10) pw.print(' '); 13709 pw.print(num); 13710 pw.print(": "); 13711 pw.print(oomAdj); 13712 pw.print(' '); 13713 pw.print(schedGroup); 13714 pw.print('/'); 13715 pw.print(foreground); 13716 pw.print('/'); 13717 pw.print(procState); 13718 pw.print(" trm:"); 13719 if (r.trimMemoryLevel < 10) pw.print(' '); 13720 pw.print(r.trimMemoryLevel); 13721 pw.print(' '); 13722 pw.print(r.toShortString()); 13723 pw.print(" ("); 13724 pw.print(r.adjType); 13725 pw.println(')'); 13726 if (r.adjSource != null || r.adjTarget != null) { 13727 pw.print(prefix); 13728 pw.print(" "); 13729 if (r.adjTarget instanceof ComponentName) { 13730 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13731 } else if (r.adjTarget != null) { 13732 pw.print(r.adjTarget.toString()); 13733 } else { 13734 pw.print("{null}"); 13735 } 13736 pw.print("<="); 13737 if (r.adjSource instanceof ProcessRecord) { 13738 pw.print("Proc{"); 13739 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13740 pw.println("}"); 13741 } else if (r.adjSource != null) { 13742 pw.println(r.adjSource.toString()); 13743 } else { 13744 pw.println("{null}"); 13745 } 13746 } 13747 if (inclDetails) { 13748 pw.print(prefix); 13749 pw.print(" "); 13750 pw.print("oom: max="); pw.print(r.maxAdj); 13751 pw.print(" curRaw="); pw.print(r.curRawAdj); 13752 pw.print(" setRaw="); pw.print(r.setRawAdj); 13753 pw.print(" cur="); pw.print(r.curAdj); 13754 pw.print(" set="); pw.println(r.setAdj); 13755 pw.print(prefix); 13756 pw.print(" "); 13757 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13758 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13759 pw.print(" lastPss="); pw.print(r.lastPss); 13760 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13761 pw.print(prefix); 13762 pw.print(" "); 13763 pw.print("cached="); pw.print(r.cached); 13764 pw.print(" empty="); pw.print(r.empty); 13765 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13766 13767 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13768 if (r.lastWakeTime != 0) { 13769 long wtime; 13770 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13771 synchronized (stats) { 13772 wtime = stats.getProcessWakeTime(r.info.uid, 13773 r.pid, curRealtime); 13774 } 13775 long timeUsed = wtime - r.lastWakeTime; 13776 pw.print(prefix); 13777 pw.print(" "); 13778 pw.print("keep awake over "); 13779 TimeUtils.formatDuration(realtimeSince, pw); 13780 pw.print(" used "); 13781 TimeUtils.formatDuration(timeUsed, pw); 13782 pw.print(" ("); 13783 pw.print((timeUsed*100)/realtimeSince); 13784 pw.println("%)"); 13785 } 13786 if (r.lastCpuTime != 0) { 13787 long timeUsed = r.curCpuTime - r.lastCpuTime; 13788 pw.print(prefix); 13789 pw.print(" "); 13790 pw.print("run cpu over "); 13791 TimeUtils.formatDuration(uptimeSince, pw); 13792 pw.print(" used "); 13793 TimeUtils.formatDuration(timeUsed, pw); 13794 pw.print(" ("); 13795 pw.print((timeUsed*100)/uptimeSince); 13796 pw.println("%)"); 13797 } 13798 } 13799 } 13800 } 13801 return true; 13802 } 13803 13804 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13805 String[] args) { 13806 ArrayList<ProcessRecord> procs; 13807 synchronized (this) { 13808 if (args != null && args.length > start 13809 && args[start].charAt(0) != '-') { 13810 procs = new ArrayList<ProcessRecord>(); 13811 int pid = -1; 13812 try { 13813 pid = Integer.parseInt(args[start]); 13814 } catch (NumberFormatException e) { 13815 } 13816 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13817 ProcessRecord proc = mLruProcesses.get(i); 13818 if (proc.pid == pid) { 13819 procs.add(proc); 13820 } else if (allPkgs && proc.pkgList != null 13821 && proc.pkgList.containsKey(args[start])) { 13822 procs.add(proc); 13823 } else if (proc.processName.equals(args[start])) { 13824 procs.add(proc); 13825 } 13826 } 13827 if (procs.size() <= 0) { 13828 return null; 13829 } 13830 } else { 13831 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13832 } 13833 } 13834 return procs; 13835 } 13836 13837 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13838 PrintWriter pw, String[] args) { 13839 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13840 if (procs == null) { 13841 pw.println("No process found for: " + args[0]); 13842 return; 13843 } 13844 13845 long uptime = SystemClock.uptimeMillis(); 13846 long realtime = SystemClock.elapsedRealtime(); 13847 pw.println("Applications Graphics Acceleration Info:"); 13848 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13849 13850 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13851 ProcessRecord r = procs.get(i); 13852 if (r.thread != null) { 13853 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13854 pw.flush(); 13855 try { 13856 TransferPipe tp = new TransferPipe(); 13857 try { 13858 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13859 tp.go(fd); 13860 } finally { 13861 tp.kill(); 13862 } 13863 } catch (IOException e) { 13864 pw.println("Failure while dumping the app: " + r); 13865 pw.flush(); 13866 } catch (RemoteException e) { 13867 pw.println("Got a RemoteException while dumping the app " + r); 13868 pw.flush(); 13869 } 13870 } 13871 } 13872 } 13873 13874 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13875 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13876 if (procs == null) { 13877 pw.println("No process found for: " + args[0]); 13878 return; 13879 } 13880 13881 pw.println("Applications Database Info:"); 13882 13883 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13884 ProcessRecord r = procs.get(i); 13885 if (r.thread != null) { 13886 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13887 pw.flush(); 13888 try { 13889 TransferPipe tp = new TransferPipe(); 13890 try { 13891 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13892 tp.go(fd); 13893 } finally { 13894 tp.kill(); 13895 } 13896 } catch (IOException e) { 13897 pw.println("Failure while dumping the app: " + r); 13898 pw.flush(); 13899 } catch (RemoteException e) { 13900 pw.println("Got a RemoteException while dumping the app " + r); 13901 pw.flush(); 13902 } 13903 } 13904 } 13905 } 13906 13907 final static class MemItem { 13908 final boolean isProc; 13909 final String label; 13910 final String shortLabel; 13911 final long pss; 13912 final int id; 13913 final boolean hasActivities; 13914 ArrayList<MemItem> subitems; 13915 13916 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13917 boolean _hasActivities) { 13918 isProc = true; 13919 label = _label; 13920 shortLabel = _shortLabel; 13921 pss = _pss; 13922 id = _id; 13923 hasActivities = _hasActivities; 13924 } 13925 13926 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13927 isProc = false; 13928 label = _label; 13929 shortLabel = _shortLabel; 13930 pss = _pss; 13931 id = _id; 13932 hasActivities = false; 13933 } 13934 } 13935 13936 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13937 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13938 if (sort && !isCompact) { 13939 Collections.sort(items, new Comparator<MemItem>() { 13940 @Override 13941 public int compare(MemItem lhs, MemItem rhs) { 13942 if (lhs.pss < rhs.pss) { 13943 return 1; 13944 } else if (lhs.pss > rhs.pss) { 13945 return -1; 13946 } 13947 return 0; 13948 } 13949 }); 13950 } 13951 13952 for (int i=0; i<items.size(); i++) { 13953 MemItem mi = items.get(i); 13954 if (!isCompact) { 13955 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13956 } else if (mi.isProc) { 13957 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13958 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13959 pw.println(mi.hasActivities ? ",a" : ",e"); 13960 } else { 13961 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13962 pw.println(mi.pss); 13963 } 13964 if (mi.subitems != null) { 13965 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13966 true, isCompact); 13967 } 13968 } 13969 } 13970 13971 // These are in KB. 13972 static final long[] DUMP_MEM_BUCKETS = new long[] { 13973 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13974 120*1024, 160*1024, 200*1024, 13975 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13976 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13977 }; 13978 13979 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13980 boolean stackLike) { 13981 int start = label.lastIndexOf('.'); 13982 if (start >= 0) start++; 13983 else start = 0; 13984 int end = label.length(); 13985 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13986 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13987 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13988 out.append(bucket); 13989 out.append(stackLike ? "MB." : "MB "); 13990 out.append(label, start, end); 13991 return; 13992 } 13993 } 13994 out.append(memKB/1024); 13995 out.append(stackLike ? "MB." : "MB "); 13996 out.append(label, start, end); 13997 } 13998 13999 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 14000 ProcessList.NATIVE_ADJ, 14001 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 14002 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14003 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14004 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14005 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14006 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14007 }; 14008 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14009 "Native", 14010 "System", "Persistent", "Persistent Service", "Foreground", 14011 "Visible", "Perceptible", 14012 "Heavy Weight", "Backup", 14013 "A Services", "Home", 14014 "Previous", "B Services", "Cached" 14015 }; 14016 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14017 "native", 14018 "sys", "pers", "persvc", "fore", 14019 "vis", "percept", 14020 "heavy", "backup", 14021 "servicea", "home", 14022 "prev", "serviceb", "cached" 14023 }; 14024 14025 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14026 long realtime, boolean isCheckinRequest, boolean isCompact) { 14027 if (isCheckinRequest || isCompact) { 14028 // short checkin version 14029 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14030 } else { 14031 pw.println("Applications Memory Usage (kB):"); 14032 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14033 } 14034 } 14035 14036 private static final int KSM_SHARED = 0; 14037 private static final int KSM_SHARING = 1; 14038 private static final int KSM_UNSHARED = 2; 14039 private static final int KSM_VOLATILE = 3; 14040 14041 private final long[] getKsmInfo() { 14042 long[] longOut = new long[4]; 14043 final int[] SINGLE_LONG_FORMAT = new int[] { 14044 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14045 }; 14046 long[] longTmp = new long[1]; 14047 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14048 SINGLE_LONG_FORMAT, null, longTmp, null); 14049 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14050 longTmp[0] = 0; 14051 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14052 SINGLE_LONG_FORMAT, null, longTmp, null); 14053 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14054 longTmp[0] = 0; 14055 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14056 SINGLE_LONG_FORMAT, null, longTmp, null); 14057 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14058 longTmp[0] = 0; 14059 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14060 SINGLE_LONG_FORMAT, null, longTmp, null); 14061 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14062 return longOut; 14063 } 14064 14065 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14066 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14067 boolean dumpDetails = false; 14068 boolean dumpFullDetails = false; 14069 boolean dumpDalvik = false; 14070 boolean oomOnly = false; 14071 boolean isCompact = false; 14072 boolean localOnly = false; 14073 boolean packages = false; 14074 14075 int opti = 0; 14076 while (opti < args.length) { 14077 String opt = args[opti]; 14078 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14079 break; 14080 } 14081 opti++; 14082 if ("-a".equals(opt)) { 14083 dumpDetails = true; 14084 dumpFullDetails = true; 14085 dumpDalvik = true; 14086 } else if ("-d".equals(opt)) { 14087 dumpDalvik = true; 14088 } else if ("-c".equals(opt)) { 14089 isCompact = true; 14090 } else if ("--oom".equals(opt)) { 14091 oomOnly = true; 14092 } else if ("--local".equals(opt)) { 14093 localOnly = true; 14094 } else if ("--package".equals(opt)) { 14095 packages = true; 14096 } else if ("-h".equals(opt)) { 14097 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14098 pw.println(" -a: include all available information for each process."); 14099 pw.println(" -d: include dalvik details when dumping process details."); 14100 pw.println(" -c: dump in a compact machine-parseable representation."); 14101 pw.println(" --oom: only show processes organized by oom adj."); 14102 pw.println(" --local: only collect details locally, don't call process."); 14103 pw.println(" --package: interpret process arg as package, dumping all"); 14104 pw.println(" processes that have loaded that package."); 14105 pw.println("If [process] is specified it can be the name or "); 14106 pw.println("pid of a specific process to dump."); 14107 return; 14108 } else { 14109 pw.println("Unknown argument: " + opt + "; use -h for help"); 14110 } 14111 } 14112 14113 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14114 long uptime = SystemClock.uptimeMillis(); 14115 long realtime = SystemClock.elapsedRealtime(); 14116 final long[] tmpLong = new long[1]; 14117 14118 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14119 if (procs == null) { 14120 // No Java processes. Maybe they want to print a native process. 14121 if (args != null && args.length > opti 14122 && args[opti].charAt(0) != '-') { 14123 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14124 = new ArrayList<ProcessCpuTracker.Stats>(); 14125 updateCpuStatsNow(); 14126 int findPid = -1; 14127 try { 14128 findPid = Integer.parseInt(args[opti]); 14129 } catch (NumberFormatException e) { 14130 } 14131 synchronized (mProcessCpuTracker) { 14132 final int N = mProcessCpuTracker.countStats(); 14133 for (int i=0; i<N; i++) { 14134 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14135 if (st.pid == findPid || (st.baseName != null 14136 && st.baseName.equals(args[opti]))) { 14137 nativeProcs.add(st); 14138 } 14139 } 14140 } 14141 if (nativeProcs.size() > 0) { 14142 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14143 isCompact); 14144 Debug.MemoryInfo mi = null; 14145 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14146 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14147 final int pid = r.pid; 14148 if (!isCheckinRequest && dumpDetails) { 14149 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14150 } 14151 if (mi == null) { 14152 mi = new Debug.MemoryInfo(); 14153 } 14154 if (dumpDetails || (!brief && !oomOnly)) { 14155 Debug.getMemoryInfo(pid, mi); 14156 } else { 14157 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14158 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14159 } 14160 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14161 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14162 if (isCheckinRequest) { 14163 pw.println(); 14164 } 14165 } 14166 return; 14167 } 14168 } 14169 pw.println("No process found for: " + args[opti]); 14170 return; 14171 } 14172 14173 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14174 dumpDetails = true; 14175 } 14176 14177 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14178 14179 String[] innerArgs = new String[args.length-opti]; 14180 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14181 14182 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14183 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14184 long nativePss = 0; 14185 long dalvikPss = 0; 14186 long otherPss = 0; 14187 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14188 14189 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14190 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14191 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14192 14193 long totalPss = 0; 14194 long cachedPss = 0; 14195 14196 Debug.MemoryInfo mi = null; 14197 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14198 final ProcessRecord r = procs.get(i); 14199 final IApplicationThread thread; 14200 final int pid; 14201 final int oomAdj; 14202 final boolean hasActivities; 14203 synchronized (this) { 14204 thread = r.thread; 14205 pid = r.pid; 14206 oomAdj = r.getSetAdjWithServices(); 14207 hasActivities = r.activities.size() > 0; 14208 } 14209 if (thread != null) { 14210 if (!isCheckinRequest && dumpDetails) { 14211 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14212 } 14213 if (mi == null) { 14214 mi = new Debug.MemoryInfo(); 14215 } 14216 if (dumpDetails || (!brief && !oomOnly)) { 14217 Debug.getMemoryInfo(pid, mi); 14218 } else { 14219 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14220 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14221 } 14222 if (dumpDetails) { 14223 if (localOnly) { 14224 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14225 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14226 if (isCheckinRequest) { 14227 pw.println(); 14228 } 14229 } else { 14230 try { 14231 pw.flush(); 14232 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14233 dumpDalvik, innerArgs); 14234 } catch (RemoteException e) { 14235 if (!isCheckinRequest) { 14236 pw.println("Got RemoteException!"); 14237 pw.flush(); 14238 } 14239 } 14240 } 14241 } 14242 14243 final long myTotalPss = mi.getTotalPss(); 14244 final long myTotalUss = mi.getTotalUss(); 14245 14246 synchronized (this) { 14247 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14248 // Record this for posterity if the process has been stable. 14249 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14250 } 14251 } 14252 14253 if (!isCheckinRequest && mi != null) { 14254 totalPss += myTotalPss; 14255 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14256 (hasActivities ? " / activities)" : ")"), 14257 r.processName, myTotalPss, pid, hasActivities); 14258 procMems.add(pssItem); 14259 procMemsMap.put(pid, pssItem); 14260 14261 nativePss += mi.nativePss; 14262 dalvikPss += mi.dalvikPss; 14263 otherPss += mi.otherPss; 14264 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14265 long mem = mi.getOtherPss(j); 14266 miscPss[j] += mem; 14267 otherPss -= mem; 14268 } 14269 14270 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14271 cachedPss += myTotalPss; 14272 } 14273 14274 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14275 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14276 || oomIndex == (oomPss.length-1)) { 14277 oomPss[oomIndex] += myTotalPss; 14278 if (oomProcs[oomIndex] == null) { 14279 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14280 } 14281 oomProcs[oomIndex].add(pssItem); 14282 break; 14283 } 14284 } 14285 } 14286 } 14287 } 14288 14289 long nativeProcTotalPss = 0; 14290 14291 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14292 // If we are showing aggregations, also look for native processes to 14293 // include so that our aggregations are more accurate. 14294 updateCpuStatsNow(); 14295 mi = null; 14296 synchronized (mProcessCpuTracker) { 14297 final int N = mProcessCpuTracker.countStats(); 14298 for (int i=0; i<N; i++) { 14299 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14300 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14301 if (mi == null) { 14302 mi = new Debug.MemoryInfo(); 14303 } 14304 if (!brief && !oomOnly) { 14305 Debug.getMemoryInfo(st.pid, mi); 14306 } else { 14307 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14308 mi.nativePrivateDirty = (int)tmpLong[0]; 14309 } 14310 14311 final long myTotalPss = mi.getTotalPss(); 14312 totalPss += myTotalPss; 14313 nativeProcTotalPss += myTotalPss; 14314 14315 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14316 st.name, myTotalPss, st.pid, false); 14317 procMems.add(pssItem); 14318 14319 nativePss += mi.nativePss; 14320 dalvikPss += mi.dalvikPss; 14321 otherPss += mi.otherPss; 14322 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14323 long mem = mi.getOtherPss(j); 14324 miscPss[j] += mem; 14325 otherPss -= mem; 14326 } 14327 oomPss[0] += myTotalPss; 14328 if (oomProcs[0] == null) { 14329 oomProcs[0] = new ArrayList<MemItem>(); 14330 } 14331 oomProcs[0].add(pssItem); 14332 } 14333 } 14334 } 14335 14336 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14337 14338 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14339 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14340 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14341 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14342 String label = Debug.MemoryInfo.getOtherLabel(j); 14343 catMems.add(new MemItem(label, label, miscPss[j], j)); 14344 } 14345 14346 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14347 for (int j=0; j<oomPss.length; j++) { 14348 if (oomPss[j] != 0) { 14349 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14350 : DUMP_MEM_OOM_LABEL[j]; 14351 MemItem item = new MemItem(label, label, oomPss[j], 14352 DUMP_MEM_OOM_ADJ[j]); 14353 item.subitems = oomProcs[j]; 14354 oomMems.add(item); 14355 } 14356 } 14357 14358 if (!brief && !oomOnly && !isCompact) { 14359 pw.println(); 14360 pw.println("Total PSS by process:"); 14361 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14362 pw.println(); 14363 } 14364 if (!isCompact) { 14365 pw.println("Total PSS by OOM adjustment:"); 14366 } 14367 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14368 if (!brief && !oomOnly) { 14369 PrintWriter out = categoryPw != null ? categoryPw : pw; 14370 if (!isCompact) { 14371 out.println(); 14372 out.println("Total PSS by category:"); 14373 } 14374 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14375 } 14376 if (!isCompact) { 14377 pw.println(); 14378 } 14379 MemInfoReader memInfo = new MemInfoReader(); 14380 memInfo.readMemInfo(); 14381 if (nativeProcTotalPss > 0) { 14382 synchronized (this) { 14383 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14384 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14385 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14386 } 14387 } 14388 if (!brief) { 14389 if (!isCompact) { 14390 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14391 pw.print(" kB (status "); 14392 switch (mLastMemoryLevel) { 14393 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14394 pw.println("normal)"); 14395 break; 14396 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14397 pw.println("moderate)"); 14398 break; 14399 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14400 pw.println("low)"); 14401 break; 14402 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14403 pw.println("critical)"); 14404 break; 14405 default: 14406 pw.print(mLastMemoryLevel); 14407 pw.println(")"); 14408 break; 14409 } 14410 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14411 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14412 pw.print(cachedPss); pw.print(" cached pss + "); 14413 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14414 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14415 } else { 14416 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14417 pw.print(cachedPss + memInfo.getCachedSizeKb() 14418 + memInfo.getFreeSizeKb()); pw.print(","); 14419 pw.println(totalPss - cachedPss); 14420 } 14421 } 14422 if (!isCompact) { 14423 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14424 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14425 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14426 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14427 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14428 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14429 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14430 } 14431 if (!brief) { 14432 if (memInfo.getZramTotalSizeKb() != 0) { 14433 if (!isCompact) { 14434 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14435 pw.print(" kB physical used for "); 14436 pw.print(memInfo.getSwapTotalSizeKb() 14437 - memInfo.getSwapFreeSizeKb()); 14438 pw.print(" kB in swap ("); 14439 pw.print(memInfo.getSwapTotalSizeKb()); 14440 pw.println(" kB total swap)"); 14441 } else { 14442 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14443 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14444 pw.println(memInfo.getSwapFreeSizeKb()); 14445 } 14446 } 14447 final long[] ksm = getKsmInfo(); 14448 if (!isCompact) { 14449 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14450 || ksm[KSM_VOLATILE] != 0) { 14451 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14452 pw.print(" kB saved from shared "); 14453 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14454 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14455 pw.print(" kB unshared; "); 14456 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14457 } 14458 pw.print(" Tuning: "); 14459 pw.print(ActivityManager.staticGetMemoryClass()); 14460 pw.print(" (large "); 14461 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14462 pw.print("), oom "); 14463 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14464 pw.print(" kB"); 14465 pw.print(", restore limit "); 14466 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14467 pw.print(" kB"); 14468 if (ActivityManager.isLowRamDeviceStatic()) { 14469 pw.print(" (low-ram)"); 14470 } 14471 if (ActivityManager.isHighEndGfx()) { 14472 pw.print(" (high-end-gfx)"); 14473 } 14474 pw.println(); 14475 } else { 14476 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14477 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14478 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14479 pw.print("tuning,"); 14480 pw.print(ActivityManager.staticGetMemoryClass()); 14481 pw.print(','); 14482 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14483 pw.print(','); 14484 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14485 if (ActivityManager.isLowRamDeviceStatic()) { 14486 pw.print(",low-ram"); 14487 } 14488 if (ActivityManager.isHighEndGfx()) { 14489 pw.print(",high-end-gfx"); 14490 } 14491 pw.println(); 14492 } 14493 } 14494 } 14495 } 14496 14497 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14498 long memtrack, String name) { 14499 sb.append(" "); 14500 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14501 sb.append(' '); 14502 sb.append(ProcessList.makeProcStateString(procState)); 14503 sb.append(' '); 14504 ProcessList.appendRamKb(sb, pss); 14505 sb.append(" kB: "); 14506 sb.append(name); 14507 if (memtrack > 0) { 14508 sb.append(" ("); 14509 sb.append(memtrack); 14510 sb.append(" kB memtrack)"); 14511 } 14512 } 14513 14514 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14515 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14516 sb.append(" (pid "); 14517 sb.append(mi.pid); 14518 sb.append(") "); 14519 sb.append(mi.adjType); 14520 sb.append('\n'); 14521 if (mi.adjReason != null) { 14522 sb.append(" "); 14523 sb.append(mi.adjReason); 14524 sb.append('\n'); 14525 } 14526 } 14527 14528 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14529 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14530 for (int i=0, N=memInfos.size(); i<N; i++) { 14531 ProcessMemInfo mi = memInfos.get(i); 14532 infoMap.put(mi.pid, mi); 14533 } 14534 updateCpuStatsNow(); 14535 long[] memtrackTmp = new long[1]; 14536 synchronized (mProcessCpuTracker) { 14537 final int N = mProcessCpuTracker.countStats(); 14538 for (int i=0; i<N; i++) { 14539 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14540 if (st.vsize > 0) { 14541 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14542 if (pss > 0) { 14543 if (infoMap.indexOfKey(st.pid) < 0) { 14544 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14545 ProcessList.NATIVE_ADJ, -1, "native", null); 14546 mi.pss = pss; 14547 mi.memtrack = memtrackTmp[0]; 14548 memInfos.add(mi); 14549 } 14550 } 14551 } 14552 } 14553 } 14554 14555 long totalPss = 0; 14556 long totalMemtrack = 0; 14557 for (int i=0, N=memInfos.size(); i<N; i++) { 14558 ProcessMemInfo mi = memInfos.get(i); 14559 if (mi.pss == 0) { 14560 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14561 mi.memtrack = memtrackTmp[0]; 14562 } 14563 totalPss += mi.pss; 14564 totalMemtrack += mi.memtrack; 14565 } 14566 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14567 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14568 if (lhs.oomAdj != rhs.oomAdj) { 14569 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14570 } 14571 if (lhs.pss != rhs.pss) { 14572 return lhs.pss < rhs.pss ? 1 : -1; 14573 } 14574 return 0; 14575 } 14576 }); 14577 14578 StringBuilder tag = new StringBuilder(128); 14579 StringBuilder stack = new StringBuilder(128); 14580 tag.append("Low on memory -- "); 14581 appendMemBucket(tag, totalPss, "total", false); 14582 appendMemBucket(stack, totalPss, "total", true); 14583 14584 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14585 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14586 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14587 14588 boolean firstLine = true; 14589 int lastOomAdj = Integer.MIN_VALUE; 14590 long extraNativeRam = 0; 14591 long extraNativeMemtrack = 0; 14592 long cachedPss = 0; 14593 for (int i=0, N=memInfos.size(); i<N; i++) { 14594 ProcessMemInfo mi = memInfos.get(i); 14595 14596 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14597 cachedPss += mi.pss; 14598 } 14599 14600 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14601 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14602 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14603 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14604 if (lastOomAdj != mi.oomAdj) { 14605 lastOomAdj = mi.oomAdj; 14606 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14607 tag.append(" / "); 14608 } 14609 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14610 if (firstLine) { 14611 stack.append(":"); 14612 firstLine = false; 14613 } 14614 stack.append("\n\t at "); 14615 } else { 14616 stack.append("$"); 14617 } 14618 } else { 14619 tag.append(" "); 14620 stack.append("$"); 14621 } 14622 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14623 appendMemBucket(tag, mi.pss, mi.name, false); 14624 } 14625 appendMemBucket(stack, mi.pss, mi.name, true); 14626 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14627 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14628 stack.append("("); 14629 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14630 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14631 stack.append(DUMP_MEM_OOM_LABEL[k]); 14632 stack.append(":"); 14633 stack.append(DUMP_MEM_OOM_ADJ[k]); 14634 } 14635 } 14636 stack.append(")"); 14637 } 14638 } 14639 14640 appendMemInfo(fullNativeBuilder, mi); 14641 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14642 // The short form only has native processes that are >= 512K. 14643 if (mi.pss >= 512) { 14644 appendMemInfo(shortNativeBuilder, mi); 14645 } else { 14646 extraNativeRam += mi.pss; 14647 extraNativeMemtrack += mi.memtrack; 14648 } 14649 } else { 14650 // Short form has all other details, but if we have collected RAM 14651 // from smaller native processes let's dump a summary of that. 14652 if (extraNativeRam > 0) { 14653 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14654 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14655 shortNativeBuilder.append('\n'); 14656 extraNativeRam = 0; 14657 } 14658 appendMemInfo(fullJavaBuilder, mi); 14659 } 14660 } 14661 14662 fullJavaBuilder.append(" "); 14663 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14664 fullJavaBuilder.append(" kB: TOTAL"); 14665 if (totalMemtrack > 0) { 14666 fullJavaBuilder.append(" ("); 14667 fullJavaBuilder.append(totalMemtrack); 14668 fullJavaBuilder.append(" kB memtrack)"); 14669 } else { 14670 } 14671 fullJavaBuilder.append("\n"); 14672 14673 MemInfoReader memInfo = new MemInfoReader(); 14674 memInfo.readMemInfo(); 14675 final long[] infos = memInfo.getRawInfo(); 14676 14677 StringBuilder memInfoBuilder = new StringBuilder(1024); 14678 Debug.getMemInfo(infos); 14679 memInfoBuilder.append(" MemInfo: "); 14680 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14681 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14682 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14683 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14684 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14685 memInfoBuilder.append(" "); 14686 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14687 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14688 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14689 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14690 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14691 memInfoBuilder.append(" ZRAM: "); 14692 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14693 memInfoBuilder.append(" kB RAM, "); 14694 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14695 memInfoBuilder.append(" kB swap total, "); 14696 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14697 memInfoBuilder.append(" kB swap free\n"); 14698 } 14699 final long[] ksm = getKsmInfo(); 14700 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14701 || ksm[KSM_VOLATILE] != 0) { 14702 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14703 memInfoBuilder.append(" kB saved from shared "); 14704 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14705 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14706 memInfoBuilder.append(" kB unshared; "); 14707 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14708 } 14709 memInfoBuilder.append(" Free RAM: "); 14710 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14711 + memInfo.getFreeSizeKb()); 14712 memInfoBuilder.append(" kB\n"); 14713 memInfoBuilder.append(" Used RAM: "); 14714 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14715 memInfoBuilder.append(" kB\n"); 14716 memInfoBuilder.append(" Lost RAM: "); 14717 memInfoBuilder.append(memInfo.getTotalSizeKb() 14718 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14719 - memInfo.getKernelUsedSizeKb()); 14720 memInfoBuilder.append(" kB\n"); 14721 Slog.i(TAG, "Low on memory:"); 14722 Slog.i(TAG, shortNativeBuilder.toString()); 14723 Slog.i(TAG, fullJavaBuilder.toString()); 14724 Slog.i(TAG, memInfoBuilder.toString()); 14725 14726 StringBuilder dropBuilder = new StringBuilder(1024); 14727 /* 14728 StringWriter oomSw = new StringWriter(); 14729 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14730 StringWriter catSw = new StringWriter(); 14731 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14732 String[] emptyArgs = new String[] { }; 14733 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14734 oomPw.flush(); 14735 String oomString = oomSw.toString(); 14736 */ 14737 dropBuilder.append("Low on memory:"); 14738 dropBuilder.append(stack); 14739 dropBuilder.append('\n'); 14740 dropBuilder.append(fullNativeBuilder); 14741 dropBuilder.append(fullJavaBuilder); 14742 dropBuilder.append('\n'); 14743 dropBuilder.append(memInfoBuilder); 14744 dropBuilder.append('\n'); 14745 /* 14746 dropBuilder.append(oomString); 14747 dropBuilder.append('\n'); 14748 */ 14749 StringWriter catSw = new StringWriter(); 14750 synchronized (ActivityManagerService.this) { 14751 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14752 String[] emptyArgs = new String[] { }; 14753 catPw.println(); 14754 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14755 catPw.println(); 14756 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14757 false, false, null); 14758 catPw.println(); 14759 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14760 catPw.flush(); 14761 } 14762 dropBuilder.append(catSw.toString()); 14763 addErrorToDropBox("lowmem", null, "system_server", null, 14764 null, tag.toString(), dropBuilder.toString(), null, null); 14765 //Slog.i(TAG, "Sent to dropbox:"); 14766 //Slog.i(TAG, dropBuilder.toString()); 14767 synchronized (ActivityManagerService.this) { 14768 long now = SystemClock.uptimeMillis(); 14769 if (mLastMemUsageReportTime < now) { 14770 mLastMemUsageReportTime = now; 14771 } 14772 } 14773 } 14774 14775 /** 14776 * Searches array of arguments for the specified string 14777 * @param args array of argument strings 14778 * @param value value to search for 14779 * @return true if the value is contained in the array 14780 */ 14781 private static boolean scanArgs(String[] args, String value) { 14782 if (args != null) { 14783 for (String arg : args) { 14784 if (value.equals(arg)) { 14785 return true; 14786 } 14787 } 14788 } 14789 return false; 14790 } 14791 14792 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14793 ContentProviderRecord cpr, boolean always) { 14794 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14795 14796 if (!inLaunching || always) { 14797 synchronized (cpr) { 14798 cpr.launchingApp = null; 14799 cpr.notifyAll(); 14800 } 14801 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14802 String names[] = cpr.info.authority.split(";"); 14803 for (int j = 0; j < names.length; j++) { 14804 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14805 } 14806 } 14807 14808 for (int i=0; i<cpr.connections.size(); i++) { 14809 ContentProviderConnection conn = cpr.connections.get(i); 14810 if (conn.waiting) { 14811 // If this connection is waiting for the provider, then we don't 14812 // need to mess with its process unless we are always removing 14813 // or for some reason the provider is not currently launching. 14814 if (inLaunching && !always) { 14815 continue; 14816 } 14817 } 14818 ProcessRecord capp = conn.client; 14819 conn.dead = true; 14820 if (conn.stableCount > 0) { 14821 if (!capp.persistent && capp.thread != null 14822 && capp.pid != 0 14823 && capp.pid != MY_PID) { 14824 capp.kill("depends on provider " 14825 + cpr.name.flattenToShortString() 14826 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14827 } 14828 } else if (capp.thread != null && conn.provider.provider != null) { 14829 try { 14830 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14831 } catch (RemoteException e) { 14832 } 14833 // In the protocol here, we don't expect the client to correctly 14834 // clean up this connection, we'll just remove it. 14835 cpr.connections.remove(i); 14836 if (conn.client.conProviders.remove(conn)) { 14837 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14838 } 14839 } 14840 } 14841 14842 if (inLaunching && always) { 14843 mLaunchingProviders.remove(cpr); 14844 } 14845 return inLaunching; 14846 } 14847 14848 /** 14849 * Main code for cleaning up a process when it has gone away. This is 14850 * called both as a result of the process dying, or directly when stopping 14851 * a process when running in single process mode. 14852 * 14853 * @return Returns true if the given process has been restarted, so the 14854 * app that was passed in must remain on the process lists. 14855 */ 14856 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14857 boolean restarting, boolean allowRestart, int index) { 14858 if (index >= 0) { 14859 removeLruProcessLocked(app); 14860 ProcessList.remove(app.pid); 14861 } 14862 14863 mProcessesToGc.remove(app); 14864 mPendingPssProcesses.remove(app); 14865 14866 // Dismiss any open dialogs. 14867 if (app.crashDialog != null && !app.forceCrashReport) { 14868 app.crashDialog.dismiss(); 14869 app.crashDialog = null; 14870 } 14871 if (app.anrDialog != null) { 14872 app.anrDialog.dismiss(); 14873 app.anrDialog = null; 14874 } 14875 if (app.waitDialog != null) { 14876 app.waitDialog.dismiss(); 14877 app.waitDialog = null; 14878 } 14879 14880 app.crashing = false; 14881 app.notResponding = false; 14882 14883 app.resetPackageList(mProcessStats); 14884 app.unlinkDeathRecipient(); 14885 app.makeInactive(mProcessStats); 14886 app.waitingToKill = null; 14887 app.forcingToForeground = null; 14888 updateProcessForegroundLocked(app, false, false); 14889 app.foregroundActivities = false; 14890 app.hasShownUi = false; 14891 app.treatLikeActivity = false; 14892 app.hasAboveClient = false; 14893 app.hasClientActivities = false; 14894 14895 mServices.killServicesLocked(app, allowRestart); 14896 14897 boolean restart = false; 14898 14899 // Remove published content providers. 14900 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14901 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14902 final boolean always = app.bad || !allowRestart; 14903 if (removeDyingProviderLocked(app, cpr, always) || always) { 14904 // We left the provider in the launching list, need to 14905 // restart it. 14906 restart = true; 14907 } 14908 14909 cpr.provider = null; 14910 cpr.proc = null; 14911 } 14912 app.pubProviders.clear(); 14913 14914 // Take care of any launching providers waiting for this process. 14915 if (checkAppInLaunchingProvidersLocked(app, false)) { 14916 restart = true; 14917 } 14918 14919 // Unregister from connected content providers. 14920 if (!app.conProviders.isEmpty()) { 14921 for (int i=0; i<app.conProviders.size(); i++) { 14922 ContentProviderConnection conn = app.conProviders.get(i); 14923 conn.provider.connections.remove(conn); 14924 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14925 conn.provider.name); 14926 } 14927 app.conProviders.clear(); 14928 } 14929 14930 // At this point there may be remaining entries in mLaunchingProviders 14931 // where we were the only one waiting, so they are no longer of use. 14932 // Look for these and clean up if found. 14933 // XXX Commented out for now. Trying to figure out a way to reproduce 14934 // the actual situation to identify what is actually going on. 14935 if (false) { 14936 for (int i=0; i<mLaunchingProviders.size(); i++) { 14937 ContentProviderRecord cpr = (ContentProviderRecord) 14938 mLaunchingProviders.get(i); 14939 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14940 synchronized (cpr) { 14941 cpr.launchingApp = null; 14942 cpr.notifyAll(); 14943 } 14944 } 14945 } 14946 } 14947 14948 skipCurrentReceiverLocked(app); 14949 14950 // Unregister any receivers. 14951 for (int i=app.receivers.size()-1; i>=0; i--) { 14952 removeReceiverLocked(app.receivers.valueAt(i)); 14953 } 14954 app.receivers.clear(); 14955 14956 // If the app is undergoing backup, tell the backup manager about it 14957 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14958 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14959 + mBackupTarget.appInfo + " died during backup"); 14960 try { 14961 IBackupManager bm = IBackupManager.Stub.asInterface( 14962 ServiceManager.getService(Context.BACKUP_SERVICE)); 14963 bm.agentDisconnected(app.info.packageName); 14964 } catch (RemoteException e) { 14965 // can't happen; backup manager is local 14966 } 14967 } 14968 14969 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14970 ProcessChangeItem item = mPendingProcessChanges.get(i); 14971 if (item.pid == app.pid) { 14972 mPendingProcessChanges.remove(i); 14973 mAvailProcessChanges.add(item); 14974 } 14975 } 14976 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14977 14978 // If the caller is restarting this app, then leave it in its 14979 // current lists and let the caller take care of it. 14980 if (restarting) { 14981 return false; 14982 } 14983 14984 if (!app.persistent || app.isolated) { 14985 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14986 "Removing non-persistent process during cleanup: " + app); 14987 mProcessNames.remove(app.processName, app.uid); 14988 mIsolatedProcesses.remove(app.uid); 14989 if (mHeavyWeightProcess == app) { 14990 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14991 mHeavyWeightProcess.userId, 0)); 14992 mHeavyWeightProcess = null; 14993 } 14994 } else if (!app.removed) { 14995 // This app is persistent, so we need to keep its record around. 14996 // If it is not already on the pending app list, add it there 14997 // and start a new process for it. 14998 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14999 mPersistentStartingProcesses.add(app); 15000 restart = true; 15001 } 15002 } 15003 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15004 "Clean-up removing on hold: " + app); 15005 mProcessesOnHold.remove(app); 15006 15007 if (app == mHomeProcess) { 15008 mHomeProcess = null; 15009 } 15010 if (app == mPreviousProcess) { 15011 mPreviousProcess = null; 15012 } 15013 15014 if (restart && !app.isolated) { 15015 // We have components that still need to be running in the 15016 // process, so re-launch it. 15017 if (index < 0) { 15018 ProcessList.remove(app.pid); 15019 } 15020 mProcessNames.put(app.processName, app.uid, app); 15021 startProcessLocked(app, "restart", app.processName); 15022 return true; 15023 } else if (app.pid > 0 && app.pid != MY_PID) { 15024 // Goodbye! 15025 boolean removed; 15026 synchronized (mPidsSelfLocked) { 15027 mPidsSelfLocked.remove(app.pid); 15028 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15029 } 15030 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15031 if (app.isolated) { 15032 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15033 } 15034 app.setPid(0); 15035 } 15036 return false; 15037 } 15038 15039 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15040 // Look through the content providers we are waiting to have launched, 15041 // and if any run in this process then either schedule a restart of 15042 // the process or kill the client waiting for it if this process has 15043 // gone bad. 15044 int NL = mLaunchingProviders.size(); 15045 boolean restart = false; 15046 for (int i=0; i<NL; i++) { 15047 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15048 if (cpr.launchingApp == app) { 15049 if (!alwaysBad && !app.bad) { 15050 restart = true; 15051 } else { 15052 removeDyingProviderLocked(app, cpr, true); 15053 // cpr should have been removed from mLaunchingProviders 15054 NL = mLaunchingProviders.size(); 15055 i--; 15056 } 15057 } 15058 } 15059 return restart; 15060 } 15061 15062 // ========================================================= 15063 // SERVICES 15064 // ========================================================= 15065 15066 @Override 15067 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15068 int flags) { 15069 enforceNotIsolatedCaller("getServices"); 15070 synchronized (this) { 15071 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15072 } 15073 } 15074 15075 @Override 15076 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15077 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15078 synchronized (this) { 15079 return mServices.getRunningServiceControlPanelLocked(name); 15080 } 15081 } 15082 15083 @Override 15084 public ComponentName startService(IApplicationThread caller, Intent service, 15085 String resolvedType, int userId) { 15086 enforceNotIsolatedCaller("startService"); 15087 // Refuse possible leaked file descriptors 15088 if (service != null && service.hasFileDescriptors() == true) { 15089 throw new IllegalArgumentException("File descriptors passed in Intent"); 15090 } 15091 15092 if (DEBUG_SERVICE) 15093 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15094 synchronized(this) { 15095 final int callingPid = Binder.getCallingPid(); 15096 final int callingUid = Binder.getCallingUid(); 15097 final long origId = Binder.clearCallingIdentity(); 15098 ComponentName res = mServices.startServiceLocked(caller, service, 15099 resolvedType, callingPid, callingUid, userId); 15100 Binder.restoreCallingIdentity(origId); 15101 return res; 15102 } 15103 } 15104 15105 ComponentName startServiceInPackage(int uid, 15106 Intent service, String resolvedType, int userId) { 15107 synchronized(this) { 15108 if (DEBUG_SERVICE) 15109 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15110 final long origId = Binder.clearCallingIdentity(); 15111 ComponentName res = mServices.startServiceLocked(null, service, 15112 resolvedType, -1, uid, userId); 15113 Binder.restoreCallingIdentity(origId); 15114 return res; 15115 } 15116 } 15117 15118 @Override 15119 public int stopService(IApplicationThread caller, Intent service, 15120 String resolvedType, int userId) { 15121 enforceNotIsolatedCaller("stopService"); 15122 // Refuse possible leaked file descriptors 15123 if (service != null && service.hasFileDescriptors() == true) { 15124 throw new IllegalArgumentException("File descriptors passed in Intent"); 15125 } 15126 15127 synchronized(this) { 15128 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15129 } 15130 } 15131 15132 @Override 15133 public IBinder peekService(Intent service, String resolvedType) { 15134 enforceNotIsolatedCaller("peekService"); 15135 // Refuse possible leaked file descriptors 15136 if (service != null && service.hasFileDescriptors() == true) { 15137 throw new IllegalArgumentException("File descriptors passed in Intent"); 15138 } 15139 synchronized(this) { 15140 return mServices.peekServiceLocked(service, resolvedType); 15141 } 15142 } 15143 15144 @Override 15145 public boolean stopServiceToken(ComponentName className, IBinder token, 15146 int startId) { 15147 synchronized(this) { 15148 return mServices.stopServiceTokenLocked(className, token, startId); 15149 } 15150 } 15151 15152 @Override 15153 public void setServiceForeground(ComponentName className, IBinder token, 15154 int id, Notification notification, boolean removeNotification) { 15155 synchronized(this) { 15156 mServices.setServiceForegroundLocked(className, token, id, notification, 15157 removeNotification); 15158 } 15159 } 15160 15161 @Override 15162 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15163 boolean requireFull, String name, String callerPackage) { 15164 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15165 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15166 } 15167 15168 int unsafeConvertIncomingUser(int userId) { 15169 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15170 ? mCurrentUserId : userId; 15171 } 15172 15173 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15174 int allowMode, String name, String callerPackage) { 15175 final int callingUserId = UserHandle.getUserId(callingUid); 15176 if (callingUserId == userId) { 15177 return userId; 15178 } 15179 15180 // Note that we may be accessing mCurrentUserId outside of a lock... 15181 // shouldn't be a big deal, if this is being called outside 15182 // of a locked context there is intrinsically a race with 15183 // the value the caller will receive and someone else changing it. 15184 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15185 // we will switch to the calling user if access to the current user fails. 15186 int targetUserId = unsafeConvertIncomingUser(userId); 15187 15188 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15189 final boolean allow; 15190 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15191 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15192 // If the caller has this permission, they always pass go. And collect $200. 15193 allow = true; 15194 } else if (allowMode == ALLOW_FULL_ONLY) { 15195 // We require full access, sucks to be you. 15196 allow = false; 15197 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15198 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15199 // If the caller does not have either permission, they are always doomed. 15200 allow = false; 15201 } else if (allowMode == ALLOW_NON_FULL) { 15202 // We are blanket allowing non-full access, you lucky caller! 15203 allow = true; 15204 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15205 // We may or may not allow this depending on whether the two users are 15206 // in the same profile. 15207 synchronized (mUserProfileGroupIdsSelfLocked) { 15208 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15209 UserInfo.NO_PROFILE_GROUP_ID); 15210 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15211 UserInfo.NO_PROFILE_GROUP_ID); 15212 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15213 && callingProfile == targetProfile; 15214 } 15215 } else { 15216 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15217 } 15218 if (!allow) { 15219 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15220 // In this case, they would like to just execute as their 15221 // owner user instead of failing. 15222 targetUserId = callingUserId; 15223 } else { 15224 StringBuilder builder = new StringBuilder(128); 15225 builder.append("Permission Denial: "); 15226 builder.append(name); 15227 if (callerPackage != null) { 15228 builder.append(" from "); 15229 builder.append(callerPackage); 15230 } 15231 builder.append(" asks to run as user "); 15232 builder.append(userId); 15233 builder.append(" but is calling from user "); 15234 builder.append(UserHandle.getUserId(callingUid)); 15235 builder.append("; this requires "); 15236 builder.append(INTERACT_ACROSS_USERS_FULL); 15237 if (allowMode != ALLOW_FULL_ONLY) { 15238 builder.append(" or "); 15239 builder.append(INTERACT_ACROSS_USERS); 15240 } 15241 String msg = builder.toString(); 15242 Slog.w(TAG, msg); 15243 throw new SecurityException(msg); 15244 } 15245 } 15246 } 15247 if (!allowAll && targetUserId < 0) { 15248 throw new IllegalArgumentException( 15249 "Call does not support special user #" + targetUserId); 15250 } 15251 // Check shell permission 15252 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15253 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15254 targetUserId)) { 15255 throw new SecurityException("Shell does not have permission to access user " 15256 + targetUserId + "\n " + Debug.getCallers(3)); 15257 } 15258 } 15259 return targetUserId; 15260 } 15261 15262 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15263 String className, int flags) { 15264 boolean result = false; 15265 // For apps that don't have pre-defined UIDs, check for permission 15266 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15267 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15268 if (ActivityManager.checkUidPermission( 15269 INTERACT_ACROSS_USERS, 15270 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15271 ComponentName comp = new ComponentName(aInfo.packageName, className); 15272 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15273 + " requests FLAG_SINGLE_USER, but app does not hold " 15274 + INTERACT_ACROSS_USERS; 15275 Slog.w(TAG, msg); 15276 throw new SecurityException(msg); 15277 } 15278 // Permission passed 15279 result = true; 15280 } 15281 } else if ("system".equals(componentProcessName)) { 15282 result = true; 15283 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15284 // Phone app and persistent apps are allowed to export singleuser providers. 15285 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15286 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15287 } 15288 if (DEBUG_MU) { 15289 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15290 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15291 } 15292 return result; 15293 } 15294 15295 /** 15296 * Checks to see if the caller is in the same app as the singleton 15297 * component, or the component is in a special app. It allows special apps 15298 * to export singleton components but prevents exporting singleton 15299 * components for regular apps. 15300 */ 15301 boolean isValidSingletonCall(int callingUid, int componentUid) { 15302 int componentAppId = UserHandle.getAppId(componentUid); 15303 return UserHandle.isSameApp(callingUid, componentUid) 15304 || componentAppId == Process.SYSTEM_UID 15305 || componentAppId == Process.PHONE_UID 15306 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15307 == PackageManager.PERMISSION_GRANTED; 15308 } 15309 15310 public int bindService(IApplicationThread caller, IBinder token, 15311 Intent service, String resolvedType, 15312 IServiceConnection connection, int flags, int userId) { 15313 enforceNotIsolatedCaller("bindService"); 15314 15315 // Refuse possible leaked file descriptors 15316 if (service != null && service.hasFileDescriptors() == true) { 15317 throw new IllegalArgumentException("File descriptors passed in Intent"); 15318 } 15319 15320 synchronized(this) { 15321 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15322 connection, flags, userId); 15323 } 15324 } 15325 15326 public boolean unbindService(IServiceConnection connection) { 15327 synchronized (this) { 15328 return mServices.unbindServiceLocked(connection); 15329 } 15330 } 15331 15332 public void publishService(IBinder token, Intent intent, IBinder service) { 15333 // Refuse possible leaked file descriptors 15334 if (intent != null && intent.hasFileDescriptors() == true) { 15335 throw new IllegalArgumentException("File descriptors passed in Intent"); 15336 } 15337 15338 synchronized(this) { 15339 if (!(token instanceof ServiceRecord)) { 15340 throw new IllegalArgumentException("Invalid service token"); 15341 } 15342 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15343 } 15344 } 15345 15346 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15347 // Refuse possible leaked file descriptors 15348 if (intent != null && intent.hasFileDescriptors() == true) { 15349 throw new IllegalArgumentException("File descriptors passed in Intent"); 15350 } 15351 15352 synchronized(this) { 15353 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15354 } 15355 } 15356 15357 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15358 synchronized(this) { 15359 if (!(token instanceof ServiceRecord)) { 15360 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 15361 throw new IllegalArgumentException("Invalid service token"); 15362 } 15363 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15364 } 15365 } 15366 15367 // ========================================================= 15368 // BACKUP AND RESTORE 15369 // ========================================================= 15370 15371 // Cause the target app to be launched if necessary and its backup agent 15372 // instantiated. The backup agent will invoke backupAgentCreated() on the 15373 // activity manager to announce its creation. 15374 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15375 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15376 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15377 15378 synchronized(this) { 15379 // !!! TODO: currently no check here that we're already bound 15380 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15381 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15382 synchronized (stats) { 15383 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15384 } 15385 15386 // Backup agent is now in use, its package can't be stopped. 15387 try { 15388 AppGlobals.getPackageManager().setPackageStoppedState( 15389 app.packageName, false, UserHandle.getUserId(app.uid)); 15390 } catch (RemoteException e) { 15391 } catch (IllegalArgumentException e) { 15392 Slog.w(TAG, "Failed trying to unstop package " 15393 + app.packageName + ": " + e); 15394 } 15395 15396 BackupRecord r = new BackupRecord(ss, app, backupMode); 15397 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15398 ? new ComponentName(app.packageName, app.backupAgentName) 15399 : new ComponentName("android", "FullBackupAgent"); 15400 // startProcessLocked() returns existing proc's record if it's already running 15401 ProcessRecord proc = startProcessLocked(app.processName, app, 15402 false, 0, "backup", hostingName, false, false, false); 15403 if (proc == null) { 15404 Slog.e(TAG, "Unable to start backup agent process " + r); 15405 return false; 15406 } 15407 15408 r.app = proc; 15409 mBackupTarget = r; 15410 mBackupAppName = app.packageName; 15411 15412 // Try not to kill the process during backup 15413 updateOomAdjLocked(proc); 15414 15415 // If the process is already attached, schedule the creation of the backup agent now. 15416 // If it is not yet live, this will be done when it attaches to the framework. 15417 if (proc.thread != null) { 15418 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15419 try { 15420 proc.thread.scheduleCreateBackupAgent(app, 15421 compatibilityInfoForPackageLocked(app), backupMode); 15422 } catch (RemoteException e) { 15423 // Will time out on the backup manager side 15424 } 15425 } else { 15426 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15427 } 15428 // Invariants: at this point, the target app process exists and the application 15429 // is either already running or in the process of coming up. mBackupTarget and 15430 // mBackupAppName describe the app, so that when it binds back to the AM we 15431 // know that it's scheduled for a backup-agent operation. 15432 } 15433 15434 return true; 15435 } 15436 15437 @Override 15438 public void clearPendingBackup() { 15439 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15440 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15441 15442 synchronized (this) { 15443 mBackupTarget = null; 15444 mBackupAppName = null; 15445 } 15446 } 15447 15448 // A backup agent has just come up 15449 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15450 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15451 + " = " + agent); 15452 15453 synchronized(this) { 15454 if (!agentPackageName.equals(mBackupAppName)) { 15455 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15456 return; 15457 } 15458 } 15459 15460 long oldIdent = Binder.clearCallingIdentity(); 15461 try { 15462 IBackupManager bm = IBackupManager.Stub.asInterface( 15463 ServiceManager.getService(Context.BACKUP_SERVICE)); 15464 bm.agentConnected(agentPackageName, agent); 15465 } catch (RemoteException e) { 15466 // can't happen; the backup manager service is local 15467 } catch (Exception e) { 15468 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15469 e.printStackTrace(); 15470 } finally { 15471 Binder.restoreCallingIdentity(oldIdent); 15472 } 15473 } 15474 15475 // done with this agent 15476 public void unbindBackupAgent(ApplicationInfo appInfo) { 15477 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15478 if (appInfo == null) { 15479 Slog.w(TAG, "unbind backup agent for null app"); 15480 return; 15481 } 15482 15483 synchronized(this) { 15484 try { 15485 if (mBackupAppName == null) { 15486 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15487 return; 15488 } 15489 15490 if (!mBackupAppName.equals(appInfo.packageName)) { 15491 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15492 return; 15493 } 15494 15495 // Not backing this app up any more; reset its OOM adjustment 15496 final ProcessRecord proc = mBackupTarget.app; 15497 updateOomAdjLocked(proc); 15498 15499 // If the app crashed during backup, 'thread' will be null here 15500 if (proc.thread != null) { 15501 try { 15502 proc.thread.scheduleDestroyBackupAgent(appInfo, 15503 compatibilityInfoForPackageLocked(appInfo)); 15504 } catch (Exception e) { 15505 Slog.e(TAG, "Exception when unbinding backup agent:"); 15506 e.printStackTrace(); 15507 } 15508 } 15509 } finally { 15510 mBackupTarget = null; 15511 mBackupAppName = null; 15512 } 15513 } 15514 } 15515 // ========================================================= 15516 // BROADCASTS 15517 // ========================================================= 15518 15519 private final List getStickiesLocked(String action, IntentFilter filter, 15520 List cur, int userId) { 15521 final ContentResolver resolver = mContext.getContentResolver(); 15522 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15523 if (stickies == null) { 15524 return cur; 15525 } 15526 final ArrayList<Intent> list = stickies.get(action); 15527 if (list == null) { 15528 return cur; 15529 } 15530 int N = list.size(); 15531 for (int i=0; i<N; i++) { 15532 Intent intent = list.get(i); 15533 if (filter.match(resolver, intent, true, TAG) >= 0) { 15534 if (cur == null) { 15535 cur = new ArrayList<Intent>(); 15536 } 15537 cur.add(intent); 15538 } 15539 } 15540 return cur; 15541 } 15542 15543 boolean isPendingBroadcastProcessLocked(int pid) { 15544 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15545 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15546 } 15547 15548 void skipPendingBroadcastLocked(int pid) { 15549 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15550 for (BroadcastQueue queue : mBroadcastQueues) { 15551 queue.skipPendingBroadcastLocked(pid); 15552 } 15553 } 15554 15555 // The app just attached; send any pending broadcasts that it should receive 15556 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15557 boolean didSomething = false; 15558 for (BroadcastQueue queue : mBroadcastQueues) { 15559 didSomething |= queue.sendPendingBroadcastsLocked(app); 15560 } 15561 return didSomething; 15562 } 15563 15564 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15565 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15566 enforceNotIsolatedCaller("registerReceiver"); 15567 int callingUid; 15568 int callingPid; 15569 synchronized(this) { 15570 ProcessRecord callerApp = null; 15571 if (caller != null) { 15572 callerApp = getRecordForAppLocked(caller); 15573 if (callerApp == null) { 15574 throw new SecurityException( 15575 "Unable to find app for caller " + caller 15576 + " (pid=" + Binder.getCallingPid() 15577 + ") when registering receiver " + receiver); 15578 } 15579 if (callerApp.info.uid != Process.SYSTEM_UID && 15580 !callerApp.pkgList.containsKey(callerPackage) && 15581 !"android".equals(callerPackage)) { 15582 throw new SecurityException("Given caller package " + callerPackage 15583 + " is not running in process " + callerApp); 15584 } 15585 callingUid = callerApp.info.uid; 15586 callingPid = callerApp.pid; 15587 } else { 15588 callerPackage = null; 15589 callingUid = Binder.getCallingUid(); 15590 callingPid = Binder.getCallingPid(); 15591 } 15592 15593 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15594 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15595 15596 List allSticky = null; 15597 15598 // Look for any matching sticky broadcasts... 15599 Iterator actions = filter.actionsIterator(); 15600 if (actions != null) { 15601 while (actions.hasNext()) { 15602 String action = (String)actions.next(); 15603 allSticky = getStickiesLocked(action, filter, allSticky, 15604 UserHandle.USER_ALL); 15605 allSticky = getStickiesLocked(action, filter, allSticky, 15606 UserHandle.getUserId(callingUid)); 15607 } 15608 } else { 15609 allSticky = getStickiesLocked(null, filter, allSticky, 15610 UserHandle.USER_ALL); 15611 allSticky = getStickiesLocked(null, filter, allSticky, 15612 UserHandle.getUserId(callingUid)); 15613 } 15614 15615 // The first sticky in the list is returned directly back to 15616 // the client. 15617 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15618 15619 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15620 + ": " + sticky); 15621 15622 if (receiver == null) { 15623 return sticky; 15624 } 15625 15626 ReceiverList rl 15627 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15628 if (rl == null) { 15629 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15630 userId, receiver); 15631 if (rl.app != null) { 15632 rl.app.receivers.add(rl); 15633 } else { 15634 try { 15635 receiver.asBinder().linkToDeath(rl, 0); 15636 } catch (RemoteException e) { 15637 return sticky; 15638 } 15639 rl.linkedToDeath = true; 15640 } 15641 mRegisteredReceivers.put(receiver.asBinder(), rl); 15642 } else if (rl.uid != callingUid) { 15643 throw new IllegalArgumentException( 15644 "Receiver requested to register for uid " + callingUid 15645 + " was previously registered for uid " + rl.uid); 15646 } else if (rl.pid != callingPid) { 15647 throw new IllegalArgumentException( 15648 "Receiver requested to register for pid " + callingPid 15649 + " was previously registered for pid " + rl.pid); 15650 } else if (rl.userId != userId) { 15651 throw new IllegalArgumentException( 15652 "Receiver requested to register for user " + userId 15653 + " was previously registered for user " + rl.userId); 15654 } 15655 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15656 permission, callingUid, userId); 15657 rl.add(bf); 15658 if (!bf.debugCheck()) { 15659 Slog.w(TAG, "==> For Dynamic broadast"); 15660 } 15661 mReceiverResolver.addFilter(bf); 15662 15663 // Enqueue broadcasts for all existing stickies that match 15664 // this filter. 15665 if (allSticky != null) { 15666 ArrayList receivers = new ArrayList(); 15667 receivers.add(bf); 15668 15669 int N = allSticky.size(); 15670 for (int i=0; i<N; i++) { 15671 Intent intent = (Intent)allSticky.get(i); 15672 BroadcastQueue queue = broadcastQueueForIntent(intent); 15673 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15674 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15675 null, null, false, true, true, -1); 15676 queue.enqueueParallelBroadcastLocked(r); 15677 queue.scheduleBroadcastsLocked(); 15678 } 15679 } 15680 15681 return sticky; 15682 } 15683 } 15684 15685 public void unregisterReceiver(IIntentReceiver receiver) { 15686 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15687 15688 final long origId = Binder.clearCallingIdentity(); 15689 try { 15690 boolean doTrim = false; 15691 15692 synchronized(this) { 15693 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15694 if (rl != null) { 15695 if (rl.curBroadcast != null) { 15696 BroadcastRecord r = rl.curBroadcast; 15697 final boolean doNext = finishReceiverLocked( 15698 receiver.asBinder(), r.resultCode, r.resultData, 15699 r.resultExtras, r.resultAbort); 15700 if (doNext) { 15701 doTrim = true; 15702 r.queue.processNextBroadcast(false); 15703 } 15704 } 15705 15706 if (rl.app != null) { 15707 rl.app.receivers.remove(rl); 15708 } 15709 removeReceiverLocked(rl); 15710 if (rl.linkedToDeath) { 15711 rl.linkedToDeath = false; 15712 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15713 } 15714 } 15715 } 15716 15717 // If we actually concluded any broadcasts, we might now be able 15718 // to trim the recipients' apps from our working set 15719 if (doTrim) { 15720 trimApplications(); 15721 return; 15722 } 15723 15724 } finally { 15725 Binder.restoreCallingIdentity(origId); 15726 } 15727 } 15728 15729 void removeReceiverLocked(ReceiverList rl) { 15730 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15731 int N = rl.size(); 15732 for (int i=0; i<N; i++) { 15733 mReceiverResolver.removeFilter(rl.get(i)); 15734 } 15735 } 15736 15737 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15738 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15739 ProcessRecord r = mLruProcesses.get(i); 15740 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15741 try { 15742 r.thread.dispatchPackageBroadcast(cmd, packages); 15743 } catch (RemoteException ex) { 15744 } 15745 } 15746 } 15747 } 15748 15749 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15750 int callingUid, int[] users) { 15751 List<ResolveInfo> receivers = null; 15752 try { 15753 HashSet<ComponentName> singleUserReceivers = null; 15754 boolean scannedFirstReceivers = false; 15755 for (int user : users) { 15756 // Skip users that have Shell restrictions 15757 if (callingUid == Process.SHELL_UID 15758 && getUserManagerLocked().hasUserRestriction( 15759 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15760 continue; 15761 } 15762 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15763 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15764 if (user != 0 && newReceivers != null) { 15765 // If this is not the primary user, we need to check for 15766 // any receivers that should be filtered out. 15767 for (int i=0; i<newReceivers.size(); i++) { 15768 ResolveInfo ri = newReceivers.get(i); 15769 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15770 newReceivers.remove(i); 15771 i--; 15772 } 15773 } 15774 } 15775 if (newReceivers != null && newReceivers.size() == 0) { 15776 newReceivers = null; 15777 } 15778 if (receivers == null) { 15779 receivers = newReceivers; 15780 } else if (newReceivers != null) { 15781 // We need to concatenate the additional receivers 15782 // found with what we have do far. This would be easy, 15783 // but we also need to de-dup any receivers that are 15784 // singleUser. 15785 if (!scannedFirstReceivers) { 15786 // Collect any single user receivers we had already retrieved. 15787 scannedFirstReceivers = true; 15788 for (int i=0; i<receivers.size(); i++) { 15789 ResolveInfo ri = receivers.get(i); 15790 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15791 ComponentName cn = new ComponentName( 15792 ri.activityInfo.packageName, ri.activityInfo.name); 15793 if (singleUserReceivers == null) { 15794 singleUserReceivers = new HashSet<ComponentName>(); 15795 } 15796 singleUserReceivers.add(cn); 15797 } 15798 } 15799 } 15800 // Add the new results to the existing results, tracking 15801 // and de-dupping single user receivers. 15802 for (int i=0; i<newReceivers.size(); i++) { 15803 ResolveInfo ri = newReceivers.get(i); 15804 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15805 ComponentName cn = new ComponentName( 15806 ri.activityInfo.packageName, ri.activityInfo.name); 15807 if (singleUserReceivers == null) { 15808 singleUserReceivers = new HashSet<ComponentName>(); 15809 } 15810 if (!singleUserReceivers.contains(cn)) { 15811 singleUserReceivers.add(cn); 15812 receivers.add(ri); 15813 } 15814 } else { 15815 receivers.add(ri); 15816 } 15817 } 15818 } 15819 } 15820 } catch (RemoteException ex) { 15821 // pm is in same process, this will never happen. 15822 } 15823 return receivers; 15824 } 15825 15826 private final int broadcastIntentLocked(ProcessRecord callerApp, 15827 String callerPackage, Intent intent, String resolvedType, 15828 IIntentReceiver resultTo, int resultCode, String resultData, 15829 Bundle map, String requiredPermission, int appOp, 15830 boolean ordered, boolean sticky, int callingPid, int callingUid, 15831 int userId) { 15832 intent = new Intent(intent); 15833 15834 // By default broadcasts do not go to stopped apps. 15835 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15836 15837 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15838 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15839 + " ordered=" + ordered + " userid=" + userId); 15840 if ((resultTo != null) && !ordered) { 15841 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15842 } 15843 15844 userId = handleIncomingUser(callingPid, callingUid, userId, 15845 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15846 15847 // Make sure that the user who is receiving this broadcast is running. 15848 // If not, we will just skip it. Make an exception for shutdown broadcasts 15849 // and upgrade steps. 15850 15851 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15852 if ((callingUid != Process.SYSTEM_UID 15853 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15854 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15855 Slog.w(TAG, "Skipping broadcast of " + intent 15856 + ": user " + userId + " is stopped"); 15857 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15858 } 15859 } 15860 15861 /* 15862 * Prevent non-system code (defined here to be non-persistent 15863 * processes) from sending protected broadcasts. 15864 */ 15865 int callingAppId = UserHandle.getAppId(callingUid); 15866 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15867 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15868 || callingAppId == Process.NFC_UID || callingUid == 0) { 15869 // Always okay. 15870 } else if (callerApp == null || !callerApp.persistent) { 15871 try { 15872 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15873 intent.getAction())) { 15874 String msg = "Permission Denial: not allowed to send broadcast " 15875 + intent.getAction() + " from pid=" 15876 + callingPid + ", uid=" + callingUid; 15877 Slog.w(TAG, msg); 15878 throw new SecurityException(msg); 15879 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15880 // Special case for compatibility: we don't want apps to send this, 15881 // but historically it has not been protected and apps may be using it 15882 // to poke their own app widget. So, instead of making it protected, 15883 // just limit it to the caller. 15884 if (callerApp == null) { 15885 String msg = "Permission Denial: not allowed to send broadcast " 15886 + intent.getAction() + " from unknown caller."; 15887 Slog.w(TAG, msg); 15888 throw new SecurityException(msg); 15889 } else if (intent.getComponent() != null) { 15890 // They are good enough to send to an explicit component... verify 15891 // it is being sent to the calling app. 15892 if (!intent.getComponent().getPackageName().equals( 15893 callerApp.info.packageName)) { 15894 String msg = "Permission Denial: not allowed to send broadcast " 15895 + intent.getAction() + " to " 15896 + intent.getComponent().getPackageName() + " from " 15897 + callerApp.info.packageName; 15898 Slog.w(TAG, msg); 15899 throw new SecurityException(msg); 15900 } 15901 } else { 15902 // Limit broadcast to their own package. 15903 intent.setPackage(callerApp.info.packageName); 15904 } 15905 } 15906 } catch (RemoteException e) { 15907 Slog.w(TAG, "Remote exception", e); 15908 return ActivityManager.BROADCAST_SUCCESS; 15909 } 15910 } 15911 15912 final String action = intent.getAction(); 15913 if (action != null) { 15914 switch (action) { 15915 case Intent.ACTION_UID_REMOVED: 15916 case Intent.ACTION_PACKAGE_REMOVED: 15917 case Intent.ACTION_PACKAGE_CHANGED: 15918 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15919 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15920 // Handle special intents: if this broadcast is from the package 15921 // manager about a package being removed, we need to remove all of 15922 // its activities from the history stack. 15923 if (checkComponentPermission( 15924 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15925 callingPid, callingUid, -1, true) 15926 != PackageManager.PERMISSION_GRANTED) { 15927 String msg = "Permission Denial: " + intent.getAction() 15928 + " broadcast from " + callerPackage + " (pid=" + callingPid 15929 + ", uid=" + callingUid + ")" 15930 + " requires " 15931 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15932 Slog.w(TAG, msg); 15933 throw new SecurityException(msg); 15934 } 15935 switch (action) { 15936 case Intent.ACTION_UID_REMOVED: 15937 final Bundle intentExtras = intent.getExtras(); 15938 final int uid = intentExtras != null 15939 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15940 if (uid >= 0) { 15941 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15942 synchronized (bs) { 15943 bs.removeUidStatsLocked(uid); 15944 } 15945 mAppOpsService.uidRemoved(uid); 15946 } 15947 break; 15948 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15949 // If resources are unavailable just force stop all those packages 15950 // and flush the attribute cache as well. 15951 String list[] = 15952 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15953 if (list != null && list.length > 0) { 15954 for (int i = 0; i < list.length; i++) { 15955 forceStopPackageLocked(list[i], -1, false, true, true, 15956 false, false, userId, "storage unmount"); 15957 } 15958 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15959 sendPackageBroadcastLocked( 15960 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15961 userId); 15962 } 15963 break; 15964 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15965 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15966 break; 15967 case Intent.ACTION_PACKAGE_REMOVED: 15968 case Intent.ACTION_PACKAGE_CHANGED: 15969 Uri data = intent.getData(); 15970 String ssp; 15971 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15972 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15973 boolean fullUninstall = removed && 15974 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15975 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15976 forceStopPackageLocked(ssp, UserHandle.getAppId( 15977 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15978 false, true, true, false, fullUninstall, userId, 15979 removed ? "pkg removed" : "pkg changed"); 15980 } 15981 if (removed) { 15982 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15983 new String[] {ssp}, userId); 15984 if (fullUninstall) { 15985 mAppOpsService.packageRemoved( 15986 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15987 15988 // Remove all permissions granted from/to this package 15989 removeUriPermissionsForPackageLocked(ssp, userId, true); 15990 15991 removeTasksByPackageNameLocked(ssp, userId); 15992 if (userId == UserHandle.USER_OWNER) { 15993 mTaskPersister.removeFromPackageCache(ssp); 15994 } 15995 } 15996 } else { 15997 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15998 if (userId == UserHandle.USER_OWNER) { 15999 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16000 } 16001 } 16002 } 16003 break; 16004 } 16005 break; 16006 case Intent.ACTION_PACKAGE_ADDED: 16007 // Special case for adding a package: by default turn on compatibility mode. 16008 Uri data = intent.getData(); 16009 String ssp; 16010 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16011 final boolean replacing = 16012 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16013 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16014 16015 if (replacing) { 16016 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16017 } 16018 if (userId == UserHandle.USER_OWNER) { 16019 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16020 } 16021 } 16022 break; 16023 case Intent.ACTION_TIMEZONE_CHANGED: 16024 // If this is the time zone changed action, queue up a message that will reset 16025 // the timezone of all currently running processes. This message will get 16026 // queued up before the broadcast happens. 16027 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16028 break; 16029 case Intent.ACTION_TIME_CHANGED: 16030 // If the user set the time, let all running processes know. 16031 final int is24Hour = 16032 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16033 : 0; 16034 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16035 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16036 synchronized (stats) { 16037 stats.noteCurrentTimeChangedLocked(); 16038 } 16039 break; 16040 case Intent.ACTION_CLEAR_DNS_CACHE: 16041 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16042 break; 16043 case Proxy.PROXY_CHANGE_ACTION: 16044 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16045 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16046 break; 16047 } 16048 } 16049 16050 // Add to the sticky list if requested. 16051 if (sticky) { 16052 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16053 callingPid, callingUid) 16054 != PackageManager.PERMISSION_GRANTED) { 16055 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16056 + callingPid + ", uid=" + callingUid 16057 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16058 Slog.w(TAG, msg); 16059 throw new SecurityException(msg); 16060 } 16061 if (requiredPermission != null) { 16062 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16063 + " and enforce permission " + requiredPermission); 16064 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16065 } 16066 if (intent.getComponent() != null) { 16067 throw new SecurityException( 16068 "Sticky broadcasts can't target a specific component"); 16069 } 16070 // We use userId directly here, since the "all" target is maintained 16071 // as a separate set of sticky broadcasts. 16072 if (userId != UserHandle.USER_ALL) { 16073 // But first, if this is not a broadcast to all users, then 16074 // make sure it doesn't conflict with an existing broadcast to 16075 // all users. 16076 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16077 UserHandle.USER_ALL); 16078 if (stickies != null) { 16079 ArrayList<Intent> list = stickies.get(intent.getAction()); 16080 if (list != null) { 16081 int N = list.size(); 16082 int i; 16083 for (i=0; i<N; i++) { 16084 if (intent.filterEquals(list.get(i))) { 16085 throw new IllegalArgumentException( 16086 "Sticky broadcast " + intent + " for user " 16087 + userId + " conflicts with existing global broadcast"); 16088 } 16089 } 16090 } 16091 } 16092 } 16093 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16094 if (stickies == null) { 16095 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16096 mStickyBroadcasts.put(userId, stickies); 16097 } 16098 ArrayList<Intent> list = stickies.get(intent.getAction()); 16099 if (list == null) { 16100 list = new ArrayList<Intent>(); 16101 stickies.put(intent.getAction(), list); 16102 } 16103 int N = list.size(); 16104 int i; 16105 for (i=0; i<N; i++) { 16106 if (intent.filterEquals(list.get(i))) { 16107 // This sticky already exists, replace it. 16108 list.set(i, new Intent(intent)); 16109 break; 16110 } 16111 } 16112 if (i >= N) { 16113 list.add(new Intent(intent)); 16114 } 16115 } 16116 16117 int[] users; 16118 if (userId == UserHandle.USER_ALL) { 16119 // Caller wants broadcast to go to all started users. 16120 users = mStartedUserArray; 16121 } else { 16122 // Caller wants broadcast to go to one specific user. 16123 users = new int[] {userId}; 16124 } 16125 16126 // Figure out who all will receive this broadcast. 16127 List receivers = null; 16128 List<BroadcastFilter> registeredReceivers = null; 16129 // Need to resolve the intent to interested receivers... 16130 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16131 == 0) { 16132 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16133 } 16134 if (intent.getComponent() == null) { 16135 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16136 // Query one target user at a time, excluding shell-restricted users 16137 UserManagerService ums = getUserManagerLocked(); 16138 for (int i = 0; i < users.length; i++) { 16139 if (ums.hasUserRestriction( 16140 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16141 continue; 16142 } 16143 List<BroadcastFilter> registeredReceiversForUser = 16144 mReceiverResolver.queryIntent(intent, 16145 resolvedType, false, users[i]); 16146 if (registeredReceivers == null) { 16147 registeredReceivers = registeredReceiversForUser; 16148 } else if (registeredReceiversForUser != null) { 16149 registeredReceivers.addAll(registeredReceiversForUser); 16150 } 16151 } 16152 } else { 16153 registeredReceivers = mReceiverResolver.queryIntent(intent, 16154 resolvedType, false, userId); 16155 } 16156 } 16157 16158 final boolean replacePending = 16159 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16160 16161 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16162 + " replacePending=" + replacePending); 16163 16164 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16165 if (!ordered && NR > 0) { 16166 // If we are not serializing this broadcast, then send the 16167 // registered receivers separately so they don't wait for the 16168 // components to be launched. 16169 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16170 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16171 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16172 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16173 ordered, sticky, false, userId); 16174 if (DEBUG_BROADCAST) Slog.v( 16175 TAG, "Enqueueing parallel broadcast " + r); 16176 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16177 if (!replaced) { 16178 queue.enqueueParallelBroadcastLocked(r); 16179 queue.scheduleBroadcastsLocked(); 16180 } 16181 registeredReceivers = null; 16182 NR = 0; 16183 } 16184 16185 // Merge into one list. 16186 int ir = 0; 16187 if (receivers != null) { 16188 // A special case for PACKAGE_ADDED: do not allow the package 16189 // being added to see this broadcast. This prevents them from 16190 // using this as a back door to get run as soon as they are 16191 // installed. Maybe in the future we want to have a special install 16192 // broadcast or such for apps, but we'd like to deliberately make 16193 // this decision. 16194 String skipPackages[] = null; 16195 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16196 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16197 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16198 Uri data = intent.getData(); 16199 if (data != null) { 16200 String pkgName = data.getSchemeSpecificPart(); 16201 if (pkgName != null) { 16202 skipPackages = new String[] { pkgName }; 16203 } 16204 } 16205 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16206 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16207 } 16208 if (skipPackages != null && (skipPackages.length > 0)) { 16209 for (String skipPackage : skipPackages) { 16210 if (skipPackage != null) { 16211 int NT = receivers.size(); 16212 for (int it=0; it<NT; it++) { 16213 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16214 if (curt.activityInfo.packageName.equals(skipPackage)) { 16215 receivers.remove(it); 16216 it--; 16217 NT--; 16218 } 16219 } 16220 } 16221 } 16222 } 16223 16224 int NT = receivers != null ? receivers.size() : 0; 16225 int it = 0; 16226 ResolveInfo curt = null; 16227 BroadcastFilter curr = null; 16228 while (it < NT && ir < NR) { 16229 if (curt == null) { 16230 curt = (ResolveInfo)receivers.get(it); 16231 } 16232 if (curr == null) { 16233 curr = registeredReceivers.get(ir); 16234 } 16235 if (curr.getPriority() >= curt.priority) { 16236 // Insert this broadcast record into the final list. 16237 receivers.add(it, curr); 16238 ir++; 16239 curr = null; 16240 it++; 16241 NT++; 16242 } else { 16243 // Skip to the next ResolveInfo in the final list. 16244 it++; 16245 curt = null; 16246 } 16247 } 16248 } 16249 while (ir < NR) { 16250 if (receivers == null) { 16251 receivers = new ArrayList(); 16252 } 16253 receivers.add(registeredReceivers.get(ir)); 16254 ir++; 16255 } 16256 16257 if ((receivers != null && receivers.size() > 0) 16258 || resultTo != null) { 16259 BroadcastQueue queue = broadcastQueueForIntent(intent); 16260 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16261 callerPackage, callingPid, callingUid, resolvedType, 16262 requiredPermission, appOp, receivers, resultTo, resultCode, 16263 resultData, map, ordered, sticky, false, userId); 16264 if (DEBUG_BROADCAST) Slog.v( 16265 TAG, "Enqueueing ordered broadcast " + r 16266 + ": prev had " + queue.mOrderedBroadcasts.size()); 16267 if (DEBUG_BROADCAST) { 16268 int seq = r.intent.getIntExtra("seq", -1); 16269 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16270 } 16271 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16272 if (!replaced) { 16273 queue.enqueueOrderedBroadcastLocked(r); 16274 queue.scheduleBroadcastsLocked(); 16275 } 16276 } 16277 16278 return ActivityManager.BROADCAST_SUCCESS; 16279 } 16280 16281 final Intent verifyBroadcastLocked(Intent intent) { 16282 // Refuse possible leaked file descriptors 16283 if (intent != null && intent.hasFileDescriptors() == true) { 16284 throw new IllegalArgumentException("File descriptors passed in Intent"); 16285 } 16286 16287 int flags = intent.getFlags(); 16288 16289 if (!mProcessesReady) { 16290 // if the caller really truly claims to know what they're doing, go 16291 // ahead and allow the broadcast without launching any receivers 16292 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16293 intent = new Intent(intent); 16294 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16295 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16296 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16297 + " before boot completion"); 16298 throw new IllegalStateException("Cannot broadcast before boot completed"); 16299 } 16300 } 16301 16302 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16303 throw new IllegalArgumentException( 16304 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16305 } 16306 16307 return intent; 16308 } 16309 16310 public final int broadcastIntent(IApplicationThread caller, 16311 Intent intent, String resolvedType, IIntentReceiver resultTo, 16312 int resultCode, String resultData, Bundle map, 16313 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16314 enforceNotIsolatedCaller("broadcastIntent"); 16315 synchronized(this) { 16316 intent = verifyBroadcastLocked(intent); 16317 16318 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16319 final int callingPid = Binder.getCallingPid(); 16320 final int callingUid = Binder.getCallingUid(); 16321 final long origId = Binder.clearCallingIdentity(); 16322 int res = broadcastIntentLocked(callerApp, 16323 callerApp != null ? callerApp.info.packageName : null, 16324 intent, resolvedType, resultTo, 16325 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16326 callingPid, callingUid, userId); 16327 Binder.restoreCallingIdentity(origId); 16328 return res; 16329 } 16330 } 16331 16332 int broadcastIntentInPackage(String packageName, int uid, 16333 Intent intent, String resolvedType, IIntentReceiver resultTo, 16334 int resultCode, String resultData, Bundle map, 16335 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16336 synchronized(this) { 16337 intent = verifyBroadcastLocked(intent); 16338 16339 final long origId = Binder.clearCallingIdentity(); 16340 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16341 resultTo, resultCode, resultData, map, requiredPermission, 16342 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16343 Binder.restoreCallingIdentity(origId); 16344 return res; 16345 } 16346 } 16347 16348 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16349 // Refuse possible leaked file descriptors 16350 if (intent != null && intent.hasFileDescriptors() == true) { 16351 throw new IllegalArgumentException("File descriptors passed in Intent"); 16352 } 16353 16354 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16355 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16356 16357 synchronized(this) { 16358 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16359 != PackageManager.PERMISSION_GRANTED) { 16360 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16361 + Binder.getCallingPid() 16362 + ", uid=" + Binder.getCallingUid() 16363 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16364 Slog.w(TAG, msg); 16365 throw new SecurityException(msg); 16366 } 16367 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16368 if (stickies != null) { 16369 ArrayList<Intent> list = stickies.get(intent.getAction()); 16370 if (list != null) { 16371 int N = list.size(); 16372 int i; 16373 for (i=0; i<N; i++) { 16374 if (intent.filterEquals(list.get(i))) { 16375 list.remove(i); 16376 break; 16377 } 16378 } 16379 if (list.size() <= 0) { 16380 stickies.remove(intent.getAction()); 16381 } 16382 } 16383 if (stickies.size() <= 0) { 16384 mStickyBroadcasts.remove(userId); 16385 } 16386 } 16387 } 16388 } 16389 16390 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16391 String resultData, Bundle resultExtras, boolean resultAbort) { 16392 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16393 if (r == null) { 16394 Slog.w(TAG, "finishReceiver called but not found on queue"); 16395 return false; 16396 } 16397 16398 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16399 } 16400 16401 void backgroundServicesFinishedLocked(int userId) { 16402 for (BroadcastQueue queue : mBroadcastQueues) { 16403 queue.backgroundServicesFinishedLocked(userId); 16404 } 16405 } 16406 16407 public void finishReceiver(IBinder who, int resultCode, String resultData, 16408 Bundle resultExtras, boolean resultAbort) { 16409 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16410 16411 // Refuse possible leaked file descriptors 16412 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16413 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16414 } 16415 16416 final long origId = Binder.clearCallingIdentity(); 16417 try { 16418 boolean doNext = false; 16419 BroadcastRecord r; 16420 16421 synchronized(this) { 16422 r = broadcastRecordForReceiverLocked(who); 16423 if (r != null) { 16424 doNext = r.queue.finishReceiverLocked(r, resultCode, 16425 resultData, resultExtras, resultAbort, true); 16426 } 16427 } 16428 16429 if (doNext) { 16430 r.queue.processNextBroadcast(false); 16431 } 16432 trimApplications(); 16433 } finally { 16434 Binder.restoreCallingIdentity(origId); 16435 } 16436 } 16437 16438 // ========================================================= 16439 // INSTRUMENTATION 16440 // ========================================================= 16441 16442 public boolean startInstrumentation(ComponentName className, 16443 String profileFile, int flags, Bundle arguments, 16444 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16445 int userId, String abiOverride) { 16446 enforceNotIsolatedCaller("startInstrumentation"); 16447 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16448 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16449 // Refuse possible leaked file descriptors 16450 if (arguments != null && arguments.hasFileDescriptors()) { 16451 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16452 } 16453 16454 synchronized(this) { 16455 InstrumentationInfo ii = null; 16456 ApplicationInfo ai = null; 16457 try { 16458 ii = mContext.getPackageManager().getInstrumentationInfo( 16459 className, STOCK_PM_FLAGS); 16460 ai = AppGlobals.getPackageManager().getApplicationInfo( 16461 ii.targetPackage, STOCK_PM_FLAGS, userId); 16462 } catch (PackageManager.NameNotFoundException e) { 16463 } catch (RemoteException e) { 16464 } 16465 if (ii == null) { 16466 reportStartInstrumentationFailure(watcher, className, 16467 "Unable to find instrumentation info for: " + className); 16468 return false; 16469 } 16470 if (ai == null) { 16471 reportStartInstrumentationFailure(watcher, className, 16472 "Unable to find instrumentation target package: " + ii.targetPackage); 16473 return false; 16474 } 16475 16476 int match = mContext.getPackageManager().checkSignatures( 16477 ii.targetPackage, ii.packageName); 16478 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16479 String msg = "Permission Denial: starting instrumentation " 16480 + className + " from pid=" 16481 + Binder.getCallingPid() 16482 + ", uid=" + Binder.getCallingPid() 16483 + " not allowed because package " + ii.packageName 16484 + " does not have a signature matching the target " 16485 + ii.targetPackage; 16486 reportStartInstrumentationFailure(watcher, className, msg); 16487 throw new SecurityException(msg); 16488 } 16489 16490 final long origId = Binder.clearCallingIdentity(); 16491 // Instrumentation can kill and relaunch even persistent processes 16492 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16493 "start instr"); 16494 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16495 app.instrumentationClass = className; 16496 app.instrumentationInfo = ai; 16497 app.instrumentationProfileFile = profileFile; 16498 app.instrumentationArguments = arguments; 16499 app.instrumentationWatcher = watcher; 16500 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16501 app.instrumentationResultClass = className; 16502 Binder.restoreCallingIdentity(origId); 16503 } 16504 16505 return true; 16506 } 16507 16508 /** 16509 * Report errors that occur while attempting to start Instrumentation. Always writes the 16510 * error to the logs, but if somebody is watching, send the report there too. This enables 16511 * the "am" command to report errors with more information. 16512 * 16513 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16514 * @param cn The component name of the instrumentation. 16515 * @param report The error report. 16516 */ 16517 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16518 ComponentName cn, String report) { 16519 Slog.w(TAG, report); 16520 try { 16521 if (watcher != null) { 16522 Bundle results = new Bundle(); 16523 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16524 results.putString("Error", report); 16525 watcher.instrumentationStatus(cn, -1, results); 16526 } 16527 } catch (RemoteException e) { 16528 Slog.w(TAG, e); 16529 } 16530 } 16531 16532 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16533 if (app.instrumentationWatcher != null) { 16534 try { 16535 // NOTE: IInstrumentationWatcher *must* be oneway here 16536 app.instrumentationWatcher.instrumentationFinished( 16537 app.instrumentationClass, 16538 resultCode, 16539 results); 16540 } catch (RemoteException e) { 16541 } 16542 } 16543 if (app.instrumentationUiAutomationConnection != null) { 16544 try { 16545 app.instrumentationUiAutomationConnection.shutdown(); 16546 } catch (RemoteException re) { 16547 /* ignore */ 16548 } 16549 // Only a UiAutomation can set this flag and now that 16550 // it is finished we make sure it is reset to its default. 16551 mUserIsMonkey = false; 16552 } 16553 app.instrumentationWatcher = null; 16554 app.instrumentationUiAutomationConnection = null; 16555 app.instrumentationClass = null; 16556 app.instrumentationInfo = null; 16557 app.instrumentationProfileFile = null; 16558 app.instrumentationArguments = null; 16559 16560 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16561 "finished inst"); 16562 } 16563 16564 public void finishInstrumentation(IApplicationThread target, 16565 int resultCode, Bundle results) { 16566 int userId = UserHandle.getCallingUserId(); 16567 // Refuse possible leaked file descriptors 16568 if (results != null && results.hasFileDescriptors()) { 16569 throw new IllegalArgumentException("File descriptors passed in Intent"); 16570 } 16571 16572 synchronized(this) { 16573 ProcessRecord app = getRecordForAppLocked(target); 16574 if (app == null) { 16575 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16576 return; 16577 } 16578 final long origId = Binder.clearCallingIdentity(); 16579 finishInstrumentationLocked(app, resultCode, results); 16580 Binder.restoreCallingIdentity(origId); 16581 } 16582 } 16583 16584 // ========================================================= 16585 // CONFIGURATION 16586 // ========================================================= 16587 16588 public ConfigurationInfo getDeviceConfigurationInfo() { 16589 ConfigurationInfo config = new ConfigurationInfo(); 16590 synchronized (this) { 16591 config.reqTouchScreen = mConfiguration.touchscreen; 16592 config.reqKeyboardType = mConfiguration.keyboard; 16593 config.reqNavigation = mConfiguration.navigation; 16594 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16595 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16596 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16597 } 16598 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16599 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16600 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16601 } 16602 config.reqGlEsVersion = GL_ES_VERSION; 16603 } 16604 return config; 16605 } 16606 16607 ActivityStack getFocusedStack() { 16608 return mStackSupervisor.getFocusedStack(); 16609 } 16610 16611 public Configuration getConfiguration() { 16612 Configuration ci; 16613 synchronized(this) { 16614 ci = new Configuration(mConfiguration); 16615 ci.userSetLocale = false; 16616 } 16617 return ci; 16618 } 16619 16620 public void updatePersistentConfiguration(Configuration values) { 16621 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16622 "updateConfiguration()"); 16623 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16624 "updateConfiguration()"); 16625 if (values == null) { 16626 throw new NullPointerException("Configuration must not be null"); 16627 } 16628 16629 synchronized(this) { 16630 final long origId = Binder.clearCallingIdentity(); 16631 updateConfigurationLocked(values, null, true, false); 16632 Binder.restoreCallingIdentity(origId); 16633 } 16634 } 16635 16636 public void updateConfiguration(Configuration values) { 16637 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16638 "updateConfiguration()"); 16639 16640 synchronized(this) { 16641 if (values == null && mWindowManager != null) { 16642 // sentinel: fetch the current configuration from the window manager 16643 values = mWindowManager.computeNewConfiguration(); 16644 } 16645 16646 if (mWindowManager != null) { 16647 mProcessList.applyDisplaySize(mWindowManager); 16648 } 16649 16650 final long origId = Binder.clearCallingIdentity(); 16651 if (values != null) { 16652 Settings.System.clearConfiguration(values); 16653 } 16654 updateConfigurationLocked(values, null, false, false); 16655 Binder.restoreCallingIdentity(origId); 16656 } 16657 } 16658 16659 /** 16660 * Do either or both things: (1) change the current configuration, and (2) 16661 * make sure the given activity is running with the (now) current 16662 * configuration. Returns true if the activity has been left running, or 16663 * false if <var>starting</var> is being destroyed to match the new 16664 * configuration. 16665 * @param persistent TODO 16666 */ 16667 boolean updateConfigurationLocked(Configuration values, 16668 ActivityRecord starting, boolean persistent, boolean initLocale) { 16669 int changes = 0; 16670 16671 if (values != null) { 16672 Configuration newConfig = new Configuration(mConfiguration); 16673 changes = newConfig.updateFrom(values); 16674 if (changes != 0) { 16675 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16676 Slog.i(TAG, "Updating configuration to: " + values); 16677 } 16678 16679 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16680 16681 if (values.locale != null && !initLocale) { 16682 saveLocaleLocked(values.locale, 16683 !values.locale.equals(mConfiguration.locale), 16684 values.userSetLocale); 16685 } 16686 16687 mConfigurationSeq++; 16688 if (mConfigurationSeq <= 0) { 16689 mConfigurationSeq = 1; 16690 } 16691 newConfig.seq = mConfigurationSeq; 16692 mConfiguration = newConfig; 16693 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16694 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16695 //mUsageStatsService.noteStartConfig(newConfig); 16696 16697 final Configuration configCopy = new Configuration(mConfiguration); 16698 16699 // TODO: If our config changes, should we auto dismiss any currently 16700 // showing dialogs? 16701 mShowDialogs = shouldShowDialogs(newConfig); 16702 16703 AttributeCache ac = AttributeCache.instance(); 16704 if (ac != null) { 16705 ac.updateConfiguration(configCopy); 16706 } 16707 16708 // Make sure all resources in our process are updated 16709 // right now, so that anyone who is going to retrieve 16710 // resource values after we return will be sure to get 16711 // the new ones. This is especially important during 16712 // boot, where the first config change needs to guarantee 16713 // all resources have that config before following boot 16714 // code is executed. 16715 mSystemThread.applyConfigurationToResources(configCopy); 16716 16717 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16718 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16719 msg.obj = new Configuration(configCopy); 16720 mHandler.sendMessage(msg); 16721 } 16722 16723 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16724 ProcessRecord app = mLruProcesses.get(i); 16725 try { 16726 if (app.thread != null) { 16727 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16728 + app.processName + " new config " + mConfiguration); 16729 app.thread.scheduleConfigurationChanged(configCopy); 16730 } 16731 } catch (Exception e) { 16732 } 16733 } 16734 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16735 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16736 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16737 | Intent.FLAG_RECEIVER_FOREGROUND); 16738 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16739 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16740 Process.SYSTEM_UID, UserHandle.USER_ALL); 16741 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16742 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16743 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16744 broadcastIntentLocked(null, null, intent, 16745 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16746 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16747 } 16748 } 16749 } 16750 16751 boolean kept = true; 16752 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16753 // mainStack is null during startup. 16754 if (mainStack != null) { 16755 if (changes != 0 && starting == null) { 16756 // If the configuration changed, and the caller is not already 16757 // in the process of starting an activity, then find the top 16758 // activity to check if its configuration needs to change. 16759 starting = mainStack.topRunningActivityLocked(null); 16760 } 16761 16762 if (starting != null) { 16763 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16764 // And we need to make sure at this point that all other activities 16765 // are made visible with the correct configuration. 16766 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16767 } 16768 } 16769 16770 if (values != null && mWindowManager != null) { 16771 mWindowManager.setNewConfiguration(mConfiguration); 16772 } 16773 16774 return kept; 16775 } 16776 16777 /** 16778 * Decide based on the configuration whether we should shouw the ANR, 16779 * crash, etc dialogs. The idea is that if there is no affordnace to 16780 * press the on-screen buttons, we shouldn't show the dialog. 16781 * 16782 * A thought: SystemUI might also want to get told about this, the Power 16783 * dialog / global actions also might want different behaviors. 16784 */ 16785 private static final boolean shouldShowDialogs(Configuration config) { 16786 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16787 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16788 } 16789 16790 /** 16791 * Save the locale. You must be inside a synchronized (this) block. 16792 */ 16793 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16794 if(isDiff) { 16795 SystemProperties.set("user.language", l.getLanguage()); 16796 SystemProperties.set("user.region", l.getCountry()); 16797 } 16798 16799 if(isPersist) { 16800 SystemProperties.set("persist.sys.language", l.getLanguage()); 16801 SystemProperties.set("persist.sys.country", l.getCountry()); 16802 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16803 16804 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16805 } 16806 } 16807 16808 @Override 16809 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16810 synchronized (this) { 16811 ActivityRecord srec = ActivityRecord.forToken(token); 16812 if (srec.task != null && srec.task.stack != null) { 16813 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16814 } 16815 } 16816 return false; 16817 } 16818 16819 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16820 Intent resultData) { 16821 16822 synchronized (this) { 16823 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16824 if (stack != null) { 16825 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16826 } 16827 return false; 16828 } 16829 } 16830 16831 public int getLaunchedFromUid(IBinder activityToken) { 16832 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16833 if (srec == null) { 16834 return -1; 16835 } 16836 return srec.launchedFromUid; 16837 } 16838 16839 public String getLaunchedFromPackage(IBinder activityToken) { 16840 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16841 if (srec == null) { 16842 return null; 16843 } 16844 return srec.launchedFromPackage; 16845 } 16846 16847 // ========================================================= 16848 // LIFETIME MANAGEMENT 16849 // ========================================================= 16850 16851 // Returns which broadcast queue the app is the current [or imminent] receiver 16852 // on, or 'null' if the app is not an active broadcast recipient. 16853 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16854 BroadcastRecord r = app.curReceiver; 16855 if (r != null) { 16856 return r.queue; 16857 } 16858 16859 // It's not the current receiver, but it might be starting up to become one 16860 synchronized (this) { 16861 for (BroadcastQueue queue : mBroadcastQueues) { 16862 r = queue.mPendingBroadcast; 16863 if (r != null && r.curApp == app) { 16864 // found it; report which queue it's in 16865 return queue; 16866 } 16867 } 16868 } 16869 16870 return null; 16871 } 16872 16873 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16874 ComponentName targetComponent, String targetProcess) { 16875 if (!mTrackingAssociations) { 16876 return null; 16877 } 16878 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16879 = mAssociations.get(targetUid); 16880 if (components == null) { 16881 components = new ArrayMap<>(); 16882 mAssociations.put(targetUid, components); 16883 } 16884 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16885 if (sourceUids == null) { 16886 sourceUids = new SparseArray<>(); 16887 components.put(targetComponent, sourceUids); 16888 } 16889 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16890 if (sourceProcesses == null) { 16891 sourceProcesses = new ArrayMap<>(); 16892 sourceUids.put(sourceUid, sourceProcesses); 16893 } 16894 Association ass = sourceProcesses.get(sourceProcess); 16895 if (ass == null) { 16896 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16897 targetProcess); 16898 sourceProcesses.put(sourceProcess, ass); 16899 } 16900 ass.mCount++; 16901 ass.mNesting++; 16902 if (ass.mNesting == 1) { 16903 ass.mStartTime = SystemClock.uptimeMillis(); 16904 } 16905 return ass; 16906 } 16907 16908 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16909 ComponentName targetComponent) { 16910 if (!mTrackingAssociations) { 16911 return; 16912 } 16913 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16914 = mAssociations.get(targetUid); 16915 if (components == null) { 16916 return; 16917 } 16918 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16919 if (sourceUids == null) { 16920 return; 16921 } 16922 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16923 if (sourceProcesses == null) { 16924 return; 16925 } 16926 Association ass = sourceProcesses.get(sourceProcess); 16927 if (ass == null || ass.mNesting <= 0) { 16928 return; 16929 } 16930 ass.mNesting--; 16931 if (ass.mNesting == 0) { 16932 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16933 } 16934 } 16935 16936 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16937 boolean doingAll, long now) { 16938 if (mAdjSeq == app.adjSeq) { 16939 // This adjustment has already been computed. 16940 return app.curRawAdj; 16941 } 16942 16943 if (app.thread == null) { 16944 app.adjSeq = mAdjSeq; 16945 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16946 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16947 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16948 } 16949 16950 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16951 app.adjSource = null; 16952 app.adjTarget = null; 16953 app.empty = false; 16954 app.cached = false; 16955 16956 final int activitiesSize = app.activities.size(); 16957 16958 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16959 // The max adjustment doesn't allow this app to be anything 16960 // below foreground, so it is not worth doing work for it. 16961 app.adjType = "fixed"; 16962 app.adjSeq = mAdjSeq; 16963 app.curRawAdj = app.maxAdj; 16964 app.foregroundActivities = false; 16965 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16966 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16967 // System processes can do UI, and when they do we want to have 16968 // them trim their memory after the user leaves the UI. To 16969 // facilitate this, here we need to determine whether or not it 16970 // is currently showing UI. 16971 app.systemNoUi = true; 16972 if (app == TOP_APP) { 16973 app.systemNoUi = false; 16974 } else if (activitiesSize > 0) { 16975 for (int j = 0; j < activitiesSize; j++) { 16976 final ActivityRecord r = app.activities.get(j); 16977 if (r.visible) { 16978 app.systemNoUi = false; 16979 } 16980 } 16981 } 16982 if (!app.systemNoUi) { 16983 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16984 } 16985 return (app.curAdj=app.maxAdj); 16986 } 16987 16988 app.systemNoUi = false; 16989 16990 // Determine the importance of the process, starting with most 16991 // important to least, and assign an appropriate OOM adjustment. 16992 int adj; 16993 int schedGroup; 16994 int procState; 16995 boolean foregroundActivities = false; 16996 BroadcastQueue queue; 16997 if (app == TOP_APP) { 16998 // The last app on the list is the foreground app. 16999 adj = ProcessList.FOREGROUND_APP_ADJ; 17000 schedGroup = Process.THREAD_GROUP_DEFAULT; 17001 app.adjType = "top-activity"; 17002 foregroundActivities = true; 17003 procState = ActivityManager.PROCESS_STATE_TOP; 17004 } else if (app.instrumentationClass != null) { 17005 // Don't want to kill running instrumentation. 17006 adj = ProcessList.FOREGROUND_APP_ADJ; 17007 schedGroup = Process.THREAD_GROUP_DEFAULT; 17008 app.adjType = "instrumentation"; 17009 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17010 } else if ((queue = isReceivingBroadcast(app)) != null) { 17011 // An app that is currently receiving a broadcast also 17012 // counts as being in the foreground for OOM killer purposes. 17013 // It's placed in a sched group based on the nature of the 17014 // broadcast as reflected by which queue it's active in. 17015 adj = ProcessList.FOREGROUND_APP_ADJ; 17016 schedGroup = (queue == mFgBroadcastQueue) 17017 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17018 app.adjType = "broadcast"; 17019 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17020 } else if (app.executingServices.size() > 0) { 17021 // An app that is currently executing a service callback also 17022 // counts as being in the foreground. 17023 adj = ProcessList.FOREGROUND_APP_ADJ; 17024 schedGroup = app.execServicesFg ? 17025 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17026 app.adjType = "exec-service"; 17027 procState = ActivityManager.PROCESS_STATE_SERVICE; 17028 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17029 } else { 17030 // As far as we know the process is empty. We may change our mind later. 17031 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17032 // At this point we don't actually know the adjustment. Use the cached adj 17033 // value that the caller wants us to. 17034 adj = cachedAdj; 17035 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17036 app.cached = true; 17037 app.empty = true; 17038 app.adjType = "cch-empty"; 17039 } 17040 17041 // Examine all activities if not already foreground. 17042 if (!foregroundActivities && activitiesSize > 0) { 17043 for (int j = 0; j < activitiesSize; j++) { 17044 final ActivityRecord r = app.activities.get(j); 17045 if (r.app != app) { 17046 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17047 + app + "?!?"); 17048 continue; 17049 } 17050 if (r.visible) { 17051 // App has a visible activity; only upgrade adjustment. 17052 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17053 adj = ProcessList.VISIBLE_APP_ADJ; 17054 app.adjType = "visible"; 17055 } 17056 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17057 procState = ActivityManager.PROCESS_STATE_TOP; 17058 } 17059 schedGroup = Process.THREAD_GROUP_DEFAULT; 17060 app.cached = false; 17061 app.empty = false; 17062 foregroundActivities = true; 17063 break; 17064 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17065 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17066 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17067 app.adjType = "pausing"; 17068 } 17069 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17070 procState = ActivityManager.PROCESS_STATE_TOP; 17071 } 17072 schedGroup = Process.THREAD_GROUP_DEFAULT; 17073 app.cached = false; 17074 app.empty = false; 17075 foregroundActivities = true; 17076 } else if (r.state == ActivityState.STOPPING) { 17077 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17078 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17079 app.adjType = "stopping"; 17080 } 17081 // For the process state, we will at this point consider the 17082 // process to be cached. It will be cached either as an activity 17083 // or empty depending on whether the activity is finishing. We do 17084 // this so that we can treat the process as cached for purposes of 17085 // memory trimming (determing current memory level, trim command to 17086 // send to process) since there can be an arbitrary number of stopping 17087 // processes and they should soon all go into the cached state. 17088 if (!r.finishing) { 17089 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17090 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17091 } 17092 } 17093 app.cached = false; 17094 app.empty = false; 17095 foregroundActivities = true; 17096 } else { 17097 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17098 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17099 app.adjType = "cch-act"; 17100 } 17101 } 17102 } 17103 } 17104 17105 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17106 if (app.foregroundServices) { 17107 // The user is aware of this app, so make it visible. 17108 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17109 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17110 app.cached = false; 17111 app.adjType = "fg-service"; 17112 schedGroup = Process.THREAD_GROUP_DEFAULT; 17113 } else if (app.forcingToForeground != null) { 17114 // The user is aware of this app, so make it visible. 17115 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17116 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17117 app.cached = false; 17118 app.adjType = "force-fg"; 17119 app.adjSource = app.forcingToForeground; 17120 schedGroup = Process.THREAD_GROUP_DEFAULT; 17121 } 17122 } 17123 17124 if (app == mHeavyWeightProcess) { 17125 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17126 // We don't want to kill the current heavy-weight process. 17127 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17128 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17129 app.cached = false; 17130 app.adjType = "heavy"; 17131 } 17132 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17133 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17134 } 17135 } 17136 17137 if (app == mHomeProcess) { 17138 if (adj > ProcessList.HOME_APP_ADJ) { 17139 // This process is hosting what we currently consider to be the 17140 // home app, so we don't want to let it go into the background. 17141 adj = ProcessList.HOME_APP_ADJ; 17142 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17143 app.cached = false; 17144 app.adjType = "home"; 17145 } 17146 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17147 procState = ActivityManager.PROCESS_STATE_HOME; 17148 } 17149 } 17150 17151 if (app == mPreviousProcess && app.activities.size() > 0) { 17152 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17153 // This was the previous process that showed UI to the user. 17154 // We want to try to keep it around more aggressively, to give 17155 // a good experience around switching between two apps. 17156 adj = ProcessList.PREVIOUS_APP_ADJ; 17157 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17158 app.cached = false; 17159 app.adjType = "previous"; 17160 } 17161 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17162 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17163 } 17164 } 17165 17166 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17167 + " reason=" + app.adjType); 17168 17169 // By default, we use the computed adjustment. It may be changed if 17170 // there are applications dependent on our services or providers, but 17171 // this gives us a baseline and makes sure we don't get into an 17172 // infinite recursion. 17173 app.adjSeq = mAdjSeq; 17174 app.curRawAdj = adj; 17175 app.hasStartedServices = false; 17176 17177 if (mBackupTarget != null && app == mBackupTarget.app) { 17178 // If possible we want to avoid killing apps while they're being backed up 17179 if (adj > ProcessList.BACKUP_APP_ADJ) { 17180 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17181 adj = ProcessList.BACKUP_APP_ADJ; 17182 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17183 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17184 } 17185 app.adjType = "backup"; 17186 app.cached = false; 17187 } 17188 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17189 procState = ActivityManager.PROCESS_STATE_BACKUP; 17190 } 17191 } 17192 17193 boolean mayBeTop = false; 17194 17195 for (int is = app.services.size()-1; 17196 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17197 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17198 || procState > ActivityManager.PROCESS_STATE_TOP); 17199 is--) { 17200 ServiceRecord s = app.services.valueAt(is); 17201 if (s.startRequested) { 17202 app.hasStartedServices = true; 17203 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17204 procState = ActivityManager.PROCESS_STATE_SERVICE; 17205 } 17206 if (app.hasShownUi && app != mHomeProcess) { 17207 // If this process has shown some UI, let it immediately 17208 // go to the LRU list because it may be pretty heavy with 17209 // UI stuff. We'll tag it with a label just to help 17210 // debug and understand what is going on. 17211 if (adj > ProcessList.SERVICE_ADJ) { 17212 app.adjType = "cch-started-ui-services"; 17213 } 17214 } else { 17215 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17216 // This service has seen some activity within 17217 // recent memory, so we will keep its process ahead 17218 // of the background processes. 17219 if (adj > ProcessList.SERVICE_ADJ) { 17220 adj = ProcessList.SERVICE_ADJ; 17221 app.adjType = "started-services"; 17222 app.cached = false; 17223 } 17224 } 17225 // If we have let the service slide into the background 17226 // state, still have some text describing what it is doing 17227 // even though the service no longer has an impact. 17228 if (adj > ProcessList.SERVICE_ADJ) { 17229 app.adjType = "cch-started-services"; 17230 } 17231 } 17232 } 17233 for (int conni = s.connections.size()-1; 17234 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17235 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17236 || procState > ActivityManager.PROCESS_STATE_TOP); 17237 conni--) { 17238 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17239 for (int i = 0; 17240 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17241 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17242 || procState > ActivityManager.PROCESS_STATE_TOP); 17243 i++) { 17244 // XXX should compute this based on the max of 17245 // all connected clients. 17246 ConnectionRecord cr = clist.get(i); 17247 if (cr.binding.client == app) { 17248 // Binding to ourself is not interesting. 17249 continue; 17250 } 17251 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17252 ProcessRecord client = cr.binding.client; 17253 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17254 TOP_APP, doingAll, now); 17255 int clientProcState = client.curProcState; 17256 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17257 // If the other app is cached for any reason, for purposes here 17258 // we are going to consider it empty. The specific cached state 17259 // doesn't propagate except under certain conditions. 17260 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17261 } 17262 String adjType = null; 17263 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17264 // Not doing bind OOM management, so treat 17265 // this guy more like a started service. 17266 if (app.hasShownUi && app != mHomeProcess) { 17267 // If this process has shown some UI, let it immediately 17268 // go to the LRU list because it may be pretty heavy with 17269 // UI stuff. We'll tag it with a label just to help 17270 // debug and understand what is going on. 17271 if (adj > clientAdj) { 17272 adjType = "cch-bound-ui-services"; 17273 } 17274 app.cached = false; 17275 clientAdj = adj; 17276 clientProcState = procState; 17277 } else { 17278 if (now >= (s.lastActivity 17279 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17280 // This service has not seen activity within 17281 // recent memory, so allow it to drop to the 17282 // LRU list if there is no other reason to keep 17283 // it around. We'll also tag it with a label just 17284 // to help debug and undertand what is going on. 17285 if (adj > clientAdj) { 17286 adjType = "cch-bound-services"; 17287 } 17288 clientAdj = adj; 17289 } 17290 } 17291 } 17292 if (adj > clientAdj) { 17293 // If this process has recently shown UI, and 17294 // the process that is binding to it is less 17295 // important than being visible, then we don't 17296 // care about the binding as much as we care 17297 // about letting this process get into the LRU 17298 // list to be killed and restarted if needed for 17299 // memory. 17300 if (app.hasShownUi && app != mHomeProcess 17301 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17302 adjType = "cch-bound-ui-services"; 17303 } else { 17304 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17305 |Context.BIND_IMPORTANT)) != 0) { 17306 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17307 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17308 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17309 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17310 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17311 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17312 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17313 adj = clientAdj; 17314 } else { 17315 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17316 adj = ProcessList.VISIBLE_APP_ADJ; 17317 } 17318 } 17319 if (!client.cached) { 17320 app.cached = false; 17321 } 17322 adjType = "service"; 17323 } 17324 } 17325 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17326 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17327 schedGroup = Process.THREAD_GROUP_DEFAULT; 17328 } 17329 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17330 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17331 // Special handling of clients who are in the top state. 17332 // We *may* want to consider this process to be in the 17333 // top state as well, but only if there is not another 17334 // reason for it to be running. Being on the top is a 17335 // special state, meaning you are specifically running 17336 // for the current top app. If the process is already 17337 // running in the background for some other reason, it 17338 // is more important to continue considering it to be 17339 // in the background state. 17340 mayBeTop = true; 17341 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17342 } else { 17343 // Special handling for above-top states (persistent 17344 // processes). These should not bring the current process 17345 // into the top state, since they are not on top. Instead 17346 // give them the best state after that. 17347 clientProcState = 17348 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17349 } 17350 } 17351 } else { 17352 if (clientProcState < 17353 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17354 clientProcState = 17355 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17356 } 17357 } 17358 if (procState > clientProcState) { 17359 procState = clientProcState; 17360 } 17361 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17362 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17363 app.pendingUiClean = true; 17364 } 17365 if (adjType != null) { 17366 app.adjType = adjType; 17367 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17368 .REASON_SERVICE_IN_USE; 17369 app.adjSource = cr.binding.client; 17370 app.adjSourceProcState = clientProcState; 17371 app.adjTarget = s.name; 17372 } 17373 } 17374 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17375 app.treatLikeActivity = true; 17376 } 17377 final ActivityRecord a = cr.activity; 17378 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17379 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17380 (a.visible || a.state == ActivityState.RESUMED 17381 || a.state == ActivityState.PAUSING)) { 17382 adj = ProcessList.FOREGROUND_APP_ADJ; 17383 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17384 schedGroup = Process.THREAD_GROUP_DEFAULT; 17385 } 17386 app.cached = false; 17387 app.adjType = "service"; 17388 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17389 .REASON_SERVICE_IN_USE; 17390 app.adjSource = a; 17391 app.adjSourceProcState = procState; 17392 app.adjTarget = s.name; 17393 } 17394 } 17395 } 17396 } 17397 } 17398 17399 for (int provi = app.pubProviders.size()-1; 17400 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17401 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17402 || procState > ActivityManager.PROCESS_STATE_TOP); 17403 provi--) { 17404 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17405 for (int i = cpr.connections.size()-1; 17406 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17407 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17408 || procState > ActivityManager.PROCESS_STATE_TOP); 17409 i--) { 17410 ContentProviderConnection conn = cpr.connections.get(i); 17411 ProcessRecord client = conn.client; 17412 if (client == app) { 17413 // Being our own client is not interesting. 17414 continue; 17415 } 17416 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17417 int clientProcState = client.curProcState; 17418 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17419 // If the other app is cached for any reason, for purposes here 17420 // we are going to consider it empty. 17421 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17422 } 17423 if (adj > clientAdj) { 17424 if (app.hasShownUi && app != mHomeProcess 17425 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17426 app.adjType = "cch-ui-provider"; 17427 } else { 17428 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17429 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17430 app.adjType = "provider"; 17431 } 17432 app.cached &= client.cached; 17433 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17434 .REASON_PROVIDER_IN_USE; 17435 app.adjSource = client; 17436 app.adjSourceProcState = clientProcState; 17437 app.adjTarget = cpr.name; 17438 } 17439 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17440 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17441 // Special handling of clients who are in the top state. 17442 // We *may* want to consider this process to be in the 17443 // top state as well, but only if there is not another 17444 // reason for it to be running. Being on the top is a 17445 // special state, meaning you are specifically running 17446 // for the current top app. If the process is already 17447 // running in the background for some other reason, it 17448 // is more important to continue considering it to be 17449 // in the background state. 17450 mayBeTop = true; 17451 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17452 } else { 17453 // Special handling for above-top states (persistent 17454 // processes). These should not bring the current process 17455 // into the top state, since they are not on top. Instead 17456 // give them the best state after that. 17457 clientProcState = 17458 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17459 } 17460 } 17461 if (procState > clientProcState) { 17462 procState = clientProcState; 17463 } 17464 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17465 schedGroup = Process.THREAD_GROUP_DEFAULT; 17466 } 17467 } 17468 // If the provider has external (non-framework) process 17469 // dependencies, ensure that its adjustment is at least 17470 // FOREGROUND_APP_ADJ. 17471 if (cpr.hasExternalProcessHandles()) { 17472 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17473 adj = ProcessList.FOREGROUND_APP_ADJ; 17474 schedGroup = Process.THREAD_GROUP_DEFAULT; 17475 app.cached = false; 17476 app.adjType = "provider"; 17477 app.adjTarget = cpr.name; 17478 } 17479 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17480 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17481 } 17482 } 17483 } 17484 17485 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17486 // A client of one of our services or providers is in the top state. We 17487 // *may* want to be in the top state, but not if we are already running in 17488 // the background for some other reason. For the decision here, we are going 17489 // to pick out a few specific states that we want to remain in when a client 17490 // is top (states that tend to be longer-term) and otherwise allow it to go 17491 // to the top state. 17492 switch (procState) { 17493 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17494 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17495 case ActivityManager.PROCESS_STATE_SERVICE: 17496 // These all are longer-term states, so pull them up to the top 17497 // of the background states, but not all the way to the top state. 17498 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17499 break; 17500 default: 17501 // Otherwise, top is a better choice, so take it. 17502 procState = ActivityManager.PROCESS_STATE_TOP; 17503 break; 17504 } 17505 } 17506 17507 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17508 if (app.hasClientActivities) { 17509 // This is a cached process, but with client activities. Mark it so. 17510 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17511 app.adjType = "cch-client-act"; 17512 } else if (app.treatLikeActivity) { 17513 // This is a cached process, but somebody wants us to treat it like it has 17514 // an activity, okay! 17515 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17516 app.adjType = "cch-as-act"; 17517 } 17518 } 17519 17520 if (adj == ProcessList.SERVICE_ADJ) { 17521 if (doingAll) { 17522 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17523 mNewNumServiceProcs++; 17524 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17525 if (!app.serviceb) { 17526 // This service isn't far enough down on the LRU list to 17527 // normally be a B service, but if we are low on RAM and it 17528 // is large we want to force it down since we would prefer to 17529 // keep launcher over it. 17530 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17531 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17532 app.serviceHighRam = true; 17533 app.serviceb = true; 17534 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17535 } else { 17536 mNewNumAServiceProcs++; 17537 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17538 } 17539 } else { 17540 app.serviceHighRam = false; 17541 } 17542 } 17543 if (app.serviceb) { 17544 adj = ProcessList.SERVICE_B_ADJ; 17545 } 17546 } 17547 17548 app.curRawAdj = adj; 17549 17550 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17551 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17552 if (adj > app.maxAdj) { 17553 adj = app.maxAdj; 17554 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17555 schedGroup = Process.THREAD_GROUP_DEFAULT; 17556 } 17557 } 17558 17559 // Do final modification to adj. Everything we do between here and applying 17560 // the final setAdj must be done in this function, because we will also use 17561 // it when computing the final cached adj later. Note that we don't need to 17562 // worry about this for max adj above, since max adj will always be used to 17563 // keep it out of the cached vaues. 17564 app.curAdj = app.modifyRawOomAdj(adj); 17565 app.curSchedGroup = schedGroup; 17566 app.curProcState = procState; 17567 app.foregroundActivities = foregroundActivities; 17568 17569 return app.curRawAdj; 17570 } 17571 17572 /** 17573 * Record new PSS sample for a process. 17574 */ 17575 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17576 proc.lastPssTime = now; 17577 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17578 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17579 + ": " + pss + " lastPss=" + proc.lastPss 17580 + " state=" + ProcessList.makeProcStateString(procState)); 17581 if (proc.initialIdlePss == 0) { 17582 proc.initialIdlePss = pss; 17583 } 17584 proc.lastPss = pss; 17585 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17586 proc.lastCachedPss = pss; 17587 } 17588 } 17589 17590 /** 17591 * Schedule PSS collection of a process. 17592 */ 17593 void requestPssLocked(ProcessRecord proc, int procState) { 17594 if (mPendingPssProcesses.contains(proc)) { 17595 return; 17596 } 17597 if (mPendingPssProcesses.size() == 0) { 17598 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17599 } 17600 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17601 proc.pssProcState = procState; 17602 mPendingPssProcesses.add(proc); 17603 } 17604 17605 /** 17606 * Schedule PSS collection of all processes. 17607 */ 17608 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17609 if (!always) { 17610 if (now < (mLastFullPssTime + 17611 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17612 return; 17613 } 17614 } 17615 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17616 mLastFullPssTime = now; 17617 mFullPssPending = true; 17618 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17619 mPendingPssProcesses.clear(); 17620 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17621 ProcessRecord app = mLruProcesses.get(i); 17622 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17623 app.pssProcState = app.setProcState; 17624 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17625 mTestPssMode, isSleeping(), now); 17626 mPendingPssProcesses.add(app); 17627 } 17628 } 17629 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17630 } 17631 17632 public void setTestPssMode(boolean enabled) { 17633 synchronized (this) { 17634 mTestPssMode = enabled; 17635 if (enabled) { 17636 // Whenever we enable the mode, we want to take a snapshot all of current 17637 // process mem use. 17638 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17639 } 17640 } 17641 } 17642 17643 /** 17644 * Ask a given process to GC right now. 17645 */ 17646 final void performAppGcLocked(ProcessRecord app) { 17647 try { 17648 app.lastRequestedGc = SystemClock.uptimeMillis(); 17649 if (app.thread != null) { 17650 if (app.reportLowMemory) { 17651 app.reportLowMemory = false; 17652 app.thread.scheduleLowMemory(); 17653 } else { 17654 app.thread.processInBackground(); 17655 } 17656 } 17657 } catch (Exception e) { 17658 // whatever. 17659 } 17660 } 17661 17662 /** 17663 * Returns true if things are idle enough to perform GCs. 17664 */ 17665 private final boolean canGcNowLocked() { 17666 boolean processingBroadcasts = false; 17667 for (BroadcastQueue q : mBroadcastQueues) { 17668 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17669 processingBroadcasts = true; 17670 } 17671 } 17672 return !processingBroadcasts 17673 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17674 } 17675 17676 /** 17677 * Perform GCs on all processes that are waiting for it, but only 17678 * if things are idle. 17679 */ 17680 final void performAppGcsLocked() { 17681 final int N = mProcessesToGc.size(); 17682 if (N <= 0) { 17683 return; 17684 } 17685 if (canGcNowLocked()) { 17686 while (mProcessesToGc.size() > 0) { 17687 ProcessRecord proc = mProcessesToGc.remove(0); 17688 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17689 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17690 <= SystemClock.uptimeMillis()) { 17691 // To avoid spamming the system, we will GC processes one 17692 // at a time, waiting a few seconds between each. 17693 performAppGcLocked(proc); 17694 scheduleAppGcsLocked(); 17695 return; 17696 } else { 17697 // It hasn't been long enough since we last GCed this 17698 // process... put it in the list to wait for its time. 17699 addProcessToGcListLocked(proc); 17700 break; 17701 } 17702 } 17703 } 17704 17705 scheduleAppGcsLocked(); 17706 } 17707 } 17708 17709 /** 17710 * If all looks good, perform GCs on all processes waiting for them. 17711 */ 17712 final void performAppGcsIfAppropriateLocked() { 17713 if (canGcNowLocked()) { 17714 performAppGcsLocked(); 17715 return; 17716 } 17717 // Still not idle, wait some more. 17718 scheduleAppGcsLocked(); 17719 } 17720 17721 /** 17722 * Schedule the execution of all pending app GCs. 17723 */ 17724 final void scheduleAppGcsLocked() { 17725 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17726 17727 if (mProcessesToGc.size() > 0) { 17728 // Schedule a GC for the time to the next process. 17729 ProcessRecord proc = mProcessesToGc.get(0); 17730 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17731 17732 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17733 long now = SystemClock.uptimeMillis(); 17734 if (when < (now+GC_TIMEOUT)) { 17735 when = now + GC_TIMEOUT; 17736 } 17737 mHandler.sendMessageAtTime(msg, when); 17738 } 17739 } 17740 17741 /** 17742 * Add a process to the array of processes waiting to be GCed. Keeps the 17743 * list in sorted order by the last GC time. The process can't already be 17744 * on the list. 17745 */ 17746 final void addProcessToGcListLocked(ProcessRecord proc) { 17747 boolean added = false; 17748 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17749 if (mProcessesToGc.get(i).lastRequestedGc < 17750 proc.lastRequestedGc) { 17751 added = true; 17752 mProcessesToGc.add(i+1, proc); 17753 break; 17754 } 17755 } 17756 if (!added) { 17757 mProcessesToGc.add(0, proc); 17758 } 17759 } 17760 17761 /** 17762 * Set up to ask a process to GC itself. This will either do it 17763 * immediately, or put it on the list of processes to gc the next 17764 * time things are idle. 17765 */ 17766 final void scheduleAppGcLocked(ProcessRecord app) { 17767 long now = SystemClock.uptimeMillis(); 17768 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17769 return; 17770 } 17771 if (!mProcessesToGc.contains(app)) { 17772 addProcessToGcListLocked(app); 17773 scheduleAppGcsLocked(); 17774 } 17775 } 17776 17777 final void checkExcessivePowerUsageLocked(boolean doKills) { 17778 updateCpuStatsNow(); 17779 17780 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17781 boolean doWakeKills = doKills; 17782 boolean doCpuKills = doKills; 17783 if (mLastPowerCheckRealtime == 0) { 17784 doWakeKills = false; 17785 } 17786 if (mLastPowerCheckUptime == 0) { 17787 doCpuKills = false; 17788 } 17789 if (stats.isScreenOn()) { 17790 doWakeKills = false; 17791 } 17792 final long curRealtime = SystemClock.elapsedRealtime(); 17793 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17794 final long curUptime = SystemClock.uptimeMillis(); 17795 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17796 mLastPowerCheckRealtime = curRealtime; 17797 mLastPowerCheckUptime = curUptime; 17798 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17799 doWakeKills = false; 17800 } 17801 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17802 doCpuKills = false; 17803 } 17804 int i = mLruProcesses.size(); 17805 while (i > 0) { 17806 i--; 17807 ProcessRecord app = mLruProcesses.get(i); 17808 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17809 long wtime; 17810 synchronized (stats) { 17811 wtime = stats.getProcessWakeTime(app.info.uid, 17812 app.pid, curRealtime); 17813 } 17814 long wtimeUsed = wtime - app.lastWakeTime; 17815 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17816 if (DEBUG_POWER) { 17817 StringBuilder sb = new StringBuilder(128); 17818 sb.append("Wake for "); 17819 app.toShortString(sb); 17820 sb.append(": over "); 17821 TimeUtils.formatDuration(realtimeSince, sb); 17822 sb.append(" used "); 17823 TimeUtils.formatDuration(wtimeUsed, sb); 17824 sb.append(" ("); 17825 sb.append((wtimeUsed*100)/realtimeSince); 17826 sb.append("%)"); 17827 Slog.i(TAG, sb.toString()); 17828 sb.setLength(0); 17829 sb.append("CPU for "); 17830 app.toShortString(sb); 17831 sb.append(": over "); 17832 TimeUtils.formatDuration(uptimeSince, sb); 17833 sb.append(" used "); 17834 TimeUtils.formatDuration(cputimeUsed, sb); 17835 sb.append(" ("); 17836 sb.append((cputimeUsed*100)/uptimeSince); 17837 sb.append("%)"); 17838 Slog.i(TAG, sb.toString()); 17839 } 17840 // If a process has held a wake lock for more 17841 // than 50% of the time during this period, 17842 // that sounds bad. Kill! 17843 if (doWakeKills && realtimeSince > 0 17844 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17845 synchronized (stats) { 17846 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17847 realtimeSince, wtimeUsed); 17848 } 17849 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17850 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17851 } else if (doCpuKills && uptimeSince > 0 17852 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17853 synchronized (stats) { 17854 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17855 uptimeSince, cputimeUsed); 17856 } 17857 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17858 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17859 } else { 17860 app.lastWakeTime = wtime; 17861 app.lastCpuTime = app.curCpuTime; 17862 } 17863 } 17864 } 17865 } 17866 17867 private final boolean applyOomAdjLocked(ProcessRecord app, 17868 ProcessRecord TOP_APP, boolean doingAll, long now) { 17869 boolean success = true; 17870 17871 if (app.curRawAdj != app.setRawAdj) { 17872 app.setRawAdj = app.curRawAdj; 17873 } 17874 17875 int changes = 0; 17876 17877 if (app.curAdj != app.setAdj) { 17878 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17879 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17880 TAG, "Set " + app.pid + " " + app.processName + 17881 " adj " + app.curAdj + ": " + app.adjType); 17882 app.setAdj = app.curAdj; 17883 } 17884 17885 if (app.setSchedGroup != app.curSchedGroup) { 17886 app.setSchedGroup = app.curSchedGroup; 17887 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17888 "Setting process group of " + app.processName 17889 + " to " + app.curSchedGroup); 17890 if (app.waitingToKill != null && 17891 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17892 app.kill(app.waitingToKill, true); 17893 success = false; 17894 } else { 17895 if (true) { 17896 long oldId = Binder.clearCallingIdentity(); 17897 try { 17898 Process.setProcessGroup(app.pid, app.curSchedGroup); 17899 } catch (Exception e) { 17900 Slog.w(TAG, "Failed setting process group of " + app.pid 17901 + " to " + app.curSchedGroup); 17902 e.printStackTrace(); 17903 } finally { 17904 Binder.restoreCallingIdentity(oldId); 17905 } 17906 } else { 17907 if (app.thread != null) { 17908 try { 17909 app.thread.setSchedulingGroup(app.curSchedGroup); 17910 } catch (RemoteException e) { 17911 } 17912 } 17913 } 17914 Process.setSwappiness(app.pid, 17915 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17916 } 17917 } 17918 if (app.repForegroundActivities != app.foregroundActivities) { 17919 app.repForegroundActivities = app.foregroundActivities; 17920 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17921 } 17922 if (app.repProcState != app.curProcState) { 17923 app.repProcState = app.curProcState; 17924 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17925 if (app.thread != null) { 17926 try { 17927 if (false) { 17928 //RuntimeException h = new RuntimeException("here"); 17929 Slog.i(TAG, "Sending new process state " + app.repProcState 17930 + " to " + app /*, h*/); 17931 } 17932 app.thread.setProcessState(app.repProcState); 17933 } catch (RemoteException e) { 17934 } 17935 } 17936 } 17937 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17938 app.setProcState)) { 17939 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17940 // Experimental code to more aggressively collect pss while 17941 // running test... the problem is that this tends to collect 17942 // the data right when a process is transitioning between process 17943 // states, which well tend to give noisy data. 17944 long start = SystemClock.uptimeMillis(); 17945 long pss = Debug.getPss(app.pid, mTmpLong, null); 17946 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17947 mPendingPssProcesses.remove(app); 17948 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17949 + " to " + app.curProcState + ": " 17950 + (SystemClock.uptimeMillis()-start) + "ms"); 17951 } 17952 app.lastStateTime = now; 17953 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17954 mTestPssMode, isSleeping(), now); 17955 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17956 + ProcessList.makeProcStateString(app.setProcState) + " to " 17957 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17958 + (app.nextPssTime-now) + ": " + app); 17959 } else { 17960 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17961 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17962 mTestPssMode)))) { 17963 requestPssLocked(app, app.setProcState); 17964 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17965 mTestPssMode, isSleeping(), now); 17966 } else if (false && DEBUG_PSS) { 17967 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17968 } 17969 } 17970 if (app.setProcState != app.curProcState) { 17971 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17972 "Proc state change of " + app.processName 17973 + " to " + app.curProcState); 17974 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17975 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17976 if (setImportant && !curImportant) { 17977 // This app is no longer something we consider important enough to allow to 17978 // use arbitrary amounts of battery power. Note 17979 // its current wake lock time to later know to kill it if 17980 // it is not behaving well. 17981 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17982 synchronized (stats) { 17983 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17984 app.pid, SystemClock.elapsedRealtime()); 17985 } 17986 app.lastCpuTime = app.curCpuTime; 17987 17988 } 17989 app.setProcState = app.curProcState; 17990 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17991 app.notCachedSinceIdle = false; 17992 } 17993 if (!doingAll) { 17994 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17995 } else { 17996 app.procStateChanged = true; 17997 } 17998 } 17999 18000 if (changes != 0) { 18001 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 18002 int i = mPendingProcessChanges.size()-1; 18003 ProcessChangeItem item = null; 18004 while (i >= 0) { 18005 item = mPendingProcessChanges.get(i); 18006 if (item.pid == app.pid) { 18007 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18008 break; 18009 } 18010 i--; 18011 } 18012 if (i < 0) { 18013 // No existing item in pending changes; need a new one. 18014 final int NA = mAvailProcessChanges.size(); 18015 if (NA > 0) { 18016 item = mAvailProcessChanges.remove(NA-1); 18017 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18018 } else { 18019 item = new ProcessChangeItem(); 18020 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18021 } 18022 item.changes = 0; 18023 item.pid = app.pid; 18024 item.uid = app.info.uid; 18025 if (mPendingProcessChanges.size() == 0) { 18026 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18027 "*** Enqueueing dispatch processes changed!"); 18028 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18029 } 18030 mPendingProcessChanges.add(item); 18031 } 18032 item.changes |= changes; 18033 item.processState = app.repProcState; 18034 item.foregroundActivities = app.repForegroundActivities; 18035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18036 + Integer.toHexString(System.identityHashCode(item)) 18037 + " " + app.toShortString() + ": changes=" + item.changes 18038 + " procState=" + item.processState 18039 + " foreground=" + item.foregroundActivities 18040 + " type=" + app.adjType + " source=" + app.adjSource 18041 + " target=" + app.adjTarget); 18042 } 18043 18044 return success; 18045 } 18046 18047 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18048 if (proc.thread != null) { 18049 if (proc.baseProcessTracker != null) { 18050 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18051 } 18052 if (proc.repProcState >= 0) { 18053 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18054 proc.repProcState); 18055 } 18056 } 18057 } 18058 18059 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18060 ProcessRecord TOP_APP, boolean doingAll, long now) { 18061 if (app.thread == null) { 18062 return false; 18063 } 18064 18065 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18066 18067 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18068 } 18069 18070 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18071 boolean oomAdj) { 18072 if (isForeground != proc.foregroundServices) { 18073 proc.foregroundServices = isForeground; 18074 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18075 proc.info.uid); 18076 if (isForeground) { 18077 if (curProcs == null) { 18078 curProcs = new ArrayList<ProcessRecord>(); 18079 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18080 } 18081 if (!curProcs.contains(proc)) { 18082 curProcs.add(proc); 18083 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18084 proc.info.packageName, proc.info.uid); 18085 } 18086 } else { 18087 if (curProcs != null) { 18088 if (curProcs.remove(proc)) { 18089 mBatteryStatsService.noteEvent( 18090 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18091 proc.info.packageName, proc.info.uid); 18092 if (curProcs.size() <= 0) { 18093 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18094 } 18095 } 18096 } 18097 } 18098 if (oomAdj) { 18099 updateOomAdjLocked(); 18100 } 18101 } 18102 } 18103 18104 private final ActivityRecord resumedAppLocked() { 18105 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18106 String pkg; 18107 int uid; 18108 if (act != null) { 18109 pkg = act.packageName; 18110 uid = act.info.applicationInfo.uid; 18111 } else { 18112 pkg = null; 18113 uid = -1; 18114 } 18115 // Has the UID or resumed package name changed? 18116 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18117 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18118 if (mCurResumedPackage != null) { 18119 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18120 mCurResumedPackage, mCurResumedUid); 18121 } 18122 mCurResumedPackage = pkg; 18123 mCurResumedUid = uid; 18124 if (mCurResumedPackage != null) { 18125 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18126 mCurResumedPackage, mCurResumedUid); 18127 } 18128 } 18129 return act; 18130 } 18131 18132 final boolean updateOomAdjLocked(ProcessRecord app) { 18133 final ActivityRecord TOP_ACT = resumedAppLocked(); 18134 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18135 final boolean wasCached = app.cached; 18136 18137 mAdjSeq++; 18138 18139 // This is the desired cached adjusment we want to tell it to use. 18140 // If our app is currently cached, we know it, and that is it. Otherwise, 18141 // we don't know it yet, and it needs to now be cached we will then 18142 // need to do a complete oom adj. 18143 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18144 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18145 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18146 SystemClock.uptimeMillis()); 18147 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18148 // Changed to/from cached state, so apps after it in the LRU 18149 // list may also be changed. 18150 updateOomAdjLocked(); 18151 } 18152 return success; 18153 } 18154 18155 final void updateOomAdjLocked() { 18156 final ActivityRecord TOP_ACT = resumedAppLocked(); 18157 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18158 final long now = SystemClock.uptimeMillis(); 18159 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18160 final int N = mLruProcesses.size(); 18161 18162 if (false) { 18163 RuntimeException e = new RuntimeException(); 18164 e.fillInStackTrace(); 18165 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18166 } 18167 18168 mAdjSeq++; 18169 mNewNumServiceProcs = 0; 18170 mNewNumAServiceProcs = 0; 18171 18172 final int emptyProcessLimit; 18173 final int cachedProcessLimit; 18174 if (mProcessLimit <= 0) { 18175 emptyProcessLimit = cachedProcessLimit = 0; 18176 } else if (mProcessLimit == 1) { 18177 emptyProcessLimit = 1; 18178 cachedProcessLimit = 0; 18179 } else { 18180 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18181 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18182 } 18183 18184 // Let's determine how many processes we have running vs. 18185 // how many slots we have for background processes; we may want 18186 // to put multiple processes in a slot of there are enough of 18187 // them. 18188 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18189 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18190 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18191 if (numEmptyProcs > cachedProcessLimit) { 18192 // If there are more empty processes than our limit on cached 18193 // processes, then use the cached process limit for the factor. 18194 // This ensures that the really old empty processes get pushed 18195 // down to the bottom, so if we are running low on memory we will 18196 // have a better chance at keeping around more cached processes 18197 // instead of a gazillion empty processes. 18198 numEmptyProcs = cachedProcessLimit; 18199 } 18200 int emptyFactor = numEmptyProcs/numSlots; 18201 if (emptyFactor < 1) emptyFactor = 1; 18202 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18203 if (cachedFactor < 1) cachedFactor = 1; 18204 int stepCached = 0; 18205 int stepEmpty = 0; 18206 int numCached = 0; 18207 int numEmpty = 0; 18208 int numTrimming = 0; 18209 18210 mNumNonCachedProcs = 0; 18211 mNumCachedHiddenProcs = 0; 18212 18213 // First update the OOM adjustment for each of the 18214 // application processes based on their current state. 18215 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18216 int nextCachedAdj = curCachedAdj+1; 18217 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18218 int nextEmptyAdj = curEmptyAdj+2; 18219 for (int i=N-1; i>=0; i--) { 18220 ProcessRecord app = mLruProcesses.get(i); 18221 if (!app.killedByAm && app.thread != null) { 18222 app.procStateChanged = false; 18223 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18224 18225 // If we haven't yet assigned the final cached adj 18226 // to the process, do that now. 18227 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18228 switch (app.curProcState) { 18229 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18230 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18231 // This process is a cached process holding activities... 18232 // assign it the next cached value for that type, and then 18233 // step that cached level. 18234 app.curRawAdj = curCachedAdj; 18235 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18236 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18237 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18238 + ")"); 18239 if (curCachedAdj != nextCachedAdj) { 18240 stepCached++; 18241 if (stepCached >= cachedFactor) { 18242 stepCached = 0; 18243 curCachedAdj = nextCachedAdj; 18244 nextCachedAdj += 2; 18245 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18246 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18247 } 18248 } 18249 } 18250 break; 18251 default: 18252 // For everything else, assign next empty cached process 18253 // level and bump that up. Note that this means that 18254 // long-running services that have dropped down to the 18255 // cached level will be treated as empty (since their process 18256 // state is still as a service), which is what we want. 18257 app.curRawAdj = curEmptyAdj; 18258 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18259 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18260 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18261 + ")"); 18262 if (curEmptyAdj != nextEmptyAdj) { 18263 stepEmpty++; 18264 if (stepEmpty >= emptyFactor) { 18265 stepEmpty = 0; 18266 curEmptyAdj = nextEmptyAdj; 18267 nextEmptyAdj += 2; 18268 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18269 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18270 } 18271 } 18272 } 18273 break; 18274 } 18275 } 18276 18277 applyOomAdjLocked(app, TOP_APP, true, now); 18278 18279 // Count the number of process types. 18280 switch (app.curProcState) { 18281 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18282 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18283 mNumCachedHiddenProcs++; 18284 numCached++; 18285 if (numCached > cachedProcessLimit) { 18286 app.kill("cached #" + numCached, true); 18287 } 18288 break; 18289 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18290 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18291 && app.lastActivityTime < oldTime) { 18292 app.kill("empty for " 18293 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18294 / 1000) + "s", true); 18295 } else { 18296 numEmpty++; 18297 if (numEmpty > emptyProcessLimit) { 18298 app.kill("empty #" + numEmpty, true); 18299 } 18300 } 18301 break; 18302 default: 18303 mNumNonCachedProcs++; 18304 break; 18305 } 18306 18307 if (app.isolated && app.services.size() <= 0) { 18308 // If this is an isolated process, and there are no 18309 // services running in it, then the process is no longer 18310 // needed. We agressively kill these because we can by 18311 // definition not re-use the same process again, and it is 18312 // good to avoid having whatever code was running in them 18313 // left sitting around after no longer needed. 18314 app.kill("isolated not needed", true); 18315 } 18316 18317 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18318 && !app.killedByAm) { 18319 numTrimming++; 18320 } 18321 } 18322 } 18323 18324 mNumServiceProcs = mNewNumServiceProcs; 18325 18326 // Now determine the memory trimming level of background processes. 18327 // Unfortunately we need to start at the back of the list to do this 18328 // properly. We only do this if the number of background apps we 18329 // are managing to keep around is less than half the maximum we desire; 18330 // if we are keeping a good number around, we'll let them use whatever 18331 // memory they want. 18332 final int numCachedAndEmpty = numCached + numEmpty; 18333 int memFactor; 18334 if (numCached <= ProcessList.TRIM_CACHED_APPS 18335 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18336 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18337 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18338 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18339 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18340 } else { 18341 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18342 } 18343 } else { 18344 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18345 } 18346 // We always allow the memory level to go up (better). We only allow it to go 18347 // down if we are in a state where that is allowed, *and* the total number of processes 18348 // has gone down since last time. 18349 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18350 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18351 + " last=" + mLastNumProcesses); 18352 if (memFactor > mLastMemoryLevel) { 18353 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18354 memFactor = mLastMemoryLevel; 18355 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18356 } 18357 } 18358 mLastMemoryLevel = memFactor; 18359 mLastNumProcesses = mLruProcesses.size(); 18360 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18361 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18362 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18363 if (mLowRamStartTime == 0) { 18364 mLowRamStartTime = now; 18365 } 18366 int step = 0; 18367 int fgTrimLevel; 18368 switch (memFactor) { 18369 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18370 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18371 break; 18372 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18373 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18374 break; 18375 default: 18376 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18377 break; 18378 } 18379 int factor = numTrimming/3; 18380 int minFactor = 2; 18381 if (mHomeProcess != null) minFactor++; 18382 if (mPreviousProcess != null) minFactor++; 18383 if (factor < minFactor) factor = minFactor; 18384 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18385 for (int i=N-1; i>=0; i--) { 18386 ProcessRecord app = mLruProcesses.get(i); 18387 if (allChanged || app.procStateChanged) { 18388 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18389 app.procStateChanged = false; 18390 } 18391 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18392 && !app.killedByAm) { 18393 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18394 try { 18395 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18396 "Trimming memory of " + app.processName 18397 + " to " + curLevel); 18398 app.thread.scheduleTrimMemory(curLevel); 18399 } catch (RemoteException e) { 18400 } 18401 if (false) { 18402 // For now we won't do this; our memory trimming seems 18403 // to be good enough at this point that destroying 18404 // activities causes more harm than good. 18405 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18406 && app != mHomeProcess && app != mPreviousProcess) { 18407 // Need to do this on its own message because the stack may not 18408 // be in a consistent state at this point. 18409 // For these apps we will also finish their activities 18410 // to help them free memory. 18411 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18412 } 18413 } 18414 } 18415 app.trimMemoryLevel = curLevel; 18416 step++; 18417 if (step >= factor) { 18418 step = 0; 18419 switch (curLevel) { 18420 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18421 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18422 break; 18423 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18424 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18425 break; 18426 } 18427 } 18428 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18429 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18430 && app.thread != null) { 18431 try { 18432 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18433 "Trimming memory of heavy-weight " + app.processName 18434 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18435 app.thread.scheduleTrimMemory( 18436 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18437 } catch (RemoteException e) { 18438 } 18439 } 18440 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18441 } else { 18442 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18443 || app.systemNoUi) && app.pendingUiClean) { 18444 // If this application is now in the background and it 18445 // had done UI, then give it the special trim level to 18446 // have it free UI resources. 18447 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18448 if (app.trimMemoryLevel < level && app.thread != null) { 18449 try { 18450 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18451 "Trimming memory of bg-ui " + app.processName 18452 + " to " + level); 18453 app.thread.scheduleTrimMemory(level); 18454 } catch (RemoteException e) { 18455 } 18456 } 18457 app.pendingUiClean = false; 18458 } 18459 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18460 try { 18461 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18462 "Trimming memory of fg " + app.processName 18463 + " to " + fgTrimLevel); 18464 app.thread.scheduleTrimMemory(fgTrimLevel); 18465 } catch (RemoteException e) { 18466 } 18467 } 18468 app.trimMemoryLevel = fgTrimLevel; 18469 } 18470 } 18471 } else { 18472 if (mLowRamStartTime != 0) { 18473 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18474 mLowRamStartTime = 0; 18475 } 18476 for (int i=N-1; i>=0; i--) { 18477 ProcessRecord app = mLruProcesses.get(i); 18478 if (allChanged || app.procStateChanged) { 18479 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18480 app.procStateChanged = false; 18481 } 18482 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18483 || app.systemNoUi) && app.pendingUiClean) { 18484 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18485 && app.thread != null) { 18486 try { 18487 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18488 "Trimming memory of ui hidden " + app.processName 18489 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18490 app.thread.scheduleTrimMemory( 18491 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18492 } catch (RemoteException e) { 18493 } 18494 } 18495 app.pendingUiClean = false; 18496 } 18497 app.trimMemoryLevel = 0; 18498 } 18499 } 18500 18501 if (mAlwaysFinishActivities) { 18502 // Need to do this on its own message because the stack may not 18503 // be in a consistent state at this point. 18504 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18505 } 18506 18507 if (allChanged) { 18508 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18509 } 18510 18511 if (mProcessStats.shouldWriteNowLocked(now)) { 18512 mHandler.post(new Runnable() { 18513 @Override public void run() { 18514 synchronized (ActivityManagerService.this) { 18515 mProcessStats.writeStateAsyncLocked(); 18516 } 18517 } 18518 }); 18519 } 18520 18521 if (DEBUG_OOM_ADJ) { 18522 if (false) { 18523 RuntimeException here = new RuntimeException("here"); 18524 here.fillInStackTrace(); 18525 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18526 } else { 18527 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18528 } 18529 } 18530 } 18531 18532 final void trimApplications() { 18533 synchronized (this) { 18534 int i; 18535 18536 // First remove any unused application processes whose package 18537 // has been removed. 18538 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18539 final ProcessRecord app = mRemovedProcesses.get(i); 18540 if (app.activities.size() == 0 18541 && app.curReceiver == null && app.services.size() == 0) { 18542 Slog.i( 18543 TAG, "Exiting empty application process " 18544 + app.processName + " (" 18545 + (app.thread != null ? app.thread.asBinder() : null) 18546 + ")\n"); 18547 if (app.pid > 0 && app.pid != MY_PID) { 18548 app.kill("empty", false); 18549 } else { 18550 try { 18551 app.thread.scheduleExit(); 18552 } catch (Exception e) { 18553 // Ignore exceptions. 18554 } 18555 } 18556 cleanUpApplicationRecordLocked(app, false, true, -1); 18557 mRemovedProcesses.remove(i); 18558 18559 if (app.persistent) { 18560 addAppLocked(app.info, false, null /* ABI override */); 18561 } 18562 } 18563 } 18564 18565 // Now update the oom adj for all processes. 18566 updateOomAdjLocked(); 18567 } 18568 } 18569 18570 /** This method sends the specified signal to each of the persistent apps */ 18571 public void signalPersistentProcesses(int sig) throws RemoteException { 18572 if (sig != Process.SIGNAL_USR1) { 18573 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18574 } 18575 18576 synchronized (this) { 18577 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18578 != PackageManager.PERMISSION_GRANTED) { 18579 throw new SecurityException("Requires permission " 18580 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18581 } 18582 18583 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18584 ProcessRecord r = mLruProcesses.get(i); 18585 if (r.thread != null && r.persistent) { 18586 Process.sendSignal(r.pid, sig); 18587 } 18588 } 18589 } 18590 } 18591 18592 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18593 if (proc == null || proc == mProfileProc) { 18594 proc = mProfileProc; 18595 profileType = mProfileType; 18596 clearProfilerLocked(); 18597 } 18598 if (proc == null) { 18599 return; 18600 } 18601 try { 18602 proc.thread.profilerControl(false, null, profileType); 18603 } catch (RemoteException e) { 18604 throw new IllegalStateException("Process disappeared"); 18605 } 18606 } 18607 18608 private void clearProfilerLocked() { 18609 if (mProfileFd != null) { 18610 try { 18611 mProfileFd.close(); 18612 } catch (IOException e) { 18613 } 18614 } 18615 mProfileApp = null; 18616 mProfileProc = null; 18617 mProfileFile = null; 18618 mProfileType = 0; 18619 mAutoStopProfiler = false; 18620 mSamplingInterval = 0; 18621 } 18622 18623 public boolean profileControl(String process, int userId, boolean start, 18624 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18625 18626 try { 18627 synchronized (this) { 18628 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18629 // its own permission. 18630 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18631 != PackageManager.PERMISSION_GRANTED) { 18632 throw new SecurityException("Requires permission " 18633 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18634 } 18635 18636 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18637 throw new IllegalArgumentException("null profile info or fd"); 18638 } 18639 18640 ProcessRecord proc = null; 18641 if (process != null) { 18642 proc = findProcessLocked(process, userId, "profileControl"); 18643 } 18644 18645 if (start && (proc == null || proc.thread == null)) { 18646 throw new IllegalArgumentException("Unknown process: " + process); 18647 } 18648 18649 if (start) { 18650 stopProfilerLocked(null, 0); 18651 setProfileApp(proc.info, proc.processName, profilerInfo); 18652 mProfileProc = proc; 18653 mProfileType = profileType; 18654 ParcelFileDescriptor fd = profilerInfo.profileFd; 18655 try { 18656 fd = fd.dup(); 18657 } catch (IOException e) { 18658 fd = null; 18659 } 18660 profilerInfo.profileFd = fd; 18661 proc.thread.profilerControl(start, profilerInfo, profileType); 18662 fd = null; 18663 mProfileFd = null; 18664 } else { 18665 stopProfilerLocked(proc, profileType); 18666 if (profilerInfo != null && profilerInfo.profileFd != null) { 18667 try { 18668 profilerInfo.profileFd.close(); 18669 } catch (IOException e) { 18670 } 18671 } 18672 } 18673 18674 return true; 18675 } 18676 } catch (RemoteException e) { 18677 throw new IllegalStateException("Process disappeared"); 18678 } finally { 18679 if (profilerInfo != null && profilerInfo.profileFd != null) { 18680 try { 18681 profilerInfo.profileFd.close(); 18682 } catch (IOException e) { 18683 } 18684 } 18685 } 18686 } 18687 18688 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18689 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18690 userId, true, ALLOW_FULL_ONLY, callName, null); 18691 ProcessRecord proc = null; 18692 try { 18693 int pid = Integer.parseInt(process); 18694 synchronized (mPidsSelfLocked) { 18695 proc = mPidsSelfLocked.get(pid); 18696 } 18697 } catch (NumberFormatException e) { 18698 } 18699 18700 if (proc == null) { 18701 ArrayMap<String, SparseArray<ProcessRecord>> all 18702 = mProcessNames.getMap(); 18703 SparseArray<ProcessRecord> procs = all.get(process); 18704 if (procs != null && procs.size() > 0) { 18705 proc = procs.valueAt(0); 18706 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18707 for (int i=1; i<procs.size(); i++) { 18708 ProcessRecord thisProc = procs.valueAt(i); 18709 if (thisProc.userId == userId) { 18710 proc = thisProc; 18711 break; 18712 } 18713 } 18714 } 18715 } 18716 } 18717 18718 return proc; 18719 } 18720 18721 public boolean dumpHeap(String process, int userId, boolean managed, 18722 String path, ParcelFileDescriptor fd) throws RemoteException { 18723 18724 try { 18725 synchronized (this) { 18726 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18727 // its own permission (same as profileControl). 18728 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18729 != PackageManager.PERMISSION_GRANTED) { 18730 throw new SecurityException("Requires permission " 18731 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18732 } 18733 18734 if (fd == null) { 18735 throw new IllegalArgumentException("null fd"); 18736 } 18737 18738 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18739 if (proc == null || proc.thread == null) { 18740 throw new IllegalArgumentException("Unknown process: " + process); 18741 } 18742 18743 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18744 if (!isDebuggable) { 18745 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18746 throw new SecurityException("Process not debuggable: " + proc); 18747 } 18748 } 18749 18750 proc.thread.dumpHeap(managed, path, fd); 18751 fd = null; 18752 return true; 18753 } 18754 } catch (RemoteException e) { 18755 throw new IllegalStateException("Process disappeared"); 18756 } finally { 18757 if (fd != null) { 18758 try { 18759 fd.close(); 18760 } catch (IOException e) { 18761 } 18762 } 18763 } 18764 } 18765 18766 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18767 public void monitor() { 18768 synchronized (this) { } 18769 } 18770 18771 void onCoreSettingsChange(Bundle settings) { 18772 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18773 ProcessRecord processRecord = mLruProcesses.get(i); 18774 try { 18775 if (processRecord.thread != null) { 18776 processRecord.thread.setCoreSettings(settings); 18777 } 18778 } catch (RemoteException re) { 18779 /* ignore */ 18780 } 18781 } 18782 } 18783 18784 // Multi-user methods 18785 18786 /** 18787 * Start user, if its not already running, but don't bring it to foreground. 18788 */ 18789 @Override 18790 public boolean startUserInBackground(final int userId) { 18791 return startUser(userId, /* foreground */ false); 18792 } 18793 18794 /** 18795 * Start user, if its not already running, and bring it to foreground. 18796 */ 18797 boolean startUserInForeground(final int userId, Dialog dlg) { 18798 boolean result = startUser(userId, /* foreground */ true); 18799 dlg.dismiss(); 18800 return result; 18801 } 18802 18803 /** 18804 * Refreshes the list of users related to the current user when either a 18805 * user switch happens or when a new related user is started in the 18806 * background. 18807 */ 18808 private void updateCurrentProfileIdsLocked() { 18809 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18810 mCurrentUserId, false /* enabledOnly */); 18811 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18812 for (int i = 0; i < currentProfileIds.length; i++) { 18813 currentProfileIds[i] = profiles.get(i).id; 18814 } 18815 mCurrentProfileIds = currentProfileIds; 18816 18817 synchronized (mUserProfileGroupIdsSelfLocked) { 18818 mUserProfileGroupIdsSelfLocked.clear(); 18819 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18820 for (int i = 0; i < users.size(); i++) { 18821 UserInfo user = users.get(i); 18822 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18823 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18824 } 18825 } 18826 } 18827 } 18828 18829 private Set getProfileIdsLocked(int userId) { 18830 Set userIds = new HashSet<Integer>(); 18831 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18832 userId, false /* enabledOnly */); 18833 for (UserInfo user : profiles) { 18834 userIds.add(Integer.valueOf(user.id)); 18835 } 18836 return userIds; 18837 } 18838 18839 @Override 18840 public boolean switchUser(final int userId) { 18841 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18842 String userName; 18843 synchronized (this) { 18844 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18845 if (userInfo == null) { 18846 Slog.w(TAG, "No user info for user #" + userId); 18847 return false; 18848 } 18849 if (userInfo.isManagedProfile()) { 18850 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18851 return false; 18852 } 18853 userName = userInfo.name; 18854 mTargetUserId = userId; 18855 } 18856 mHandler.removeMessages(START_USER_SWITCH_MSG); 18857 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18858 return true; 18859 } 18860 18861 private void showUserSwitchDialog(int userId, String userName) { 18862 // The dialog will show and then initiate the user switch by calling startUserInForeground 18863 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18864 true /* above system */); 18865 d.show(); 18866 } 18867 18868 private boolean startUser(final int userId, final boolean foreground) { 18869 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18870 != PackageManager.PERMISSION_GRANTED) { 18871 String msg = "Permission Denial: switchUser() from pid=" 18872 + Binder.getCallingPid() 18873 + ", uid=" + Binder.getCallingUid() 18874 + " requires " + INTERACT_ACROSS_USERS_FULL; 18875 Slog.w(TAG, msg); 18876 throw new SecurityException(msg); 18877 } 18878 18879 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18880 18881 final long ident = Binder.clearCallingIdentity(); 18882 try { 18883 synchronized (this) { 18884 final int oldUserId = mCurrentUserId; 18885 if (oldUserId == userId) { 18886 return true; 18887 } 18888 18889 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser"); 18890 18891 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18892 if (userInfo == null) { 18893 Slog.w(TAG, "No user info for user #" + userId); 18894 return false; 18895 } 18896 if (foreground && userInfo.isManagedProfile()) { 18897 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18898 return false; 18899 } 18900 18901 if (foreground) { 18902 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18903 R.anim.screen_user_enter); 18904 } 18905 18906 boolean needStart = false; 18907 18908 // If the user we are switching to is not currently started, then 18909 // we need to start it now. 18910 if (mStartedUsers.get(userId) == null) { 18911 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18912 updateStartedUserArrayLocked(); 18913 needStart = true; 18914 } 18915 18916 final Integer userIdInt = Integer.valueOf(userId); 18917 mUserLru.remove(userIdInt); 18918 mUserLru.add(userIdInt); 18919 18920 if (foreground) { 18921 mCurrentUserId = userId; 18922 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18923 updateCurrentProfileIdsLocked(); 18924 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18925 // Once the internal notion of the active user has switched, we lock the device 18926 // with the option to show the user switcher on the keyguard. 18927 mWindowManager.lockNow(null); 18928 } else { 18929 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18930 updateCurrentProfileIdsLocked(); 18931 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18932 mUserLru.remove(currentUserIdInt); 18933 mUserLru.add(currentUserIdInt); 18934 } 18935 18936 final UserStartedState uss = mStartedUsers.get(userId); 18937 18938 // Make sure user is in the started state. If it is currently 18939 // stopping, we need to knock that off. 18940 if (uss.mState == UserStartedState.STATE_STOPPING) { 18941 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18942 // so we can just fairly silently bring the user back from 18943 // the almost-dead. 18944 uss.mState = UserStartedState.STATE_RUNNING; 18945 updateStartedUserArrayLocked(); 18946 needStart = true; 18947 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18948 // This means ACTION_SHUTDOWN has been sent, so we will 18949 // need to treat this as a new boot of the user. 18950 uss.mState = UserStartedState.STATE_BOOTING; 18951 updateStartedUserArrayLocked(); 18952 needStart = true; 18953 } 18954 18955 if (uss.mState == UserStartedState.STATE_BOOTING) { 18956 // Booting up a new user, need to tell system services about it. 18957 // Note that this is on the same handler as scheduling of broadcasts, 18958 // which is important because it needs to go first. 18959 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18960 } 18961 18962 if (foreground) { 18963 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18964 oldUserId)); 18965 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18966 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18967 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18968 oldUserId, userId, uss)); 18969 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18970 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18971 } 18972 18973 if (needStart) { 18974 // Send USER_STARTED broadcast 18975 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18976 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18977 | Intent.FLAG_RECEIVER_FOREGROUND); 18978 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18979 broadcastIntentLocked(null, null, intent, 18980 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18981 false, false, MY_PID, Process.SYSTEM_UID, userId); 18982 } 18983 18984 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18985 if (userId != UserHandle.USER_OWNER) { 18986 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18987 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18988 broadcastIntentLocked(null, null, intent, null, 18989 new IIntentReceiver.Stub() { 18990 public void performReceive(Intent intent, int resultCode, 18991 String data, Bundle extras, boolean ordered, 18992 boolean sticky, int sendingUser) { 18993 onUserInitialized(uss, foreground, oldUserId, userId); 18994 } 18995 }, 0, null, null, null, AppOpsManager.OP_NONE, 18996 true, false, MY_PID, Process.SYSTEM_UID, 18997 userId); 18998 uss.initializing = true; 18999 } else { 19000 getUserManagerLocked().makeInitialized(userInfo.id); 19001 } 19002 } 19003 19004 if (foreground) { 19005 if (!uss.initializing) { 19006 moveUserToForeground(uss, oldUserId, userId); 19007 } 19008 } else { 19009 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19010 } 19011 19012 if (needStart) { 19013 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19014 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19015 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19016 broadcastIntentLocked(null, null, intent, 19017 null, new IIntentReceiver.Stub() { 19018 @Override 19019 public void performReceive(Intent intent, int resultCode, String data, 19020 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19021 throws RemoteException { 19022 } 19023 }, 0, null, null, 19024 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19025 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19026 } 19027 } 19028 } finally { 19029 Binder.restoreCallingIdentity(ident); 19030 } 19031 19032 return true; 19033 } 19034 19035 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19036 long ident = Binder.clearCallingIdentity(); 19037 try { 19038 Intent intent; 19039 if (oldUserId >= 0) { 19040 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19041 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19042 int count = profiles.size(); 19043 for (int i = 0; i < count; i++) { 19044 int profileUserId = profiles.get(i).id; 19045 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19046 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19047 | Intent.FLAG_RECEIVER_FOREGROUND); 19048 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19049 broadcastIntentLocked(null, null, intent, 19050 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19051 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19052 } 19053 } 19054 if (newUserId >= 0) { 19055 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19056 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19057 int count = profiles.size(); 19058 for (int i = 0; i < count; i++) { 19059 int profileUserId = profiles.get(i).id; 19060 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19061 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19062 | Intent.FLAG_RECEIVER_FOREGROUND); 19063 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19064 broadcastIntentLocked(null, null, intent, 19065 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19066 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19067 } 19068 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19069 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19070 | Intent.FLAG_RECEIVER_FOREGROUND); 19071 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19072 broadcastIntentLocked(null, null, intent, 19073 null, null, 0, null, null, 19074 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19075 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19076 } 19077 } finally { 19078 Binder.restoreCallingIdentity(ident); 19079 } 19080 } 19081 19082 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19083 final int newUserId) { 19084 final int N = mUserSwitchObservers.beginBroadcast(); 19085 if (N > 0) { 19086 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19087 int mCount = 0; 19088 @Override 19089 public void sendResult(Bundle data) throws RemoteException { 19090 synchronized (ActivityManagerService.this) { 19091 if (mCurUserSwitchCallback == this) { 19092 mCount++; 19093 if (mCount == N) { 19094 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19095 } 19096 } 19097 } 19098 } 19099 }; 19100 synchronized (this) { 19101 uss.switching = true; 19102 mCurUserSwitchCallback = callback; 19103 } 19104 for (int i=0; i<N; i++) { 19105 try { 19106 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19107 newUserId, callback); 19108 } catch (RemoteException e) { 19109 } 19110 } 19111 } else { 19112 synchronized (this) { 19113 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19114 } 19115 } 19116 mUserSwitchObservers.finishBroadcast(); 19117 } 19118 19119 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19120 synchronized (this) { 19121 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19122 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19123 } 19124 } 19125 19126 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19127 mCurUserSwitchCallback = null; 19128 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19129 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19130 oldUserId, newUserId, uss)); 19131 } 19132 19133 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19134 synchronized (this) { 19135 if (foreground) { 19136 moveUserToForeground(uss, oldUserId, newUserId); 19137 } 19138 } 19139 19140 completeSwitchAndInitalize(uss, newUserId, true, false); 19141 } 19142 19143 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19144 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19145 if (homeInFront) { 19146 startHomeActivityLocked(newUserId, "moveUserToFroreground"); 19147 } else { 19148 mStackSupervisor.resumeTopActivitiesLocked(); 19149 } 19150 EventLogTags.writeAmSwitchUser(newUserId); 19151 getUserManagerLocked().userForeground(newUserId); 19152 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19153 } 19154 19155 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19156 completeSwitchAndInitalize(uss, newUserId, false, true); 19157 } 19158 19159 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19160 boolean clearInitializing, boolean clearSwitching) { 19161 boolean unfrozen = false; 19162 synchronized (this) { 19163 if (clearInitializing) { 19164 uss.initializing = false; 19165 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19166 } 19167 if (clearSwitching) { 19168 uss.switching = false; 19169 } 19170 if (!uss.switching && !uss.initializing) { 19171 mWindowManager.stopFreezingScreen(); 19172 unfrozen = true; 19173 } 19174 } 19175 if (unfrozen) { 19176 final int N = mUserSwitchObservers.beginBroadcast(); 19177 for (int i=0; i<N; i++) { 19178 try { 19179 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19180 } catch (RemoteException e) { 19181 } 19182 } 19183 mUserSwitchObservers.finishBroadcast(); 19184 } 19185 stopGuestUserIfBackground(); 19186 } 19187 19188 /** 19189 * Stops the guest user if it has gone to the background. 19190 */ 19191 private void stopGuestUserIfBackground() { 19192 synchronized (this) { 19193 final int num = mUserLru.size(); 19194 for (int i = 0; i < num; i++) { 19195 Integer oldUserId = mUserLru.get(i); 19196 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19197 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19198 || oldUss.mState == UserStartedState.STATE_STOPPING 19199 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19200 continue; 19201 } 19202 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19203 if (userInfo.isGuest()) { 19204 // This is a user to be stopped. 19205 stopUserLocked(oldUserId, null); 19206 break; 19207 } 19208 } 19209 } 19210 } 19211 19212 void scheduleStartProfilesLocked() { 19213 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19214 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19215 DateUtils.SECOND_IN_MILLIS); 19216 } 19217 } 19218 19219 void startProfilesLocked() { 19220 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19221 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19222 mCurrentUserId, false /* enabledOnly */); 19223 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19224 for (UserInfo user : profiles) { 19225 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19226 && user.id != mCurrentUserId) { 19227 toStart.add(user); 19228 } 19229 } 19230 final int n = toStart.size(); 19231 int i = 0; 19232 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19233 startUserInBackground(toStart.get(i).id); 19234 } 19235 if (i < n) { 19236 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19237 } 19238 } 19239 19240 void finishUserBoot(UserStartedState uss) { 19241 synchronized (this) { 19242 if (uss.mState == UserStartedState.STATE_BOOTING 19243 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19244 uss.mState = UserStartedState.STATE_RUNNING; 19245 final int userId = uss.mHandle.getIdentifier(); 19246 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19247 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19248 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19249 broadcastIntentLocked(null, null, intent, 19250 null, null, 0, null, null, 19251 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19252 true, false, MY_PID, Process.SYSTEM_UID, userId); 19253 } 19254 } 19255 } 19256 19257 void finishUserSwitch(UserStartedState uss) { 19258 synchronized (this) { 19259 finishUserBoot(uss); 19260 19261 startProfilesLocked(); 19262 19263 int num = mUserLru.size(); 19264 int i = 0; 19265 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19266 Integer oldUserId = mUserLru.get(i); 19267 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19268 if (oldUss == null) { 19269 // Shouldn't happen, but be sane if it does. 19270 mUserLru.remove(i); 19271 num--; 19272 continue; 19273 } 19274 if (oldUss.mState == UserStartedState.STATE_STOPPING 19275 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19276 // This user is already stopping, doesn't count. 19277 num--; 19278 i++; 19279 continue; 19280 } 19281 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19282 // Owner and current can't be stopped, but count as running. 19283 i++; 19284 continue; 19285 } 19286 // This is a user to be stopped. 19287 stopUserLocked(oldUserId, null); 19288 num--; 19289 i++; 19290 } 19291 } 19292 } 19293 19294 @Override 19295 public int stopUser(final int userId, final IStopUserCallback callback) { 19296 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19297 != PackageManager.PERMISSION_GRANTED) { 19298 String msg = "Permission Denial: switchUser() from pid=" 19299 + Binder.getCallingPid() 19300 + ", uid=" + Binder.getCallingUid() 19301 + " requires " + INTERACT_ACROSS_USERS_FULL; 19302 Slog.w(TAG, msg); 19303 throw new SecurityException(msg); 19304 } 19305 if (userId <= 0) { 19306 throw new IllegalArgumentException("Can't stop primary user " + userId); 19307 } 19308 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19309 synchronized (this) { 19310 return stopUserLocked(userId, callback); 19311 } 19312 } 19313 19314 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19315 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19316 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19317 return ActivityManager.USER_OP_IS_CURRENT; 19318 } 19319 19320 final UserStartedState uss = mStartedUsers.get(userId); 19321 if (uss == null) { 19322 // User is not started, nothing to do... but we do need to 19323 // callback if requested. 19324 if (callback != null) { 19325 mHandler.post(new Runnable() { 19326 @Override 19327 public void run() { 19328 try { 19329 callback.userStopped(userId); 19330 } catch (RemoteException e) { 19331 } 19332 } 19333 }); 19334 } 19335 return ActivityManager.USER_OP_SUCCESS; 19336 } 19337 19338 if (callback != null) { 19339 uss.mStopCallbacks.add(callback); 19340 } 19341 19342 if (uss.mState != UserStartedState.STATE_STOPPING 19343 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19344 uss.mState = UserStartedState.STATE_STOPPING; 19345 updateStartedUserArrayLocked(); 19346 19347 long ident = Binder.clearCallingIdentity(); 19348 try { 19349 // We are going to broadcast ACTION_USER_STOPPING and then 19350 // once that is done send a final ACTION_SHUTDOWN and then 19351 // stop the user. 19352 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19353 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19354 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19355 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19356 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19357 // This is the result receiver for the final shutdown broadcast. 19358 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19359 @Override 19360 public void performReceive(Intent intent, int resultCode, String data, 19361 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19362 finishUserStop(uss); 19363 } 19364 }; 19365 // This is the result receiver for the initial stopping broadcast. 19366 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19367 @Override 19368 public void performReceive(Intent intent, int resultCode, String data, 19369 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19370 // On to the next. 19371 synchronized (ActivityManagerService.this) { 19372 if (uss.mState != UserStartedState.STATE_STOPPING) { 19373 // Whoops, we are being started back up. Abort, abort! 19374 return; 19375 } 19376 uss.mState = UserStartedState.STATE_SHUTDOWN; 19377 } 19378 mBatteryStatsService.noteEvent( 19379 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19380 Integer.toString(userId), userId); 19381 mSystemServiceManager.stopUser(userId); 19382 broadcastIntentLocked(null, null, shutdownIntent, 19383 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19384 true, false, MY_PID, Process.SYSTEM_UID, userId); 19385 } 19386 }; 19387 // Kick things off. 19388 broadcastIntentLocked(null, null, stoppingIntent, 19389 null, stoppingReceiver, 0, null, null, 19390 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19391 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19392 } finally { 19393 Binder.restoreCallingIdentity(ident); 19394 } 19395 } 19396 19397 return ActivityManager.USER_OP_SUCCESS; 19398 } 19399 19400 void finishUserStop(UserStartedState uss) { 19401 final int userId = uss.mHandle.getIdentifier(); 19402 boolean stopped; 19403 ArrayList<IStopUserCallback> callbacks; 19404 synchronized (this) { 19405 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19406 if (mStartedUsers.get(userId) != uss) { 19407 stopped = false; 19408 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19409 stopped = false; 19410 } else { 19411 stopped = true; 19412 // User can no longer run. 19413 mStartedUsers.remove(userId); 19414 mUserLru.remove(Integer.valueOf(userId)); 19415 updateStartedUserArrayLocked(); 19416 19417 // Clean up all state and processes associated with the user. 19418 // Kill all the processes for the user. 19419 forceStopUserLocked(userId, "finish user"); 19420 } 19421 19422 // Explicitly remove the old information in mRecentTasks. 19423 removeRecentTasksForUserLocked(userId); 19424 } 19425 19426 for (int i=0; i<callbacks.size(); i++) { 19427 try { 19428 if (stopped) callbacks.get(i).userStopped(userId); 19429 else callbacks.get(i).userStopAborted(userId); 19430 } catch (RemoteException e) { 19431 } 19432 } 19433 19434 if (stopped) { 19435 mSystemServiceManager.cleanupUser(userId); 19436 synchronized (this) { 19437 mStackSupervisor.removeUserLocked(userId); 19438 } 19439 } 19440 } 19441 19442 @Override 19443 public UserInfo getCurrentUser() { 19444 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19445 != PackageManager.PERMISSION_GRANTED) && ( 19446 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19447 != PackageManager.PERMISSION_GRANTED)) { 19448 String msg = "Permission Denial: getCurrentUser() from pid=" 19449 + Binder.getCallingPid() 19450 + ", uid=" + Binder.getCallingUid() 19451 + " requires " + INTERACT_ACROSS_USERS; 19452 Slog.w(TAG, msg); 19453 throw new SecurityException(msg); 19454 } 19455 synchronized (this) { 19456 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19457 return getUserManagerLocked().getUserInfo(userId); 19458 } 19459 } 19460 19461 int getCurrentUserIdLocked() { 19462 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19463 } 19464 19465 @Override 19466 public boolean isUserRunning(int userId, boolean orStopped) { 19467 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19468 != PackageManager.PERMISSION_GRANTED) { 19469 String msg = "Permission Denial: isUserRunning() from pid=" 19470 + Binder.getCallingPid() 19471 + ", uid=" + Binder.getCallingUid() 19472 + " requires " + INTERACT_ACROSS_USERS; 19473 Slog.w(TAG, msg); 19474 throw new SecurityException(msg); 19475 } 19476 synchronized (this) { 19477 return isUserRunningLocked(userId, orStopped); 19478 } 19479 } 19480 19481 boolean isUserRunningLocked(int userId, boolean orStopped) { 19482 UserStartedState state = mStartedUsers.get(userId); 19483 if (state == null) { 19484 return false; 19485 } 19486 if (orStopped) { 19487 return true; 19488 } 19489 return state.mState != UserStartedState.STATE_STOPPING 19490 && state.mState != UserStartedState.STATE_SHUTDOWN; 19491 } 19492 19493 @Override 19494 public int[] getRunningUserIds() { 19495 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19496 != PackageManager.PERMISSION_GRANTED) { 19497 String msg = "Permission Denial: isUserRunning() from pid=" 19498 + Binder.getCallingPid() 19499 + ", uid=" + Binder.getCallingUid() 19500 + " requires " + INTERACT_ACROSS_USERS; 19501 Slog.w(TAG, msg); 19502 throw new SecurityException(msg); 19503 } 19504 synchronized (this) { 19505 return mStartedUserArray; 19506 } 19507 } 19508 19509 private void updateStartedUserArrayLocked() { 19510 int num = 0; 19511 for (int i=0; i<mStartedUsers.size(); i++) { 19512 UserStartedState uss = mStartedUsers.valueAt(i); 19513 // This list does not include stopping users. 19514 if (uss.mState != UserStartedState.STATE_STOPPING 19515 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19516 num++; 19517 } 19518 } 19519 mStartedUserArray = new int[num]; 19520 num = 0; 19521 for (int i=0; i<mStartedUsers.size(); i++) { 19522 UserStartedState uss = mStartedUsers.valueAt(i); 19523 if (uss.mState != UserStartedState.STATE_STOPPING 19524 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19525 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19526 num++; 19527 } 19528 } 19529 } 19530 19531 @Override 19532 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19533 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19534 != PackageManager.PERMISSION_GRANTED) { 19535 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19536 + Binder.getCallingPid() 19537 + ", uid=" + Binder.getCallingUid() 19538 + " requires " + INTERACT_ACROSS_USERS_FULL; 19539 Slog.w(TAG, msg); 19540 throw new SecurityException(msg); 19541 } 19542 19543 mUserSwitchObservers.register(observer); 19544 } 19545 19546 @Override 19547 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19548 mUserSwitchObservers.unregister(observer); 19549 } 19550 19551 private boolean userExists(int userId) { 19552 if (userId == 0) { 19553 return true; 19554 } 19555 UserManagerService ums = getUserManagerLocked(); 19556 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19557 } 19558 19559 int[] getUsersLocked() { 19560 UserManagerService ums = getUserManagerLocked(); 19561 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19562 } 19563 19564 UserManagerService getUserManagerLocked() { 19565 if (mUserManager == null) { 19566 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19567 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19568 } 19569 return mUserManager; 19570 } 19571 19572 private int applyUserId(int uid, int userId) { 19573 return UserHandle.getUid(userId, uid); 19574 } 19575 19576 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19577 if (info == null) return null; 19578 ApplicationInfo newInfo = new ApplicationInfo(info); 19579 newInfo.uid = applyUserId(info.uid, userId); 19580 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19581 + info.packageName; 19582 return newInfo; 19583 } 19584 19585 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19586 if (aInfo == null 19587 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19588 return aInfo; 19589 } 19590 19591 ActivityInfo info = new ActivityInfo(aInfo); 19592 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19593 return info; 19594 } 19595 19596 private final class LocalService extends ActivityManagerInternal { 19597 @Override 19598 public void onWakefulnessChanged(int wakefulness) { 19599 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19600 } 19601 19602 @Override 19603 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19604 String processName, String abiOverride, int uid, Runnable crashHandler) { 19605 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19606 processName, abiOverride, uid, crashHandler); 19607 } 19608 } 19609 19610 /** 19611 * An implementation of IAppTask, that allows an app to manage its own tasks via 19612 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19613 * only the process that calls getAppTasks() can call the AppTask methods. 19614 */ 19615 class AppTaskImpl extends IAppTask.Stub { 19616 private int mTaskId; 19617 private int mCallingUid; 19618 19619 public AppTaskImpl(int taskId, int callingUid) { 19620 mTaskId = taskId; 19621 mCallingUid = callingUid; 19622 } 19623 19624 private void checkCaller() { 19625 if (mCallingUid != Binder.getCallingUid()) { 19626 throw new SecurityException("Caller " + mCallingUid 19627 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19628 } 19629 } 19630 19631 @Override 19632 public void finishAndRemoveTask() { 19633 checkCaller(); 19634 19635 synchronized (ActivityManagerService.this) { 19636 long origId = Binder.clearCallingIdentity(); 19637 try { 19638 if (!removeTaskByIdLocked(mTaskId, false)) { 19639 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19640 } 19641 } finally { 19642 Binder.restoreCallingIdentity(origId); 19643 } 19644 } 19645 } 19646 19647 @Override 19648 public ActivityManager.RecentTaskInfo getTaskInfo() { 19649 checkCaller(); 19650 19651 synchronized (ActivityManagerService.this) { 19652 long origId = Binder.clearCallingIdentity(); 19653 try { 19654 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19655 if (tr == null) { 19656 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19657 } 19658 return createRecentTaskInfoFromTaskRecord(tr); 19659 } finally { 19660 Binder.restoreCallingIdentity(origId); 19661 } 19662 } 19663 } 19664 19665 @Override 19666 public void moveToFront() { 19667 checkCaller(); 19668 // Will bring task to front if it already has a root activity. 19669 startActivityFromRecentsInner(mTaskId, null); 19670 } 19671 19672 @Override 19673 public int startActivity(IBinder whoThread, String callingPackage, 19674 Intent intent, String resolvedType, Bundle options) { 19675 checkCaller(); 19676 19677 int callingUser = UserHandle.getCallingUserId(); 19678 TaskRecord tr; 19679 IApplicationThread appThread; 19680 synchronized (ActivityManagerService.this) { 19681 tr = recentTaskForIdLocked(mTaskId); 19682 if (tr == null) { 19683 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19684 } 19685 appThread = ApplicationThreadNative.asInterface(whoThread); 19686 if (appThread == null) { 19687 throw new IllegalArgumentException("Bad app thread " + appThread); 19688 } 19689 } 19690 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19691 resolvedType, null, null, null, null, 0, 0, null, null, 19692 null, options, callingUser, null, tr); 19693 } 19694 19695 @Override 19696 public void setExcludeFromRecents(boolean exclude) { 19697 checkCaller(); 19698 19699 synchronized (ActivityManagerService.this) { 19700 long origId = Binder.clearCallingIdentity(); 19701 try { 19702 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19703 if (tr == null) { 19704 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19705 } 19706 Intent intent = tr.getBaseIntent(); 19707 if (exclude) { 19708 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19709 } else { 19710 intent.setFlags(intent.getFlags() 19711 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19712 } 19713 } finally { 19714 Binder.restoreCallingIdentity(origId); 19715 } 19716 } 19717 } 19718 } 19719} 19720