ActivityManagerService.java revision ab2df067fc9757f19061b968c53953ca90a4c384
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.setLocale(Locale.getDefault()); 2110 2111 mConfigurationSeq = mConfiguration.seq = 1; 2112 mProcessCpuTracker.init(); 2113 2114 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2115 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2116 mStackSupervisor = new ActivityStackSupervisor(this); 2117 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2118 2119 mProcessCpuThread = new Thread("CpuTracker") { 2120 @Override 2121 public void run() { 2122 while (true) { 2123 try { 2124 try { 2125 synchronized(this) { 2126 final long now = SystemClock.uptimeMillis(); 2127 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2128 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2129 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2130 // + ", write delay=" + nextWriteDelay); 2131 if (nextWriteDelay < nextCpuDelay) { 2132 nextCpuDelay = nextWriteDelay; 2133 } 2134 if (nextCpuDelay > 0) { 2135 mProcessCpuMutexFree.set(true); 2136 this.wait(nextCpuDelay); 2137 } 2138 } 2139 } catch (InterruptedException e) { 2140 } 2141 updateCpuStatsNow(); 2142 } catch (Exception e) { 2143 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2144 } 2145 } 2146 } 2147 }; 2148 2149 Watchdog.getInstance().addMonitor(this); 2150 Watchdog.getInstance().addThread(mHandler); 2151 } 2152 2153 public void setSystemServiceManager(SystemServiceManager mgr) { 2154 mSystemServiceManager = mgr; 2155 } 2156 2157 public void setInstaller(Installer installer) { 2158 mInstaller = installer; 2159 } 2160 2161 private void start() { 2162 Process.removeAllProcessGroups(); 2163 mProcessCpuThread.start(); 2164 2165 mBatteryStatsService.publish(mContext); 2166 mAppOpsService.publish(mContext); 2167 Slog.d("AppOps", "AppOpsService published"); 2168 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2169 } 2170 2171 public void initPowerManagement() { 2172 mStackSupervisor.initPowerManagement(); 2173 mBatteryStatsService.initPowerManagement(); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuTracker) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<>(); 2347 2348 // Isolated processes won't get this optimization, so that we don't 2349 // violate the rules about which services they have access to. 2350 if (!isolated) { 2351 // Setup the application init args 2352 mAppBindArgs.put("package", ServiceManager.getService("package")); 2353 mAppBindArgs.put("window", ServiceManager.getService("window")); 2354 mAppBindArgs.put(Context.ALARM_SERVICE, 2355 ServiceManager.getService(Context.ALARM_SERVICE)); 2356 } 2357 } 2358 return mAppBindArgs; 2359 } 2360 2361 final void setFocusedActivityLocked(ActivityRecord r) { 2362 if (mFocusedActivity != r) { 2363 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2364 mFocusedActivity = r; 2365 if (r.task != null && r.task.voiceInteractor != null) { 2366 startRunningVoiceLocked(); 2367 } else { 2368 finishRunningVoiceLocked(); 2369 } 2370 mStackSupervisor.setFocusedStack(r); 2371 if (r != null) { 2372 mWindowManager.setFocusedApp(r.appToken, true); 2373 } 2374 applyUpdateLockStateLocked(r); 2375 } 2376 } 2377 2378 final void clearFocusedActivity(ActivityRecord r) { 2379 if (mFocusedActivity == r) { 2380 mFocusedActivity = null; 2381 } 2382 } 2383 2384 @Override 2385 public void setFocusedStack(int stackId) { 2386 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2387 synchronized (ActivityManagerService.this) { 2388 ActivityStack stack = mStackSupervisor.getStack(stackId); 2389 if (stack != null) { 2390 ActivityRecord r = stack.topRunningActivityLocked(null); 2391 if (r != null) { 2392 setFocusedActivityLocked(r); 2393 } 2394 } 2395 } 2396 } 2397 2398 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2399 @Override 2400 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2401 synchronized (ActivityManagerService.this) { 2402 if (listener != null) { 2403 mTaskStackListeners.register(listener); 2404 } 2405 } 2406 } 2407 2408 @Override 2409 public void notifyActivityDrawn(IBinder token) { 2410 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2411 synchronized (this) { 2412 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2413 if (r != null) { 2414 r.task.stack.notifyActivityDrawnLocked(r); 2415 } 2416 } 2417 } 2418 2419 final void applyUpdateLockStateLocked(ActivityRecord r) { 2420 // Modifications to the UpdateLock state are done on our handler, outside 2421 // the activity manager's locks. The new state is determined based on the 2422 // state *now* of the relevant activity record. The object is passed to 2423 // the handler solely for logging detail, not to be consulted/modified. 2424 final boolean nextState = r != null && r.immersive; 2425 mHandler.sendMessage( 2426 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2427 } 2428 2429 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2430 Message msg = Message.obtain(); 2431 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2432 msg.obj = r.task.askedCompatMode ? null : r; 2433 mHandler.sendMessage(msg); 2434 } 2435 2436 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2437 String what, Object obj, ProcessRecord srcApp) { 2438 app.lastActivityTime = now; 2439 2440 if (app.activities.size() > 0) { 2441 // Don't want to touch dependent processes that are hosting activities. 2442 return index; 2443 } 2444 2445 int lrui = mLruProcesses.lastIndexOf(app); 2446 if (lrui < 0) { 2447 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2448 + what + " " + obj + " from " + srcApp); 2449 return index; 2450 } 2451 2452 if (lrui >= index) { 2453 // Don't want to cause this to move dependent processes *back* in the 2454 // list as if they were less frequently used. 2455 return index; 2456 } 2457 2458 if (lrui >= mLruProcessActivityStart) { 2459 // Don't want to touch dependent processes that are hosting activities. 2460 return index; 2461 } 2462 2463 mLruProcesses.remove(lrui); 2464 if (index > 0) { 2465 index--; 2466 } 2467 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2468 + " in LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 return index; 2471 } 2472 2473 final void removeLruProcessLocked(ProcessRecord app) { 2474 int lrui = mLruProcesses.lastIndexOf(app); 2475 if (lrui >= 0) { 2476 if (!app.killed) { 2477 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2478 Process.killProcessQuiet(app.pid); 2479 Process.killProcessGroup(app.info.uid, app.pid); 2480 } 2481 if (lrui <= mLruProcessActivityStart) { 2482 mLruProcessActivityStart--; 2483 } 2484 if (lrui <= mLruProcessServiceStart) { 2485 mLruProcessServiceStart--; 2486 } 2487 mLruProcesses.remove(lrui); 2488 } 2489 } 2490 2491 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2492 ProcessRecord client) { 2493 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2494 || app.treatLikeActivity; 2495 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2496 if (!activityChange && hasActivity) { 2497 // The process has activities, so we are only allowing activity-based adjustments 2498 // to move it. It should be kept in the front of the list with other 2499 // processes that have activities, and we don't want those to change their 2500 // order except due to activity operations. 2501 return; 2502 } 2503 2504 mLruSeq++; 2505 final long now = SystemClock.uptimeMillis(); 2506 app.lastActivityTime = now; 2507 2508 // First a quick reject: if the app is already at the position we will 2509 // put it, then there is nothing to do. 2510 if (hasActivity) { 2511 final int N = mLruProcesses.size(); 2512 if (N > 0 && mLruProcesses.get(N-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2514 return; 2515 } 2516 } else { 2517 if (mLruProcessServiceStart > 0 2518 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2519 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2520 return; 2521 } 2522 } 2523 2524 int lrui = mLruProcesses.lastIndexOf(app); 2525 2526 if (app.persistent && lrui >= 0) { 2527 // We don't care about the position of persistent processes, as long as 2528 // they are in the list. 2529 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2530 return; 2531 } 2532 2533 /* In progress: compute new position first, so we can avoid doing work 2534 if the process is not actually going to move. Not yet working. 2535 int addIndex; 2536 int nextIndex; 2537 boolean inActivity = false, inService = false; 2538 if (hasActivity) { 2539 // Process has activities, put it at the very tipsy-top. 2540 addIndex = mLruProcesses.size(); 2541 nextIndex = mLruProcessServiceStart; 2542 inActivity = true; 2543 } else if (hasService) { 2544 // Process has services, put it at the top of the service list. 2545 addIndex = mLruProcessActivityStart; 2546 nextIndex = mLruProcessServiceStart; 2547 inActivity = true; 2548 inService = true; 2549 } else { 2550 // Process not otherwise of interest, it goes to the top of the non-service area. 2551 addIndex = mLruProcessServiceStart; 2552 if (client != null) { 2553 int clientIndex = mLruProcesses.lastIndexOf(client); 2554 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2555 + app); 2556 if (clientIndex >= 0 && addIndex > clientIndex) { 2557 addIndex = clientIndex; 2558 } 2559 } 2560 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2561 } 2562 2563 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2564 + mLruProcessActivityStart + "): " + app); 2565 */ 2566 2567 if (lrui >= 0) { 2568 if (lrui < mLruProcessActivityStart) { 2569 mLruProcessActivityStart--; 2570 } 2571 if (lrui < mLruProcessServiceStart) { 2572 mLruProcessServiceStart--; 2573 } 2574 /* 2575 if (addIndex > lrui) { 2576 addIndex--; 2577 } 2578 if (nextIndex > lrui) { 2579 nextIndex--; 2580 } 2581 */ 2582 mLruProcesses.remove(lrui); 2583 } 2584 2585 /* 2586 mLruProcesses.add(addIndex, app); 2587 if (inActivity) { 2588 mLruProcessActivityStart++; 2589 } 2590 if (inService) { 2591 mLruProcessActivityStart++; 2592 } 2593 */ 2594 2595 int nextIndex; 2596 if (hasActivity) { 2597 final int N = mLruProcesses.size(); 2598 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2599 // Process doesn't have activities, but has clients with 2600 // activities... move it up, but one below the top (the top 2601 // should always have a real activity). 2602 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2603 mLruProcesses.add(N-1, app); 2604 // To keep it from spamming the LRU list (by making a bunch of clients), 2605 // we will push down any other entries owned by the app. 2606 final int uid = app.info.uid; 2607 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2608 ProcessRecord subProc = mLruProcesses.get(i); 2609 if (subProc.info.uid == uid) { 2610 // We want to push this one down the list. If the process after 2611 // it is for the same uid, however, don't do so, because we don't 2612 // want them internally to be re-ordered. 2613 if (mLruProcesses.get(i-1).info.uid != uid) { 2614 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2615 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2616 ProcessRecord tmp = mLruProcesses.get(i); 2617 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2618 mLruProcesses.set(i-1, tmp); 2619 i--; 2620 } 2621 } else { 2622 // A gap, we can stop here. 2623 break; 2624 } 2625 } 2626 } else { 2627 // Process has activities, put it at the very tipsy-top. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2629 mLruProcesses.add(app); 2630 } 2631 nextIndex = mLruProcessServiceStart; 2632 } else if (hasService) { 2633 // Process has services, put it at the top of the service list. 2634 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2635 mLruProcesses.add(mLruProcessActivityStart, app); 2636 nextIndex = mLruProcessServiceStart; 2637 mLruProcessActivityStart++; 2638 } else { 2639 // Process not otherwise of interest, it goes to the top of the non-service area. 2640 int index = mLruProcessServiceStart; 2641 if (client != null) { 2642 // If there is a client, don't allow the process to be moved up higher 2643 // in the list than that client. 2644 int clientIndex = mLruProcesses.lastIndexOf(client); 2645 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2646 + " when updating " + app); 2647 if (clientIndex <= lrui) { 2648 // Don't allow the client index restriction to push it down farther in the 2649 // list than it already is. 2650 clientIndex = lrui; 2651 } 2652 if (clientIndex >= 0 && index > clientIndex) { 2653 index = clientIndex; 2654 } 2655 } 2656 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2657 mLruProcesses.add(index, app); 2658 nextIndex = index-1; 2659 mLruProcessActivityStart++; 2660 mLruProcessServiceStart++; 2661 } 2662 2663 // If the app is currently using a content provider or service, 2664 // bump those processes as well. 2665 for (int j=app.connections.size()-1; j>=0; j--) { 2666 ConnectionRecord cr = app.connections.valueAt(j); 2667 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2668 && cr.binding.service.app != null 2669 && cr.binding.service.app.lruSeq != mLruSeq 2670 && !cr.binding.service.app.persistent) { 2671 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2672 "service connection", cr, app); 2673 } 2674 } 2675 for (int j=app.conProviders.size()-1; j>=0; j--) { 2676 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2677 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2678 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2679 "provider reference", cpr, app); 2680 } 2681 } 2682 } 2683 2684 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2685 if (uid == Process.SYSTEM_UID) { 2686 // The system gets to run in any process. If there are multiple 2687 // processes with the same uid, just pick the first (this 2688 // should never happen). 2689 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2690 if (procs == null) return null; 2691 final int N = procs.size(); 2692 for (int i = 0; i < N; i++) { 2693 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2694 } 2695 } 2696 ProcessRecord proc = mProcessNames.get(processName, uid); 2697 if (false && proc != null && !keepIfLarge 2698 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2699 && proc.lastCachedPss >= 4000) { 2700 // Turn this condition on to cause killing to happen regularly, for testing. 2701 if (proc.baseProcessTracker != null) { 2702 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2703 } 2704 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2705 } else if (proc != null && !keepIfLarge 2706 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2707 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2708 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2709 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2710 if (proc.baseProcessTracker != null) { 2711 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2712 } 2713 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2714 } 2715 } 2716 return proc; 2717 } 2718 2719 void ensurePackageDexOpt(String packageName) { 2720 IPackageManager pm = AppGlobals.getPackageManager(); 2721 try { 2722 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2723 mDidDexOpt = true; 2724 } 2725 } catch (RemoteException e) { 2726 } 2727 } 2728 2729 boolean isNextTransitionForward() { 2730 int transit = mWindowManager.getPendingAppTransition(); 2731 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2732 || transit == AppTransition.TRANSIT_TASK_OPEN 2733 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2734 } 2735 2736 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2737 String processName, String abiOverride, int uid, Runnable crashHandler) { 2738 synchronized(this) { 2739 ApplicationInfo info = new ApplicationInfo(); 2740 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2741 // For isolated processes, the former contains the parent's uid and the latter the 2742 // actual uid of the isolated process. 2743 // In the special case introduced by this method (which is, starting an isolated 2744 // process directly from the SystemServer without an actual parent app process) the 2745 // closest thing to a parent's uid is SYSTEM_UID. 2746 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2747 // the |isolated| logic in the ProcessRecord constructor. 2748 info.uid = Process.SYSTEM_UID; 2749 info.processName = processName; 2750 info.className = entryPoint; 2751 info.packageName = "android"; 2752 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2753 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2754 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2755 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2756 crashHandler); 2757 return proc != null ? proc.pid : 0; 2758 } 2759 } 2760 2761 final ProcessRecord startProcessLocked(String processName, 2762 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2763 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2764 boolean isolated, boolean keepIfLarge) { 2765 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2766 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2767 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2768 null /* crashHandler */); 2769 } 2770 2771 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2772 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2773 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2774 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2775 long startTime = SystemClock.elapsedRealtime(); 2776 ProcessRecord app; 2777 if (!isolated) { 2778 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2779 checkTime(startTime, "startProcess: after getProcessRecord"); 2780 } else { 2781 // If this is an isolated process, it can't re-use an existing process. 2782 app = null; 2783 } 2784 // We don't have to do anything more if: 2785 // (1) There is an existing application record; and 2786 // (2) The caller doesn't think it is dead, OR there is no thread 2787 // object attached to it so we know it couldn't have crashed; and 2788 // (3) There is a pid assigned to it, so it is either starting or 2789 // already running. 2790 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2791 + " app=" + app + " knownToBeDead=" + knownToBeDead 2792 + " thread=" + (app != null ? app.thread : null) 2793 + " pid=" + (app != null ? app.pid : -1)); 2794 if (app != null && app.pid > 0) { 2795 if (!knownToBeDead || app.thread == null) { 2796 // We already have the app running, or are waiting for it to 2797 // come up (we have a pid but not yet its thread), so keep it. 2798 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2799 // If this is a new package in the process, add the package to the list 2800 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2801 checkTime(startTime, "startProcess: done, added package to proc"); 2802 return app; 2803 } 2804 2805 // An application record is attached to a previous process, 2806 // clean it up now. 2807 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2808 checkTime(startTime, "startProcess: bad proc running, killing"); 2809 Process.killProcessGroup(app.info.uid, app.pid); 2810 handleAppDiedLocked(app, true, true); 2811 checkTime(startTime, "startProcess: done killing old proc"); 2812 } 2813 2814 String hostingNameStr = hostingName != null 2815 ? hostingName.flattenToShortString() : null; 2816 2817 if (!isolated) { 2818 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2819 // If we are in the background, then check to see if this process 2820 // is bad. If so, we will just silently fail. 2821 if (mBadProcesses.get(info.processName, info.uid) != null) { 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2823 + "/" + info.processName); 2824 return null; 2825 } 2826 } else { 2827 // When the user is explicitly starting a process, then clear its 2828 // crash count so that we won't make it bad until they see at 2829 // least one crash dialog again, and make the process good again 2830 // if it had been bad. 2831 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2832 + "/" + info.processName); 2833 mProcessCrashTimes.remove(info.processName, info.uid); 2834 if (mBadProcesses.get(info.processName, info.uid) != null) { 2835 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2836 UserHandle.getUserId(info.uid), info.uid, 2837 info.processName); 2838 mBadProcesses.remove(info.processName, info.uid); 2839 if (app != null) { 2840 app.bad = false; 2841 } 2842 } 2843 } 2844 } 2845 2846 if (app == null) { 2847 checkTime(startTime, "startProcess: creating new process record"); 2848 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2849 if (app == null) { 2850 Slog.w(TAG, "Failed making new process record for " 2851 + processName + "/" + info.uid + " isolated=" + isolated); 2852 return null; 2853 } 2854 app.crashHandler = crashHandler; 2855 mProcessNames.put(processName, app.uid, app); 2856 if (isolated) { 2857 mIsolatedProcesses.put(app.uid, app); 2858 } 2859 checkTime(startTime, "startProcess: done creating new process record"); 2860 } else { 2861 // If this is a new package in the process, add the package to the list 2862 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2863 checkTime(startTime, "startProcess: added package to existing proc"); 2864 } 2865 2866 // If the system is not ready yet, then hold off on starting this 2867 // process until it is. 2868 if (!mProcessesReady 2869 && !isAllowedWhileBooting(info) 2870 && !allowWhileBooting) { 2871 if (!mProcessesOnHold.contains(app)) { 2872 mProcessesOnHold.add(app); 2873 } 2874 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2875 checkTime(startTime, "startProcess: returning with proc on hold"); 2876 return app; 2877 } 2878 2879 checkTime(startTime, "startProcess: stepping in to startProcess"); 2880 startProcessLocked( 2881 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2882 checkTime(startTime, "startProcess: done starting proc!"); 2883 return (app.pid != 0) ? app : null; 2884 } 2885 2886 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2887 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2888 } 2889 2890 private final void startProcessLocked(ProcessRecord app, 2891 String hostingType, String hostingNameStr) { 2892 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2893 null /* entryPoint */, null /* entryPointArgs */); 2894 } 2895 2896 private final void startProcessLocked(ProcessRecord app, String hostingType, 2897 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2898 long startTime = SystemClock.elapsedRealtime(); 2899 if (app.pid > 0 && app.pid != MY_PID) { 2900 checkTime(startTime, "startProcess: removing from pids map"); 2901 synchronized (mPidsSelfLocked) { 2902 mPidsSelfLocked.remove(app.pid); 2903 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2904 } 2905 checkTime(startTime, "startProcess: done removing from pids map"); 2906 app.setPid(0); 2907 } 2908 2909 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2910 "startProcessLocked removing on hold: " + app); 2911 mProcessesOnHold.remove(app); 2912 2913 checkTime(startTime, "startProcess: starting to update cpu stats"); 2914 updateCpuStats(); 2915 checkTime(startTime, "startProcess: done updating cpu stats"); 2916 2917 try { 2918 int uid = app.uid; 2919 2920 int[] gids = null; 2921 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2922 if (!app.isolated) { 2923 int[] permGids = null; 2924 try { 2925 checkTime(startTime, "startProcess: getting gids from package manager"); 2926 final PackageManager pm = mContext.getPackageManager(); 2927 permGids = pm.getPackageGids(app.info.packageName); 2928 2929 if (Environment.isExternalStorageEmulated()) { 2930 checkTime(startTime, "startProcess: checking external storage perm"); 2931 if (pm.checkPermission( 2932 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2933 app.info.packageName) == PERMISSION_GRANTED) { 2934 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2935 } else { 2936 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2937 } 2938 } 2939 } catch (PackageManager.NameNotFoundException e) { 2940 Slog.w(TAG, "Unable to retrieve gids", e); 2941 } 2942 2943 /* 2944 * Add shared application and profile GIDs so applications can share some 2945 * resources like shared libraries and access user-wide resources 2946 */ 2947 if (permGids == null) { 2948 gids = new int[2]; 2949 } else { 2950 gids = new int[permGids.length + 2]; 2951 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2952 } 2953 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2954 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2955 } 2956 checkTime(startTime, "startProcess: building args"); 2957 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2958 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2959 && mTopComponent != null 2960 && app.processName.equals(mTopComponent.getPackageName())) { 2961 uid = 0; 2962 } 2963 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2964 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2965 uid = 0; 2966 } 2967 } 2968 int debugFlags = 0; 2969 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2970 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2971 // Also turn on CheckJNI for debuggable apps. It's quite 2972 // awkward to turn on otherwise. 2973 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2974 } 2975 // Run the app in safe mode if its manifest requests so or the 2976 // system is booted in safe mode. 2977 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2978 mSafeMode == true) { 2979 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2980 } 2981 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2986 } 2987 if ("1".equals(SystemProperties.get("debug.assert"))) { 2988 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2989 } 2990 2991 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2992 if (requiredAbi == null) { 2993 requiredAbi = Build.SUPPORTED_ABIS[0]; 2994 } 2995 2996 String instructionSet = null; 2997 if (app.info.primaryCpuAbi != null) { 2998 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2999 } 3000 3001 // Start the process. It will either succeed and return a result containing 3002 // the PID of the new process, or else throw a RuntimeException. 3003 boolean isActivityProcess = (entryPoint == null); 3004 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3005 checkTime(startTime, "startProcess: asking zygote to start proc"); 3006 Process.ProcessStartResult startResult = Process.start(entryPoint, 3007 app.processName, uid, uid, gids, debugFlags, mountExternal, 3008 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3009 app.info.dataDir, entryPointArgs); 3010 checkTime(startTime, "startProcess: returned from zygote!"); 3011 3012 if (app.isolated) { 3013 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3014 } 3015 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3016 checkTime(startTime, "startProcess: done updating battery stats"); 3017 3018 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3019 UserHandle.getUserId(uid), startResult.pid, uid, 3020 app.processName, hostingType, 3021 hostingNameStr != null ? hostingNameStr : ""); 3022 3023 if (app.persistent) { 3024 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3025 } 3026 3027 checkTime(startTime, "startProcess: building log message"); 3028 StringBuilder buf = mStringBuilder; 3029 buf.setLength(0); 3030 buf.append("Start proc "); 3031 buf.append(app.processName); 3032 if (!isActivityProcess) { 3033 buf.append(" ["); 3034 buf.append(entryPoint); 3035 buf.append("]"); 3036 } 3037 buf.append(" for "); 3038 buf.append(hostingType); 3039 if (hostingNameStr != null) { 3040 buf.append(" "); 3041 buf.append(hostingNameStr); 3042 } 3043 buf.append(": pid="); 3044 buf.append(startResult.pid); 3045 buf.append(" uid="); 3046 buf.append(uid); 3047 buf.append(" gids={"); 3048 if (gids != null) { 3049 for (int gi=0; gi<gids.length; gi++) { 3050 if (gi != 0) buf.append(", "); 3051 buf.append(gids[gi]); 3052 3053 } 3054 } 3055 buf.append("}"); 3056 if (requiredAbi != null) { 3057 buf.append(" abi="); 3058 buf.append(requiredAbi); 3059 } 3060 Slog.i(TAG, buf.toString()); 3061 app.setPid(startResult.pid); 3062 app.usingWrapper = startResult.usingWrapper; 3063 app.removed = false; 3064 app.killed = false; 3065 app.killedByAm = false; 3066 checkTime(startTime, "startProcess: starting to update pids map"); 3067 synchronized (mPidsSelfLocked) { 3068 this.mPidsSelfLocked.put(startResult.pid, app); 3069 if (isActivityProcess) { 3070 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3071 msg.obj = app; 3072 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3073 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3074 } 3075 } 3076 checkTime(startTime, "startProcess: done updating pids map"); 3077 } catch (RuntimeException e) { 3078 // XXX do better error recovery. 3079 app.setPid(0); 3080 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3081 if (app.isolated) { 3082 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3083 } 3084 Slog.e(TAG, "Failure starting process " + app.processName, e); 3085 } 3086 } 3087 3088 void updateUsageStats(ActivityRecord component, boolean resumed) { 3089 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3090 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3091 if (resumed) { 3092 if (mUsageStatsService != null) { 3093 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3094 UsageEvents.Event.MOVE_TO_FOREGROUND); 3095 } 3096 synchronized (stats) { 3097 stats.noteActivityResumedLocked(component.app.uid); 3098 } 3099 } else { 3100 if (mUsageStatsService != null) { 3101 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3102 UsageEvents.Event.MOVE_TO_BACKGROUND); 3103 } 3104 synchronized (stats) { 3105 stats.noteActivityPausedLocked(component.app.uid); 3106 } 3107 } 3108 } 3109 3110 Intent getHomeIntent() { 3111 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3112 intent.setComponent(mTopComponent); 3113 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3114 intent.addCategory(Intent.CATEGORY_HOME); 3115 } 3116 return intent; 3117 } 3118 3119 boolean startHomeActivityLocked(int userId) { 3120 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3121 && mTopAction == null) { 3122 // We are running in factory test mode, but unable to find 3123 // the factory test app, so just sit around displaying the 3124 // error message and don't try to start anything. 3125 return false; 3126 } 3127 Intent intent = getHomeIntent(); 3128 ActivityInfo aInfo = 3129 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3130 if (aInfo != null) { 3131 intent.setComponent(new ComponentName( 3132 aInfo.applicationInfo.packageName, aInfo.name)); 3133 // Don't do this if the home app is currently being 3134 // instrumented. 3135 aInfo = new ActivityInfo(aInfo); 3136 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3137 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3138 aInfo.applicationInfo.uid, true); 3139 if (app == null || app.instrumentationClass == null) { 3140 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3141 mStackSupervisor.startHomeActivity(intent, aInfo); 3142 } 3143 } 3144 3145 return true; 3146 } 3147 3148 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3149 ActivityInfo ai = null; 3150 ComponentName comp = intent.getComponent(); 3151 try { 3152 if (comp != null) { 3153 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3154 } else { 3155 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3156 intent, 3157 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3158 flags, userId); 3159 3160 if (info != null) { 3161 ai = info.activityInfo; 3162 } 3163 } 3164 } catch (RemoteException e) { 3165 // ignore 3166 } 3167 3168 return ai; 3169 } 3170 3171 /** 3172 * Starts the "new version setup screen" if appropriate. 3173 */ 3174 void startSetupActivityLocked() { 3175 // Only do this once per boot. 3176 if (mCheckedForSetup) { 3177 return; 3178 } 3179 3180 // We will show this screen if the current one is a different 3181 // version than the last one shown, and we are not running in 3182 // low-level factory test mode. 3183 final ContentResolver resolver = mContext.getContentResolver(); 3184 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3185 Settings.Global.getInt(resolver, 3186 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3187 mCheckedForSetup = true; 3188 3189 // See if we should be showing the platform update setup UI. 3190 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3191 List<ResolveInfo> ris = mContext.getPackageManager() 3192 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3193 3194 // We don't allow third party apps to replace this. 3195 ResolveInfo ri = null; 3196 for (int i=0; ris != null && i<ris.size(); i++) { 3197 if ((ris.get(i).activityInfo.applicationInfo.flags 3198 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3199 ri = ris.get(i); 3200 break; 3201 } 3202 } 3203 3204 if (ri != null) { 3205 String vers = ri.activityInfo.metaData != null 3206 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3207 : null; 3208 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3209 vers = ri.activityInfo.applicationInfo.metaData.getString( 3210 Intent.METADATA_SETUP_VERSION); 3211 } 3212 String lastVers = Settings.Secure.getString( 3213 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3214 if (vers != null && !vers.equals(lastVers)) { 3215 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3216 intent.setComponent(new ComponentName( 3217 ri.activityInfo.packageName, ri.activityInfo.name)); 3218 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3219 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3220 null); 3221 } 3222 } 3223 } 3224 } 3225 3226 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3227 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3228 } 3229 3230 void enforceNotIsolatedCaller(String caller) { 3231 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3232 throw new SecurityException("Isolated process not allowed to call " + caller); 3233 } 3234 } 3235 3236 void enforceShellRestriction(String restriction, int userHandle) { 3237 if (Binder.getCallingUid() == Process.SHELL_UID) { 3238 if (userHandle < 0 3239 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3240 throw new SecurityException("Shell does not have permission to access user " 3241 + userHandle); 3242 } 3243 } 3244 } 3245 3246 @Override 3247 public int getFrontActivityScreenCompatMode() { 3248 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3249 synchronized (this) { 3250 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3251 } 3252 } 3253 3254 @Override 3255 public void setFrontActivityScreenCompatMode(int mode) { 3256 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3257 "setFrontActivityScreenCompatMode"); 3258 synchronized (this) { 3259 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3260 } 3261 } 3262 3263 @Override 3264 public int getPackageScreenCompatMode(String packageName) { 3265 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3266 synchronized (this) { 3267 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3268 } 3269 } 3270 3271 @Override 3272 public void setPackageScreenCompatMode(String packageName, int mode) { 3273 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3274 "setPackageScreenCompatMode"); 3275 synchronized (this) { 3276 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3277 } 3278 } 3279 3280 @Override 3281 public boolean getPackageAskScreenCompat(String packageName) { 3282 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3283 synchronized (this) { 3284 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3285 } 3286 } 3287 3288 @Override 3289 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3290 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3291 "setPackageAskScreenCompat"); 3292 synchronized (this) { 3293 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3294 } 3295 } 3296 3297 private void dispatchProcessesChanged() { 3298 int N; 3299 synchronized (this) { 3300 N = mPendingProcessChanges.size(); 3301 if (mActiveProcessChanges.length < N) { 3302 mActiveProcessChanges = new ProcessChangeItem[N]; 3303 } 3304 mPendingProcessChanges.toArray(mActiveProcessChanges); 3305 mAvailProcessChanges.addAll(mPendingProcessChanges); 3306 mPendingProcessChanges.clear(); 3307 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3308 } 3309 3310 int i = mProcessObservers.beginBroadcast(); 3311 while (i > 0) { 3312 i--; 3313 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3314 if (observer != null) { 3315 try { 3316 for (int j=0; j<N; j++) { 3317 ProcessChangeItem item = mActiveProcessChanges[j]; 3318 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3320 + item.pid + " uid=" + item.uid + ": " 3321 + item.foregroundActivities); 3322 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3323 item.foregroundActivities); 3324 } 3325 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3326 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3327 + item.pid + " uid=" + item.uid + ": " + item.processState); 3328 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3329 } 3330 } 3331 } catch (RemoteException e) { 3332 } 3333 } 3334 } 3335 mProcessObservers.finishBroadcast(); 3336 } 3337 3338 private void dispatchProcessDied(int pid, int uid) { 3339 int i = mProcessObservers.beginBroadcast(); 3340 while (i > 0) { 3341 i--; 3342 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3343 if (observer != null) { 3344 try { 3345 observer.onProcessDied(pid, uid); 3346 } catch (RemoteException e) { 3347 } 3348 } 3349 } 3350 mProcessObservers.finishBroadcast(); 3351 } 3352 3353 @Override 3354 public final int startActivity(IApplicationThread caller, String callingPackage, 3355 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3356 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3357 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3358 resultWho, requestCode, startFlags, profilerInfo, options, 3359 UserHandle.getCallingUserId()); 3360 } 3361 3362 @Override 3363 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3364 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3365 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3366 enforceNotIsolatedCaller("startActivity"); 3367 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3368 false, ALLOW_FULL_ONLY, "startActivity", null); 3369 // TODO: Switch to user app stacks here. 3370 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3371 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3372 profilerInfo, null, null, options, userId, null, null); 3373 } 3374 3375 @Override 3376 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3377 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3378 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3379 3380 // This is very dangerous -- it allows you to perform a start activity (including 3381 // permission grants) as any app that may launch one of your own activities. So 3382 // we will only allow this to be done from activities that are part of the core framework, 3383 // and then only when they are running as the system. 3384 final ActivityRecord sourceRecord; 3385 final int targetUid; 3386 final String targetPackage; 3387 synchronized (this) { 3388 if (resultTo == null) { 3389 throw new SecurityException("Must be called from an activity"); 3390 } 3391 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3392 if (sourceRecord == null) { 3393 throw new SecurityException("Called with bad activity token: " + resultTo); 3394 } 3395 if (!sourceRecord.info.packageName.equals("android")) { 3396 throw new SecurityException( 3397 "Must be called from an activity that is declared in the android package"); 3398 } 3399 if (sourceRecord.app == null) { 3400 throw new SecurityException("Called without a process attached to activity"); 3401 } 3402 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3403 // This is still okay, as long as this activity is running under the 3404 // uid of the original calling activity. 3405 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3406 throw new SecurityException( 3407 "Calling activity in uid " + sourceRecord.app.uid 3408 + " must be system uid or original calling uid " 3409 + sourceRecord.launchedFromUid); 3410 } 3411 } 3412 targetUid = sourceRecord.launchedFromUid; 3413 targetPackage = sourceRecord.launchedFromPackage; 3414 } 3415 3416 if (userId == UserHandle.USER_NULL) { 3417 userId = UserHandle.getUserId(sourceRecord.app.uid); 3418 } 3419 3420 // TODO: Switch to user app stacks here. 3421 try { 3422 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3423 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3424 null, null, options, userId, null, null); 3425 return ret; 3426 } catch (SecurityException e) { 3427 // XXX need to figure out how to propagate to original app. 3428 // A SecurityException here is generally actually a fault of the original 3429 // calling activity (such as a fairly granting permissions), so propagate it 3430 // back to them. 3431 /* 3432 StringBuilder msg = new StringBuilder(); 3433 msg.append("While launching"); 3434 msg.append(intent.toString()); 3435 msg.append(": "); 3436 msg.append(e.getMessage()); 3437 */ 3438 throw e; 3439 } 3440 } 3441 3442 @Override 3443 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3444 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3445 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3446 enforceNotIsolatedCaller("startActivityAndWait"); 3447 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3448 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3449 WaitResult res = new WaitResult(); 3450 // TODO: Switch to user app stacks here. 3451 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3452 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3453 options, userId, null, null); 3454 return res; 3455 } 3456 3457 @Override 3458 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3459 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3460 int startFlags, Configuration config, Bundle options, int userId) { 3461 enforceNotIsolatedCaller("startActivityWithConfig"); 3462 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3463 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3464 // TODO: Switch to user app stacks here. 3465 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3466 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3467 null, null, config, options, userId, null, null); 3468 return ret; 3469 } 3470 3471 @Override 3472 public int startActivityIntentSender(IApplicationThread caller, 3473 IntentSender intent, Intent fillInIntent, String resolvedType, 3474 IBinder resultTo, String resultWho, int requestCode, 3475 int flagsMask, int flagsValues, Bundle options) { 3476 enforceNotIsolatedCaller("startActivityIntentSender"); 3477 // Refuse possible leaked file descriptors 3478 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3479 throw new IllegalArgumentException("File descriptors passed in Intent"); 3480 } 3481 3482 IIntentSender sender = intent.getTarget(); 3483 if (!(sender instanceof PendingIntentRecord)) { 3484 throw new IllegalArgumentException("Bad PendingIntent object"); 3485 } 3486 3487 PendingIntentRecord pir = (PendingIntentRecord)sender; 3488 3489 synchronized (this) { 3490 // If this is coming from the currently resumed activity, it is 3491 // effectively saying that app switches are allowed at this point. 3492 final ActivityStack stack = getFocusedStack(); 3493 if (stack.mResumedActivity != null && 3494 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3495 mAppSwitchesAllowedTime = 0; 3496 } 3497 } 3498 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3499 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3500 return ret; 3501 } 3502 3503 @Override 3504 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3505 Intent intent, String resolvedType, IVoiceInteractionSession session, 3506 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3507 Bundle options, int userId) { 3508 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3509 != PackageManager.PERMISSION_GRANTED) { 3510 String msg = "Permission Denial: startVoiceActivity() from pid=" 3511 + Binder.getCallingPid() 3512 + ", uid=" + Binder.getCallingUid() 3513 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3514 Slog.w(TAG, msg); 3515 throw new SecurityException(msg); 3516 } 3517 if (session == null || interactor == null) { 3518 throw new NullPointerException("null session or interactor"); 3519 } 3520 userId = handleIncomingUser(callingPid, callingUid, userId, 3521 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3522 // TODO: Switch to user app stacks here. 3523 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3524 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3525 null, options, userId, null, null); 3526 } 3527 3528 @Override 3529 public boolean startNextMatchingActivity(IBinder callingActivity, 3530 Intent intent, Bundle options) { 3531 // Refuse possible leaked file descriptors 3532 if (intent != null && intent.hasFileDescriptors() == true) { 3533 throw new IllegalArgumentException("File descriptors passed in Intent"); 3534 } 3535 3536 synchronized (this) { 3537 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3538 if (r == null) { 3539 ActivityOptions.abort(options); 3540 return false; 3541 } 3542 if (r.app == null || r.app.thread == null) { 3543 // The caller is not running... d'oh! 3544 ActivityOptions.abort(options); 3545 return false; 3546 } 3547 intent = new Intent(intent); 3548 // The caller is not allowed to change the data. 3549 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3550 // And we are resetting to find the next component... 3551 intent.setComponent(null); 3552 3553 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3554 3555 ActivityInfo aInfo = null; 3556 try { 3557 List<ResolveInfo> resolves = 3558 AppGlobals.getPackageManager().queryIntentActivities( 3559 intent, r.resolvedType, 3560 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3561 UserHandle.getCallingUserId()); 3562 3563 // Look for the original activity in the list... 3564 final int N = resolves != null ? resolves.size() : 0; 3565 for (int i=0; i<N; i++) { 3566 ResolveInfo rInfo = resolves.get(i); 3567 if (rInfo.activityInfo.packageName.equals(r.packageName) 3568 && rInfo.activityInfo.name.equals(r.info.name)) { 3569 // We found the current one... the next matching is 3570 // after it. 3571 i++; 3572 if (i<N) { 3573 aInfo = resolves.get(i).activityInfo; 3574 } 3575 if (debug) { 3576 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3577 + "/" + r.info.name); 3578 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3579 + "/" + aInfo.name); 3580 } 3581 break; 3582 } 3583 } 3584 } catch (RemoteException e) { 3585 } 3586 3587 if (aInfo == null) { 3588 // Nobody who is next! 3589 ActivityOptions.abort(options); 3590 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3591 return false; 3592 } 3593 3594 intent.setComponent(new ComponentName( 3595 aInfo.applicationInfo.packageName, aInfo.name)); 3596 intent.setFlags(intent.getFlags()&~( 3597 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3598 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3599 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3600 Intent.FLAG_ACTIVITY_NEW_TASK)); 3601 3602 // Okay now we need to start the new activity, replacing the 3603 // currently running activity. This is a little tricky because 3604 // we want to start the new one as if the current one is finished, 3605 // but not finish the current one first so that there is no flicker. 3606 // And thus... 3607 final boolean wasFinishing = r.finishing; 3608 r.finishing = true; 3609 3610 // Propagate reply information over to the new activity. 3611 final ActivityRecord resultTo = r.resultTo; 3612 final String resultWho = r.resultWho; 3613 final int requestCode = r.requestCode; 3614 r.resultTo = null; 3615 if (resultTo != null) { 3616 resultTo.removeResultsLocked(r, resultWho, requestCode); 3617 } 3618 3619 final long origId = Binder.clearCallingIdentity(); 3620 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3621 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3622 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3623 -1, r.launchedFromUid, 0, options, false, null, null, null); 3624 Binder.restoreCallingIdentity(origId); 3625 3626 r.finishing = wasFinishing; 3627 if (res != ActivityManager.START_SUCCESS) { 3628 return false; 3629 } 3630 return true; 3631 } 3632 } 3633 3634 @Override 3635 public final int startActivityFromRecents(int taskId, Bundle options) { 3636 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3637 String msg = "Permission Denial: startActivityFromRecents called without " + 3638 START_TASKS_FROM_RECENTS; 3639 Slog.w(TAG, msg); 3640 throw new SecurityException(msg); 3641 } 3642 return startActivityFromRecentsInner(taskId, options); 3643 } 3644 3645 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3646 final TaskRecord task; 3647 final int callingUid; 3648 final String callingPackage; 3649 final Intent intent; 3650 final int userId; 3651 synchronized (this) { 3652 task = recentTaskForIdLocked(taskId); 3653 if (task == null) { 3654 throw new IllegalArgumentException("Task " + taskId + " not found."); 3655 } 3656 callingUid = task.mCallingUid; 3657 callingPackage = task.mCallingPackage; 3658 intent = task.intent; 3659 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3660 userId = task.userId; 3661 } 3662 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3663 options, userId, null, task); 3664 } 3665 3666 final int startActivityInPackage(int uid, String callingPackage, 3667 Intent intent, String resolvedType, IBinder resultTo, 3668 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3669 IActivityContainer container, TaskRecord inTask) { 3670 3671 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3672 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3673 3674 // TODO: Switch to user app stacks here. 3675 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3676 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3677 null, null, null, options, userId, container, inTask); 3678 return ret; 3679 } 3680 3681 @Override 3682 public final int startActivities(IApplicationThread caller, String callingPackage, 3683 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3684 int userId) { 3685 enforceNotIsolatedCaller("startActivities"); 3686 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3687 false, ALLOW_FULL_ONLY, "startActivity", null); 3688 // TODO: Switch to user app stacks here. 3689 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3690 resolvedTypes, resultTo, options, userId); 3691 return ret; 3692 } 3693 3694 final int startActivitiesInPackage(int uid, String callingPackage, 3695 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3696 Bundle options, int userId) { 3697 3698 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3699 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3700 // TODO: Switch to user app stacks here. 3701 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3702 resultTo, options, userId); 3703 return ret; 3704 } 3705 3706 //explicitly remove thd old information in mRecentTasks when removing existing user. 3707 private void removeRecentTasksForUserLocked(int userId) { 3708 if(userId <= 0) { 3709 Slog.i(TAG, "Can't remove recent task on user " + userId); 3710 return; 3711 } 3712 3713 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3714 TaskRecord tr = mRecentTasks.get(i); 3715 if (tr.userId == userId) { 3716 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3717 + " when finishing user" + userId); 3718 mRecentTasks.remove(i); 3719 tr.removedFromRecents(); 3720 } 3721 } 3722 3723 // Remove tasks from persistent storage. 3724 notifyTaskPersisterLocked(null, true); 3725 } 3726 3727 // Sort by taskId 3728 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3729 @Override 3730 public int compare(TaskRecord lhs, TaskRecord rhs) { 3731 return rhs.taskId - lhs.taskId; 3732 } 3733 }; 3734 3735 // Extract the affiliates of the chain containing mRecentTasks[start]. 3736 private int processNextAffiliateChainLocked(int start) { 3737 final TaskRecord startTask = mRecentTasks.get(start); 3738 final int affiliateId = startTask.mAffiliatedTaskId; 3739 3740 // Quick identification of isolated tasks. I.e. those not launched behind. 3741 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3742 startTask.mNextAffiliate == null) { 3743 // There is still a slim chance that there are other tasks that point to this task 3744 // and that the chain is so messed up that this task no longer points to them but 3745 // the gain of this optimization outweighs the risk. 3746 startTask.inRecents = true; 3747 return start + 1; 3748 } 3749 3750 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3751 mTmpRecents.clear(); 3752 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3753 final TaskRecord task = mRecentTasks.get(i); 3754 if (task.mAffiliatedTaskId == affiliateId) { 3755 mRecentTasks.remove(i); 3756 mTmpRecents.add(task); 3757 } 3758 } 3759 3760 // Sort them all by taskId. That is the order they were create in and that order will 3761 // always be correct. 3762 Collections.sort(mTmpRecents, mTaskRecordComparator); 3763 3764 // Go through and fix up the linked list. 3765 // The first one is the end of the chain and has no next. 3766 final TaskRecord first = mTmpRecents.get(0); 3767 first.inRecents = true; 3768 if (first.mNextAffiliate != null) { 3769 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3770 first.setNextAffiliate(null); 3771 notifyTaskPersisterLocked(first, false); 3772 } 3773 // Everything in the middle is doubly linked from next to prev. 3774 final int tmpSize = mTmpRecents.size(); 3775 for (int i = 0; i < tmpSize - 1; ++i) { 3776 final TaskRecord next = mTmpRecents.get(i); 3777 final TaskRecord prev = mTmpRecents.get(i + 1); 3778 if (next.mPrevAffiliate != prev) { 3779 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3780 " setting prev=" + prev); 3781 next.setPrevAffiliate(prev); 3782 notifyTaskPersisterLocked(next, false); 3783 } 3784 if (prev.mNextAffiliate != next) { 3785 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3786 " setting next=" + next); 3787 prev.setNextAffiliate(next); 3788 notifyTaskPersisterLocked(prev, false); 3789 } 3790 prev.inRecents = true; 3791 } 3792 // The last one is the beginning of the list and has no prev. 3793 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3794 if (last.mPrevAffiliate != null) { 3795 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3796 last.setPrevAffiliate(null); 3797 notifyTaskPersisterLocked(last, false); 3798 } 3799 3800 // Insert the group back into mRecentTasks at start. 3801 mRecentTasks.addAll(start, mTmpRecents); 3802 3803 // Let the caller know where we left off. 3804 return start + tmpSize; 3805 } 3806 3807 /** 3808 * Update the recent tasks lists: make sure tasks should still be here (their 3809 * applications / activities still exist), update their availability, fixup ordering 3810 * of affiliations. 3811 */ 3812 void cleanupRecentTasksLocked(int userId) { 3813 if (mRecentTasks == null) { 3814 // Happens when called from the packagemanager broadcast before boot. 3815 return; 3816 } 3817 3818 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3819 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3820 final IPackageManager pm = AppGlobals.getPackageManager(); 3821 final ActivityInfo dummyAct = new ActivityInfo(); 3822 final ApplicationInfo dummyApp = new ApplicationInfo(); 3823 3824 int N = mRecentTasks.size(); 3825 3826 int[] users = userId == UserHandle.USER_ALL 3827 ? getUsersLocked() : new int[] { userId }; 3828 for (int user : users) { 3829 for (int i = 0; i < N; i++) { 3830 TaskRecord task = mRecentTasks.get(i); 3831 if (task.userId != user) { 3832 // Only look at tasks for the user ID of interest. 3833 continue; 3834 } 3835 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3836 // This situation is broken, and we should just get rid of it now. 3837 mRecentTasks.remove(i); 3838 task.removedFromRecents(); 3839 i--; 3840 N--; 3841 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3842 continue; 3843 } 3844 // Check whether this activity is currently available. 3845 if (task.realActivity != null) { 3846 ActivityInfo ai = availActCache.get(task.realActivity); 3847 if (ai == null) { 3848 try { 3849 ai = pm.getActivityInfo(task.realActivity, 3850 PackageManager.GET_UNINSTALLED_PACKAGES 3851 | PackageManager.GET_DISABLED_COMPONENTS, user); 3852 } catch (RemoteException e) { 3853 // Will never happen. 3854 continue; 3855 } 3856 if (ai == null) { 3857 ai = dummyAct; 3858 } 3859 availActCache.put(task.realActivity, ai); 3860 } 3861 if (ai == dummyAct) { 3862 // This could be either because the activity no longer exists, or the 3863 // app is temporarily gone. For the former we want to remove the recents 3864 // entry; for the latter we want to mark it as unavailable. 3865 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3866 if (app == null) { 3867 try { 3868 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3869 PackageManager.GET_UNINSTALLED_PACKAGES 3870 | PackageManager.GET_DISABLED_COMPONENTS, user); 3871 } catch (RemoteException e) { 3872 // Will never happen. 3873 continue; 3874 } 3875 if (app == null) { 3876 app = dummyApp; 3877 } 3878 availAppCache.put(task.realActivity.getPackageName(), app); 3879 } 3880 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3881 // Doesn't exist any more! Good-bye. 3882 mRecentTasks.remove(i); 3883 task.removedFromRecents(); 3884 i--; 3885 N--; 3886 Slog.w(TAG, "Removing no longer valid recent: " + task); 3887 continue; 3888 } else { 3889 // Otherwise just not available for now. 3890 if (task.isAvailable) { 3891 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3892 + task); 3893 } 3894 task.isAvailable = false; 3895 } 3896 } else { 3897 if (!ai.enabled || !ai.applicationInfo.enabled 3898 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3899 if (task.isAvailable) { 3900 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3901 + task + " (enabled=" + ai.enabled + "/" 3902 + ai.applicationInfo.enabled + " flags=" 3903 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3904 } 3905 task.isAvailable = false; 3906 } else { 3907 if (!task.isAvailable) { 3908 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3909 + task); 3910 } 3911 task.isAvailable = true; 3912 } 3913 } 3914 } 3915 } 3916 } 3917 3918 // Verify the affiliate chain for each task. 3919 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3920 } 3921 3922 mTmpRecents.clear(); 3923 // mRecentTasks is now in sorted, affiliated order. 3924 } 3925 3926 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3927 int N = mRecentTasks.size(); 3928 TaskRecord top = task; 3929 int topIndex = taskIndex; 3930 while (top.mNextAffiliate != null && topIndex > 0) { 3931 top = top.mNextAffiliate; 3932 topIndex--; 3933 } 3934 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3935 + topIndex + " from intial " + taskIndex); 3936 // Find the end of the chain, doing a sanity check along the way. 3937 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3938 int endIndex = topIndex; 3939 TaskRecord prev = top; 3940 while (endIndex < N) { 3941 TaskRecord cur = mRecentTasks.get(endIndex); 3942 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3943 + endIndex + " " + cur); 3944 if (cur == top) { 3945 // Verify start of the chain. 3946 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3947 Slog.wtf(TAG, "Bad chain @" + endIndex 3948 + ": first task has next affiliate: " + prev); 3949 sane = false; 3950 break; 3951 } 3952 } else { 3953 // Verify middle of the chain's next points back to the one before. 3954 if (cur.mNextAffiliate != prev 3955 || cur.mNextAffiliateTaskId != prev.taskId) { 3956 Slog.wtf(TAG, "Bad chain @" + endIndex 3957 + ": middle task " + cur + " @" + endIndex 3958 + " has bad next affiliate " 3959 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3960 + ", expected " + prev); 3961 sane = false; 3962 break; 3963 } 3964 } 3965 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3966 // Chain ends here. 3967 if (cur.mPrevAffiliate != null) { 3968 Slog.wtf(TAG, "Bad chain @" + endIndex 3969 + ": last task " + cur + " has previous affiliate " 3970 + cur.mPrevAffiliate); 3971 sane = false; 3972 } 3973 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3974 break; 3975 } else { 3976 // Verify middle of the chain's prev points to a valid item. 3977 if (cur.mPrevAffiliate == null) { 3978 Slog.wtf(TAG, "Bad chain @" + endIndex 3979 + ": task " + cur + " has previous affiliate " 3980 + cur.mPrevAffiliate + " but should be id " 3981 + cur.mPrevAffiliate); 3982 sane = false; 3983 break; 3984 } 3985 } 3986 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3987 Slog.wtf(TAG, "Bad chain @" + endIndex 3988 + ": task " + cur + " has affiliated id " 3989 + cur.mAffiliatedTaskId + " but should be " 3990 + task.mAffiliatedTaskId); 3991 sane = false; 3992 break; 3993 } 3994 prev = cur; 3995 endIndex++; 3996 if (endIndex >= N) { 3997 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3998 + ": last task " + prev); 3999 sane = false; 4000 break; 4001 } 4002 } 4003 if (sane) { 4004 if (endIndex < taskIndex) { 4005 Slog.wtf(TAG, "Bad chain @" + endIndex 4006 + ": did not extend to task " + task + " @" + taskIndex); 4007 sane = false; 4008 } 4009 } 4010 if (sane) { 4011 // All looks good, we can just move all of the affiliated tasks 4012 // to the top. 4013 for (int i=topIndex; i<=endIndex; i++) { 4014 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4015 + " from " + i + " to " + (i-topIndex)); 4016 TaskRecord cur = mRecentTasks.remove(i); 4017 mRecentTasks.add(i-topIndex, cur); 4018 } 4019 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4020 + " to " + endIndex); 4021 return true; 4022 } 4023 4024 // Whoops, couldn't do it. 4025 return false; 4026 } 4027 4028 final void addRecentTaskLocked(TaskRecord task) { 4029 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4030 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4031 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4032 4033 int N = mRecentTasks.size(); 4034 // Quick case: check if the top-most recent task is the same. 4035 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4036 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4037 return; 4038 } 4039 // Another quick case: check if this is part of a set of affiliated 4040 // tasks that are at the top. 4041 if (isAffiliated && N > 0 && task.inRecents 4042 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4043 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4044 + " at top when adding " + task); 4045 return; 4046 } 4047 // Another quick case: never add voice sessions. 4048 if (task.voiceSession != null) { 4049 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4050 return; 4051 } 4052 4053 boolean needAffiliationFix = false; 4054 4055 // Slightly less quick case: the task is already in recents, so all we need 4056 // to do is move it. 4057 if (task.inRecents) { 4058 int taskIndex = mRecentTasks.indexOf(task); 4059 if (taskIndex >= 0) { 4060 if (!isAffiliated) { 4061 // Simple case: this is not an affiliated task, so we just move it to the front. 4062 mRecentTasks.remove(taskIndex); 4063 mRecentTasks.add(0, task); 4064 notifyTaskPersisterLocked(task, false); 4065 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4066 + " from " + taskIndex); 4067 return; 4068 } else { 4069 // More complicated: need to keep all affiliated tasks together. 4070 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4071 // All went well. 4072 return; 4073 } 4074 4075 // Uh oh... something bad in the affiliation chain, try to rebuild 4076 // everything and then go through our general path of adding a new task. 4077 needAffiliationFix = true; 4078 } 4079 } else { 4080 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4081 needAffiliationFix = true; 4082 } 4083 } 4084 4085 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4086 trimRecentsForTaskLocked(task, true); 4087 4088 N = mRecentTasks.size(); 4089 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4090 final TaskRecord tr = mRecentTasks.remove(N - 1); 4091 tr.removedFromRecents(); 4092 N--; 4093 } 4094 task.inRecents = true; 4095 if (!isAffiliated || needAffiliationFix) { 4096 // If this is a simple non-affiliated task, or we had some failure trying to 4097 // handle it as part of an affilated task, then just place it at the top. 4098 mRecentTasks.add(0, task); 4099 } else if (isAffiliated) { 4100 // If this is a new affiliated task, then move all of the affiliated tasks 4101 // to the front and insert this new one. 4102 TaskRecord other = task.mNextAffiliate; 4103 if (other == null) { 4104 other = task.mPrevAffiliate; 4105 } 4106 if (other != null) { 4107 int otherIndex = mRecentTasks.indexOf(other); 4108 if (otherIndex >= 0) { 4109 // Insert new task at appropriate location. 4110 int taskIndex; 4111 if (other == task.mNextAffiliate) { 4112 // We found the index of our next affiliation, which is who is 4113 // before us in the list, so add after that point. 4114 taskIndex = otherIndex+1; 4115 } else { 4116 // We found the index of our previous affiliation, which is who is 4117 // after us in the list, so add at their position. 4118 taskIndex = otherIndex; 4119 } 4120 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4121 + taskIndex + ": " + task); 4122 mRecentTasks.add(taskIndex, task); 4123 4124 // Now move everything to the front. 4125 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4126 // All went well. 4127 return; 4128 } 4129 4130 // Uh oh... something bad in the affiliation chain, try to rebuild 4131 // everything and then go through our general path of adding a new task. 4132 needAffiliationFix = true; 4133 } else { 4134 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4135 + other); 4136 needAffiliationFix = true; 4137 } 4138 } else { 4139 if (DEBUG_RECENTS) Slog.d(TAG, 4140 "addRecent: adding affiliated task without next/prev:" + task); 4141 needAffiliationFix = true; 4142 } 4143 } 4144 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4145 4146 if (needAffiliationFix) { 4147 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4148 cleanupRecentTasksLocked(task.userId); 4149 } 4150 } 4151 4152 /** 4153 * If needed, remove oldest existing entries in recents that are for the same kind 4154 * of task as the given one. 4155 */ 4156 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4157 int N = mRecentTasks.size(); 4158 final Intent intent = task.intent; 4159 final boolean document = intent != null && intent.isDocument(); 4160 4161 int maxRecents = task.maxRecents - 1; 4162 for (int i=0; i<N; i++) { 4163 final TaskRecord tr = mRecentTasks.get(i); 4164 if (task != tr) { 4165 if (task.userId != tr.userId) { 4166 continue; 4167 } 4168 if (i > MAX_RECENT_BITMAPS) { 4169 tr.freeLastThumbnail(); 4170 } 4171 final Intent trIntent = tr.intent; 4172 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4173 (intent == null || !intent.filterEquals(trIntent))) { 4174 continue; 4175 } 4176 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4177 if (document && trIsDocument) { 4178 // These are the same document activity (not necessarily the same doc). 4179 if (maxRecents > 0) { 4180 --maxRecents; 4181 continue; 4182 } 4183 // Hit the maximum number of documents for this task. Fall through 4184 // and remove this document from recents. 4185 } else if (document || trIsDocument) { 4186 // Only one of these is a document. Not the droid we're looking for. 4187 continue; 4188 } 4189 } 4190 4191 if (!doTrim) { 4192 // If the caller is not actually asking for a trim, just tell them we reached 4193 // a point where the trim would happen. 4194 return i; 4195 } 4196 4197 // Either task and tr are the same or, their affinities match or their intents match 4198 // and neither of them is a document, or they are documents using the same activity 4199 // and their maxRecents has been reached. 4200 tr.disposeThumbnail(); 4201 mRecentTasks.remove(i); 4202 if (task != tr) { 4203 tr.removedFromRecents(); 4204 } 4205 i--; 4206 N--; 4207 if (task.intent == null) { 4208 // If the new recent task we are adding is not fully 4209 // specified, then replace it with the existing recent task. 4210 task = tr; 4211 } 4212 notifyTaskPersisterLocked(tr, false); 4213 } 4214 4215 return -1; 4216 } 4217 4218 @Override 4219 public void reportActivityFullyDrawn(IBinder token) { 4220 synchronized (this) { 4221 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4222 if (r == null) { 4223 return; 4224 } 4225 r.reportFullyDrawnLocked(); 4226 } 4227 } 4228 4229 @Override 4230 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4231 synchronized (this) { 4232 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4233 if (r == null) { 4234 return; 4235 } 4236 final long origId = Binder.clearCallingIdentity(); 4237 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4238 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4239 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4240 if (config != null) { 4241 r.frozenBeforeDestroy = true; 4242 if (!updateConfigurationLocked(config, r, false, false)) { 4243 mStackSupervisor.resumeTopActivitiesLocked(); 4244 } 4245 } 4246 Binder.restoreCallingIdentity(origId); 4247 } 4248 } 4249 4250 @Override 4251 public int getRequestedOrientation(IBinder token) { 4252 synchronized (this) { 4253 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4254 if (r == null) { 4255 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4256 } 4257 return mWindowManager.getAppOrientation(r.appToken); 4258 } 4259 } 4260 4261 /** 4262 * This is the internal entry point for handling Activity.finish(). 4263 * 4264 * @param token The Binder token referencing the Activity we want to finish. 4265 * @param resultCode Result code, if any, from this Activity. 4266 * @param resultData Result data (Intent), if any, from this Activity. 4267 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4268 * the root Activity in the task. 4269 * 4270 * @return Returns true if the activity successfully finished, or false if it is still running. 4271 */ 4272 @Override 4273 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4274 boolean finishTask) { 4275 // Refuse possible leaked file descriptors 4276 if (resultData != null && resultData.hasFileDescriptors() == true) { 4277 throw new IllegalArgumentException("File descriptors passed in Intent"); 4278 } 4279 4280 synchronized(this) { 4281 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4282 if (r == null) { 4283 return true; 4284 } 4285 // Keep track of the root activity of the task before we finish it 4286 TaskRecord tr = r.task; 4287 ActivityRecord rootR = tr.getRootActivity(); 4288 if (rootR == null) { 4289 Slog.w(TAG, "Finishing task with all activities already finished"); 4290 } 4291 // Do not allow task to finish in Lock Task mode. 4292 if (tr == mStackSupervisor.mLockTaskModeTask) { 4293 if (rootR == r) { 4294 Slog.i(TAG, "Not finishing task in lock task mode"); 4295 mStackSupervisor.showLockTaskToast(); 4296 return false; 4297 } 4298 } 4299 if (mController != null) { 4300 // Find the first activity that is not finishing. 4301 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4302 if (next != null) { 4303 // ask watcher if this is allowed 4304 boolean resumeOK = true; 4305 try { 4306 resumeOK = mController.activityResuming(next.packageName); 4307 } catch (RemoteException e) { 4308 mController = null; 4309 Watchdog.getInstance().setActivityController(null); 4310 } 4311 4312 if (!resumeOK) { 4313 Slog.i(TAG, "Not finishing activity because controller resumed"); 4314 return false; 4315 } 4316 } 4317 } 4318 final long origId = Binder.clearCallingIdentity(); 4319 try { 4320 boolean res; 4321 if (finishTask && r == rootR) { 4322 // If requested, remove the task that is associated to this activity only if it 4323 // was the root activity in the task. The result code and data is ignored 4324 // because we don't support returning them across task boundaries. 4325 res = removeTaskByIdLocked(tr.taskId, false); 4326 if (!res) { 4327 Slog.i(TAG, "Removing task failed to finish activity"); 4328 } 4329 } else { 4330 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4331 resultData, "app-request", true); 4332 if (!res) { 4333 Slog.i(TAG, "Failed to finish by app-request"); 4334 } 4335 } 4336 return res; 4337 } finally { 4338 Binder.restoreCallingIdentity(origId); 4339 } 4340 } 4341 } 4342 4343 @Override 4344 public final void finishHeavyWeightApp() { 4345 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4346 != PackageManager.PERMISSION_GRANTED) { 4347 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4348 + Binder.getCallingPid() 4349 + ", uid=" + Binder.getCallingUid() 4350 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4351 Slog.w(TAG, msg); 4352 throw new SecurityException(msg); 4353 } 4354 4355 synchronized(this) { 4356 if (mHeavyWeightProcess == null) { 4357 return; 4358 } 4359 4360 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4361 mHeavyWeightProcess.activities); 4362 for (int i=0; i<activities.size(); i++) { 4363 ActivityRecord r = activities.get(i); 4364 if (!r.finishing) { 4365 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4366 null, "finish-heavy", true); 4367 } 4368 } 4369 4370 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4371 mHeavyWeightProcess.userId, 0)); 4372 mHeavyWeightProcess = null; 4373 } 4374 } 4375 4376 @Override 4377 public void crashApplication(int uid, int initialPid, String packageName, 4378 String message) { 4379 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4380 != PackageManager.PERMISSION_GRANTED) { 4381 String msg = "Permission Denial: crashApplication() from pid=" 4382 + Binder.getCallingPid() 4383 + ", uid=" + Binder.getCallingUid() 4384 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4385 Slog.w(TAG, msg); 4386 throw new SecurityException(msg); 4387 } 4388 4389 synchronized(this) { 4390 ProcessRecord proc = null; 4391 4392 // Figure out which process to kill. We don't trust that initialPid 4393 // still has any relation to current pids, so must scan through the 4394 // list. 4395 synchronized (mPidsSelfLocked) { 4396 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4397 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4398 if (p.uid != uid) { 4399 continue; 4400 } 4401 if (p.pid == initialPid) { 4402 proc = p; 4403 break; 4404 } 4405 if (p.pkgList.containsKey(packageName)) { 4406 proc = p; 4407 } 4408 } 4409 } 4410 4411 if (proc == null) { 4412 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4413 + " initialPid=" + initialPid 4414 + " packageName=" + packageName); 4415 return; 4416 } 4417 4418 if (proc.thread != null) { 4419 if (proc.pid == Process.myPid()) { 4420 Log.w(TAG, "crashApplication: trying to crash self!"); 4421 return; 4422 } 4423 long ident = Binder.clearCallingIdentity(); 4424 try { 4425 proc.thread.scheduleCrash(message); 4426 } catch (RemoteException e) { 4427 } 4428 Binder.restoreCallingIdentity(ident); 4429 } 4430 } 4431 } 4432 4433 @Override 4434 public final void finishSubActivity(IBinder token, String resultWho, 4435 int requestCode) { 4436 synchronized(this) { 4437 final long origId = Binder.clearCallingIdentity(); 4438 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4439 if (r != null) { 4440 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4441 } 4442 Binder.restoreCallingIdentity(origId); 4443 } 4444 } 4445 4446 @Override 4447 public boolean finishActivityAffinity(IBinder token) { 4448 synchronized(this) { 4449 final long origId = Binder.clearCallingIdentity(); 4450 try { 4451 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4452 4453 ActivityRecord rootR = r.task.getRootActivity(); 4454 // Do not allow task to finish in Lock Task mode. 4455 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4456 if (rootR == r) { 4457 mStackSupervisor.showLockTaskToast(); 4458 return false; 4459 } 4460 } 4461 boolean res = false; 4462 if (r != null) { 4463 res = r.task.stack.finishActivityAffinityLocked(r); 4464 } 4465 return res; 4466 } finally { 4467 Binder.restoreCallingIdentity(origId); 4468 } 4469 } 4470 } 4471 4472 @Override 4473 public void finishVoiceTask(IVoiceInteractionSession session) { 4474 synchronized(this) { 4475 final long origId = Binder.clearCallingIdentity(); 4476 try { 4477 mStackSupervisor.finishVoiceTask(session); 4478 } finally { 4479 Binder.restoreCallingIdentity(origId); 4480 } 4481 } 4482 4483 } 4484 4485 @Override 4486 public boolean releaseActivityInstance(IBinder token) { 4487 synchronized(this) { 4488 final long origId = Binder.clearCallingIdentity(); 4489 try { 4490 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4491 if (r.task == null || r.task.stack == null) { 4492 return false; 4493 } 4494 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4495 } finally { 4496 Binder.restoreCallingIdentity(origId); 4497 } 4498 } 4499 } 4500 4501 @Override 4502 public void releaseSomeActivities(IApplicationThread appInt) { 4503 synchronized(this) { 4504 final long origId = Binder.clearCallingIdentity(); 4505 try { 4506 ProcessRecord app = getRecordForAppLocked(appInt); 4507 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4508 } finally { 4509 Binder.restoreCallingIdentity(origId); 4510 } 4511 } 4512 } 4513 4514 @Override 4515 public boolean willActivityBeVisible(IBinder token) { 4516 synchronized(this) { 4517 ActivityStack stack = ActivityRecord.getStackLocked(token); 4518 if (stack != null) { 4519 return stack.willActivityBeVisibleLocked(token); 4520 } 4521 return false; 4522 } 4523 } 4524 4525 @Override 4526 public void overridePendingTransition(IBinder token, String packageName, 4527 int enterAnim, int exitAnim) { 4528 synchronized(this) { 4529 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4530 if (self == null) { 4531 return; 4532 } 4533 4534 final long origId = Binder.clearCallingIdentity(); 4535 4536 if (self.state == ActivityState.RESUMED 4537 || self.state == ActivityState.PAUSING) { 4538 mWindowManager.overridePendingAppTransition(packageName, 4539 enterAnim, exitAnim, null); 4540 } 4541 4542 Binder.restoreCallingIdentity(origId); 4543 } 4544 } 4545 4546 /** 4547 * Main function for removing an existing process from the activity manager 4548 * as a result of that process going away. Clears out all connections 4549 * to the process. 4550 */ 4551 private final void handleAppDiedLocked(ProcessRecord app, 4552 boolean restarting, boolean allowRestart) { 4553 int pid = app.pid; 4554 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4555 if (!kept && !restarting) { 4556 removeLruProcessLocked(app); 4557 if (pid > 0) { 4558 ProcessList.remove(pid); 4559 } 4560 } 4561 4562 if (mProfileProc == app) { 4563 clearProfilerLocked(); 4564 } 4565 4566 // Remove this application's activities from active lists. 4567 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4568 4569 app.activities.clear(); 4570 4571 if (app.instrumentationClass != null) { 4572 Slog.w(TAG, "Crash of app " + app.processName 4573 + " running instrumentation " + app.instrumentationClass); 4574 Bundle info = new Bundle(); 4575 info.putString("shortMsg", "Process crashed."); 4576 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4577 } 4578 4579 if (!restarting) { 4580 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4581 // If there was nothing to resume, and we are not already 4582 // restarting this process, but there is a visible activity that 4583 // is hosted by the process... then make sure all visible 4584 // activities are running, taking care of restarting this 4585 // process. 4586 if (hasVisibleActivities) { 4587 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4588 } 4589 } 4590 } 4591 } 4592 4593 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4594 IBinder threadBinder = thread.asBinder(); 4595 // Find the application record. 4596 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4597 ProcessRecord rec = mLruProcesses.get(i); 4598 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4599 return i; 4600 } 4601 } 4602 return -1; 4603 } 4604 4605 final ProcessRecord getRecordForAppLocked( 4606 IApplicationThread thread) { 4607 if (thread == null) { 4608 return null; 4609 } 4610 4611 int appIndex = getLRURecordIndexForAppLocked(thread); 4612 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4613 } 4614 4615 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4616 // If there are no longer any background processes running, 4617 // and the app that died was not running instrumentation, 4618 // then tell everyone we are now low on memory. 4619 boolean haveBg = false; 4620 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4621 ProcessRecord rec = mLruProcesses.get(i); 4622 if (rec.thread != null 4623 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4624 haveBg = true; 4625 break; 4626 } 4627 } 4628 4629 if (!haveBg) { 4630 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4631 if (doReport) { 4632 long now = SystemClock.uptimeMillis(); 4633 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4634 doReport = false; 4635 } else { 4636 mLastMemUsageReportTime = now; 4637 } 4638 } 4639 final ArrayList<ProcessMemInfo> memInfos 4640 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4641 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4642 long now = SystemClock.uptimeMillis(); 4643 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4644 ProcessRecord rec = mLruProcesses.get(i); 4645 if (rec == dyingProc || rec.thread == null) { 4646 continue; 4647 } 4648 if (doReport) { 4649 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4650 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4651 } 4652 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4653 // The low memory report is overriding any current 4654 // state for a GC request. Make sure to do 4655 // heavy/important/visible/foreground processes first. 4656 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4657 rec.lastRequestedGc = 0; 4658 } else { 4659 rec.lastRequestedGc = rec.lastLowMemory; 4660 } 4661 rec.reportLowMemory = true; 4662 rec.lastLowMemory = now; 4663 mProcessesToGc.remove(rec); 4664 addProcessToGcListLocked(rec); 4665 } 4666 } 4667 if (doReport) { 4668 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4669 mHandler.sendMessage(msg); 4670 } 4671 scheduleAppGcsLocked(); 4672 } 4673 } 4674 4675 final void appDiedLocked(ProcessRecord app) { 4676 appDiedLocked(app, app.pid, app.thread); 4677 } 4678 4679 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4680 // First check if this ProcessRecord is actually active for the pid. 4681 synchronized (mPidsSelfLocked) { 4682 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4683 if (curProc != app) { 4684 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4685 return; 4686 } 4687 } 4688 4689 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4690 synchronized (stats) { 4691 stats.noteProcessDiedLocked(app.info.uid, pid); 4692 } 4693 4694 if (!app.killed) { 4695 Process.killProcessQuiet(pid); 4696 Process.killProcessGroup(app.info.uid, pid); 4697 app.killed = true; 4698 } 4699 4700 // Clean up already done if the process has been re-started. 4701 if (app.pid == pid && app.thread != null && 4702 app.thread.asBinder() == thread.asBinder()) { 4703 boolean doLowMem = app.instrumentationClass == null; 4704 boolean doOomAdj = doLowMem; 4705 if (!app.killedByAm) { 4706 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4707 + ") has died"); 4708 mAllowLowerMemLevel = true; 4709 } else { 4710 // Note that we always want to do oom adj to update our state with the 4711 // new number of procs. 4712 mAllowLowerMemLevel = false; 4713 doLowMem = false; 4714 } 4715 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4716 if (DEBUG_CLEANUP) Slog.v( 4717 TAG, "Dying app: " + app + ", pid: " + pid 4718 + ", thread: " + thread.asBinder()); 4719 handleAppDiedLocked(app, false, true); 4720 4721 if (doOomAdj) { 4722 updateOomAdjLocked(); 4723 } 4724 if (doLowMem) { 4725 doLowMemReportIfNeededLocked(app); 4726 } 4727 } else if (app.pid != pid) { 4728 // A new process has already been started. 4729 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4730 + ") has died and restarted (pid " + app.pid + ")."); 4731 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4732 } else if (DEBUG_PROCESSES) { 4733 Slog.d(TAG, "Received spurious death notification for thread " 4734 + thread.asBinder()); 4735 } 4736 } 4737 4738 /** 4739 * If a stack trace dump file is configured, dump process stack traces. 4740 * @param clearTraces causes the dump file to be erased prior to the new 4741 * traces being written, if true; when false, the new traces will be 4742 * appended to any existing file content. 4743 * @param firstPids of dalvik VM processes to dump stack traces for first 4744 * @param lastPids of dalvik VM processes to dump stack traces for last 4745 * @param nativeProcs optional list of native process names to dump stack crawls 4746 * @return file containing stack traces, or null if no dump file is configured 4747 */ 4748 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4749 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4750 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4751 if (tracesPath == null || tracesPath.length() == 0) { 4752 return null; 4753 } 4754 4755 File tracesFile = new File(tracesPath); 4756 try { 4757 File tracesDir = tracesFile.getParentFile(); 4758 if (!tracesDir.exists()) { 4759 tracesDir.mkdirs(); 4760 if (!SELinux.restorecon(tracesDir)) { 4761 return null; 4762 } 4763 } 4764 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4765 4766 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4767 tracesFile.createNewFile(); 4768 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4769 } catch (IOException e) { 4770 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4771 return null; 4772 } 4773 4774 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4775 return tracesFile; 4776 } 4777 4778 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4779 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4780 // Use a FileObserver to detect when traces finish writing. 4781 // The order of traces is considered important to maintain for legibility. 4782 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4783 @Override 4784 public synchronized void onEvent(int event, String path) { notify(); } 4785 }; 4786 4787 try { 4788 observer.startWatching(); 4789 4790 // First collect all of the stacks of the most important pids. 4791 if (firstPids != null) { 4792 try { 4793 int num = firstPids.size(); 4794 for (int i = 0; i < num; i++) { 4795 synchronized (observer) { 4796 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4797 observer.wait(200); // Wait for write-close, give up after 200msec 4798 } 4799 } 4800 } catch (InterruptedException e) { 4801 Slog.wtf(TAG, e); 4802 } 4803 } 4804 4805 // Next collect the stacks of the native pids 4806 if (nativeProcs != null) { 4807 int[] pids = Process.getPidsForCommands(nativeProcs); 4808 if (pids != null) { 4809 for (int pid : pids) { 4810 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4811 } 4812 } 4813 } 4814 4815 // Lastly, measure CPU usage. 4816 if (processCpuTracker != null) { 4817 processCpuTracker.init(); 4818 System.gc(); 4819 processCpuTracker.update(); 4820 try { 4821 synchronized (processCpuTracker) { 4822 processCpuTracker.wait(500); // measure over 1/2 second. 4823 } 4824 } catch (InterruptedException e) { 4825 } 4826 processCpuTracker.update(); 4827 4828 // We'll take the stack crawls of just the top apps using CPU. 4829 final int N = processCpuTracker.countWorkingStats(); 4830 int numProcs = 0; 4831 for (int i=0; i<N && numProcs<5; i++) { 4832 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4833 if (lastPids.indexOfKey(stats.pid) >= 0) { 4834 numProcs++; 4835 try { 4836 synchronized (observer) { 4837 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4838 observer.wait(200); // Wait for write-close, give up after 200msec 4839 } 4840 } catch (InterruptedException e) { 4841 Slog.wtf(TAG, e); 4842 } 4843 4844 } 4845 } 4846 } 4847 } finally { 4848 observer.stopWatching(); 4849 } 4850 } 4851 4852 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4853 if (true || IS_USER_BUILD) { 4854 return; 4855 } 4856 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4857 if (tracesPath == null || tracesPath.length() == 0) { 4858 return; 4859 } 4860 4861 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4862 StrictMode.allowThreadDiskWrites(); 4863 try { 4864 final File tracesFile = new File(tracesPath); 4865 final File tracesDir = tracesFile.getParentFile(); 4866 final File tracesTmp = new File(tracesDir, "__tmp__"); 4867 try { 4868 if (!tracesDir.exists()) { 4869 tracesDir.mkdirs(); 4870 if (!SELinux.restorecon(tracesDir.getPath())) { 4871 return; 4872 } 4873 } 4874 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4875 4876 if (tracesFile.exists()) { 4877 tracesTmp.delete(); 4878 tracesFile.renameTo(tracesTmp); 4879 } 4880 StringBuilder sb = new StringBuilder(); 4881 Time tobj = new Time(); 4882 tobj.set(System.currentTimeMillis()); 4883 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4884 sb.append(": "); 4885 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4886 sb.append(" since "); 4887 sb.append(msg); 4888 FileOutputStream fos = new FileOutputStream(tracesFile); 4889 fos.write(sb.toString().getBytes()); 4890 if (app == null) { 4891 fos.write("\n*** No application process!".getBytes()); 4892 } 4893 fos.close(); 4894 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4895 } catch (IOException e) { 4896 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4897 return; 4898 } 4899 4900 if (app != null) { 4901 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4902 firstPids.add(app.pid); 4903 dumpStackTraces(tracesPath, firstPids, null, null, null); 4904 } 4905 4906 File lastTracesFile = null; 4907 File curTracesFile = null; 4908 for (int i=9; i>=0; i--) { 4909 String name = String.format(Locale.US, "slow%02d.txt", i); 4910 curTracesFile = new File(tracesDir, name); 4911 if (curTracesFile.exists()) { 4912 if (lastTracesFile != null) { 4913 curTracesFile.renameTo(lastTracesFile); 4914 } else { 4915 curTracesFile.delete(); 4916 } 4917 } 4918 lastTracesFile = curTracesFile; 4919 } 4920 tracesFile.renameTo(curTracesFile); 4921 if (tracesTmp.exists()) { 4922 tracesTmp.renameTo(tracesFile); 4923 } 4924 } finally { 4925 StrictMode.setThreadPolicy(oldPolicy); 4926 } 4927 } 4928 4929 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4930 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4931 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4932 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4933 4934 if (mController != null) { 4935 try { 4936 // 0 == continue, -1 = kill process immediately 4937 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4938 if (res < 0 && app.pid != MY_PID) { 4939 app.kill("anr", true); 4940 } 4941 } catch (RemoteException e) { 4942 mController = null; 4943 Watchdog.getInstance().setActivityController(null); 4944 } 4945 } 4946 4947 long anrTime = SystemClock.uptimeMillis(); 4948 if (MONITOR_CPU_USAGE) { 4949 updateCpuStatsNow(); 4950 } 4951 4952 synchronized (this) { 4953 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4954 if (mShuttingDown) { 4955 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4956 return; 4957 } else if (app.notResponding) { 4958 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4959 return; 4960 } else if (app.crashing) { 4961 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4962 return; 4963 } 4964 4965 // In case we come through here for the same app before completing 4966 // this one, mark as anring now so we will bail out. 4967 app.notResponding = true; 4968 4969 // Log the ANR to the event log. 4970 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4971 app.processName, app.info.flags, annotation); 4972 4973 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4974 firstPids.add(app.pid); 4975 4976 int parentPid = app.pid; 4977 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4978 if (parentPid != app.pid) firstPids.add(parentPid); 4979 4980 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4981 4982 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4983 ProcessRecord r = mLruProcesses.get(i); 4984 if (r != null && r.thread != null) { 4985 int pid = r.pid; 4986 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4987 if (r.persistent) { 4988 firstPids.add(pid); 4989 } else { 4990 lastPids.put(pid, Boolean.TRUE); 4991 } 4992 } 4993 } 4994 } 4995 } 4996 4997 // Log the ANR to the main log. 4998 StringBuilder info = new StringBuilder(); 4999 info.setLength(0); 5000 info.append("ANR in ").append(app.processName); 5001 if (activity != null && activity.shortComponentName != null) { 5002 info.append(" (").append(activity.shortComponentName).append(")"); 5003 } 5004 info.append("\n"); 5005 info.append("PID: ").append(app.pid).append("\n"); 5006 if (annotation != null) { 5007 info.append("Reason: ").append(annotation).append("\n"); 5008 } 5009 if (parent != null && parent != activity) { 5010 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5011 } 5012 5013 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5014 5015 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5016 NATIVE_STACKS_OF_INTEREST); 5017 5018 String cpuInfo = null; 5019 if (MONITOR_CPU_USAGE) { 5020 updateCpuStatsNow(); 5021 synchronized (mProcessCpuTracker) { 5022 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5023 } 5024 info.append(processCpuTracker.printCurrentLoad()); 5025 info.append(cpuInfo); 5026 } 5027 5028 info.append(processCpuTracker.printCurrentState(anrTime)); 5029 5030 Slog.e(TAG, info.toString()); 5031 if (tracesFile == null) { 5032 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5033 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5034 } 5035 5036 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5037 cpuInfo, tracesFile, null); 5038 5039 if (mController != null) { 5040 try { 5041 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5042 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5043 if (res != 0) { 5044 if (res < 0 && app.pid != MY_PID) { 5045 app.kill("anr", true); 5046 } else { 5047 synchronized (this) { 5048 mServices.scheduleServiceTimeoutLocked(app); 5049 } 5050 } 5051 return; 5052 } 5053 } catch (RemoteException e) { 5054 mController = null; 5055 Watchdog.getInstance().setActivityController(null); 5056 } 5057 } 5058 5059 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5060 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5061 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5062 5063 synchronized (this) { 5064 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5065 5066 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5067 app.kill("bg anr", true); 5068 return; 5069 } 5070 5071 // Set the app's notResponding state, and look up the errorReportReceiver 5072 makeAppNotRespondingLocked(app, 5073 activity != null ? activity.shortComponentName : null, 5074 annotation != null ? "ANR " + annotation : "ANR", 5075 info.toString()); 5076 5077 // Bring up the infamous App Not Responding dialog 5078 Message msg = Message.obtain(); 5079 HashMap<String, Object> map = new HashMap<String, Object>(); 5080 msg.what = SHOW_NOT_RESPONDING_MSG; 5081 msg.obj = map; 5082 msg.arg1 = aboveSystem ? 1 : 0; 5083 map.put("app", app); 5084 if (activity != null) { 5085 map.put("activity", activity); 5086 } 5087 5088 mHandler.sendMessage(msg); 5089 } 5090 } 5091 5092 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5093 if (!mLaunchWarningShown) { 5094 mLaunchWarningShown = true; 5095 mHandler.post(new Runnable() { 5096 @Override 5097 public void run() { 5098 synchronized (ActivityManagerService.this) { 5099 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5100 d.show(); 5101 mHandler.postDelayed(new Runnable() { 5102 @Override 5103 public void run() { 5104 synchronized (ActivityManagerService.this) { 5105 d.dismiss(); 5106 mLaunchWarningShown = false; 5107 } 5108 } 5109 }, 4000); 5110 } 5111 } 5112 }); 5113 } 5114 } 5115 5116 @Override 5117 public boolean clearApplicationUserData(final String packageName, 5118 final IPackageDataObserver observer, int userId) { 5119 enforceNotIsolatedCaller("clearApplicationUserData"); 5120 int uid = Binder.getCallingUid(); 5121 int pid = Binder.getCallingPid(); 5122 userId = handleIncomingUser(pid, uid, 5123 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5124 long callingId = Binder.clearCallingIdentity(); 5125 try { 5126 IPackageManager pm = AppGlobals.getPackageManager(); 5127 int pkgUid = -1; 5128 synchronized(this) { 5129 try { 5130 pkgUid = pm.getPackageUid(packageName, userId); 5131 } catch (RemoteException e) { 5132 } 5133 if (pkgUid == -1) { 5134 Slog.w(TAG, "Invalid packageName: " + packageName); 5135 if (observer != null) { 5136 try { 5137 observer.onRemoveCompleted(packageName, false); 5138 } catch (RemoteException e) { 5139 Slog.i(TAG, "Observer no longer exists."); 5140 } 5141 } 5142 return false; 5143 } 5144 if (uid == pkgUid || checkComponentPermission( 5145 android.Manifest.permission.CLEAR_APP_USER_DATA, 5146 pid, uid, -1, true) 5147 == PackageManager.PERMISSION_GRANTED) { 5148 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5149 } else { 5150 throw new SecurityException("PID " + pid + " does not have permission " 5151 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5152 + " of package " + packageName); 5153 } 5154 5155 // Remove all tasks match the cleared application package and user 5156 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5157 final TaskRecord tr = mRecentTasks.get(i); 5158 final String taskPackageName = 5159 tr.getBaseIntent().getComponent().getPackageName(); 5160 if (tr.userId != userId) continue; 5161 if (!taskPackageName.equals(packageName)) continue; 5162 removeTaskByIdLocked(tr.taskId, false); 5163 } 5164 } 5165 5166 try { 5167 // Clear application user data 5168 pm.clearApplicationUserData(packageName, observer, userId); 5169 5170 synchronized(this) { 5171 // Remove all permissions granted from/to this package 5172 removeUriPermissionsForPackageLocked(packageName, userId, true); 5173 } 5174 5175 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5176 Uri.fromParts("package", packageName, null)); 5177 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5178 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5179 null, null, 0, null, null, null, false, false, userId); 5180 } catch (RemoteException e) { 5181 } 5182 } finally { 5183 Binder.restoreCallingIdentity(callingId); 5184 } 5185 return true; 5186 } 5187 5188 @Override 5189 public void killBackgroundProcesses(final String packageName, int userId) { 5190 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5191 != PackageManager.PERMISSION_GRANTED && 5192 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5193 != PackageManager.PERMISSION_GRANTED) { 5194 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5195 + Binder.getCallingPid() 5196 + ", uid=" + Binder.getCallingUid() 5197 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5198 Slog.w(TAG, msg); 5199 throw new SecurityException(msg); 5200 } 5201 5202 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5203 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5204 long callingId = Binder.clearCallingIdentity(); 5205 try { 5206 IPackageManager pm = AppGlobals.getPackageManager(); 5207 synchronized(this) { 5208 int appId = -1; 5209 try { 5210 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5211 } catch (RemoteException e) { 5212 } 5213 if (appId == -1) { 5214 Slog.w(TAG, "Invalid packageName: " + packageName); 5215 return; 5216 } 5217 killPackageProcessesLocked(packageName, appId, userId, 5218 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5219 } 5220 } finally { 5221 Binder.restoreCallingIdentity(callingId); 5222 } 5223 } 5224 5225 @Override 5226 public void killAllBackgroundProcesses() { 5227 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5228 != PackageManager.PERMISSION_GRANTED) { 5229 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5230 + Binder.getCallingPid() 5231 + ", uid=" + Binder.getCallingUid() 5232 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5233 Slog.w(TAG, msg); 5234 throw new SecurityException(msg); 5235 } 5236 5237 long callingId = Binder.clearCallingIdentity(); 5238 try { 5239 synchronized(this) { 5240 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5241 final int NP = mProcessNames.getMap().size(); 5242 for (int ip=0; ip<NP; ip++) { 5243 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5244 final int NA = apps.size(); 5245 for (int ia=0; ia<NA; ia++) { 5246 ProcessRecord app = apps.valueAt(ia); 5247 if (app.persistent) { 5248 // we don't kill persistent processes 5249 continue; 5250 } 5251 if (app.removed) { 5252 procs.add(app); 5253 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5254 app.removed = true; 5255 procs.add(app); 5256 } 5257 } 5258 } 5259 5260 int N = procs.size(); 5261 for (int i=0; i<N; i++) { 5262 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5263 } 5264 mAllowLowerMemLevel = true; 5265 updateOomAdjLocked(); 5266 doLowMemReportIfNeededLocked(null); 5267 } 5268 } finally { 5269 Binder.restoreCallingIdentity(callingId); 5270 } 5271 } 5272 5273 @Override 5274 public void forceStopPackage(final String packageName, int userId) { 5275 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5276 != PackageManager.PERMISSION_GRANTED) { 5277 String msg = "Permission Denial: forceStopPackage() from pid=" 5278 + Binder.getCallingPid() 5279 + ", uid=" + Binder.getCallingUid() 5280 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5281 Slog.w(TAG, msg); 5282 throw new SecurityException(msg); 5283 } 5284 final int callingPid = Binder.getCallingPid(); 5285 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5286 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5287 long callingId = Binder.clearCallingIdentity(); 5288 try { 5289 IPackageManager pm = AppGlobals.getPackageManager(); 5290 synchronized(this) { 5291 int[] users = userId == UserHandle.USER_ALL 5292 ? getUsersLocked() : new int[] { userId }; 5293 for (int user : users) { 5294 int pkgUid = -1; 5295 try { 5296 pkgUid = pm.getPackageUid(packageName, user); 5297 } catch (RemoteException e) { 5298 } 5299 if (pkgUid == -1) { 5300 Slog.w(TAG, "Invalid packageName: " + packageName); 5301 continue; 5302 } 5303 try { 5304 pm.setPackageStoppedState(packageName, true, user); 5305 } catch (RemoteException e) { 5306 } catch (IllegalArgumentException e) { 5307 Slog.w(TAG, "Failed trying to unstop package " 5308 + packageName + ": " + e); 5309 } 5310 if (isUserRunningLocked(user, false)) { 5311 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5312 } 5313 } 5314 } 5315 } finally { 5316 Binder.restoreCallingIdentity(callingId); 5317 } 5318 } 5319 5320 @Override 5321 public void addPackageDependency(String packageName) { 5322 synchronized (this) { 5323 int callingPid = Binder.getCallingPid(); 5324 if (callingPid == Process.myPid()) { 5325 // Yeah, um, no. 5326 Slog.w(TAG, "Can't addPackageDependency on system process"); 5327 return; 5328 } 5329 ProcessRecord proc; 5330 synchronized (mPidsSelfLocked) { 5331 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5332 } 5333 if (proc != null) { 5334 if (proc.pkgDeps == null) { 5335 proc.pkgDeps = new ArraySet<String>(1); 5336 } 5337 proc.pkgDeps.add(packageName); 5338 } 5339 } 5340 } 5341 5342 /* 5343 * The pkg name and app id have to be specified. 5344 */ 5345 @Override 5346 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5347 if (pkg == null) { 5348 return; 5349 } 5350 // Make sure the uid is valid. 5351 if (appid < 0) { 5352 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5353 return; 5354 } 5355 int callerUid = Binder.getCallingUid(); 5356 // Only the system server can kill an application 5357 if (callerUid == Process.SYSTEM_UID) { 5358 // Post an aysnc message to kill the application 5359 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5360 msg.arg1 = appid; 5361 msg.arg2 = 0; 5362 Bundle bundle = new Bundle(); 5363 bundle.putString("pkg", pkg); 5364 bundle.putString("reason", reason); 5365 msg.obj = bundle; 5366 mHandler.sendMessage(msg); 5367 } else { 5368 throw new SecurityException(callerUid + " cannot kill pkg: " + 5369 pkg); 5370 } 5371 } 5372 5373 @Override 5374 public void closeSystemDialogs(String reason) { 5375 enforceNotIsolatedCaller("closeSystemDialogs"); 5376 5377 final int pid = Binder.getCallingPid(); 5378 final int uid = Binder.getCallingUid(); 5379 final long origId = Binder.clearCallingIdentity(); 5380 try { 5381 synchronized (this) { 5382 // Only allow this from foreground processes, so that background 5383 // applications can't abuse it to prevent system UI from being shown. 5384 if (uid >= Process.FIRST_APPLICATION_UID) { 5385 ProcessRecord proc; 5386 synchronized (mPidsSelfLocked) { 5387 proc = mPidsSelfLocked.get(pid); 5388 } 5389 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5390 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5391 + " from background process " + proc); 5392 return; 5393 } 5394 } 5395 closeSystemDialogsLocked(reason); 5396 } 5397 } finally { 5398 Binder.restoreCallingIdentity(origId); 5399 } 5400 } 5401 5402 void closeSystemDialogsLocked(String reason) { 5403 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5404 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5405 | Intent.FLAG_RECEIVER_FOREGROUND); 5406 if (reason != null) { 5407 intent.putExtra("reason", reason); 5408 } 5409 mWindowManager.closeSystemDialogs(reason); 5410 5411 mStackSupervisor.closeSystemDialogsLocked(); 5412 5413 broadcastIntentLocked(null, null, intent, null, 5414 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5415 Process.SYSTEM_UID, UserHandle.USER_ALL); 5416 } 5417 5418 @Override 5419 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5420 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5421 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5422 for (int i=pids.length-1; i>=0; i--) { 5423 ProcessRecord proc; 5424 int oomAdj; 5425 synchronized (this) { 5426 synchronized (mPidsSelfLocked) { 5427 proc = mPidsSelfLocked.get(pids[i]); 5428 oomAdj = proc != null ? proc.setAdj : 0; 5429 } 5430 } 5431 infos[i] = new Debug.MemoryInfo(); 5432 Debug.getMemoryInfo(pids[i], infos[i]); 5433 if (proc != null) { 5434 synchronized (this) { 5435 if (proc.thread != null && proc.setAdj == oomAdj) { 5436 // Record this for posterity if the process has been stable. 5437 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5438 infos[i].getTotalUss(), false, proc.pkgList); 5439 } 5440 } 5441 } 5442 } 5443 return infos; 5444 } 5445 5446 @Override 5447 public long[] getProcessPss(int[] pids) { 5448 enforceNotIsolatedCaller("getProcessPss"); 5449 long[] pss = new long[pids.length]; 5450 for (int i=pids.length-1; i>=0; i--) { 5451 ProcessRecord proc; 5452 int oomAdj; 5453 synchronized (this) { 5454 synchronized (mPidsSelfLocked) { 5455 proc = mPidsSelfLocked.get(pids[i]); 5456 oomAdj = proc != null ? proc.setAdj : 0; 5457 } 5458 } 5459 long[] tmpUss = new long[1]; 5460 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5461 if (proc != null) { 5462 synchronized (this) { 5463 if (proc.thread != null && proc.setAdj == oomAdj) { 5464 // Record this for posterity if the process has been stable. 5465 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5466 } 5467 } 5468 } 5469 } 5470 return pss; 5471 } 5472 5473 @Override 5474 public void killApplicationProcess(String processName, int uid) { 5475 if (processName == null) { 5476 return; 5477 } 5478 5479 int callerUid = Binder.getCallingUid(); 5480 // Only the system server can kill an application 5481 if (callerUid == Process.SYSTEM_UID) { 5482 synchronized (this) { 5483 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5484 if (app != null && app.thread != null) { 5485 try { 5486 app.thread.scheduleSuicide(); 5487 } catch (RemoteException e) { 5488 // If the other end already died, then our work here is done. 5489 } 5490 } else { 5491 Slog.w(TAG, "Process/uid not found attempting kill of " 5492 + processName + " / " + uid); 5493 } 5494 } 5495 } else { 5496 throw new SecurityException(callerUid + " cannot kill app process: " + 5497 processName); 5498 } 5499 } 5500 5501 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5502 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5503 false, true, false, false, UserHandle.getUserId(uid), reason); 5504 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5505 Uri.fromParts("package", packageName, null)); 5506 if (!mProcessesReady) { 5507 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5508 | Intent.FLAG_RECEIVER_FOREGROUND); 5509 } 5510 intent.putExtra(Intent.EXTRA_UID, uid); 5511 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5512 broadcastIntentLocked(null, null, intent, 5513 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5514 false, false, 5515 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5516 } 5517 5518 private void forceStopUserLocked(int userId, String reason) { 5519 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5520 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5521 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5522 | Intent.FLAG_RECEIVER_FOREGROUND); 5523 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5524 broadcastIntentLocked(null, null, intent, 5525 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5526 false, false, 5527 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5528 } 5529 5530 private final boolean killPackageProcessesLocked(String packageName, int appId, 5531 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5532 boolean doit, boolean evenPersistent, String reason) { 5533 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5534 5535 // Remove all processes this package may have touched: all with the 5536 // same UID (except for the system or root user), and all whose name 5537 // matches the package name. 5538 final int NP = mProcessNames.getMap().size(); 5539 for (int ip=0; ip<NP; ip++) { 5540 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5541 final int NA = apps.size(); 5542 for (int ia=0; ia<NA; ia++) { 5543 ProcessRecord app = apps.valueAt(ia); 5544 if (app.persistent && !evenPersistent) { 5545 // we don't kill persistent processes 5546 continue; 5547 } 5548 if (app.removed) { 5549 if (doit) { 5550 procs.add(app); 5551 } 5552 continue; 5553 } 5554 5555 // Skip process if it doesn't meet our oom adj requirement. 5556 if (app.setAdj < minOomAdj) { 5557 continue; 5558 } 5559 5560 // If no package is specified, we call all processes under the 5561 // give user id. 5562 if (packageName == null) { 5563 if (app.userId != userId) { 5564 continue; 5565 } 5566 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5567 continue; 5568 } 5569 // Package has been specified, we want to hit all processes 5570 // that match it. We need to qualify this by the processes 5571 // that are running under the specified app and user ID. 5572 } else { 5573 final boolean isDep = app.pkgDeps != null 5574 && app.pkgDeps.contains(packageName); 5575 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5576 continue; 5577 } 5578 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5579 continue; 5580 } 5581 if (!app.pkgList.containsKey(packageName) && !isDep) { 5582 continue; 5583 } 5584 } 5585 5586 // Process has passed all conditions, kill it! 5587 if (!doit) { 5588 return true; 5589 } 5590 app.removed = true; 5591 procs.add(app); 5592 } 5593 } 5594 5595 int N = procs.size(); 5596 for (int i=0; i<N; i++) { 5597 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5598 } 5599 updateOomAdjLocked(); 5600 return N > 0; 5601 } 5602 5603 private final boolean forceStopPackageLocked(String name, int appId, 5604 boolean callerWillRestart, boolean purgeCache, boolean doit, 5605 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5606 int i; 5607 int N; 5608 5609 if (userId == UserHandle.USER_ALL && name == null) { 5610 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5611 } 5612 5613 if (appId < 0 && name != null) { 5614 try { 5615 appId = UserHandle.getAppId( 5616 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5617 } catch (RemoteException e) { 5618 } 5619 } 5620 5621 if (doit) { 5622 if (name != null) { 5623 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5624 + " user=" + userId + ": " + reason); 5625 } else { 5626 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5627 } 5628 5629 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5630 for (int ip=pmap.size()-1; ip>=0; ip--) { 5631 SparseArray<Long> ba = pmap.valueAt(ip); 5632 for (i=ba.size()-1; i>=0; i--) { 5633 boolean remove = false; 5634 final int entUid = ba.keyAt(i); 5635 if (name != null) { 5636 if (userId == UserHandle.USER_ALL) { 5637 if (UserHandle.getAppId(entUid) == appId) { 5638 remove = true; 5639 } 5640 } else { 5641 if (entUid == UserHandle.getUid(userId, appId)) { 5642 remove = true; 5643 } 5644 } 5645 } else if (UserHandle.getUserId(entUid) == userId) { 5646 remove = true; 5647 } 5648 if (remove) { 5649 ba.removeAt(i); 5650 } 5651 } 5652 if (ba.size() == 0) { 5653 pmap.removeAt(ip); 5654 } 5655 } 5656 } 5657 5658 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5659 -100, callerWillRestart, true, doit, evenPersistent, 5660 name == null ? ("stop user " + userId) : ("stop " + name)); 5661 5662 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5663 if (!doit) { 5664 return true; 5665 } 5666 didSomething = true; 5667 } 5668 5669 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5670 if (!doit) { 5671 return true; 5672 } 5673 didSomething = true; 5674 } 5675 5676 if (name == null) { 5677 // Remove all sticky broadcasts from this user. 5678 mStickyBroadcasts.remove(userId); 5679 } 5680 5681 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5682 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5683 userId, providers)) { 5684 if (!doit) { 5685 return true; 5686 } 5687 didSomething = true; 5688 } 5689 N = providers.size(); 5690 for (i=0; i<N; i++) { 5691 removeDyingProviderLocked(null, providers.get(i), true); 5692 } 5693 5694 // Remove transient permissions granted from/to this package/user 5695 removeUriPermissionsForPackageLocked(name, userId, false); 5696 5697 if (name == null || uninstalling) { 5698 // Remove pending intents. For now we only do this when force 5699 // stopping users, because we have some problems when doing this 5700 // for packages -- app widgets are not currently cleaned up for 5701 // such packages, so they can be left with bad pending intents. 5702 if (mIntentSenderRecords.size() > 0) { 5703 Iterator<WeakReference<PendingIntentRecord>> it 5704 = mIntentSenderRecords.values().iterator(); 5705 while (it.hasNext()) { 5706 WeakReference<PendingIntentRecord> wpir = it.next(); 5707 if (wpir == null) { 5708 it.remove(); 5709 continue; 5710 } 5711 PendingIntentRecord pir = wpir.get(); 5712 if (pir == null) { 5713 it.remove(); 5714 continue; 5715 } 5716 if (name == null) { 5717 // Stopping user, remove all objects for the user. 5718 if (pir.key.userId != userId) { 5719 // Not the same user, skip it. 5720 continue; 5721 } 5722 } else { 5723 if (UserHandle.getAppId(pir.uid) != appId) { 5724 // Different app id, skip it. 5725 continue; 5726 } 5727 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5728 // Different user, skip it. 5729 continue; 5730 } 5731 if (!pir.key.packageName.equals(name)) { 5732 // Different package, skip it. 5733 continue; 5734 } 5735 } 5736 if (!doit) { 5737 return true; 5738 } 5739 didSomething = true; 5740 it.remove(); 5741 pir.canceled = true; 5742 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5743 pir.key.activity.pendingResults.remove(pir.ref); 5744 } 5745 } 5746 } 5747 } 5748 5749 if (doit) { 5750 if (purgeCache && name != null) { 5751 AttributeCache ac = AttributeCache.instance(); 5752 if (ac != null) { 5753 ac.removePackage(name); 5754 } 5755 } 5756 if (mBooted) { 5757 mStackSupervisor.resumeTopActivitiesLocked(); 5758 mStackSupervisor.scheduleIdleLocked(); 5759 } 5760 } 5761 5762 return didSomething; 5763 } 5764 5765 private final boolean removeProcessLocked(ProcessRecord app, 5766 boolean callerWillRestart, boolean allowRestart, String reason) { 5767 final String name = app.processName; 5768 final int uid = app.uid; 5769 if (DEBUG_PROCESSES) Slog.d( 5770 TAG, "Force removing proc " + app.toShortString() + " (" + name 5771 + "/" + uid + ")"); 5772 5773 mProcessNames.remove(name, uid); 5774 mIsolatedProcesses.remove(app.uid); 5775 if (mHeavyWeightProcess == app) { 5776 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5777 mHeavyWeightProcess.userId, 0)); 5778 mHeavyWeightProcess = null; 5779 } 5780 boolean needRestart = false; 5781 if (app.pid > 0 && app.pid != MY_PID) { 5782 int pid = app.pid; 5783 synchronized (mPidsSelfLocked) { 5784 mPidsSelfLocked.remove(pid); 5785 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5786 } 5787 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5788 if (app.isolated) { 5789 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5790 } 5791 app.kill(reason, true); 5792 handleAppDiedLocked(app, true, allowRestart); 5793 removeLruProcessLocked(app); 5794 5795 if (app.persistent && !app.isolated) { 5796 if (!callerWillRestart) { 5797 addAppLocked(app.info, false, null /* ABI override */); 5798 } else { 5799 needRestart = true; 5800 } 5801 } 5802 } else { 5803 mRemovedProcesses.add(app); 5804 } 5805 5806 return needRestart; 5807 } 5808 5809 private final void processStartTimedOutLocked(ProcessRecord app) { 5810 final int pid = app.pid; 5811 boolean gone = false; 5812 synchronized (mPidsSelfLocked) { 5813 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5814 if (knownApp != null && knownApp.thread == null) { 5815 mPidsSelfLocked.remove(pid); 5816 gone = true; 5817 } 5818 } 5819 5820 if (gone) { 5821 Slog.w(TAG, "Process " + app + " failed to attach"); 5822 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5823 pid, app.uid, app.processName); 5824 mProcessNames.remove(app.processName, app.uid); 5825 mIsolatedProcesses.remove(app.uid); 5826 if (mHeavyWeightProcess == app) { 5827 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5828 mHeavyWeightProcess.userId, 0)); 5829 mHeavyWeightProcess = null; 5830 } 5831 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5832 if (app.isolated) { 5833 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5834 } 5835 // Take care of any launching providers waiting for this process. 5836 checkAppInLaunchingProvidersLocked(app, true); 5837 // Take care of any services that are waiting for the process. 5838 mServices.processStartTimedOutLocked(app); 5839 app.kill("start timeout", true); 5840 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5841 Slog.w(TAG, "Unattached app died before backup, skipping"); 5842 try { 5843 IBackupManager bm = IBackupManager.Stub.asInterface( 5844 ServiceManager.getService(Context.BACKUP_SERVICE)); 5845 bm.agentDisconnected(app.info.packageName); 5846 } catch (RemoteException e) { 5847 // Can't happen; the backup manager is local 5848 } 5849 } 5850 if (isPendingBroadcastProcessLocked(pid)) { 5851 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5852 skipPendingBroadcastLocked(pid); 5853 } 5854 } else { 5855 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5856 } 5857 } 5858 5859 private final boolean attachApplicationLocked(IApplicationThread thread, 5860 int pid) { 5861 5862 // Find the application record that is being attached... either via 5863 // the pid if we are running in multiple processes, or just pull the 5864 // next app record if we are emulating process with anonymous threads. 5865 ProcessRecord app; 5866 if (pid != MY_PID && pid >= 0) { 5867 synchronized (mPidsSelfLocked) { 5868 app = mPidsSelfLocked.get(pid); 5869 } 5870 } else { 5871 app = null; 5872 } 5873 5874 if (app == null) { 5875 Slog.w(TAG, "No pending application record for pid " + pid 5876 + " (IApplicationThread " + thread + "); dropping process"); 5877 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5878 if (pid > 0 && pid != MY_PID) { 5879 Process.killProcessQuiet(pid); 5880 //TODO: Process.killProcessGroup(app.info.uid, pid); 5881 } else { 5882 try { 5883 thread.scheduleExit(); 5884 } catch (Exception e) { 5885 // Ignore exceptions. 5886 } 5887 } 5888 return false; 5889 } 5890 5891 // If this application record is still attached to a previous 5892 // process, clean it up now. 5893 if (app.thread != null) { 5894 handleAppDiedLocked(app, true, true); 5895 } 5896 5897 // Tell the process all about itself. 5898 5899 if (localLOGV) Slog.v( 5900 TAG, "Binding process pid " + pid + " to record " + app); 5901 5902 final String processName = app.processName; 5903 try { 5904 AppDeathRecipient adr = new AppDeathRecipient( 5905 app, pid, thread); 5906 thread.asBinder().linkToDeath(adr, 0); 5907 app.deathRecipient = adr; 5908 } catch (RemoteException e) { 5909 app.resetPackageList(mProcessStats); 5910 startProcessLocked(app, "link fail", processName); 5911 return false; 5912 } 5913 5914 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5915 5916 app.makeActive(thread, mProcessStats); 5917 app.curAdj = app.setAdj = -100; 5918 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5919 app.forcingToForeground = null; 5920 updateProcessForegroundLocked(app, false, false); 5921 app.hasShownUi = false; 5922 app.debugging = false; 5923 app.cached = false; 5924 app.killedByAm = false; 5925 5926 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5927 5928 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5929 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5930 5931 if (!normalMode) { 5932 Slog.i(TAG, "Launching preboot mode app: " + app); 5933 } 5934 5935 if (localLOGV) Slog.v( 5936 TAG, "New app record " + app 5937 + " thread=" + thread.asBinder() + " pid=" + pid); 5938 try { 5939 int testMode = IApplicationThread.DEBUG_OFF; 5940 if (mDebugApp != null && mDebugApp.equals(processName)) { 5941 testMode = mWaitForDebugger 5942 ? IApplicationThread.DEBUG_WAIT 5943 : IApplicationThread.DEBUG_ON; 5944 app.debugging = true; 5945 if (mDebugTransient) { 5946 mDebugApp = mOrigDebugApp; 5947 mWaitForDebugger = mOrigWaitForDebugger; 5948 } 5949 } 5950 String profileFile = app.instrumentationProfileFile; 5951 ParcelFileDescriptor profileFd = null; 5952 int samplingInterval = 0; 5953 boolean profileAutoStop = false; 5954 if (mProfileApp != null && mProfileApp.equals(processName)) { 5955 mProfileProc = app; 5956 profileFile = mProfileFile; 5957 profileFd = mProfileFd; 5958 samplingInterval = mSamplingInterval; 5959 profileAutoStop = mAutoStopProfiler; 5960 } 5961 boolean enableOpenGlTrace = false; 5962 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5963 enableOpenGlTrace = true; 5964 mOpenGlTraceApp = null; 5965 } 5966 5967 // If the app is being launched for restore or full backup, set it up specially 5968 boolean isRestrictedBackupMode = false; 5969 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5970 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5971 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5972 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5973 } 5974 5975 ensurePackageDexOpt(app.instrumentationInfo != null 5976 ? app.instrumentationInfo.packageName 5977 : app.info.packageName); 5978 if (app.instrumentationClass != null) { 5979 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5980 } 5981 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5982 + processName + " with config " + mConfiguration); 5983 ApplicationInfo appInfo = app.instrumentationInfo != null 5984 ? app.instrumentationInfo : app.info; 5985 app.compat = compatibilityInfoForPackageLocked(appInfo); 5986 if (profileFd != null) { 5987 profileFd = profileFd.dup(); 5988 } 5989 ProfilerInfo profilerInfo = profileFile == null ? null 5990 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5991 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5992 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5993 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5994 isRestrictedBackupMode || !normalMode, app.persistent, 5995 new Configuration(mConfiguration), app.compat, 5996 getCommonServicesLocked(app.isolated), 5997 mCoreSettingsObserver.getCoreSettingsLocked()); 5998 updateLruProcessLocked(app, false, null); 5999 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6000 } catch (Exception e) { 6001 // todo: Yikes! What should we do? For now we will try to 6002 // start another process, but that could easily get us in 6003 // an infinite loop of restarting processes... 6004 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6005 6006 app.resetPackageList(mProcessStats); 6007 app.unlinkDeathRecipient(); 6008 startProcessLocked(app, "bind fail", processName); 6009 return false; 6010 } 6011 6012 // Remove this record from the list of starting applications. 6013 mPersistentStartingProcesses.remove(app); 6014 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6015 "Attach application locked removing on hold: " + app); 6016 mProcessesOnHold.remove(app); 6017 6018 boolean badApp = false; 6019 boolean didSomething = false; 6020 6021 // See if the top visible activity is waiting to run in this process... 6022 if (normalMode) { 6023 try { 6024 if (mStackSupervisor.attachApplicationLocked(app)) { 6025 didSomething = true; 6026 } 6027 } catch (Exception e) { 6028 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6029 badApp = true; 6030 } 6031 } 6032 6033 // Find any services that should be running in this process... 6034 if (!badApp) { 6035 try { 6036 didSomething |= mServices.attachApplicationLocked(app, processName); 6037 } catch (Exception e) { 6038 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6039 badApp = true; 6040 } 6041 } 6042 6043 // Check if a next-broadcast receiver is in this process... 6044 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6045 try { 6046 didSomething |= sendPendingBroadcastsLocked(app); 6047 } catch (Exception e) { 6048 // If the app died trying to launch the receiver we declare it 'bad' 6049 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6050 badApp = true; 6051 } 6052 } 6053 6054 // Check whether the next backup agent is in this process... 6055 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6056 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6057 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6058 try { 6059 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6060 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6061 mBackupTarget.backupMode); 6062 } catch (Exception e) { 6063 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6064 badApp = true; 6065 } 6066 } 6067 6068 if (badApp) { 6069 app.kill("error during init", true); 6070 handleAppDiedLocked(app, false, true); 6071 return false; 6072 } 6073 6074 if (!didSomething) { 6075 updateOomAdjLocked(); 6076 } 6077 6078 return true; 6079 } 6080 6081 @Override 6082 public final void attachApplication(IApplicationThread thread) { 6083 synchronized (this) { 6084 int callingPid = Binder.getCallingPid(); 6085 final long origId = Binder.clearCallingIdentity(); 6086 attachApplicationLocked(thread, callingPid); 6087 Binder.restoreCallingIdentity(origId); 6088 } 6089 } 6090 6091 @Override 6092 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6093 final long origId = Binder.clearCallingIdentity(); 6094 synchronized (this) { 6095 ActivityStack stack = ActivityRecord.getStackLocked(token); 6096 if (stack != null) { 6097 ActivityRecord r = 6098 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6099 if (stopProfiling) { 6100 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6101 try { 6102 mProfileFd.close(); 6103 } catch (IOException e) { 6104 } 6105 clearProfilerLocked(); 6106 } 6107 } 6108 } 6109 } 6110 Binder.restoreCallingIdentity(origId); 6111 } 6112 6113 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6114 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6115 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6116 } 6117 6118 void enableScreenAfterBoot() { 6119 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6120 SystemClock.uptimeMillis()); 6121 mWindowManager.enableScreenAfterBoot(); 6122 6123 synchronized (this) { 6124 updateEventDispatchingLocked(); 6125 } 6126 } 6127 6128 @Override 6129 public void showBootMessage(final CharSequence msg, final boolean always) { 6130 enforceNotIsolatedCaller("showBootMessage"); 6131 mWindowManager.showBootMessage(msg, always); 6132 } 6133 6134 @Override 6135 public void keyguardWaitingForActivityDrawn() { 6136 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6137 final long token = Binder.clearCallingIdentity(); 6138 try { 6139 synchronized (this) { 6140 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6141 mWindowManager.keyguardWaitingForActivityDrawn(); 6142 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6143 mLockScreenShown = LOCK_SCREEN_LEAVING; 6144 updateSleepIfNeededLocked(); 6145 } 6146 } 6147 } finally { 6148 Binder.restoreCallingIdentity(token); 6149 } 6150 } 6151 6152 final void finishBooting() { 6153 synchronized (this) { 6154 if (!mBootAnimationComplete) { 6155 mCallFinishBooting = true; 6156 return; 6157 } 6158 mCallFinishBooting = false; 6159 } 6160 6161 ArraySet<String> completedIsas = new ArraySet<String>(); 6162 for (String abi : Build.SUPPORTED_ABIS) { 6163 Process.establishZygoteConnectionForAbi(abi); 6164 final String instructionSet = VMRuntime.getInstructionSet(abi); 6165 if (!completedIsas.contains(instructionSet)) { 6166 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6167 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6168 } 6169 completedIsas.add(instructionSet); 6170 } 6171 } 6172 6173 IntentFilter pkgFilter = new IntentFilter(); 6174 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6175 pkgFilter.addDataScheme("package"); 6176 mContext.registerReceiver(new BroadcastReceiver() { 6177 @Override 6178 public void onReceive(Context context, Intent intent) { 6179 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6180 if (pkgs != null) { 6181 for (String pkg : pkgs) { 6182 synchronized (ActivityManagerService.this) { 6183 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6184 0, "finished booting")) { 6185 setResultCode(Activity.RESULT_OK); 6186 return; 6187 } 6188 } 6189 } 6190 } 6191 } 6192 }, pkgFilter); 6193 6194 // Let system services know. 6195 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6196 6197 synchronized (this) { 6198 // Ensure that any processes we had put on hold are now started 6199 // up. 6200 final int NP = mProcessesOnHold.size(); 6201 if (NP > 0) { 6202 ArrayList<ProcessRecord> procs = 6203 new ArrayList<ProcessRecord>(mProcessesOnHold); 6204 for (int ip=0; ip<NP; ip++) { 6205 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6206 + procs.get(ip)); 6207 startProcessLocked(procs.get(ip), "on-hold", null); 6208 } 6209 } 6210 6211 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6212 // Start looking for apps that are abusing wake locks. 6213 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6214 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6215 // Tell anyone interested that we are done booting! 6216 SystemProperties.set("sys.boot_completed", "1"); 6217 6218 // And trigger dev.bootcomplete if we are not showing encryption progress 6219 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6220 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6221 SystemProperties.set("dev.bootcomplete", "1"); 6222 } 6223 for (int i=0; i<mStartedUsers.size(); i++) { 6224 UserStartedState uss = mStartedUsers.valueAt(i); 6225 if (uss.mState == UserStartedState.STATE_BOOTING) { 6226 uss.mState = UserStartedState.STATE_RUNNING; 6227 final int userId = mStartedUsers.keyAt(i); 6228 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6229 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6230 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6231 broadcastIntentLocked(null, null, intent, null, 6232 new IIntentReceiver.Stub() { 6233 @Override 6234 public void performReceive(Intent intent, int resultCode, 6235 String data, Bundle extras, boolean ordered, 6236 boolean sticky, int sendingUser) { 6237 synchronized (ActivityManagerService.this) { 6238 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6239 true, false); 6240 } 6241 } 6242 }, 6243 0, null, null, 6244 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6245 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6246 userId); 6247 } 6248 } 6249 scheduleStartProfilesLocked(); 6250 } 6251 } 6252 } 6253 6254 @Override 6255 public void bootAnimationComplete() { 6256 final boolean callFinishBooting; 6257 synchronized (this) { 6258 callFinishBooting = mCallFinishBooting; 6259 mBootAnimationComplete = true; 6260 } 6261 if (callFinishBooting) { 6262 finishBooting(); 6263 } 6264 } 6265 6266 @Override 6267 public void systemBackupRestored() { 6268 synchronized (this) { 6269 if (mSystemReady) { 6270 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6271 } else { 6272 Slog.w(TAG, "System backup restored before system is ready"); 6273 } 6274 } 6275 } 6276 6277 final void ensureBootCompleted() { 6278 boolean booting; 6279 boolean enableScreen; 6280 synchronized (this) { 6281 booting = mBooting; 6282 mBooting = false; 6283 enableScreen = !mBooted; 6284 mBooted = true; 6285 } 6286 6287 if (booting) { 6288 finishBooting(); 6289 } 6290 6291 if (enableScreen) { 6292 enableScreenAfterBoot(); 6293 } 6294 } 6295 6296 @Override 6297 public final void activityResumed(IBinder token) { 6298 final long origId = Binder.clearCallingIdentity(); 6299 synchronized(this) { 6300 ActivityStack stack = ActivityRecord.getStackLocked(token); 6301 if (stack != null) { 6302 ActivityRecord.activityResumedLocked(token); 6303 } 6304 } 6305 Binder.restoreCallingIdentity(origId); 6306 } 6307 6308 @Override 6309 public final void activityPaused(IBinder token) { 6310 final long origId = Binder.clearCallingIdentity(); 6311 synchronized(this) { 6312 ActivityStack stack = ActivityRecord.getStackLocked(token); 6313 if (stack != null) { 6314 stack.activityPausedLocked(token, false); 6315 } 6316 } 6317 Binder.restoreCallingIdentity(origId); 6318 } 6319 6320 @Override 6321 public final void activityStopped(IBinder token, Bundle icicle, 6322 PersistableBundle persistentState, CharSequence description) { 6323 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6324 6325 // Refuse possible leaked file descriptors 6326 if (icicle != null && icicle.hasFileDescriptors()) { 6327 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6328 } 6329 6330 final long origId = Binder.clearCallingIdentity(); 6331 6332 synchronized (this) { 6333 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6334 if (r != null) { 6335 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6336 } 6337 } 6338 6339 trimApplications(); 6340 6341 Binder.restoreCallingIdentity(origId); 6342 } 6343 6344 @Override 6345 public final void activityDestroyed(IBinder token) { 6346 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6347 synchronized (this) { 6348 ActivityStack stack = ActivityRecord.getStackLocked(token); 6349 if (stack != null) { 6350 stack.activityDestroyedLocked(token); 6351 } 6352 } 6353 } 6354 6355 @Override 6356 public final void backgroundResourcesReleased(IBinder token) { 6357 final long origId = Binder.clearCallingIdentity(); 6358 try { 6359 synchronized (this) { 6360 ActivityStack stack = ActivityRecord.getStackLocked(token); 6361 if (stack != null) { 6362 stack.backgroundResourcesReleased(); 6363 } 6364 } 6365 } finally { 6366 Binder.restoreCallingIdentity(origId); 6367 } 6368 } 6369 6370 @Override 6371 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6372 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6373 } 6374 6375 @Override 6376 public final void notifyEnterAnimationComplete(IBinder token) { 6377 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6378 } 6379 6380 @Override 6381 public String getCallingPackage(IBinder token) { 6382 synchronized (this) { 6383 ActivityRecord r = getCallingRecordLocked(token); 6384 return r != null ? r.info.packageName : null; 6385 } 6386 } 6387 6388 @Override 6389 public ComponentName getCallingActivity(IBinder token) { 6390 synchronized (this) { 6391 ActivityRecord r = getCallingRecordLocked(token); 6392 return r != null ? r.intent.getComponent() : null; 6393 } 6394 } 6395 6396 private ActivityRecord getCallingRecordLocked(IBinder token) { 6397 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6398 if (r == null) { 6399 return null; 6400 } 6401 return r.resultTo; 6402 } 6403 6404 @Override 6405 public ComponentName getActivityClassForToken(IBinder token) { 6406 synchronized(this) { 6407 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6408 if (r == null) { 6409 return null; 6410 } 6411 return r.intent.getComponent(); 6412 } 6413 } 6414 6415 @Override 6416 public String getPackageForToken(IBinder token) { 6417 synchronized(this) { 6418 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6419 if (r == null) { 6420 return null; 6421 } 6422 return r.packageName; 6423 } 6424 } 6425 6426 @Override 6427 public IIntentSender getIntentSender(int type, 6428 String packageName, IBinder token, String resultWho, 6429 int requestCode, Intent[] intents, String[] resolvedTypes, 6430 int flags, Bundle options, int userId) { 6431 enforceNotIsolatedCaller("getIntentSender"); 6432 // Refuse possible leaked file descriptors 6433 if (intents != null) { 6434 if (intents.length < 1) { 6435 throw new IllegalArgumentException("Intents array length must be >= 1"); 6436 } 6437 for (int i=0; i<intents.length; i++) { 6438 Intent intent = intents[i]; 6439 if (intent != null) { 6440 if (intent.hasFileDescriptors()) { 6441 throw new IllegalArgumentException("File descriptors passed in Intent"); 6442 } 6443 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6444 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6445 throw new IllegalArgumentException( 6446 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6447 } 6448 intents[i] = new Intent(intent); 6449 } 6450 } 6451 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6452 throw new IllegalArgumentException( 6453 "Intent array length does not match resolvedTypes length"); 6454 } 6455 } 6456 if (options != null) { 6457 if (options.hasFileDescriptors()) { 6458 throw new IllegalArgumentException("File descriptors passed in options"); 6459 } 6460 } 6461 6462 synchronized(this) { 6463 int callingUid = Binder.getCallingUid(); 6464 int origUserId = userId; 6465 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6466 type == ActivityManager.INTENT_SENDER_BROADCAST, 6467 ALLOW_NON_FULL, "getIntentSender", null); 6468 if (origUserId == UserHandle.USER_CURRENT) { 6469 // We don't want to evaluate this until the pending intent is 6470 // actually executed. However, we do want to always do the 6471 // security checking for it above. 6472 userId = UserHandle.USER_CURRENT; 6473 } 6474 try { 6475 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6476 int uid = AppGlobals.getPackageManager() 6477 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6478 if (!UserHandle.isSameApp(callingUid, uid)) { 6479 String msg = "Permission Denial: getIntentSender() from pid=" 6480 + Binder.getCallingPid() 6481 + ", uid=" + Binder.getCallingUid() 6482 + ", (need uid=" + uid + ")" 6483 + " is not allowed to send as package " + packageName; 6484 Slog.w(TAG, msg); 6485 throw new SecurityException(msg); 6486 } 6487 } 6488 6489 return getIntentSenderLocked(type, packageName, callingUid, userId, 6490 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6491 6492 } catch (RemoteException e) { 6493 throw new SecurityException(e); 6494 } 6495 } 6496 } 6497 6498 IIntentSender getIntentSenderLocked(int type, String packageName, 6499 int callingUid, int userId, IBinder token, String resultWho, 6500 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6501 Bundle options) { 6502 if (DEBUG_MU) 6503 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6504 ActivityRecord activity = null; 6505 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6506 activity = ActivityRecord.isInStackLocked(token); 6507 if (activity == null) { 6508 return null; 6509 } 6510 if (activity.finishing) { 6511 return null; 6512 } 6513 } 6514 6515 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6516 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6517 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6518 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6519 |PendingIntent.FLAG_UPDATE_CURRENT); 6520 6521 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6522 type, packageName, activity, resultWho, 6523 requestCode, intents, resolvedTypes, flags, options, userId); 6524 WeakReference<PendingIntentRecord> ref; 6525 ref = mIntentSenderRecords.get(key); 6526 PendingIntentRecord rec = ref != null ? ref.get() : null; 6527 if (rec != null) { 6528 if (!cancelCurrent) { 6529 if (updateCurrent) { 6530 if (rec.key.requestIntent != null) { 6531 rec.key.requestIntent.replaceExtras(intents != null ? 6532 intents[intents.length - 1] : null); 6533 } 6534 if (intents != null) { 6535 intents[intents.length-1] = rec.key.requestIntent; 6536 rec.key.allIntents = intents; 6537 rec.key.allResolvedTypes = resolvedTypes; 6538 } else { 6539 rec.key.allIntents = null; 6540 rec.key.allResolvedTypes = null; 6541 } 6542 } 6543 return rec; 6544 } 6545 rec.canceled = true; 6546 mIntentSenderRecords.remove(key); 6547 } 6548 if (noCreate) { 6549 return rec; 6550 } 6551 rec = new PendingIntentRecord(this, key, callingUid); 6552 mIntentSenderRecords.put(key, rec.ref); 6553 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6554 if (activity.pendingResults == null) { 6555 activity.pendingResults 6556 = new HashSet<WeakReference<PendingIntentRecord>>(); 6557 } 6558 activity.pendingResults.add(rec.ref); 6559 } 6560 return rec; 6561 } 6562 6563 @Override 6564 public void cancelIntentSender(IIntentSender sender) { 6565 if (!(sender instanceof PendingIntentRecord)) { 6566 return; 6567 } 6568 synchronized(this) { 6569 PendingIntentRecord rec = (PendingIntentRecord)sender; 6570 try { 6571 int uid = AppGlobals.getPackageManager() 6572 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6573 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6574 String msg = "Permission Denial: cancelIntentSender() from pid=" 6575 + Binder.getCallingPid() 6576 + ", uid=" + Binder.getCallingUid() 6577 + " is not allowed to cancel packges " 6578 + rec.key.packageName; 6579 Slog.w(TAG, msg); 6580 throw new SecurityException(msg); 6581 } 6582 } catch (RemoteException e) { 6583 throw new SecurityException(e); 6584 } 6585 cancelIntentSenderLocked(rec, true); 6586 } 6587 } 6588 6589 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6590 rec.canceled = true; 6591 mIntentSenderRecords.remove(rec.key); 6592 if (cleanActivity && rec.key.activity != null) { 6593 rec.key.activity.pendingResults.remove(rec.ref); 6594 } 6595 } 6596 6597 @Override 6598 public String getPackageForIntentSender(IIntentSender pendingResult) { 6599 if (!(pendingResult instanceof PendingIntentRecord)) { 6600 return null; 6601 } 6602 try { 6603 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6604 return res.key.packageName; 6605 } catch (ClassCastException e) { 6606 } 6607 return null; 6608 } 6609 6610 @Override 6611 public int getUidForIntentSender(IIntentSender sender) { 6612 if (sender instanceof PendingIntentRecord) { 6613 try { 6614 PendingIntentRecord res = (PendingIntentRecord)sender; 6615 return res.uid; 6616 } catch (ClassCastException e) { 6617 } 6618 } 6619 return -1; 6620 } 6621 6622 @Override 6623 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6624 if (!(pendingResult instanceof PendingIntentRecord)) { 6625 return false; 6626 } 6627 try { 6628 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6629 if (res.key.allIntents == null) { 6630 return false; 6631 } 6632 for (int i=0; i<res.key.allIntents.length; i++) { 6633 Intent intent = res.key.allIntents[i]; 6634 if (intent.getPackage() != null && intent.getComponent() != null) { 6635 return false; 6636 } 6637 } 6638 return true; 6639 } catch (ClassCastException e) { 6640 } 6641 return false; 6642 } 6643 6644 @Override 6645 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6646 if (!(pendingResult instanceof PendingIntentRecord)) { 6647 return false; 6648 } 6649 try { 6650 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6651 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6652 return true; 6653 } 6654 return false; 6655 } catch (ClassCastException e) { 6656 } 6657 return false; 6658 } 6659 6660 @Override 6661 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6662 if (!(pendingResult instanceof PendingIntentRecord)) { 6663 return null; 6664 } 6665 try { 6666 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6667 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6668 } catch (ClassCastException e) { 6669 } 6670 return null; 6671 } 6672 6673 @Override 6674 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6675 if (!(pendingResult instanceof PendingIntentRecord)) { 6676 return null; 6677 } 6678 try { 6679 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6680 Intent intent = res.key.requestIntent; 6681 if (intent != null) { 6682 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6683 || res.lastTagPrefix.equals(prefix))) { 6684 return res.lastTag; 6685 } 6686 res.lastTagPrefix = prefix; 6687 StringBuilder sb = new StringBuilder(128); 6688 if (prefix != null) { 6689 sb.append(prefix); 6690 } 6691 if (intent.getAction() != null) { 6692 sb.append(intent.getAction()); 6693 } else if (intent.getComponent() != null) { 6694 intent.getComponent().appendShortString(sb); 6695 } else { 6696 sb.append("?"); 6697 } 6698 return res.lastTag = sb.toString(); 6699 } 6700 } catch (ClassCastException e) { 6701 } 6702 return null; 6703 } 6704 6705 @Override 6706 public void setProcessLimit(int max) { 6707 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6708 "setProcessLimit()"); 6709 synchronized (this) { 6710 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6711 mProcessLimitOverride = max; 6712 } 6713 trimApplications(); 6714 } 6715 6716 @Override 6717 public int getProcessLimit() { 6718 synchronized (this) { 6719 return mProcessLimitOverride; 6720 } 6721 } 6722 6723 void foregroundTokenDied(ForegroundToken token) { 6724 synchronized (ActivityManagerService.this) { 6725 synchronized (mPidsSelfLocked) { 6726 ForegroundToken cur 6727 = mForegroundProcesses.get(token.pid); 6728 if (cur != token) { 6729 return; 6730 } 6731 mForegroundProcesses.remove(token.pid); 6732 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6733 if (pr == null) { 6734 return; 6735 } 6736 pr.forcingToForeground = null; 6737 updateProcessForegroundLocked(pr, false, false); 6738 } 6739 updateOomAdjLocked(); 6740 } 6741 } 6742 6743 @Override 6744 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6745 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6746 "setProcessForeground()"); 6747 synchronized(this) { 6748 boolean changed = false; 6749 6750 synchronized (mPidsSelfLocked) { 6751 ProcessRecord pr = mPidsSelfLocked.get(pid); 6752 if (pr == null && isForeground) { 6753 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6754 return; 6755 } 6756 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6757 if (oldToken != null) { 6758 oldToken.token.unlinkToDeath(oldToken, 0); 6759 mForegroundProcesses.remove(pid); 6760 if (pr != null) { 6761 pr.forcingToForeground = null; 6762 } 6763 changed = true; 6764 } 6765 if (isForeground && token != null) { 6766 ForegroundToken newToken = new ForegroundToken() { 6767 @Override 6768 public void binderDied() { 6769 foregroundTokenDied(this); 6770 } 6771 }; 6772 newToken.pid = pid; 6773 newToken.token = token; 6774 try { 6775 token.linkToDeath(newToken, 0); 6776 mForegroundProcesses.put(pid, newToken); 6777 pr.forcingToForeground = token; 6778 changed = true; 6779 } catch (RemoteException e) { 6780 // If the process died while doing this, we will later 6781 // do the cleanup with the process death link. 6782 } 6783 } 6784 } 6785 6786 if (changed) { 6787 updateOomAdjLocked(); 6788 } 6789 } 6790 } 6791 6792 // ========================================================= 6793 // PERMISSIONS 6794 // ========================================================= 6795 6796 static class PermissionController extends IPermissionController.Stub { 6797 ActivityManagerService mActivityManagerService; 6798 PermissionController(ActivityManagerService activityManagerService) { 6799 mActivityManagerService = activityManagerService; 6800 } 6801 6802 @Override 6803 public boolean checkPermission(String permission, int pid, int uid) { 6804 return mActivityManagerService.checkPermission(permission, pid, 6805 uid) == PackageManager.PERMISSION_GRANTED; 6806 } 6807 } 6808 6809 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6810 @Override 6811 public int checkComponentPermission(String permission, int pid, int uid, 6812 int owningUid, boolean exported) { 6813 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6814 owningUid, exported); 6815 } 6816 6817 @Override 6818 public Object getAMSLock() { 6819 return ActivityManagerService.this; 6820 } 6821 } 6822 6823 /** 6824 * This can be called with or without the global lock held. 6825 */ 6826 int checkComponentPermission(String permission, int pid, int uid, 6827 int owningUid, boolean exported) { 6828 if (pid == MY_PID) { 6829 return PackageManager.PERMISSION_GRANTED; 6830 } 6831 return ActivityManager.checkComponentPermission(permission, uid, 6832 owningUid, exported); 6833 } 6834 6835 /** 6836 * As the only public entry point for permissions checking, this method 6837 * can enforce the semantic that requesting a check on a null global 6838 * permission is automatically denied. (Internally a null permission 6839 * string is used when calling {@link #checkComponentPermission} in cases 6840 * when only uid-based security is needed.) 6841 * 6842 * This can be called with or without the global lock held. 6843 */ 6844 @Override 6845 public int checkPermission(String permission, int pid, int uid) { 6846 if (permission == null) { 6847 return PackageManager.PERMISSION_DENIED; 6848 } 6849 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6850 } 6851 6852 @Override 6853 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6854 if (permission == null) { 6855 return PackageManager.PERMISSION_DENIED; 6856 } 6857 6858 // We might be performing an operation on behalf of an indirect binder 6859 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6860 // client identity accordingly before proceeding. 6861 Identity tlsIdentity = sCallerIdentity.get(); 6862 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6863 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6864 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6865 uid = tlsIdentity.uid; 6866 pid = tlsIdentity.pid; 6867 } 6868 6869 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6870 } 6871 6872 /** 6873 * Binder IPC calls go through the public entry point. 6874 * This can be called with or without the global lock held. 6875 */ 6876 int checkCallingPermission(String permission) { 6877 return checkPermission(permission, 6878 Binder.getCallingPid(), 6879 UserHandle.getAppId(Binder.getCallingUid())); 6880 } 6881 6882 /** 6883 * This can be called with or without the global lock held. 6884 */ 6885 void enforceCallingPermission(String permission, String func) { 6886 if (checkCallingPermission(permission) 6887 == PackageManager.PERMISSION_GRANTED) { 6888 return; 6889 } 6890 6891 String msg = "Permission Denial: " + func + " from pid=" 6892 + Binder.getCallingPid() 6893 + ", uid=" + Binder.getCallingUid() 6894 + " requires " + permission; 6895 Slog.w(TAG, msg); 6896 throw new SecurityException(msg); 6897 } 6898 6899 /** 6900 * Determine if UID is holding permissions required to access {@link Uri} in 6901 * the given {@link ProviderInfo}. Final permission checking is always done 6902 * in {@link ContentProvider}. 6903 */ 6904 private final boolean checkHoldingPermissionsLocked( 6905 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6906 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6907 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6908 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6909 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6910 != PERMISSION_GRANTED) { 6911 return false; 6912 } 6913 } 6914 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6915 } 6916 6917 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6918 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6919 if (pi.applicationInfo.uid == uid) { 6920 return true; 6921 } else if (!pi.exported) { 6922 return false; 6923 } 6924 6925 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6926 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6927 try { 6928 // check if target holds top-level <provider> permissions 6929 if (!readMet && pi.readPermission != null && considerUidPermissions 6930 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6931 readMet = true; 6932 } 6933 if (!writeMet && pi.writePermission != null && considerUidPermissions 6934 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6935 writeMet = true; 6936 } 6937 6938 // track if unprotected read/write is allowed; any denied 6939 // <path-permission> below removes this ability 6940 boolean allowDefaultRead = pi.readPermission == null; 6941 boolean allowDefaultWrite = pi.writePermission == null; 6942 6943 // check if target holds any <path-permission> that match uri 6944 final PathPermission[] pps = pi.pathPermissions; 6945 if (pps != null) { 6946 final String path = grantUri.uri.getPath(); 6947 int i = pps.length; 6948 while (i > 0 && (!readMet || !writeMet)) { 6949 i--; 6950 PathPermission pp = pps[i]; 6951 if (pp.match(path)) { 6952 if (!readMet) { 6953 final String pprperm = pp.getReadPermission(); 6954 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6955 + pprperm + " for " + pp.getPath() 6956 + ": match=" + pp.match(path) 6957 + " check=" + pm.checkUidPermission(pprperm, uid)); 6958 if (pprperm != null) { 6959 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6960 == PERMISSION_GRANTED) { 6961 readMet = true; 6962 } else { 6963 allowDefaultRead = false; 6964 } 6965 } 6966 } 6967 if (!writeMet) { 6968 final String ppwperm = pp.getWritePermission(); 6969 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6970 + ppwperm + " for " + pp.getPath() 6971 + ": match=" + pp.match(path) 6972 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6973 if (ppwperm != null) { 6974 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6975 == PERMISSION_GRANTED) { 6976 writeMet = true; 6977 } else { 6978 allowDefaultWrite = false; 6979 } 6980 } 6981 } 6982 } 6983 } 6984 } 6985 6986 // grant unprotected <provider> read/write, if not blocked by 6987 // <path-permission> above 6988 if (allowDefaultRead) readMet = true; 6989 if (allowDefaultWrite) writeMet = true; 6990 6991 } catch (RemoteException e) { 6992 return false; 6993 } 6994 6995 return readMet && writeMet; 6996 } 6997 6998 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6999 ProviderInfo pi = null; 7000 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7001 if (cpr != null) { 7002 pi = cpr.info; 7003 } else { 7004 try { 7005 pi = AppGlobals.getPackageManager().resolveContentProvider( 7006 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7007 } catch (RemoteException ex) { 7008 } 7009 } 7010 return pi; 7011 } 7012 7013 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7014 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7015 if (targetUris != null) { 7016 return targetUris.get(grantUri); 7017 } 7018 return null; 7019 } 7020 7021 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7022 String targetPkg, int targetUid, GrantUri grantUri) { 7023 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7024 if (targetUris == null) { 7025 targetUris = Maps.newArrayMap(); 7026 mGrantedUriPermissions.put(targetUid, targetUris); 7027 } 7028 7029 UriPermission perm = targetUris.get(grantUri); 7030 if (perm == null) { 7031 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7032 targetUris.put(grantUri, perm); 7033 } 7034 7035 return perm; 7036 } 7037 7038 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7039 final int modeFlags) { 7040 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7041 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7042 : UriPermission.STRENGTH_OWNED; 7043 7044 // Root gets to do everything. 7045 if (uid == 0) { 7046 return true; 7047 } 7048 7049 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7050 if (perms == null) return false; 7051 7052 // First look for exact match 7053 final UriPermission exactPerm = perms.get(grantUri); 7054 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7055 return true; 7056 } 7057 7058 // No exact match, look for prefixes 7059 final int N = perms.size(); 7060 for (int i = 0; i < N; i++) { 7061 final UriPermission perm = perms.valueAt(i); 7062 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7063 && perm.getStrength(modeFlags) >= minStrength) { 7064 return true; 7065 } 7066 } 7067 7068 return false; 7069 } 7070 7071 /** 7072 * @param uri This uri must NOT contain an embedded userId. 7073 * @param userId The userId in which the uri is to be resolved. 7074 */ 7075 @Override 7076 public int checkUriPermission(Uri uri, int pid, int uid, 7077 final int modeFlags, int userId, IBinder callerToken) { 7078 enforceNotIsolatedCaller("checkUriPermission"); 7079 7080 // Another redirected-binder-call permissions check as in 7081 // {@link checkPermissionWithToken}. 7082 Identity tlsIdentity = sCallerIdentity.get(); 7083 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7084 uid = tlsIdentity.uid; 7085 pid = tlsIdentity.pid; 7086 } 7087 7088 // Our own process gets to do everything. 7089 if (pid == MY_PID) { 7090 return PackageManager.PERMISSION_GRANTED; 7091 } 7092 synchronized (this) { 7093 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7094 ? PackageManager.PERMISSION_GRANTED 7095 : PackageManager.PERMISSION_DENIED; 7096 } 7097 } 7098 7099 /** 7100 * Check if the targetPkg can be granted permission to access uri by 7101 * the callingUid using the given modeFlags. Throws a security exception 7102 * if callingUid is not allowed to do this. Returns the uid of the target 7103 * if the URI permission grant should be performed; returns -1 if it is not 7104 * needed (for example targetPkg already has permission to access the URI). 7105 * If you already know the uid of the target, you can supply it in 7106 * lastTargetUid else set that to -1. 7107 */ 7108 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7109 final int modeFlags, int lastTargetUid) { 7110 if (!Intent.isAccessUriMode(modeFlags)) { 7111 return -1; 7112 } 7113 7114 if (targetPkg != null) { 7115 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7116 "Checking grant " + targetPkg + " permission to " + grantUri); 7117 } 7118 7119 final IPackageManager pm = AppGlobals.getPackageManager(); 7120 7121 // If this is not a content: uri, we can't do anything with it. 7122 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7123 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7124 "Can't grant URI permission for non-content URI: " + grantUri); 7125 return -1; 7126 } 7127 7128 final String authority = grantUri.uri.getAuthority(); 7129 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7130 if (pi == null) { 7131 Slog.w(TAG, "No content provider found for permission check: " + 7132 grantUri.uri.toSafeString()); 7133 return -1; 7134 } 7135 7136 int targetUid = lastTargetUid; 7137 if (targetUid < 0 && targetPkg != null) { 7138 try { 7139 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7140 if (targetUid < 0) { 7141 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7142 "Can't grant URI permission no uid for: " + targetPkg); 7143 return -1; 7144 } 7145 } catch (RemoteException ex) { 7146 return -1; 7147 } 7148 } 7149 7150 if (targetUid >= 0) { 7151 // First... does the target actually need this permission? 7152 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7153 // No need to grant the target this permission. 7154 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7155 "Target " + targetPkg + " already has full permission to " + grantUri); 7156 return -1; 7157 } 7158 } else { 7159 // First... there is no target package, so can anyone access it? 7160 boolean allowed = pi.exported; 7161 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7162 if (pi.readPermission != null) { 7163 allowed = false; 7164 } 7165 } 7166 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7167 if (pi.writePermission != null) { 7168 allowed = false; 7169 } 7170 } 7171 if (allowed) { 7172 return -1; 7173 } 7174 } 7175 7176 /* There is a special cross user grant if: 7177 * - The target is on another user. 7178 * - Apps on the current user can access the uri without any uid permissions. 7179 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7180 * grant uri permissions. 7181 */ 7182 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7183 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7184 modeFlags, false /*without considering the uid permissions*/); 7185 7186 // Second... is the provider allowing granting of URI permissions? 7187 if (!specialCrossUserGrant) { 7188 if (!pi.grantUriPermissions) { 7189 throw new SecurityException("Provider " + pi.packageName 7190 + "/" + pi.name 7191 + " does not allow granting of Uri permissions (uri " 7192 + grantUri + ")"); 7193 } 7194 if (pi.uriPermissionPatterns != null) { 7195 final int N = pi.uriPermissionPatterns.length; 7196 boolean allowed = false; 7197 for (int i=0; i<N; i++) { 7198 if (pi.uriPermissionPatterns[i] != null 7199 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7200 allowed = true; 7201 break; 7202 } 7203 } 7204 if (!allowed) { 7205 throw new SecurityException("Provider " + pi.packageName 7206 + "/" + pi.name 7207 + " does not allow granting of permission to path of Uri " 7208 + grantUri); 7209 } 7210 } 7211 } 7212 7213 // Third... does the caller itself have permission to access 7214 // this uri? 7215 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7216 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7217 // Require they hold a strong enough Uri permission 7218 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7219 throw new SecurityException("Uid " + callingUid 7220 + " does not have permission to uri " + grantUri); 7221 } 7222 } 7223 } 7224 return targetUid; 7225 } 7226 7227 /** 7228 * @param uri This uri must NOT contain an embedded userId. 7229 * @param userId The userId in which the uri is to be resolved. 7230 */ 7231 @Override 7232 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7233 final int modeFlags, int userId) { 7234 enforceNotIsolatedCaller("checkGrantUriPermission"); 7235 synchronized(this) { 7236 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7237 new GrantUri(userId, uri, false), modeFlags, -1); 7238 } 7239 } 7240 7241 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7242 final int modeFlags, UriPermissionOwner owner) { 7243 if (!Intent.isAccessUriMode(modeFlags)) { 7244 return; 7245 } 7246 7247 // So here we are: the caller has the assumed permission 7248 // to the uri, and the target doesn't. Let's now give this to 7249 // the target. 7250 7251 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7252 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7253 7254 final String authority = grantUri.uri.getAuthority(); 7255 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7256 if (pi == null) { 7257 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7258 return; 7259 } 7260 7261 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7262 grantUri.prefix = true; 7263 } 7264 final UriPermission perm = findOrCreateUriPermissionLocked( 7265 pi.packageName, targetPkg, targetUid, grantUri); 7266 perm.grantModes(modeFlags, owner); 7267 } 7268 7269 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7270 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7271 if (targetPkg == null) { 7272 throw new NullPointerException("targetPkg"); 7273 } 7274 int targetUid; 7275 final IPackageManager pm = AppGlobals.getPackageManager(); 7276 try { 7277 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7278 } catch (RemoteException ex) { 7279 return; 7280 } 7281 7282 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7283 targetUid); 7284 if (targetUid < 0) { 7285 return; 7286 } 7287 7288 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7289 owner); 7290 } 7291 7292 static class NeededUriGrants extends ArrayList<GrantUri> { 7293 final String targetPkg; 7294 final int targetUid; 7295 final int flags; 7296 7297 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7298 this.targetPkg = targetPkg; 7299 this.targetUid = targetUid; 7300 this.flags = flags; 7301 } 7302 } 7303 7304 /** 7305 * Like checkGrantUriPermissionLocked, but takes an Intent. 7306 */ 7307 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7308 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7309 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7310 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7311 + " clip=" + (intent != null ? intent.getClipData() : null) 7312 + " from " + intent + "; flags=0x" 7313 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7314 7315 if (targetPkg == null) { 7316 throw new NullPointerException("targetPkg"); 7317 } 7318 7319 if (intent == null) { 7320 return null; 7321 } 7322 Uri data = intent.getData(); 7323 ClipData clip = intent.getClipData(); 7324 if (data == null && clip == null) { 7325 return null; 7326 } 7327 // Default userId for uris in the intent (if they don't specify it themselves) 7328 int contentUserHint = intent.getContentUserHint(); 7329 if (contentUserHint == UserHandle.USER_CURRENT) { 7330 contentUserHint = UserHandle.getUserId(callingUid); 7331 } 7332 final IPackageManager pm = AppGlobals.getPackageManager(); 7333 int targetUid; 7334 if (needed != null) { 7335 targetUid = needed.targetUid; 7336 } else { 7337 try { 7338 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7339 } catch (RemoteException ex) { 7340 return null; 7341 } 7342 if (targetUid < 0) { 7343 if (DEBUG_URI_PERMISSION) { 7344 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7345 + " on user " + targetUserId); 7346 } 7347 return null; 7348 } 7349 } 7350 if (data != null) { 7351 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7352 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7353 targetUid); 7354 if (targetUid > 0) { 7355 if (needed == null) { 7356 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7357 } 7358 needed.add(grantUri); 7359 } 7360 } 7361 if (clip != null) { 7362 for (int i=0; i<clip.getItemCount(); i++) { 7363 Uri uri = clip.getItemAt(i).getUri(); 7364 if (uri != null) { 7365 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7366 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7367 targetUid); 7368 if (targetUid > 0) { 7369 if (needed == null) { 7370 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7371 } 7372 needed.add(grantUri); 7373 } 7374 } else { 7375 Intent clipIntent = clip.getItemAt(i).getIntent(); 7376 if (clipIntent != null) { 7377 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7378 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7379 if (newNeeded != null) { 7380 needed = newNeeded; 7381 } 7382 } 7383 } 7384 } 7385 } 7386 7387 return needed; 7388 } 7389 7390 /** 7391 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7392 */ 7393 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7394 UriPermissionOwner owner) { 7395 if (needed != null) { 7396 for (int i=0; i<needed.size(); i++) { 7397 GrantUri grantUri = needed.get(i); 7398 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7399 grantUri, needed.flags, owner); 7400 } 7401 } 7402 } 7403 7404 void grantUriPermissionFromIntentLocked(int callingUid, 7405 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7406 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7407 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7408 if (needed == null) { 7409 return; 7410 } 7411 7412 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7413 } 7414 7415 /** 7416 * @param uri This uri must NOT contain an embedded userId. 7417 * @param userId The userId in which the uri is to be resolved. 7418 */ 7419 @Override 7420 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7421 final int modeFlags, int userId) { 7422 enforceNotIsolatedCaller("grantUriPermission"); 7423 GrantUri grantUri = new GrantUri(userId, uri, false); 7424 synchronized(this) { 7425 final ProcessRecord r = getRecordForAppLocked(caller); 7426 if (r == null) { 7427 throw new SecurityException("Unable to find app for caller " 7428 + caller 7429 + " when granting permission to uri " + grantUri); 7430 } 7431 if (targetPkg == null) { 7432 throw new IllegalArgumentException("null target"); 7433 } 7434 if (grantUri == null) { 7435 throw new IllegalArgumentException("null uri"); 7436 } 7437 7438 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7439 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7440 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7441 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7442 7443 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7444 UserHandle.getUserId(r.uid)); 7445 } 7446 } 7447 7448 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7449 if (perm.modeFlags == 0) { 7450 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7451 perm.targetUid); 7452 if (perms != null) { 7453 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7454 "Removing " + perm.targetUid + " permission to " + perm.uri); 7455 7456 perms.remove(perm.uri); 7457 if (perms.isEmpty()) { 7458 mGrantedUriPermissions.remove(perm.targetUid); 7459 } 7460 } 7461 } 7462 } 7463 7464 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7465 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7466 7467 final IPackageManager pm = AppGlobals.getPackageManager(); 7468 final String authority = grantUri.uri.getAuthority(); 7469 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7470 if (pi == null) { 7471 Slog.w(TAG, "No content provider found for permission revoke: " 7472 + grantUri.toSafeString()); 7473 return; 7474 } 7475 7476 // Does the caller have this permission on the URI? 7477 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7478 // If they don't have direct access to the URI, then revoke any 7479 // ownerless URI permissions that have been granted to them. 7480 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7481 if (perms != null) { 7482 boolean persistChanged = false; 7483 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7484 final UriPermission perm = it.next(); 7485 if (perm.uri.sourceUserId == grantUri.sourceUserId 7486 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7487 if (DEBUG_URI_PERMISSION) 7488 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7489 " permission to " + perm.uri); 7490 persistChanged |= perm.revokeModes( 7491 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7492 if (perm.modeFlags == 0) { 7493 it.remove(); 7494 } 7495 } 7496 } 7497 if (perms.isEmpty()) { 7498 mGrantedUriPermissions.remove(callingUid); 7499 } 7500 if (persistChanged) { 7501 schedulePersistUriGrants(); 7502 } 7503 } 7504 return; 7505 } 7506 7507 boolean persistChanged = false; 7508 7509 // Go through all of the permissions and remove any that match. 7510 int N = mGrantedUriPermissions.size(); 7511 for (int i = 0; i < N; i++) { 7512 final int targetUid = mGrantedUriPermissions.keyAt(i); 7513 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7514 7515 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7516 final UriPermission perm = it.next(); 7517 if (perm.uri.sourceUserId == grantUri.sourceUserId 7518 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7519 if (DEBUG_URI_PERMISSION) 7520 Slog.v(TAG, 7521 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7522 persistChanged |= perm.revokeModes( 7523 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7524 if (perm.modeFlags == 0) { 7525 it.remove(); 7526 } 7527 } 7528 } 7529 7530 if (perms.isEmpty()) { 7531 mGrantedUriPermissions.remove(targetUid); 7532 N--; 7533 i--; 7534 } 7535 } 7536 7537 if (persistChanged) { 7538 schedulePersistUriGrants(); 7539 } 7540 } 7541 7542 /** 7543 * @param uri This uri must NOT contain an embedded userId. 7544 * @param userId The userId in which the uri is to be resolved. 7545 */ 7546 @Override 7547 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7548 int userId) { 7549 enforceNotIsolatedCaller("revokeUriPermission"); 7550 synchronized(this) { 7551 final ProcessRecord r = getRecordForAppLocked(caller); 7552 if (r == null) { 7553 throw new SecurityException("Unable to find app for caller " 7554 + caller 7555 + " when revoking permission to uri " + uri); 7556 } 7557 if (uri == null) { 7558 Slog.w(TAG, "revokeUriPermission: null uri"); 7559 return; 7560 } 7561 7562 if (!Intent.isAccessUriMode(modeFlags)) { 7563 return; 7564 } 7565 7566 final IPackageManager pm = AppGlobals.getPackageManager(); 7567 final String authority = uri.getAuthority(); 7568 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7569 if (pi == null) { 7570 Slog.w(TAG, "No content provider found for permission revoke: " 7571 + uri.toSafeString()); 7572 return; 7573 } 7574 7575 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7576 } 7577 } 7578 7579 /** 7580 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7581 * given package. 7582 * 7583 * @param packageName Package name to match, or {@code null} to apply to all 7584 * packages. 7585 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7586 * to all users. 7587 * @param persistable If persistable grants should be removed. 7588 */ 7589 private void removeUriPermissionsForPackageLocked( 7590 String packageName, int userHandle, boolean persistable) { 7591 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7592 throw new IllegalArgumentException("Must narrow by either package or user"); 7593 } 7594 7595 boolean persistChanged = false; 7596 7597 int N = mGrantedUriPermissions.size(); 7598 for (int i = 0; i < N; i++) { 7599 final int targetUid = mGrantedUriPermissions.keyAt(i); 7600 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7601 7602 // Only inspect grants matching user 7603 if (userHandle == UserHandle.USER_ALL 7604 || userHandle == UserHandle.getUserId(targetUid)) { 7605 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7606 final UriPermission perm = it.next(); 7607 7608 // Only inspect grants matching package 7609 if (packageName == null || perm.sourcePkg.equals(packageName) 7610 || perm.targetPkg.equals(packageName)) { 7611 persistChanged |= perm.revokeModes(persistable 7612 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7613 7614 // Only remove when no modes remain; any persisted grants 7615 // will keep this alive. 7616 if (perm.modeFlags == 0) { 7617 it.remove(); 7618 } 7619 } 7620 } 7621 7622 if (perms.isEmpty()) { 7623 mGrantedUriPermissions.remove(targetUid); 7624 N--; 7625 i--; 7626 } 7627 } 7628 } 7629 7630 if (persistChanged) { 7631 schedulePersistUriGrants(); 7632 } 7633 } 7634 7635 @Override 7636 public IBinder newUriPermissionOwner(String name) { 7637 enforceNotIsolatedCaller("newUriPermissionOwner"); 7638 synchronized(this) { 7639 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7640 return owner.getExternalTokenLocked(); 7641 } 7642 } 7643 7644 /** 7645 * @param uri This uri must NOT contain an embedded userId. 7646 * @param sourceUserId The userId in which the uri is to be resolved. 7647 * @param targetUserId The userId of the app that receives the grant. 7648 */ 7649 @Override 7650 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7651 final int modeFlags, int sourceUserId, int targetUserId) { 7652 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7653 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7654 synchronized(this) { 7655 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7656 if (owner == null) { 7657 throw new IllegalArgumentException("Unknown owner: " + token); 7658 } 7659 if (fromUid != Binder.getCallingUid()) { 7660 if (Binder.getCallingUid() != Process.myUid()) { 7661 // Only system code can grant URI permissions on behalf 7662 // of other users. 7663 throw new SecurityException("nice try"); 7664 } 7665 } 7666 if (targetPkg == null) { 7667 throw new IllegalArgumentException("null target"); 7668 } 7669 if (uri == null) { 7670 throw new IllegalArgumentException("null uri"); 7671 } 7672 7673 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7674 modeFlags, owner, targetUserId); 7675 } 7676 } 7677 7678 /** 7679 * @param uri This uri must NOT contain an embedded userId. 7680 * @param userId The userId in which the uri is to be resolved. 7681 */ 7682 @Override 7683 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7684 synchronized(this) { 7685 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7686 if (owner == null) { 7687 throw new IllegalArgumentException("Unknown owner: " + token); 7688 } 7689 7690 if (uri == null) { 7691 owner.removeUriPermissionsLocked(mode); 7692 } else { 7693 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7694 } 7695 } 7696 } 7697 7698 private void schedulePersistUriGrants() { 7699 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7700 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7701 10 * DateUtils.SECOND_IN_MILLIS); 7702 } 7703 } 7704 7705 private void writeGrantedUriPermissions() { 7706 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7707 7708 // Snapshot permissions so we can persist without lock 7709 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7710 synchronized (this) { 7711 final int size = mGrantedUriPermissions.size(); 7712 for (int i = 0; i < size; i++) { 7713 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7714 for (UriPermission perm : perms.values()) { 7715 if (perm.persistedModeFlags != 0) { 7716 persist.add(perm.snapshot()); 7717 } 7718 } 7719 } 7720 } 7721 7722 FileOutputStream fos = null; 7723 try { 7724 fos = mGrantFile.startWrite(); 7725 7726 XmlSerializer out = new FastXmlSerializer(); 7727 out.setOutput(fos, "utf-8"); 7728 out.startDocument(null, true); 7729 out.startTag(null, TAG_URI_GRANTS); 7730 for (UriPermission.Snapshot perm : persist) { 7731 out.startTag(null, TAG_URI_GRANT); 7732 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7733 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7734 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7735 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7736 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7737 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7738 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7739 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7740 out.endTag(null, TAG_URI_GRANT); 7741 } 7742 out.endTag(null, TAG_URI_GRANTS); 7743 out.endDocument(); 7744 7745 mGrantFile.finishWrite(fos); 7746 } catch (IOException e) { 7747 if (fos != null) { 7748 mGrantFile.failWrite(fos); 7749 } 7750 } 7751 } 7752 7753 private void readGrantedUriPermissionsLocked() { 7754 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7755 7756 final long now = System.currentTimeMillis(); 7757 7758 FileInputStream fis = null; 7759 try { 7760 fis = mGrantFile.openRead(); 7761 final XmlPullParser in = Xml.newPullParser(); 7762 in.setInput(fis, null); 7763 7764 int type; 7765 while ((type = in.next()) != END_DOCUMENT) { 7766 final String tag = in.getName(); 7767 if (type == START_TAG) { 7768 if (TAG_URI_GRANT.equals(tag)) { 7769 final int sourceUserId; 7770 final int targetUserId; 7771 final int userHandle = readIntAttribute(in, 7772 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7773 if (userHandle != UserHandle.USER_NULL) { 7774 // For backwards compatibility. 7775 sourceUserId = userHandle; 7776 targetUserId = userHandle; 7777 } else { 7778 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7779 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7780 } 7781 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7782 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7783 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7784 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7785 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7786 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7787 7788 // Sanity check that provider still belongs to source package 7789 final ProviderInfo pi = getProviderInfoLocked( 7790 uri.getAuthority(), sourceUserId); 7791 if (pi != null && sourcePkg.equals(pi.packageName)) { 7792 int targetUid = -1; 7793 try { 7794 targetUid = AppGlobals.getPackageManager() 7795 .getPackageUid(targetPkg, targetUserId); 7796 } catch (RemoteException e) { 7797 } 7798 if (targetUid != -1) { 7799 final UriPermission perm = findOrCreateUriPermissionLocked( 7800 sourcePkg, targetPkg, targetUid, 7801 new GrantUri(sourceUserId, uri, prefix)); 7802 perm.initPersistedModes(modeFlags, createdTime); 7803 } 7804 } else { 7805 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7806 + " but instead found " + pi); 7807 } 7808 } 7809 } 7810 } 7811 } catch (FileNotFoundException e) { 7812 // Missing grants is okay 7813 } catch (IOException e) { 7814 Slog.wtf(TAG, "Failed reading Uri grants", e); 7815 } catch (XmlPullParserException e) { 7816 Slog.wtf(TAG, "Failed reading Uri grants", e); 7817 } finally { 7818 IoUtils.closeQuietly(fis); 7819 } 7820 } 7821 7822 /** 7823 * @param uri This uri must NOT contain an embedded userId. 7824 * @param userId The userId in which the uri is to be resolved. 7825 */ 7826 @Override 7827 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7828 enforceNotIsolatedCaller("takePersistableUriPermission"); 7829 7830 Preconditions.checkFlagsArgument(modeFlags, 7831 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7832 7833 synchronized (this) { 7834 final int callingUid = Binder.getCallingUid(); 7835 boolean persistChanged = false; 7836 GrantUri grantUri = new GrantUri(userId, uri, false); 7837 7838 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7839 new GrantUri(userId, uri, false)); 7840 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7841 new GrantUri(userId, uri, true)); 7842 7843 final boolean exactValid = (exactPerm != null) 7844 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7845 final boolean prefixValid = (prefixPerm != null) 7846 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7847 7848 if (!(exactValid || prefixValid)) { 7849 throw new SecurityException("No persistable permission grants found for UID " 7850 + callingUid + " and Uri " + grantUri.toSafeString()); 7851 } 7852 7853 if (exactValid) { 7854 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7855 } 7856 if (prefixValid) { 7857 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7858 } 7859 7860 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7861 7862 if (persistChanged) { 7863 schedulePersistUriGrants(); 7864 } 7865 } 7866 } 7867 7868 /** 7869 * @param uri This uri must NOT contain an embedded userId. 7870 * @param userId The userId in which the uri is to be resolved. 7871 */ 7872 @Override 7873 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7874 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7875 7876 Preconditions.checkFlagsArgument(modeFlags, 7877 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7878 7879 synchronized (this) { 7880 final int callingUid = Binder.getCallingUid(); 7881 boolean persistChanged = false; 7882 7883 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7884 new GrantUri(userId, uri, false)); 7885 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7886 new GrantUri(userId, uri, true)); 7887 if (exactPerm == null && prefixPerm == null) { 7888 throw new SecurityException("No permission grants found for UID " + callingUid 7889 + " and Uri " + uri.toSafeString()); 7890 } 7891 7892 if (exactPerm != null) { 7893 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7894 removeUriPermissionIfNeededLocked(exactPerm); 7895 } 7896 if (prefixPerm != null) { 7897 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7898 removeUriPermissionIfNeededLocked(prefixPerm); 7899 } 7900 7901 if (persistChanged) { 7902 schedulePersistUriGrants(); 7903 } 7904 } 7905 } 7906 7907 /** 7908 * Prune any older {@link UriPermission} for the given UID until outstanding 7909 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7910 * 7911 * @return if any mutations occured that require persisting. 7912 */ 7913 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7914 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7915 if (perms == null) return false; 7916 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7917 7918 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7919 for (UriPermission perm : perms.values()) { 7920 if (perm.persistedModeFlags != 0) { 7921 persisted.add(perm); 7922 } 7923 } 7924 7925 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7926 if (trimCount <= 0) return false; 7927 7928 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7929 for (int i = 0; i < trimCount; i++) { 7930 final UriPermission perm = persisted.get(i); 7931 7932 if (DEBUG_URI_PERMISSION) { 7933 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7934 } 7935 7936 perm.releasePersistableModes(~0); 7937 removeUriPermissionIfNeededLocked(perm); 7938 } 7939 7940 return true; 7941 } 7942 7943 @Override 7944 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7945 String packageName, boolean incoming) { 7946 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7947 Preconditions.checkNotNull(packageName, "packageName"); 7948 7949 final int callingUid = Binder.getCallingUid(); 7950 final IPackageManager pm = AppGlobals.getPackageManager(); 7951 try { 7952 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7953 if (packageUid != callingUid) { 7954 throw new SecurityException( 7955 "Package " + packageName + " does not belong to calling UID " + callingUid); 7956 } 7957 } catch (RemoteException e) { 7958 throw new SecurityException("Failed to verify package name ownership"); 7959 } 7960 7961 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7962 synchronized (this) { 7963 if (incoming) { 7964 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7965 callingUid); 7966 if (perms == null) { 7967 Slog.w(TAG, "No permission grants found for " + packageName); 7968 } else { 7969 for (UriPermission perm : perms.values()) { 7970 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7971 result.add(perm.buildPersistedPublicApiObject()); 7972 } 7973 } 7974 } 7975 } else { 7976 final int size = mGrantedUriPermissions.size(); 7977 for (int i = 0; i < size; i++) { 7978 final ArrayMap<GrantUri, UriPermission> perms = 7979 mGrantedUriPermissions.valueAt(i); 7980 for (UriPermission perm : perms.values()) { 7981 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7982 result.add(perm.buildPersistedPublicApiObject()); 7983 } 7984 } 7985 } 7986 } 7987 } 7988 return new ParceledListSlice<android.content.UriPermission>(result); 7989 } 7990 7991 @Override 7992 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7993 synchronized (this) { 7994 ProcessRecord app = 7995 who != null ? getRecordForAppLocked(who) : null; 7996 if (app == null) return; 7997 7998 Message msg = Message.obtain(); 7999 msg.what = WAIT_FOR_DEBUGGER_MSG; 8000 msg.obj = app; 8001 msg.arg1 = waiting ? 1 : 0; 8002 mHandler.sendMessage(msg); 8003 } 8004 } 8005 8006 @Override 8007 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8008 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8009 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8010 outInfo.availMem = Process.getFreeMemory(); 8011 outInfo.totalMem = Process.getTotalMemory(); 8012 outInfo.threshold = homeAppMem; 8013 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8014 outInfo.hiddenAppThreshold = cachedAppMem; 8015 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8016 ProcessList.SERVICE_ADJ); 8017 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8018 ProcessList.VISIBLE_APP_ADJ); 8019 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8020 ProcessList.FOREGROUND_APP_ADJ); 8021 } 8022 8023 // ========================================================= 8024 // TASK MANAGEMENT 8025 // ========================================================= 8026 8027 @Override 8028 public List<IAppTask> getAppTasks(String callingPackage) { 8029 int callingUid = Binder.getCallingUid(); 8030 long ident = Binder.clearCallingIdentity(); 8031 8032 synchronized(this) { 8033 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8034 try { 8035 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8036 8037 final int N = mRecentTasks.size(); 8038 for (int i = 0; i < N; i++) { 8039 TaskRecord tr = mRecentTasks.get(i); 8040 // Skip tasks that do not match the caller. We don't need to verify 8041 // callingPackage, because we are also limiting to callingUid and know 8042 // that will limit to the correct security sandbox. 8043 if (tr.effectiveUid != callingUid) { 8044 continue; 8045 } 8046 Intent intent = tr.getBaseIntent(); 8047 if (intent == null || 8048 !callingPackage.equals(intent.getComponent().getPackageName())) { 8049 continue; 8050 } 8051 ActivityManager.RecentTaskInfo taskInfo = 8052 createRecentTaskInfoFromTaskRecord(tr); 8053 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8054 list.add(taskImpl); 8055 } 8056 } finally { 8057 Binder.restoreCallingIdentity(ident); 8058 } 8059 return list; 8060 } 8061 } 8062 8063 @Override 8064 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8065 final int callingUid = Binder.getCallingUid(); 8066 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8067 8068 synchronized(this) { 8069 if (localLOGV) Slog.v( 8070 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8071 8072 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8073 callingUid); 8074 8075 // TODO: Improve with MRU list from all ActivityStacks. 8076 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8077 } 8078 8079 return list; 8080 } 8081 8082 /** 8083 * Creates a new RecentTaskInfo from a TaskRecord. 8084 */ 8085 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8086 // Update the task description to reflect any changes in the task stack 8087 tr.updateTaskDescription(); 8088 8089 // Compose the recent task info 8090 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8091 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8092 rti.persistentId = tr.taskId; 8093 rti.baseIntent = new Intent(tr.getBaseIntent()); 8094 rti.origActivity = tr.origActivity; 8095 rti.description = tr.lastDescription; 8096 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8097 rti.userId = tr.userId; 8098 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8099 rti.firstActiveTime = tr.firstActiveTime; 8100 rti.lastActiveTime = tr.lastActiveTime; 8101 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8102 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8103 return rti; 8104 } 8105 8106 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8107 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8108 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8109 if (!allowed) { 8110 if (checkPermission(android.Manifest.permission.GET_TASKS, 8111 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8112 // Temporary compatibility: some existing apps on the system image may 8113 // still be requesting the old permission and not switched to the new 8114 // one; if so, we'll still allow them full access. This means we need 8115 // to see if they are holding the old permission and are a system app. 8116 try { 8117 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8118 allowed = true; 8119 Slog.w(TAG, caller + ": caller " + callingUid 8120 + " is using old GET_TASKS but privileged; allowing"); 8121 } 8122 } catch (RemoteException e) { 8123 } 8124 } 8125 } 8126 if (!allowed) { 8127 Slog.w(TAG, caller + ": caller " + callingUid 8128 + " does not hold GET_TASKS; limiting output"); 8129 } 8130 return allowed; 8131 } 8132 8133 @Override 8134 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8135 final int callingUid = Binder.getCallingUid(); 8136 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8137 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8138 8139 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8140 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8141 synchronized (this) { 8142 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8143 callingUid); 8144 final boolean detailed = checkCallingPermission( 8145 android.Manifest.permission.GET_DETAILED_TASKS) 8146 == PackageManager.PERMISSION_GRANTED; 8147 8148 final int N = mRecentTasks.size(); 8149 ArrayList<ActivityManager.RecentTaskInfo> res 8150 = new ArrayList<ActivityManager.RecentTaskInfo>( 8151 maxNum < N ? maxNum : N); 8152 8153 final Set<Integer> includedUsers; 8154 if (includeProfiles) { 8155 includedUsers = getProfileIdsLocked(userId); 8156 } else { 8157 includedUsers = new HashSet<Integer>(); 8158 } 8159 includedUsers.add(Integer.valueOf(userId)); 8160 8161 for (int i=0; i<N && maxNum > 0; i++) { 8162 TaskRecord tr = mRecentTasks.get(i); 8163 // Only add calling user or related users recent tasks 8164 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8165 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8166 continue; 8167 } 8168 8169 // Return the entry if desired by the caller. We always return 8170 // the first entry, because callers always expect this to be the 8171 // foreground app. We may filter others if the caller has 8172 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8173 // we should exclude the entry. 8174 8175 if (i == 0 8176 || withExcluded 8177 || (tr.intent == null) 8178 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8179 == 0)) { 8180 if (!allowed) { 8181 // If the caller doesn't have the GET_TASKS permission, then only 8182 // allow them to see a small subset of tasks -- their own and home. 8183 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8184 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8185 continue; 8186 } 8187 } 8188 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8189 if (tr.stack != null && tr.stack.isHomeStack()) { 8190 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8191 continue; 8192 } 8193 } 8194 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8195 // Don't include auto remove tasks that are finished or finishing. 8196 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8197 + tr); 8198 continue; 8199 } 8200 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8201 && !tr.isAvailable) { 8202 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8203 continue; 8204 } 8205 8206 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8207 if (!detailed) { 8208 rti.baseIntent.replaceExtras((Bundle)null); 8209 } 8210 8211 res.add(rti); 8212 maxNum--; 8213 } 8214 } 8215 return res; 8216 } 8217 } 8218 8219 TaskRecord recentTaskForIdLocked(int id) { 8220 final int N = mRecentTasks.size(); 8221 for (int i=0; i<N; i++) { 8222 TaskRecord tr = mRecentTasks.get(i); 8223 if (tr.taskId == id) { 8224 return tr; 8225 } 8226 } 8227 return null; 8228 } 8229 8230 @Override 8231 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8232 synchronized (this) { 8233 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8234 "getTaskThumbnail()"); 8235 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8236 if (tr != null) { 8237 return tr.getTaskThumbnailLocked(); 8238 } 8239 } 8240 return null; 8241 } 8242 8243 @Override 8244 public int addAppTask(IBinder activityToken, Intent intent, 8245 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8246 final int callingUid = Binder.getCallingUid(); 8247 final long callingIdent = Binder.clearCallingIdentity(); 8248 8249 try { 8250 synchronized (this) { 8251 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8252 if (r == null) { 8253 throw new IllegalArgumentException("Activity does not exist; token=" 8254 + activityToken); 8255 } 8256 ComponentName comp = intent.getComponent(); 8257 if (comp == null) { 8258 throw new IllegalArgumentException("Intent " + intent 8259 + " must specify explicit component"); 8260 } 8261 if (thumbnail.getWidth() != mThumbnailWidth 8262 || thumbnail.getHeight() != mThumbnailHeight) { 8263 throw new IllegalArgumentException("Bad thumbnail size: got " 8264 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8265 + mThumbnailWidth + "x" + mThumbnailHeight); 8266 } 8267 if (intent.getSelector() != null) { 8268 intent.setSelector(null); 8269 } 8270 if (intent.getSourceBounds() != null) { 8271 intent.setSourceBounds(null); 8272 } 8273 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8274 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8275 // The caller has added this as an auto-remove task... that makes no 8276 // sense, so turn off auto-remove. 8277 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8278 } 8279 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8280 // Must be a new task. 8281 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8282 } 8283 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8284 mLastAddedTaskActivity = null; 8285 } 8286 ActivityInfo ainfo = mLastAddedTaskActivity; 8287 if (ainfo == null) { 8288 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8289 comp, 0, UserHandle.getUserId(callingUid)); 8290 if (ainfo.applicationInfo.uid != callingUid) { 8291 throw new SecurityException( 8292 "Can't add task for another application: target uid=" 8293 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8294 } 8295 } 8296 8297 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8298 intent, description); 8299 8300 int trimIdx = trimRecentsForTaskLocked(task, false); 8301 if (trimIdx >= 0) { 8302 // If this would have caused a trim, then we'll abort because that 8303 // means it would be added at the end of the list but then just removed. 8304 return INVALID_TASK_ID; 8305 } 8306 8307 final int N = mRecentTasks.size(); 8308 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8309 final TaskRecord tr = mRecentTasks.remove(N - 1); 8310 tr.removedFromRecents(); 8311 } 8312 8313 task.inRecents = true; 8314 mRecentTasks.add(task); 8315 r.task.stack.addTask(task, false, false); 8316 8317 task.setLastThumbnail(thumbnail); 8318 task.freeLastThumbnail(); 8319 8320 return task.taskId; 8321 } 8322 } finally { 8323 Binder.restoreCallingIdentity(callingIdent); 8324 } 8325 } 8326 8327 @Override 8328 public Point getAppTaskThumbnailSize() { 8329 synchronized (this) { 8330 return new Point(mThumbnailWidth, mThumbnailHeight); 8331 } 8332 } 8333 8334 @Override 8335 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8336 synchronized (this) { 8337 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8338 if (r != null) { 8339 r.setTaskDescription(td); 8340 r.task.updateTaskDescription(); 8341 } 8342 } 8343 } 8344 8345 @Override 8346 public Bitmap getTaskDescriptionIcon(String filename) { 8347 if (!FileUtils.isValidExtFilename(filename) 8348 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8349 throw new IllegalArgumentException("Bad filename: " + filename); 8350 } 8351 return mTaskPersister.getTaskDescriptionIcon(filename); 8352 } 8353 8354 @Override 8355 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8356 throws RemoteException { 8357 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8358 opts.getCustomInPlaceResId() == 0) { 8359 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8360 "with valid animation"); 8361 } 8362 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8363 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8364 opts.getCustomInPlaceResId()); 8365 mWindowManager.executeAppTransition(); 8366 } 8367 8368 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8369 mRecentTasks.remove(tr); 8370 tr.removedFromRecents(); 8371 ComponentName component = tr.getBaseIntent().getComponent(); 8372 if (component == null) { 8373 Slog.w(TAG, "No component for base intent of task: " + tr); 8374 return; 8375 } 8376 8377 if (!killProcess) { 8378 return; 8379 } 8380 8381 // Determine if the process(es) for this task should be killed. 8382 final String pkg = component.getPackageName(); 8383 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8384 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8385 for (int i = 0; i < pmap.size(); i++) { 8386 8387 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8388 for (int j = 0; j < uids.size(); j++) { 8389 ProcessRecord proc = uids.valueAt(j); 8390 if (proc.userId != tr.userId) { 8391 // Don't kill process for a different user. 8392 continue; 8393 } 8394 if (proc == mHomeProcess) { 8395 // Don't kill the home process along with tasks from the same package. 8396 continue; 8397 } 8398 if (!proc.pkgList.containsKey(pkg)) { 8399 // Don't kill process that is not associated with this task. 8400 continue; 8401 } 8402 8403 for (int k = 0; k < proc.activities.size(); k++) { 8404 TaskRecord otherTask = proc.activities.get(k).task; 8405 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8406 // Don't kill process(es) that has an activity in a different task that is 8407 // also in recents. 8408 return; 8409 } 8410 } 8411 8412 // Add process to kill list. 8413 procsToKill.add(proc); 8414 } 8415 } 8416 8417 // Find any running services associated with this app and stop if needed. 8418 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8419 8420 // Kill the running processes. 8421 for (int i = 0; i < procsToKill.size(); i++) { 8422 ProcessRecord pr = procsToKill.get(i); 8423 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8424 pr.kill("remove task", true); 8425 } else { 8426 pr.waitingToKill = "remove task"; 8427 } 8428 } 8429 } 8430 8431 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8432 // Remove all tasks with activities in the specified package from the list of recent tasks 8433 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8434 TaskRecord tr = mRecentTasks.get(i); 8435 if (tr.userId != userId) continue; 8436 8437 ComponentName cn = tr.intent.getComponent(); 8438 if (cn != null && cn.getPackageName().equals(packageName)) { 8439 // If the package name matches, remove the task. 8440 removeTaskByIdLocked(tr.taskId, true); 8441 } 8442 } 8443 } 8444 8445 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8446 final IPackageManager pm = AppGlobals.getPackageManager(); 8447 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8448 8449 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8450 TaskRecord tr = mRecentTasks.get(i); 8451 if (tr.userId != userId) continue; 8452 8453 ComponentName cn = tr.intent.getComponent(); 8454 if (cn != null && cn.getPackageName().equals(packageName)) { 8455 // Skip if component still exists in the package. 8456 if (componentsKnownToExist.contains(cn)) continue; 8457 8458 try { 8459 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8460 if (info != null) { 8461 componentsKnownToExist.add(cn); 8462 } else { 8463 removeTaskByIdLocked(tr.taskId, false); 8464 } 8465 } catch (RemoteException e) { 8466 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8467 } 8468 } 8469 } 8470 } 8471 8472 /** 8473 * Removes the task with the specified task id. 8474 * 8475 * @param taskId Identifier of the task to be removed. 8476 * @param killProcess Kill any process associated with the task if possible. 8477 * @return Returns true if the given task was found and removed. 8478 */ 8479 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8480 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8481 if (tr != null) { 8482 tr.removeTaskActivitiesLocked(); 8483 cleanUpRemovedTaskLocked(tr, killProcess); 8484 if (tr.isPersistable) { 8485 notifyTaskPersisterLocked(null, true); 8486 } 8487 return true; 8488 } 8489 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8490 return false; 8491 } 8492 8493 @Override 8494 public boolean removeTask(int taskId) { 8495 synchronized (this) { 8496 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8497 "removeTask()"); 8498 long ident = Binder.clearCallingIdentity(); 8499 try { 8500 return removeTaskByIdLocked(taskId, true); 8501 } finally { 8502 Binder.restoreCallingIdentity(ident); 8503 } 8504 } 8505 } 8506 8507 /** 8508 * TODO: Add mController hook 8509 */ 8510 @Override 8511 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8512 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8513 "moveTaskToFront()"); 8514 8515 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8516 synchronized(this) { 8517 moveTaskToFrontLocked(taskId, flags, options); 8518 } 8519 } 8520 8521 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8522 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8523 Binder.getCallingUid(), -1, -1, "Task to front")) { 8524 ActivityOptions.abort(options); 8525 return; 8526 } 8527 final long origId = Binder.clearCallingIdentity(); 8528 try { 8529 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8530 if (task == null) { 8531 Slog.d(TAG, "Could not find task for id: "+ taskId); 8532 return; 8533 } 8534 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8535 mStackSupervisor.showLockTaskToast(); 8536 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8537 return; 8538 } 8539 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8540 if (prev != null && prev.isRecentsActivity()) { 8541 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8542 } 8543 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8544 } finally { 8545 Binder.restoreCallingIdentity(origId); 8546 } 8547 ActivityOptions.abort(options); 8548 } 8549 8550 @Override 8551 public void moveTaskToBack(int taskId) { 8552 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8553 "moveTaskToBack()"); 8554 8555 synchronized(this) { 8556 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8557 if (tr != null) { 8558 if (tr == mStackSupervisor.mLockTaskModeTask) { 8559 mStackSupervisor.showLockTaskToast(); 8560 return; 8561 } 8562 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8563 ActivityStack stack = tr.stack; 8564 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8565 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8566 Binder.getCallingUid(), -1, -1, "Task to back")) { 8567 return; 8568 } 8569 } 8570 final long origId = Binder.clearCallingIdentity(); 8571 try { 8572 stack.moveTaskToBackLocked(taskId, null); 8573 } finally { 8574 Binder.restoreCallingIdentity(origId); 8575 } 8576 } 8577 } 8578 } 8579 8580 /** 8581 * Moves an activity, and all of the other activities within the same task, to the bottom 8582 * of the history stack. The activity's order within the task is unchanged. 8583 * 8584 * @param token A reference to the activity we wish to move 8585 * @param nonRoot If false then this only works if the activity is the root 8586 * of a task; if true it will work for any activity in a task. 8587 * @return Returns true if the move completed, false if not. 8588 */ 8589 @Override 8590 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8591 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8592 synchronized(this) { 8593 final long origId = Binder.clearCallingIdentity(); 8594 try { 8595 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8596 if (taskId >= 0) { 8597 if ((mStackSupervisor.mLockTaskModeTask != null) 8598 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8599 mStackSupervisor.showLockTaskToast(); 8600 return false; 8601 } 8602 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8603 } 8604 } finally { 8605 Binder.restoreCallingIdentity(origId); 8606 } 8607 } 8608 return false; 8609 } 8610 8611 @Override 8612 public void moveTaskBackwards(int task) { 8613 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8614 "moveTaskBackwards()"); 8615 8616 synchronized(this) { 8617 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8618 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8619 return; 8620 } 8621 final long origId = Binder.clearCallingIdentity(); 8622 moveTaskBackwardsLocked(task); 8623 Binder.restoreCallingIdentity(origId); 8624 } 8625 } 8626 8627 private final void moveTaskBackwardsLocked(int task) { 8628 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8629 } 8630 8631 @Override 8632 public IBinder getHomeActivityToken() throws RemoteException { 8633 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8634 "getHomeActivityToken()"); 8635 synchronized (this) { 8636 return mStackSupervisor.getHomeActivityToken(); 8637 } 8638 } 8639 8640 @Override 8641 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8642 IActivityContainerCallback callback) throws RemoteException { 8643 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8644 "createActivityContainer()"); 8645 synchronized (this) { 8646 if (parentActivityToken == null) { 8647 throw new IllegalArgumentException("parent token must not be null"); 8648 } 8649 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8650 if (r == null) { 8651 return null; 8652 } 8653 if (callback == null) { 8654 throw new IllegalArgumentException("callback must not be null"); 8655 } 8656 return mStackSupervisor.createActivityContainer(r, callback); 8657 } 8658 } 8659 8660 @Override 8661 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8662 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8663 "deleteActivityContainer()"); 8664 synchronized (this) { 8665 mStackSupervisor.deleteActivityContainer(container); 8666 } 8667 } 8668 8669 @Override 8670 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8671 throws RemoteException { 8672 synchronized (this) { 8673 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8674 if (stack != null) { 8675 return stack.mActivityContainer; 8676 } 8677 return null; 8678 } 8679 } 8680 8681 @Override 8682 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8683 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8684 "moveTaskToStack()"); 8685 if (stackId == HOME_STACK_ID) { 8686 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8687 new RuntimeException("here").fillInStackTrace()); 8688 } 8689 synchronized (this) { 8690 long ident = Binder.clearCallingIdentity(); 8691 try { 8692 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8693 + stackId + " toTop=" + toTop); 8694 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 } 8699 } 8700 8701 @Override 8702 public void resizeStack(int stackBoxId, Rect bounds) { 8703 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8704 "resizeStackBox()"); 8705 long ident = Binder.clearCallingIdentity(); 8706 try { 8707 mWindowManager.resizeStack(stackBoxId, bounds); 8708 } finally { 8709 Binder.restoreCallingIdentity(ident); 8710 } 8711 } 8712 8713 @Override 8714 public List<StackInfo> getAllStackInfos() { 8715 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8716 "getAllStackInfos()"); 8717 long ident = Binder.clearCallingIdentity(); 8718 try { 8719 synchronized (this) { 8720 return mStackSupervisor.getAllStackInfosLocked(); 8721 } 8722 } finally { 8723 Binder.restoreCallingIdentity(ident); 8724 } 8725 } 8726 8727 @Override 8728 public StackInfo getStackInfo(int stackId) { 8729 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8730 "getStackInfo()"); 8731 long ident = Binder.clearCallingIdentity(); 8732 try { 8733 synchronized (this) { 8734 return mStackSupervisor.getStackInfoLocked(stackId); 8735 } 8736 } finally { 8737 Binder.restoreCallingIdentity(ident); 8738 } 8739 } 8740 8741 @Override 8742 public boolean isInHomeStack(int taskId) { 8743 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8744 "getStackInfo()"); 8745 long ident = Binder.clearCallingIdentity(); 8746 try { 8747 synchronized (this) { 8748 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8749 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8750 } 8751 } finally { 8752 Binder.restoreCallingIdentity(ident); 8753 } 8754 } 8755 8756 @Override 8757 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8758 synchronized(this) { 8759 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8760 } 8761 } 8762 8763 private boolean isLockTaskAuthorized(String pkg) { 8764 final DevicePolicyManager dpm = (DevicePolicyManager) 8765 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8766 try { 8767 int uid = mContext.getPackageManager().getPackageUid(pkg, 8768 Binder.getCallingUserHandle().getIdentifier()); 8769 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8770 } catch (NameNotFoundException e) { 8771 return false; 8772 } 8773 } 8774 8775 void startLockTaskMode(TaskRecord task) { 8776 final String pkg; 8777 synchronized (this) { 8778 pkg = task.intent.getComponent().getPackageName(); 8779 } 8780 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8781 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8782 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8783 StatusBarManagerInternal.class); 8784 if (statusBarManager != null) { 8785 statusBarManager.showScreenPinningRequest(); 8786 } 8787 return; 8788 } 8789 long ident = Binder.clearCallingIdentity(); 8790 try { 8791 synchronized (this) { 8792 // Since we lost lock on task, make sure it is still there. 8793 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8794 if (task != null) { 8795 if (!isSystemInitiated 8796 && ((mStackSupervisor.getFocusedStack() == null) 8797 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8798 throw new IllegalArgumentException("Invalid task, not in foreground"); 8799 } 8800 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8801 } 8802 } 8803 } finally { 8804 Binder.restoreCallingIdentity(ident); 8805 } 8806 } 8807 8808 @Override 8809 public void startLockTaskMode(int taskId) { 8810 final TaskRecord task; 8811 long ident = Binder.clearCallingIdentity(); 8812 try { 8813 synchronized (this) { 8814 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8815 } 8816 } finally { 8817 Binder.restoreCallingIdentity(ident); 8818 } 8819 if (task != null) { 8820 startLockTaskMode(task); 8821 } 8822 } 8823 8824 @Override 8825 public void startLockTaskMode(IBinder token) { 8826 final TaskRecord task; 8827 long ident = Binder.clearCallingIdentity(); 8828 try { 8829 synchronized (this) { 8830 final ActivityRecord r = ActivityRecord.forToken(token); 8831 if (r == null) { 8832 return; 8833 } 8834 task = r.task; 8835 } 8836 } finally { 8837 Binder.restoreCallingIdentity(ident); 8838 } 8839 if (task != null) { 8840 startLockTaskMode(task); 8841 } 8842 } 8843 8844 @Override 8845 public void startLockTaskModeOnCurrent() throws RemoteException { 8846 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8847 "startLockTaskModeOnCurrent"); 8848 long ident = Binder.clearCallingIdentity(); 8849 try { 8850 ActivityRecord r = null; 8851 synchronized (this) { 8852 r = mStackSupervisor.topRunningActivityLocked(); 8853 } 8854 startLockTaskMode(r.task); 8855 } finally { 8856 Binder.restoreCallingIdentity(ident); 8857 } 8858 } 8859 8860 @Override 8861 public void stopLockTaskMode() { 8862 // Verify that the user matches the package of the intent for the TaskRecord 8863 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8864 // and stopLockTaskMode. 8865 final int callingUid = Binder.getCallingUid(); 8866 if (callingUid != Process.SYSTEM_UID) { 8867 try { 8868 String pkg = 8869 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8870 int uid = mContext.getPackageManager().getPackageUid(pkg, 8871 Binder.getCallingUserHandle().getIdentifier()); 8872 if (uid != callingUid) { 8873 throw new SecurityException("Invalid uid, expected " + uid); 8874 } 8875 } catch (NameNotFoundException e) { 8876 Log.d(TAG, "stopLockTaskMode " + e); 8877 return; 8878 } 8879 } 8880 long ident = Binder.clearCallingIdentity(); 8881 try { 8882 Log.d(TAG, "stopLockTaskMode"); 8883 // Stop lock task 8884 synchronized (this) { 8885 mStackSupervisor.setLockTaskModeLocked(null, false); 8886 } 8887 } finally { 8888 Binder.restoreCallingIdentity(ident); 8889 } 8890 } 8891 8892 @Override 8893 public void stopLockTaskModeOnCurrent() throws RemoteException { 8894 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8895 "stopLockTaskModeOnCurrent"); 8896 long ident = Binder.clearCallingIdentity(); 8897 try { 8898 stopLockTaskMode(); 8899 } finally { 8900 Binder.restoreCallingIdentity(ident); 8901 } 8902 } 8903 8904 @Override 8905 public boolean isInLockTaskMode() { 8906 synchronized (this) { 8907 return mStackSupervisor.isInLockTaskMode(); 8908 } 8909 } 8910 8911 // ========================================================= 8912 // CONTENT PROVIDERS 8913 // ========================================================= 8914 8915 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8916 List<ProviderInfo> providers = null; 8917 try { 8918 providers = AppGlobals.getPackageManager(). 8919 queryContentProviders(app.processName, app.uid, 8920 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8921 } catch (RemoteException ex) { 8922 } 8923 if (DEBUG_MU) 8924 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8925 int userId = app.userId; 8926 if (providers != null) { 8927 int N = providers.size(); 8928 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8929 for (int i=0; i<N; i++) { 8930 ProviderInfo cpi = 8931 (ProviderInfo)providers.get(i); 8932 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8933 cpi.name, cpi.flags); 8934 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8935 // This is a singleton provider, but a user besides the 8936 // default user is asking to initialize a process it runs 8937 // in... well, no, it doesn't actually run in this process, 8938 // it runs in the process of the default user. Get rid of it. 8939 providers.remove(i); 8940 N--; 8941 i--; 8942 continue; 8943 } 8944 8945 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8946 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8947 if (cpr == null) { 8948 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8949 mProviderMap.putProviderByClass(comp, cpr); 8950 } 8951 if (DEBUG_MU) 8952 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8953 app.pubProviders.put(cpi.name, cpr); 8954 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8955 // Don't add this if it is a platform component that is marked 8956 // to run in multiple processes, because this is actually 8957 // part of the framework so doesn't make sense to track as a 8958 // separate apk in the process. 8959 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8960 mProcessStats); 8961 } 8962 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8963 } 8964 } 8965 return providers; 8966 } 8967 8968 /** 8969 * Check if {@link ProcessRecord} has a possible chance at accessing the 8970 * given {@link ProviderInfo}. Final permission checking is always done 8971 * in {@link ContentProvider}. 8972 */ 8973 private final String checkContentProviderPermissionLocked( 8974 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8975 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8976 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8977 boolean checkedGrants = false; 8978 if (checkUser) { 8979 // Looking for cross-user grants before enforcing the typical cross-users permissions 8980 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8981 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8982 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8983 return null; 8984 } 8985 checkedGrants = true; 8986 } 8987 userId = handleIncomingUser(callingPid, callingUid, userId, 8988 false, ALLOW_NON_FULL, 8989 "checkContentProviderPermissionLocked " + cpi.authority, null); 8990 if (userId != tmpTargetUserId) { 8991 // When we actually went to determine the final targer user ID, this ended 8992 // up different than our initial check for the authority. This is because 8993 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8994 // SELF. So we need to re-check the grants again. 8995 checkedGrants = false; 8996 } 8997 } 8998 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8999 cpi.applicationInfo.uid, cpi.exported) 9000 == PackageManager.PERMISSION_GRANTED) { 9001 return null; 9002 } 9003 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9004 cpi.applicationInfo.uid, cpi.exported) 9005 == PackageManager.PERMISSION_GRANTED) { 9006 return null; 9007 } 9008 9009 PathPermission[] pps = cpi.pathPermissions; 9010 if (pps != null) { 9011 int i = pps.length; 9012 while (i > 0) { 9013 i--; 9014 PathPermission pp = pps[i]; 9015 String pprperm = pp.getReadPermission(); 9016 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9017 cpi.applicationInfo.uid, cpi.exported) 9018 == PackageManager.PERMISSION_GRANTED) { 9019 return null; 9020 } 9021 String ppwperm = pp.getWritePermission(); 9022 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9023 cpi.applicationInfo.uid, cpi.exported) 9024 == PackageManager.PERMISSION_GRANTED) { 9025 return null; 9026 } 9027 } 9028 } 9029 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9030 return null; 9031 } 9032 9033 String msg; 9034 if (!cpi.exported) { 9035 msg = "Permission Denial: opening provider " + cpi.name 9036 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9037 + ", uid=" + callingUid + ") that is not exported from uid " 9038 + cpi.applicationInfo.uid; 9039 } else { 9040 msg = "Permission Denial: opening provider " + cpi.name 9041 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9042 + ", uid=" + callingUid + ") requires " 9043 + cpi.readPermission + " or " + cpi.writePermission; 9044 } 9045 Slog.w(TAG, msg); 9046 return msg; 9047 } 9048 9049 /** 9050 * Returns if the ContentProvider has granted a uri to callingUid 9051 */ 9052 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9053 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9054 if (perms != null) { 9055 for (int i=perms.size()-1; i>=0; i--) { 9056 GrantUri grantUri = perms.keyAt(i); 9057 if (grantUri.sourceUserId == userId || !checkUser) { 9058 if (matchesProvider(grantUri.uri, cpi)) { 9059 return true; 9060 } 9061 } 9062 } 9063 } 9064 return false; 9065 } 9066 9067 /** 9068 * Returns true if the uri authority is one of the authorities specified in the provider. 9069 */ 9070 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9071 String uriAuth = uri.getAuthority(); 9072 String cpiAuth = cpi.authority; 9073 if (cpiAuth.indexOf(';') == -1) { 9074 return cpiAuth.equals(uriAuth); 9075 } 9076 String[] cpiAuths = cpiAuth.split(";"); 9077 int length = cpiAuths.length; 9078 for (int i = 0; i < length; i++) { 9079 if (cpiAuths[i].equals(uriAuth)) return true; 9080 } 9081 return false; 9082 } 9083 9084 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9085 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9086 if (r != null) { 9087 for (int i=0; i<r.conProviders.size(); i++) { 9088 ContentProviderConnection conn = r.conProviders.get(i); 9089 if (conn.provider == cpr) { 9090 if (DEBUG_PROVIDER) Slog.v(TAG, 9091 "Adding provider requested by " 9092 + r.processName + " from process " 9093 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9094 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9095 if (stable) { 9096 conn.stableCount++; 9097 conn.numStableIncs++; 9098 } else { 9099 conn.unstableCount++; 9100 conn.numUnstableIncs++; 9101 } 9102 return conn; 9103 } 9104 } 9105 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9106 if (stable) { 9107 conn.stableCount = 1; 9108 conn.numStableIncs = 1; 9109 } else { 9110 conn.unstableCount = 1; 9111 conn.numUnstableIncs = 1; 9112 } 9113 cpr.connections.add(conn); 9114 r.conProviders.add(conn); 9115 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9116 return conn; 9117 } 9118 cpr.addExternalProcessHandleLocked(externalProcessToken); 9119 return null; 9120 } 9121 9122 boolean decProviderCountLocked(ContentProviderConnection conn, 9123 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9124 if (conn != null) { 9125 cpr = conn.provider; 9126 if (DEBUG_PROVIDER) Slog.v(TAG, 9127 "Removing provider requested by " 9128 + conn.client.processName + " from process " 9129 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9130 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9131 if (stable) { 9132 conn.stableCount--; 9133 } else { 9134 conn.unstableCount--; 9135 } 9136 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9137 cpr.connections.remove(conn); 9138 conn.client.conProviders.remove(conn); 9139 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9140 return true; 9141 } 9142 return false; 9143 } 9144 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9145 return false; 9146 } 9147 9148 private void checkTime(long startTime, String where) { 9149 long now = SystemClock.elapsedRealtime(); 9150 if ((now-startTime) > 1000) { 9151 // If we are taking more than a second, log about it. 9152 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9153 } 9154 } 9155 9156 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9157 String name, IBinder token, boolean stable, int userId) { 9158 ContentProviderRecord cpr; 9159 ContentProviderConnection conn = null; 9160 ProviderInfo cpi = null; 9161 9162 synchronized(this) { 9163 long startTime = SystemClock.elapsedRealtime(); 9164 9165 ProcessRecord r = null; 9166 if (caller != null) { 9167 r = getRecordForAppLocked(caller); 9168 if (r == null) { 9169 throw new SecurityException( 9170 "Unable to find app for caller " + caller 9171 + " (pid=" + Binder.getCallingPid() 9172 + ") when getting content provider " + name); 9173 } 9174 } 9175 9176 boolean checkCrossUser = true; 9177 9178 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9179 9180 // First check if this content provider has been published... 9181 cpr = mProviderMap.getProviderByName(name, userId); 9182 // If that didn't work, check if it exists for user 0 and then 9183 // verify that it's a singleton provider before using it. 9184 if (cpr == null && userId != UserHandle.USER_OWNER) { 9185 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9186 if (cpr != null) { 9187 cpi = cpr.info; 9188 if (isSingleton(cpi.processName, cpi.applicationInfo, 9189 cpi.name, cpi.flags) 9190 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9191 userId = UserHandle.USER_OWNER; 9192 checkCrossUser = false; 9193 } else { 9194 cpr = null; 9195 cpi = null; 9196 } 9197 } 9198 } 9199 9200 boolean providerRunning = cpr != null; 9201 if (providerRunning) { 9202 cpi = cpr.info; 9203 String msg; 9204 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9205 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9206 != null) { 9207 throw new SecurityException(msg); 9208 } 9209 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9210 9211 if (r != null && cpr.canRunHere(r)) { 9212 // This provider has been published or is in the process 9213 // of being published... but it is also allowed to run 9214 // in the caller's process, so don't make a connection 9215 // and just let the caller instantiate its own instance. 9216 ContentProviderHolder holder = cpr.newHolder(null); 9217 // don't give caller the provider object, it needs 9218 // to make its own. 9219 holder.provider = null; 9220 return holder; 9221 } 9222 9223 final long origId = Binder.clearCallingIdentity(); 9224 9225 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9226 9227 // In this case the provider instance already exists, so we can 9228 // return it right away. 9229 conn = incProviderCountLocked(r, cpr, token, stable); 9230 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9231 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9232 // If this is a perceptible app accessing the provider, 9233 // make sure to count it as being accessed and thus 9234 // back up on the LRU list. This is good because 9235 // content providers are often expensive to start. 9236 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9237 updateLruProcessLocked(cpr.proc, false, null); 9238 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9239 } 9240 } 9241 9242 if (cpr.proc != null) { 9243 if (false) { 9244 if (cpr.name.flattenToShortString().equals( 9245 "com.android.providers.calendar/.CalendarProvider2")) { 9246 Slog.v(TAG, "****************** KILLING " 9247 + cpr.name.flattenToShortString()); 9248 Process.killProcess(cpr.proc.pid); 9249 } 9250 } 9251 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9252 boolean success = updateOomAdjLocked(cpr.proc); 9253 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9254 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9255 // NOTE: there is still a race here where a signal could be 9256 // pending on the process even though we managed to update its 9257 // adj level. Not sure what to do about this, but at least 9258 // the race is now smaller. 9259 if (!success) { 9260 // Uh oh... it looks like the provider's process 9261 // has been killed on us. We need to wait for a new 9262 // process to be started, and make sure its death 9263 // doesn't kill our process. 9264 Slog.i(TAG, 9265 "Existing provider " + cpr.name.flattenToShortString() 9266 + " is crashing; detaching " + r); 9267 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9268 checkTime(startTime, "getContentProviderImpl: before appDied"); 9269 appDiedLocked(cpr.proc); 9270 checkTime(startTime, "getContentProviderImpl: after appDied"); 9271 if (!lastRef) { 9272 // This wasn't the last ref our process had on 9273 // the provider... we have now been killed, bail. 9274 return null; 9275 } 9276 providerRunning = false; 9277 conn = null; 9278 } 9279 } 9280 9281 Binder.restoreCallingIdentity(origId); 9282 } 9283 9284 boolean singleton; 9285 if (!providerRunning) { 9286 try { 9287 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9288 cpi = AppGlobals.getPackageManager(). 9289 resolveContentProvider(name, 9290 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9291 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9292 } catch (RemoteException ex) { 9293 } 9294 if (cpi == null) { 9295 return null; 9296 } 9297 // If the provider is a singleton AND 9298 // (it's a call within the same user || the provider is a 9299 // privileged app) 9300 // Then allow connecting to the singleton provider 9301 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9302 cpi.name, cpi.flags) 9303 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9304 if (singleton) { 9305 userId = UserHandle.USER_OWNER; 9306 } 9307 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9308 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9309 9310 String msg; 9311 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9312 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9313 != null) { 9314 throw new SecurityException(msg); 9315 } 9316 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9317 9318 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9319 && !cpi.processName.equals("system")) { 9320 // If this content provider does not run in the system 9321 // process, and the system is not yet ready to run other 9322 // processes, then fail fast instead of hanging. 9323 throw new IllegalArgumentException( 9324 "Attempt to launch content provider before system ready"); 9325 } 9326 9327 // Make sure that the user who owns this provider is running. If not, 9328 // we don't want to allow it to run. 9329 if (!isUserRunningLocked(userId, false)) { 9330 Slog.w(TAG, "Unable to launch app " 9331 + cpi.applicationInfo.packageName + "/" 9332 + cpi.applicationInfo.uid + " for provider " 9333 + name + ": user " + userId + " is stopped"); 9334 return null; 9335 } 9336 9337 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9338 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9339 cpr = mProviderMap.getProviderByClass(comp, userId); 9340 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9341 final boolean firstClass = cpr == null; 9342 if (firstClass) { 9343 final long ident = Binder.clearCallingIdentity(); 9344 try { 9345 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9346 ApplicationInfo ai = 9347 AppGlobals.getPackageManager(). 9348 getApplicationInfo( 9349 cpi.applicationInfo.packageName, 9350 STOCK_PM_FLAGS, userId); 9351 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9352 if (ai == null) { 9353 Slog.w(TAG, "No package info for content provider " 9354 + cpi.name); 9355 return null; 9356 } 9357 ai = getAppInfoForUser(ai, userId); 9358 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9359 } catch (RemoteException ex) { 9360 // pm is in same process, this will never happen. 9361 } finally { 9362 Binder.restoreCallingIdentity(ident); 9363 } 9364 } 9365 9366 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9367 9368 if (r != null && cpr.canRunHere(r)) { 9369 // If this is a multiprocess provider, then just return its 9370 // info and allow the caller to instantiate it. Only do 9371 // this if the provider is the same user as the caller's 9372 // process, or can run as root (so can be in any process). 9373 return cpr.newHolder(null); 9374 } 9375 9376 if (DEBUG_PROVIDER) { 9377 RuntimeException e = new RuntimeException("here"); 9378 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9379 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9380 } 9381 9382 // This is single process, and our app is now connecting to it. 9383 // See if we are already in the process of launching this 9384 // provider. 9385 final int N = mLaunchingProviders.size(); 9386 int i; 9387 for (i=0; i<N; i++) { 9388 if (mLaunchingProviders.get(i) == cpr) { 9389 break; 9390 } 9391 } 9392 9393 // If the provider is not already being launched, then get it 9394 // started. 9395 if (i >= N) { 9396 final long origId = Binder.clearCallingIdentity(); 9397 9398 try { 9399 // Content provider is now in use, its package can't be stopped. 9400 try { 9401 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9402 AppGlobals.getPackageManager().setPackageStoppedState( 9403 cpr.appInfo.packageName, false, userId); 9404 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9405 } catch (RemoteException e) { 9406 } catch (IllegalArgumentException e) { 9407 Slog.w(TAG, "Failed trying to unstop package " 9408 + cpr.appInfo.packageName + ": " + e); 9409 } 9410 9411 // Use existing process if already started 9412 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9413 ProcessRecord proc = getProcessRecordLocked( 9414 cpi.processName, cpr.appInfo.uid, false); 9415 if (proc != null && proc.thread != null) { 9416 if (DEBUG_PROVIDER) { 9417 Slog.d(TAG, "Installing in existing process " + proc); 9418 } 9419 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9420 proc.pubProviders.put(cpi.name, cpr); 9421 try { 9422 proc.thread.scheduleInstallProvider(cpi); 9423 } catch (RemoteException e) { 9424 } 9425 } else { 9426 checkTime(startTime, "getContentProviderImpl: before start process"); 9427 proc = startProcessLocked(cpi.processName, 9428 cpr.appInfo, false, 0, "content provider", 9429 new ComponentName(cpi.applicationInfo.packageName, 9430 cpi.name), false, false, false); 9431 checkTime(startTime, "getContentProviderImpl: after start process"); 9432 if (proc == null) { 9433 Slog.w(TAG, "Unable to launch app " 9434 + cpi.applicationInfo.packageName + "/" 9435 + cpi.applicationInfo.uid + " for provider " 9436 + name + ": process is bad"); 9437 return null; 9438 } 9439 } 9440 cpr.launchingApp = proc; 9441 mLaunchingProviders.add(cpr); 9442 } finally { 9443 Binder.restoreCallingIdentity(origId); 9444 } 9445 } 9446 9447 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9448 9449 // Make sure the provider is published (the same provider class 9450 // may be published under multiple names). 9451 if (firstClass) { 9452 mProviderMap.putProviderByClass(comp, cpr); 9453 } 9454 9455 mProviderMap.putProviderByName(name, cpr); 9456 conn = incProviderCountLocked(r, cpr, token, stable); 9457 if (conn != null) { 9458 conn.waiting = true; 9459 } 9460 } 9461 checkTime(startTime, "getContentProviderImpl: done!"); 9462 } 9463 9464 // Wait for the provider to be published... 9465 synchronized (cpr) { 9466 while (cpr.provider == null) { 9467 if (cpr.launchingApp == null) { 9468 Slog.w(TAG, "Unable to launch app " 9469 + cpi.applicationInfo.packageName + "/" 9470 + cpi.applicationInfo.uid + " for provider " 9471 + name + ": launching app became null"); 9472 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9473 UserHandle.getUserId(cpi.applicationInfo.uid), 9474 cpi.applicationInfo.packageName, 9475 cpi.applicationInfo.uid, name); 9476 return null; 9477 } 9478 try { 9479 if (DEBUG_MU) { 9480 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9481 + cpr.launchingApp); 9482 } 9483 if (conn != null) { 9484 conn.waiting = true; 9485 } 9486 cpr.wait(); 9487 } catch (InterruptedException ex) { 9488 } finally { 9489 if (conn != null) { 9490 conn.waiting = false; 9491 } 9492 } 9493 } 9494 } 9495 return cpr != null ? cpr.newHolder(conn) : null; 9496 } 9497 9498 @Override 9499 public final ContentProviderHolder getContentProvider( 9500 IApplicationThread caller, String name, int userId, boolean stable) { 9501 enforceNotIsolatedCaller("getContentProvider"); 9502 if (caller == null) { 9503 String msg = "null IApplicationThread when getting content provider " 9504 + name; 9505 Slog.w(TAG, msg); 9506 throw new SecurityException(msg); 9507 } 9508 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9509 // with cross-user grant. 9510 return getContentProviderImpl(caller, name, null, stable, userId); 9511 } 9512 9513 public ContentProviderHolder getContentProviderExternal( 9514 String name, int userId, IBinder token) { 9515 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9516 "Do not have permission in call getContentProviderExternal()"); 9517 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9518 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9519 return getContentProviderExternalUnchecked(name, token, userId); 9520 } 9521 9522 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9523 IBinder token, int userId) { 9524 return getContentProviderImpl(null, name, token, true, userId); 9525 } 9526 9527 /** 9528 * Drop a content provider from a ProcessRecord's bookkeeping 9529 */ 9530 public void removeContentProvider(IBinder connection, boolean stable) { 9531 enforceNotIsolatedCaller("removeContentProvider"); 9532 long ident = Binder.clearCallingIdentity(); 9533 try { 9534 synchronized (this) { 9535 ContentProviderConnection conn; 9536 try { 9537 conn = (ContentProviderConnection)connection; 9538 } catch (ClassCastException e) { 9539 String msg ="removeContentProvider: " + connection 9540 + " not a ContentProviderConnection"; 9541 Slog.w(TAG, msg); 9542 throw new IllegalArgumentException(msg); 9543 } 9544 if (conn == null) { 9545 throw new NullPointerException("connection is null"); 9546 } 9547 if (decProviderCountLocked(conn, null, null, stable)) { 9548 updateOomAdjLocked(); 9549 } 9550 } 9551 } finally { 9552 Binder.restoreCallingIdentity(ident); 9553 } 9554 } 9555 9556 public void removeContentProviderExternal(String name, IBinder token) { 9557 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9558 "Do not have permission in call removeContentProviderExternal()"); 9559 int userId = UserHandle.getCallingUserId(); 9560 long ident = Binder.clearCallingIdentity(); 9561 try { 9562 removeContentProviderExternalUnchecked(name, token, userId); 9563 } finally { 9564 Binder.restoreCallingIdentity(ident); 9565 } 9566 } 9567 9568 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9569 synchronized (this) { 9570 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9571 if(cpr == null) { 9572 //remove from mProvidersByClass 9573 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9574 return; 9575 } 9576 9577 //update content provider record entry info 9578 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9579 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9580 if (localCpr.hasExternalProcessHandles()) { 9581 if (localCpr.removeExternalProcessHandleLocked(token)) { 9582 updateOomAdjLocked(); 9583 } else { 9584 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9585 + " with no external reference for token: " 9586 + token + "."); 9587 } 9588 } else { 9589 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9590 + " with no external references."); 9591 } 9592 } 9593 } 9594 9595 public final void publishContentProviders(IApplicationThread caller, 9596 List<ContentProviderHolder> providers) { 9597 if (providers == null) { 9598 return; 9599 } 9600 9601 enforceNotIsolatedCaller("publishContentProviders"); 9602 synchronized (this) { 9603 final ProcessRecord r = getRecordForAppLocked(caller); 9604 if (DEBUG_MU) 9605 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9606 if (r == null) { 9607 throw new SecurityException( 9608 "Unable to find app for caller " + caller 9609 + " (pid=" + Binder.getCallingPid() 9610 + ") when publishing content providers"); 9611 } 9612 9613 final long origId = Binder.clearCallingIdentity(); 9614 9615 final int N = providers.size(); 9616 for (int i=0; i<N; i++) { 9617 ContentProviderHolder src = providers.get(i); 9618 if (src == null || src.info == null || src.provider == null) { 9619 continue; 9620 } 9621 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9622 if (DEBUG_MU) 9623 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9624 if (dst != null) { 9625 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9626 mProviderMap.putProviderByClass(comp, dst); 9627 String names[] = dst.info.authority.split(";"); 9628 for (int j = 0; j < names.length; j++) { 9629 mProviderMap.putProviderByName(names[j], dst); 9630 } 9631 9632 int NL = mLaunchingProviders.size(); 9633 int j; 9634 for (j=0; j<NL; j++) { 9635 if (mLaunchingProviders.get(j) == dst) { 9636 mLaunchingProviders.remove(j); 9637 j--; 9638 NL--; 9639 } 9640 } 9641 synchronized (dst) { 9642 dst.provider = src.provider; 9643 dst.proc = r; 9644 dst.notifyAll(); 9645 } 9646 updateOomAdjLocked(r); 9647 } 9648 } 9649 9650 Binder.restoreCallingIdentity(origId); 9651 } 9652 } 9653 9654 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9655 ContentProviderConnection conn; 9656 try { 9657 conn = (ContentProviderConnection)connection; 9658 } catch (ClassCastException e) { 9659 String msg ="refContentProvider: " + connection 9660 + " not a ContentProviderConnection"; 9661 Slog.w(TAG, msg); 9662 throw new IllegalArgumentException(msg); 9663 } 9664 if (conn == null) { 9665 throw new NullPointerException("connection is null"); 9666 } 9667 9668 synchronized (this) { 9669 if (stable > 0) { 9670 conn.numStableIncs += stable; 9671 } 9672 stable = conn.stableCount + stable; 9673 if (stable < 0) { 9674 throw new IllegalStateException("stableCount < 0: " + stable); 9675 } 9676 9677 if (unstable > 0) { 9678 conn.numUnstableIncs += unstable; 9679 } 9680 unstable = conn.unstableCount + unstable; 9681 if (unstable < 0) { 9682 throw new IllegalStateException("unstableCount < 0: " + unstable); 9683 } 9684 9685 if ((stable+unstable) <= 0) { 9686 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9687 + stable + " unstable=" + unstable); 9688 } 9689 conn.stableCount = stable; 9690 conn.unstableCount = unstable; 9691 return !conn.dead; 9692 } 9693 } 9694 9695 public void unstableProviderDied(IBinder connection) { 9696 ContentProviderConnection conn; 9697 try { 9698 conn = (ContentProviderConnection)connection; 9699 } catch (ClassCastException e) { 9700 String msg ="refContentProvider: " + connection 9701 + " not a ContentProviderConnection"; 9702 Slog.w(TAG, msg); 9703 throw new IllegalArgumentException(msg); 9704 } 9705 if (conn == null) { 9706 throw new NullPointerException("connection is null"); 9707 } 9708 9709 // Safely retrieve the content provider associated with the connection. 9710 IContentProvider provider; 9711 synchronized (this) { 9712 provider = conn.provider.provider; 9713 } 9714 9715 if (provider == null) { 9716 // Um, yeah, we're way ahead of you. 9717 return; 9718 } 9719 9720 // Make sure the caller is being honest with us. 9721 if (provider.asBinder().pingBinder()) { 9722 // Er, no, still looks good to us. 9723 synchronized (this) { 9724 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9725 + " says " + conn + " died, but we don't agree"); 9726 return; 9727 } 9728 } 9729 9730 // Well look at that! It's dead! 9731 synchronized (this) { 9732 if (conn.provider.provider != provider) { 9733 // But something changed... good enough. 9734 return; 9735 } 9736 9737 ProcessRecord proc = conn.provider.proc; 9738 if (proc == null || proc.thread == null) { 9739 // Seems like the process is already cleaned up. 9740 return; 9741 } 9742 9743 // As far as we're concerned, this is just like receiving a 9744 // death notification... just a bit prematurely. 9745 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9746 + ") early provider death"); 9747 final long ident = Binder.clearCallingIdentity(); 9748 try { 9749 appDiedLocked(proc); 9750 } finally { 9751 Binder.restoreCallingIdentity(ident); 9752 } 9753 } 9754 } 9755 9756 @Override 9757 public void appNotRespondingViaProvider(IBinder connection) { 9758 enforceCallingPermission( 9759 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9760 9761 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9762 if (conn == null) { 9763 Slog.w(TAG, "ContentProviderConnection is null"); 9764 return; 9765 } 9766 9767 final ProcessRecord host = conn.provider.proc; 9768 if (host == null) { 9769 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9770 return; 9771 } 9772 9773 final long token = Binder.clearCallingIdentity(); 9774 try { 9775 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9776 } finally { 9777 Binder.restoreCallingIdentity(token); 9778 } 9779 } 9780 9781 public final void installSystemProviders() { 9782 List<ProviderInfo> providers; 9783 synchronized (this) { 9784 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9785 providers = generateApplicationProvidersLocked(app); 9786 if (providers != null) { 9787 for (int i=providers.size()-1; i>=0; i--) { 9788 ProviderInfo pi = (ProviderInfo)providers.get(i); 9789 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9790 Slog.w(TAG, "Not installing system proc provider " + pi.name 9791 + ": not system .apk"); 9792 providers.remove(i); 9793 } 9794 } 9795 } 9796 } 9797 if (providers != null) { 9798 mSystemThread.installSystemProviders(providers); 9799 } 9800 9801 mCoreSettingsObserver = new CoreSettingsObserver(this); 9802 9803 //mUsageStatsService.monitorPackages(); 9804 } 9805 9806 /** 9807 * Allows apps to retrieve the MIME type of a URI. 9808 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9809 * users, then it does not need permission to access the ContentProvider. 9810 * Either, it needs cross-user uri grants. 9811 * 9812 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9813 * 9814 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9815 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9816 */ 9817 public String getProviderMimeType(Uri uri, int userId) { 9818 enforceNotIsolatedCaller("getProviderMimeType"); 9819 final String name = uri.getAuthority(); 9820 int callingUid = Binder.getCallingUid(); 9821 int callingPid = Binder.getCallingPid(); 9822 long ident = 0; 9823 boolean clearedIdentity = false; 9824 userId = unsafeConvertIncomingUser(userId); 9825 if (canClearIdentity(callingPid, callingUid, userId)) { 9826 clearedIdentity = true; 9827 ident = Binder.clearCallingIdentity(); 9828 } 9829 ContentProviderHolder holder = null; 9830 try { 9831 holder = getContentProviderExternalUnchecked(name, null, userId); 9832 if (holder != null) { 9833 return holder.provider.getType(uri); 9834 } 9835 } catch (RemoteException e) { 9836 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9837 return null; 9838 } finally { 9839 // We need to clear the identity to call removeContentProviderExternalUnchecked 9840 if (!clearedIdentity) { 9841 ident = Binder.clearCallingIdentity(); 9842 } 9843 try { 9844 if (holder != null) { 9845 removeContentProviderExternalUnchecked(name, null, userId); 9846 } 9847 } finally { 9848 Binder.restoreCallingIdentity(ident); 9849 } 9850 } 9851 9852 return null; 9853 } 9854 9855 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9856 if (UserHandle.getUserId(callingUid) == userId) { 9857 return true; 9858 } 9859 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9860 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9861 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9862 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9863 return true; 9864 } 9865 return false; 9866 } 9867 9868 // ========================================================= 9869 // GLOBAL MANAGEMENT 9870 // ========================================================= 9871 9872 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9873 boolean isolated, int isolatedUid) { 9874 String proc = customProcess != null ? customProcess : info.processName; 9875 BatteryStatsImpl.Uid.Proc ps = null; 9876 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9877 int uid = info.uid; 9878 if (isolated) { 9879 if (isolatedUid == 0) { 9880 int userId = UserHandle.getUserId(uid); 9881 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9882 while (true) { 9883 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9884 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9885 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9886 } 9887 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9888 mNextIsolatedProcessUid++; 9889 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9890 // No process for this uid, use it. 9891 break; 9892 } 9893 stepsLeft--; 9894 if (stepsLeft <= 0) { 9895 return null; 9896 } 9897 } 9898 } else { 9899 // Special case for startIsolatedProcess (internal only), where 9900 // the uid of the isolated process is specified by the caller. 9901 uid = isolatedUid; 9902 } 9903 } 9904 return new ProcessRecord(stats, info, proc, uid); 9905 } 9906 9907 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9908 String abiOverride) { 9909 ProcessRecord app; 9910 if (!isolated) { 9911 app = getProcessRecordLocked(info.processName, info.uid, true); 9912 } else { 9913 app = null; 9914 } 9915 9916 if (app == null) { 9917 app = newProcessRecordLocked(info, null, isolated, 0); 9918 mProcessNames.put(info.processName, app.uid, app); 9919 if (isolated) { 9920 mIsolatedProcesses.put(app.uid, app); 9921 } 9922 updateLruProcessLocked(app, false, null); 9923 updateOomAdjLocked(); 9924 } 9925 9926 // This package really, really can not be stopped. 9927 try { 9928 AppGlobals.getPackageManager().setPackageStoppedState( 9929 info.packageName, false, UserHandle.getUserId(app.uid)); 9930 } catch (RemoteException e) { 9931 } catch (IllegalArgumentException e) { 9932 Slog.w(TAG, "Failed trying to unstop package " 9933 + info.packageName + ": " + e); 9934 } 9935 9936 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9937 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9938 app.persistent = true; 9939 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9940 } 9941 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9942 mPersistentStartingProcesses.add(app); 9943 startProcessLocked(app, "added application", app.processName, abiOverride, 9944 null /* entryPoint */, null /* entryPointArgs */); 9945 } 9946 9947 return app; 9948 } 9949 9950 public void unhandledBack() { 9951 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9952 "unhandledBack()"); 9953 9954 synchronized(this) { 9955 final long origId = Binder.clearCallingIdentity(); 9956 try { 9957 getFocusedStack().unhandledBackLocked(); 9958 } finally { 9959 Binder.restoreCallingIdentity(origId); 9960 } 9961 } 9962 } 9963 9964 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9965 enforceNotIsolatedCaller("openContentUri"); 9966 final int userId = UserHandle.getCallingUserId(); 9967 String name = uri.getAuthority(); 9968 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9969 ParcelFileDescriptor pfd = null; 9970 if (cph != null) { 9971 // We record the binder invoker's uid in thread-local storage before 9972 // going to the content provider to open the file. Later, in the code 9973 // that handles all permissions checks, we look for this uid and use 9974 // that rather than the Activity Manager's own uid. The effect is that 9975 // we do the check against the caller's permissions even though it looks 9976 // to the content provider like the Activity Manager itself is making 9977 // the request. 9978 Binder token = new Binder(); 9979 sCallerIdentity.set(new Identity( 9980 token, Binder.getCallingPid(), Binder.getCallingUid())); 9981 try { 9982 pfd = cph.provider.openFile(null, uri, "r", null, token); 9983 } catch (FileNotFoundException e) { 9984 // do nothing; pfd will be returned null 9985 } finally { 9986 // Ensure that whatever happens, we clean up the identity state 9987 sCallerIdentity.remove(); 9988 } 9989 9990 // We've got the fd now, so we're done with the provider. 9991 removeContentProviderExternalUnchecked(name, null, userId); 9992 } else { 9993 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9994 } 9995 return pfd; 9996 } 9997 9998 // Actually is sleeping or shutting down or whatever else in the future 9999 // is an inactive state. 10000 public boolean isSleepingOrShuttingDown() { 10001 return isSleeping() || mShuttingDown; 10002 } 10003 10004 public boolean isSleeping() { 10005 return mSleeping; 10006 } 10007 10008 void onWakefulnessChanged(int wakefulness) { 10009 synchronized(this) { 10010 mWakefulness = wakefulness; 10011 updateSleepIfNeededLocked(); 10012 } 10013 } 10014 10015 void finishRunningVoiceLocked() { 10016 if (mRunningVoice) { 10017 mRunningVoice = false; 10018 updateSleepIfNeededLocked(); 10019 } 10020 } 10021 10022 void updateSleepIfNeededLocked() { 10023 if (mSleeping && !shouldSleepLocked()) { 10024 mSleeping = false; 10025 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10026 } else if (!mSleeping && shouldSleepLocked()) { 10027 mSleeping = true; 10028 mStackSupervisor.goingToSleepLocked(); 10029 10030 // Initialize the wake times of all processes. 10031 checkExcessivePowerUsageLocked(false); 10032 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10033 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10034 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10035 } 10036 } 10037 10038 private boolean shouldSleepLocked() { 10039 // Resume applications while running a voice interactor. 10040 if (mRunningVoice) { 10041 return false; 10042 } 10043 10044 switch (mWakefulness) { 10045 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10046 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10047 // If we're interactive but applications are already paused then defer 10048 // resuming them until the lock screen is hidden. 10049 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10050 case PowerManagerInternal.WAKEFULNESS_DOZING: 10051 // If we're dozing then pause applications whenever the lock screen is shown. 10052 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10053 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10054 default: 10055 // If we're asleep then pause applications unconditionally. 10056 return true; 10057 } 10058 } 10059 10060 /** Pokes the task persister. */ 10061 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10062 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10063 // Never persist the home stack. 10064 return; 10065 } 10066 mTaskPersister.wakeup(task, flush); 10067 } 10068 10069 /** Notifies all listeners when the task stack has changed. */ 10070 void notifyTaskStackChangedLocked() { 10071 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10072 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10073 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10074 } 10075 10076 @Override 10077 public boolean shutdown(int timeout) { 10078 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10079 != PackageManager.PERMISSION_GRANTED) { 10080 throw new SecurityException("Requires permission " 10081 + android.Manifest.permission.SHUTDOWN); 10082 } 10083 10084 boolean timedout = false; 10085 10086 synchronized(this) { 10087 mShuttingDown = true; 10088 updateEventDispatchingLocked(); 10089 timedout = mStackSupervisor.shutdownLocked(timeout); 10090 } 10091 10092 mAppOpsService.shutdown(); 10093 if (mUsageStatsService != null) { 10094 mUsageStatsService.prepareShutdown(); 10095 } 10096 mBatteryStatsService.shutdown(); 10097 synchronized (this) { 10098 mProcessStats.shutdownLocked(); 10099 notifyTaskPersisterLocked(null, true); 10100 } 10101 10102 return timedout; 10103 } 10104 10105 public final void activitySlept(IBinder token) { 10106 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10107 10108 final long origId = Binder.clearCallingIdentity(); 10109 10110 synchronized (this) { 10111 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10112 if (r != null) { 10113 mStackSupervisor.activitySleptLocked(r); 10114 } 10115 } 10116 10117 Binder.restoreCallingIdentity(origId); 10118 } 10119 10120 private String lockScreenShownToString() { 10121 switch (mLockScreenShown) { 10122 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10123 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10124 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10125 default: return "Unknown=" + mLockScreenShown; 10126 } 10127 } 10128 10129 void logLockScreen(String msg) { 10130 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10131 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10132 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10133 + " mSleeping=" + mSleeping); 10134 } 10135 10136 void startRunningVoiceLocked() { 10137 if (!mRunningVoice) { 10138 mRunningVoice = true; 10139 updateSleepIfNeededLocked(); 10140 } 10141 } 10142 10143 private void updateEventDispatchingLocked() { 10144 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10145 } 10146 10147 public void setLockScreenShown(boolean shown) { 10148 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10149 != PackageManager.PERMISSION_GRANTED) { 10150 throw new SecurityException("Requires permission " 10151 + android.Manifest.permission.DEVICE_POWER); 10152 } 10153 10154 synchronized(this) { 10155 long ident = Binder.clearCallingIdentity(); 10156 try { 10157 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10158 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10159 updateSleepIfNeededLocked(); 10160 } finally { 10161 Binder.restoreCallingIdentity(ident); 10162 } 10163 } 10164 } 10165 10166 @Override 10167 public void stopAppSwitches() { 10168 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10169 != PackageManager.PERMISSION_GRANTED) { 10170 throw new SecurityException("Requires permission " 10171 + android.Manifest.permission.STOP_APP_SWITCHES); 10172 } 10173 10174 synchronized(this) { 10175 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10176 + APP_SWITCH_DELAY_TIME; 10177 mDidAppSwitch = false; 10178 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10179 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10180 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10181 } 10182 } 10183 10184 public void resumeAppSwitches() { 10185 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10186 != PackageManager.PERMISSION_GRANTED) { 10187 throw new SecurityException("Requires permission " 10188 + android.Manifest.permission.STOP_APP_SWITCHES); 10189 } 10190 10191 synchronized(this) { 10192 // Note that we don't execute any pending app switches... we will 10193 // let those wait until either the timeout, or the next start 10194 // activity request. 10195 mAppSwitchesAllowedTime = 0; 10196 } 10197 } 10198 10199 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10200 int callingPid, int callingUid, String name) { 10201 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10202 return true; 10203 } 10204 10205 int perm = checkComponentPermission( 10206 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10207 sourceUid, -1, true); 10208 if (perm == PackageManager.PERMISSION_GRANTED) { 10209 return true; 10210 } 10211 10212 // If the actual IPC caller is different from the logical source, then 10213 // also see if they are allowed to control app switches. 10214 if (callingUid != -1 && callingUid != sourceUid) { 10215 perm = checkComponentPermission( 10216 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10217 callingUid, -1, true); 10218 if (perm == PackageManager.PERMISSION_GRANTED) { 10219 return true; 10220 } 10221 } 10222 10223 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10224 return false; 10225 } 10226 10227 public void setDebugApp(String packageName, boolean waitForDebugger, 10228 boolean persistent) { 10229 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10230 "setDebugApp()"); 10231 10232 long ident = Binder.clearCallingIdentity(); 10233 try { 10234 // Note that this is not really thread safe if there are multiple 10235 // callers into it at the same time, but that's not a situation we 10236 // care about. 10237 if (persistent) { 10238 final ContentResolver resolver = mContext.getContentResolver(); 10239 Settings.Global.putString( 10240 resolver, Settings.Global.DEBUG_APP, 10241 packageName); 10242 Settings.Global.putInt( 10243 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10244 waitForDebugger ? 1 : 0); 10245 } 10246 10247 synchronized (this) { 10248 if (!persistent) { 10249 mOrigDebugApp = mDebugApp; 10250 mOrigWaitForDebugger = mWaitForDebugger; 10251 } 10252 mDebugApp = packageName; 10253 mWaitForDebugger = waitForDebugger; 10254 mDebugTransient = !persistent; 10255 if (packageName != null) { 10256 forceStopPackageLocked(packageName, -1, false, false, true, true, 10257 false, UserHandle.USER_ALL, "set debug app"); 10258 } 10259 } 10260 } finally { 10261 Binder.restoreCallingIdentity(ident); 10262 } 10263 } 10264 10265 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10266 synchronized (this) { 10267 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10268 if (!isDebuggable) { 10269 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10270 throw new SecurityException("Process not debuggable: " + app.packageName); 10271 } 10272 } 10273 10274 mOpenGlTraceApp = processName; 10275 } 10276 } 10277 10278 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10279 synchronized (this) { 10280 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10281 if (!isDebuggable) { 10282 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10283 throw new SecurityException("Process not debuggable: " + app.packageName); 10284 } 10285 } 10286 mProfileApp = processName; 10287 mProfileFile = profilerInfo.profileFile; 10288 if (mProfileFd != null) { 10289 try { 10290 mProfileFd.close(); 10291 } catch (IOException e) { 10292 } 10293 mProfileFd = null; 10294 } 10295 mProfileFd = profilerInfo.profileFd; 10296 mSamplingInterval = profilerInfo.samplingInterval; 10297 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10298 mProfileType = 0; 10299 } 10300 } 10301 10302 @Override 10303 public void setAlwaysFinish(boolean enabled) { 10304 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10305 "setAlwaysFinish()"); 10306 10307 Settings.Global.putInt( 10308 mContext.getContentResolver(), 10309 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10310 10311 synchronized (this) { 10312 mAlwaysFinishActivities = enabled; 10313 } 10314 } 10315 10316 @Override 10317 public void setActivityController(IActivityController controller) { 10318 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10319 "setActivityController()"); 10320 synchronized (this) { 10321 mController = controller; 10322 Watchdog.getInstance().setActivityController(controller); 10323 } 10324 } 10325 10326 @Override 10327 public void setUserIsMonkey(boolean userIsMonkey) { 10328 synchronized (this) { 10329 synchronized (mPidsSelfLocked) { 10330 final int callingPid = Binder.getCallingPid(); 10331 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10332 if (precessRecord == null) { 10333 throw new SecurityException("Unknown process: " + callingPid); 10334 } 10335 if (precessRecord.instrumentationUiAutomationConnection == null) { 10336 throw new SecurityException("Only an instrumentation process " 10337 + "with a UiAutomation can call setUserIsMonkey"); 10338 } 10339 } 10340 mUserIsMonkey = userIsMonkey; 10341 } 10342 } 10343 10344 @Override 10345 public boolean isUserAMonkey() { 10346 synchronized (this) { 10347 // If there is a controller also implies the user is a monkey. 10348 return (mUserIsMonkey || mController != null); 10349 } 10350 } 10351 10352 public void requestBugReport() { 10353 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10354 SystemProperties.set("ctl.start", "bugreport"); 10355 } 10356 10357 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10358 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10359 } 10360 10361 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10362 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10363 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10364 } 10365 return KEY_DISPATCHING_TIMEOUT; 10366 } 10367 10368 @Override 10369 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10370 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10371 != PackageManager.PERMISSION_GRANTED) { 10372 throw new SecurityException("Requires permission " 10373 + android.Manifest.permission.FILTER_EVENTS); 10374 } 10375 ProcessRecord proc; 10376 long timeout; 10377 synchronized (this) { 10378 synchronized (mPidsSelfLocked) { 10379 proc = mPidsSelfLocked.get(pid); 10380 } 10381 timeout = getInputDispatchingTimeoutLocked(proc); 10382 } 10383 10384 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10385 return -1; 10386 } 10387 10388 return timeout; 10389 } 10390 10391 /** 10392 * Handle input dispatching timeouts. 10393 * Returns whether input dispatching should be aborted or not. 10394 */ 10395 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10396 final ActivityRecord activity, final ActivityRecord parent, 10397 final boolean aboveSystem, String reason) { 10398 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10399 != PackageManager.PERMISSION_GRANTED) { 10400 throw new SecurityException("Requires permission " 10401 + android.Manifest.permission.FILTER_EVENTS); 10402 } 10403 10404 final String annotation; 10405 if (reason == null) { 10406 annotation = "Input dispatching timed out"; 10407 } else { 10408 annotation = "Input dispatching timed out (" + reason + ")"; 10409 } 10410 10411 if (proc != null) { 10412 synchronized (this) { 10413 if (proc.debugging) { 10414 return false; 10415 } 10416 10417 if (mDidDexOpt) { 10418 // Give more time since we were dexopting. 10419 mDidDexOpt = false; 10420 return false; 10421 } 10422 10423 if (proc.instrumentationClass != null) { 10424 Bundle info = new Bundle(); 10425 info.putString("shortMsg", "keyDispatchingTimedOut"); 10426 info.putString("longMsg", annotation); 10427 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10428 return true; 10429 } 10430 } 10431 mHandler.post(new Runnable() { 10432 @Override 10433 public void run() { 10434 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10435 } 10436 }); 10437 } 10438 10439 return true; 10440 } 10441 10442 public Bundle getAssistContextExtras(int requestType) { 10443 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10444 UserHandle.getCallingUserId()); 10445 if (pae == null) { 10446 return null; 10447 } 10448 synchronized (pae) { 10449 while (!pae.haveResult) { 10450 try { 10451 pae.wait(); 10452 } catch (InterruptedException e) { 10453 } 10454 } 10455 if (pae.result != null) { 10456 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10457 } 10458 } 10459 synchronized (this) { 10460 mPendingAssistExtras.remove(pae); 10461 mHandler.removeCallbacks(pae); 10462 } 10463 return pae.extras; 10464 } 10465 10466 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10467 int userHandle) { 10468 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10469 "getAssistContextExtras()"); 10470 PendingAssistExtras pae; 10471 Bundle extras = new Bundle(); 10472 synchronized (this) { 10473 ActivityRecord activity = getFocusedStack().mResumedActivity; 10474 if (activity == null) { 10475 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10476 return null; 10477 } 10478 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10479 if (activity.app == null || activity.app.thread == null) { 10480 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10481 return null; 10482 } 10483 if (activity.app.pid == Binder.getCallingPid()) { 10484 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10485 return null; 10486 } 10487 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10488 try { 10489 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10490 requestType); 10491 mPendingAssistExtras.add(pae); 10492 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10493 } catch (RemoteException e) { 10494 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10495 return null; 10496 } 10497 return pae; 10498 } 10499 } 10500 10501 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10502 PendingAssistExtras pae = (PendingAssistExtras)token; 10503 synchronized (pae) { 10504 pae.result = extras; 10505 pae.haveResult = true; 10506 pae.notifyAll(); 10507 if (pae.intent == null) { 10508 // Caller is just waiting for the result. 10509 return; 10510 } 10511 } 10512 10513 // We are now ready to launch the assist activity. 10514 synchronized (this) { 10515 boolean exists = mPendingAssistExtras.remove(pae); 10516 mHandler.removeCallbacks(pae); 10517 if (!exists) { 10518 // Timed out. 10519 return; 10520 } 10521 } 10522 pae.intent.replaceExtras(extras); 10523 if (pae.hint != null) { 10524 pae.intent.putExtra(pae.hint, true); 10525 } 10526 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10527 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10528 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10529 closeSystemDialogs("assist"); 10530 try { 10531 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10532 } catch (ActivityNotFoundException e) { 10533 Slog.w(TAG, "No activity to handle assist action.", e); 10534 } 10535 } 10536 10537 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10538 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10539 } 10540 10541 public void registerProcessObserver(IProcessObserver observer) { 10542 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10543 "registerProcessObserver()"); 10544 synchronized (this) { 10545 mProcessObservers.register(observer); 10546 } 10547 } 10548 10549 @Override 10550 public void unregisterProcessObserver(IProcessObserver observer) { 10551 synchronized (this) { 10552 mProcessObservers.unregister(observer); 10553 } 10554 } 10555 10556 @Override 10557 public boolean convertFromTranslucent(IBinder token) { 10558 final long origId = Binder.clearCallingIdentity(); 10559 try { 10560 synchronized (this) { 10561 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10562 if (r == null) { 10563 return false; 10564 } 10565 final boolean translucentChanged = r.changeWindowTranslucency(true); 10566 if (translucentChanged) { 10567 r.task.stack.releaseBackgroundResources(); 10568 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10569 } 10570 mWindowManager.setAppFullscreen(token, true); 10571 return translucentChanged; 10572 } 10573 } finally { 10574 Binder.restoreCallingIdentity(origId); 10575 } 10576 } 10577 10578 @Override 10579 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10580 final long origId = Binder.clearCallingIdentity(); 10581 try { 10582 synchronized (this) { 10583 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10584 if (r == null) { 10585 return false; 10586 } 10587 int index = r.task.mActivities.lastIndexOf(r); 10588 if (index > 0) { 10589 ActivityRecord under = r.task.mActivities.get(index - 1); 10590 under.returningOptions = options; 10591 } 10592 final boolean translucentChanged = r.changeWindowTranslucency(false); 10593 if (translucentChanged) { 10594 r.task.stack.convertToTranslucent(r); 10595 } 10596 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10597 mWindowManager.setAppFullscreen(token, false); 10598 return translucentChanged; 10599 } 10600 } finally { 10601 Binder.restoreCallingIdentity(origId); 10602 } 10603 } 10604 10605 @Override 10606 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10607 final long origId = Binder.clearCallingIdentity(); 10608 try { 10609 synchronized (this) { 10610 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10611 if (r != null) { 10612 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10613 } 10614 } 10615 return false; 10616 } finally { 10617 Binder.restoreCallingIdentity(origId); 10618 } 10619 } 10620 10621 @Override 10622 public boolean isBackgroundVisibleBehind(IBinder token) { 10623 final long origId = Binder.clearCallingIdentity(); 10624 try { 10625 synchronized (this) { 10626 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10627 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10628 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10629 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10630 return visible; 10631 } 10632 } finally { 10633 Binder.restoreCallingIdentity(origId); 10634 } 10635 } 10636 10637 @Override 10638 public ActivityOptions getActivityOptions(IBinder token) { 10639 final long origId = Binder.clearCallingIdentity(); 10640 try { 10641 synchronized (this) { 10642 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10643 if (r != null) { 10644 final ActivityOptions activityOptions = r.pendingOptions; 10645 r.pendingOptions = null; 10646 return activityOptions; 10647 } 10648 return null; 10649 } 10650 } finally { 10651 Binder.restoreCallingIdentity(origId); 10652 } 10653 } 10654 10655 @Override 10656 public void setImmersive(IBinder token, boolean immersive) { 10657 synchronized(this) { 10658 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10659 if (r == null) { 10660 throw new IllegalArgumentException(); 10661 } 10662 r.immersive = immersive; 10663 10664 // update associated state if we're frontmost 10665 if (r == mFocusedActivity) { 10666 if (DEBUG_IMMERSIVE) { 10667 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10668 } 10669 applyUpdateLockStateLocked(r); 10670 } 10671 } 10672 } 10673 10674 @Override 10675 public boolean isImmersive(IBinder token) { 10676 synchronized (this) { 10677 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10678 if (r == null) { 10679 throw new IllegalArgumentException(); 10680 } 10681 return r.immersive; 10682 } 10683 } 10684 10685 public boolean isTopActivityImmersive() { 10686 enforceNotIsolatedCaller("startActivity"); 10687 synchronized (this) { 10688 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10689 return (r != null) ? r.immersive : false; 10690 } 10691 } 10692 10693 @Override 10694 public boolean isTopOfTask(IBinder token) { 10695 synchronized (this) { 10696 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10697 if (r == null) { 10698 throw new IllegalArgumentException(); 10699 } 10700 return r.task.getTopActivity() == r; 10701 } 10702 } 10703 10704 public final void enterSafeMode() { 10705 synchronized(this) { 10706 // It only makes sense to do this before the system is ready 10707 // and started launching other packages. 10708 if (!mSystemReady) { 10709 try { 10710 AppGlobals.getPackageManager().enterSafeMode(); 10711 } catch (RemoteException e) { 10712 } 10713 } 10714 10715 mSafeMode = true; 10716 } 10717 } 10718 10719 public final void showSafeModeOverlay() { 10720 View v = LayoutInflater.from(mContext).inflate( 10721 com.android.internal.R.layout.safe_mode, null); 10722 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10723 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10724 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10725 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10726 lp.gravity = Gravity.BOTTOM | Gravity.START; 10727 lp.format = v.getBackground().getOpacity(); 10728 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10729 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10730 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10731 ((WindowManager)mContext.getSystemService( 10732 Context.WINDOW_SERVICE)).addView(v, lp); 10733 } 10734 10735 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10736 if (!(sender instanceof PendingIntentRecord)) { 10737 return; 10738 } 10739 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10740 synchronized (stats) { 10741 if (mBatteryStatsService.isOnBattery()) { 10742 mBatteryStatsService.enforceCallingPermission(); 10743 PendingIntentRecord rec = (PendingIntentRecord)sender; 10744 int MY_UID = Binder.getCallingUid(); 10745 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10746 BatteryStatsImpl.Uid.Pkg pkg = 10747 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10748 sourcePkg != null ? sourcePkg : rec.key.packageName); 10749 pkg.incWakeupsLocked(); 10750 } 10751 } 10752 } 10753 10754 public boolean killPids(int[] pids, String pReason, boolean secure) { 10755 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10756 throw new SecurityException("killPids only available to the system"); 10757 } 10758 String reason = (pReason == null) ? "Unknown" : pReason; 10759 // XXX Note: don't acquire main activity lock here, because the window 10760 // manager calls in with its locks held. 10761 10762 boolean killed = false; 10763 synchronized (mPidsSelfLocked) { 10764 int[] types = new int[pids.length]; 10765 int worstType = 0; 10766 for (int i=0; i<pids.length; i++) { 10767 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10768 if (proc != null) { 10769 int type = proc.setAdj; 10770 types[i] = type; 10771 if (type > worstType) { 10772 worstType = type; 10773 } 10774 } 10775 } 10776 10777 // If the worst oom_adj is somewhere in the cached proc LRU range, 10778 // then constrain it so we will kill all cached procs. 10779 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10780 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10781 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10782 } 10783 10784 // If this is not a secure call, don't let it kill processes that 10785 // are important. 10786 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10787 worstType = ProcessList.SERVICE_ADJ; 10788 } 10789 10790 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10791 for (int i=0; i<pids.length; i++) { 10792 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10793 if (proc == null) { 10794 continue; 10795 } 10796 int adj = proc.setAdj; 10797 if (adj >= worstType && !proc.killedByAm) { 10798 proc.kill(reason, true); 10799 killed = true; 10800 } 10801 } 10802 } 10803 return killed; 10804 } 10805 10806 @Override 10807 public void killUid(int uid, String reason) { 10808 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10809 throw new SecurityException("killUid only available to the system"); 10810 } 10811 synchronized (this) { 10812 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10813 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10814 reason != null ? reason : "kill uid"); 10815 } 10816 } 10817 10818 @Override 10819 public boolean killProcessesBelowForeground(String reason) { 10820 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10821 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10822 } 10823 10824 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10825 } 10826 10827 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10828 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10829 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10830 } 10831 10832 boolean killed = false; 10833 synchronized (mPidsSelfLocked) { 10834 final int size = mPidsSelfLocked.size(); 10835 for (int i = 0; i < size; i++) { 10836 final int pid = mPidsSelfLocked.keyAt(i); 10837 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10838 if (proc == null) continue; 10839 10840 final int adj = proc.setAdj; 10841 if (adj > belowAdj && !proc.killedByAm) { 10842 proc.kill(reason, true); 10843 killed = true; 10844 } 10845 } 10846 } 10847 return killed; 10848 } 10849 10850 @Override 10851 public void hang(final IBinder who, boolean allowRestart) { 10852 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10853 != PackageManager.PERMISSION_GRANTED) { 10854 throw new SecurityException("Requires permission " 10855 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10856 } 10857 10858 final IBinder.DeathRecipient death = new DeathRecipient() { 10859 @Override 10860 public void binderDied() { 10861 synchronized (this) { 10862 notifyAll(); 10863 } 10864 } 10865 }; 10866 10867 try { 10868 who.linkToDeath(death, 0); 10869 } catch (RemoteException e) { 10870 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10871 return; 10872 } 10873 10874 synchronized (this) { 10875 Watchdog.getInstance().setAllowRestart(allowRestart); 10876 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10877 synchronized (death) { 10878 while (who.isBinderAlive()) { 10879 try { 10880 death.wait(); 10881 } catch (InterruptedException e) { 10882 } 10883 } 10884 } 10885 Watchdog.getInstance().setAllowRestart(true); 10886 } 10887 } 10888 10889 @Override 10890 public void restart() { 10891 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10892 != PackageManager.PERMISSION_GRANTED) { 10893 throw new SecurityException("Requires permission " 10894 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10895 } 10896 10897 Log.i(TAG, "Sending shutdown broadcast..."); 10898 10899 BroadcastReceiver br = new BroadcastReceiver() { 10900 @Override public void onReceive(Context context, Intent intent) { 10901 // Now the broadcast is done, finish up the low-level shutdown. 10902 Log.i(TAG, "Shutting down activity manager..."); 10903 shutdown(10000); 10904 Log.i(TAG, "Shutdown complete, restarting!"); 10905 Process.killProcess(Process.myPid()); 10906 System.exit(10); 10907 } 10908 }; 10909 10910 // First send the high-level shut down broadcast. 10911 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10912 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10913 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10914 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10915 mContext.sendOrderedBroadcastAsUser(intent, 10916 UserHandle.ALL, null, br, mHandler, 0, null, null); 10917 */ 10918 br.onReceive(mContext, intent); 10919 } 10920 10921 private long getLowRamTimeSinceIdle(long now) { 10922 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10923 } 10924 10925 @Override 10926 public void performIdleMaintenance() { 10927 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10928 != PackageManager.PERMISSION_GRANTED) { 10929 throw new SecurityException("Requires permission " 10930 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10931 } 10932 10933 synchronized (this) { 10934 final long now = SystemClock.uptimeMillis(); 10935 final long timeSinceLastIdle = now - mLastIdleTime; 10936 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10937 mLastIdleTime = now; 10938 mLowRamTimeSinceLastIdle = 0; 10939 if (mLowRamStartTime != 0) { 10940 mLowRamStartTime = now; 10941 } 10942 10943 StringBuilder sb = new StringBuilder(128); 10944 sb.append("Idle maintenance over "); 10945 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10946 sb.append(" low RAM for "); 10947 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10948 Slog.i(TAG, sb.toString()); 10949 10950 // If at least 1/3 of our time since the last idle period has been spent 10951 // with RAM low, then we want to kill processes. 10952 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10953 10954 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10955 ProcessRecord proc = mLruProcesses.get(i); 10956 if (proc.notCachedSinceIdle) { 10957 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10958 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10959 if (doKilling && proc.initialIdlePss != 0 10960 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10961 sb = new StringBuilder(128); 10962 sb.append("Kill"); 10963 sb.append(proc.processName); 10964 sb.append(" in idle maint: pss="); 10965 sb.append(proc.lastPss); 10966 sb.append(", initialPss="); 10967 sb.append(proc.initialIdlePss); 10968 sb.append(", period="); 10969 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10970 sb.append(", lowRamPeriod="); 10971 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10972 Slog.wtfQuiet(TAG, sb.toString()); 10973 proc.kill("idle maint (pss " + proc.lastPss 10974 + " from " + proc.initialIdlePss + ")", true); 10975 } 10976 } 10977 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10978 proc.notCachedSinceIdle = true; 10979 proc.initialIdlePss = 0; 10980 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10981 mTestPssMode, isSleeping(), now); 10982 } 10983 } 10984 10985 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10986 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10987 } 10988 } 10989 10990 private void retrieveSettings() { 10991 final ContentResolver resolver = mContext.getContentResolver(); 10992 String debugApp = Settings.Global.getString( 10993 resolver, Settings.Global.DEBUG_APP); 10994 boolean waitForDebugger = Settings.Global.getInt( 10995 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10996 boolean alwaysFinishActivities = Settings.Global.getInt( 10997 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10998 boolean forceRtl = Settings.Global.getInt( 10999 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11000 // Transfer any global setting for forcing RTL layout, into a System Property 11001 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11002 11003 Configuration configuration = new Configuration(); 11004 Settings.System.getConfiguration(resolver, configuration); 11005 if (forceRtl) { 11006 // This will take care of setting the correct layout direction flags 11007 configuration.setLayoutDirection(configuration.locale); 11008 } 11009 11010 synchronized (this) { 11011 mDebugApp = mOrigDebugApp = debugApp; 11012 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11013 mAlwaysFinishActivities = alwaysFinishActivities; 11014 // This happens before any activities are started, so we can 11015 // change mConfiguration in-place. 11016 updateConfigurationLocked(configuration, null, false, true); 11017 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11018 } 11019 } 11020 11021 /** Loads resources after the current configuration has been set. */ 11022 private void loadResourcesOnSystemReady() { 11023 final Resources res = mContext.getResources(); 11024 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11025 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11026 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11027 } 11028 11029 public boolean testIsSystemReady() { 11030 // no need to synchronize(this) just to read & return the value 11031 return mSystemReady; 11032 } 11033 11034 private static File getCalledPreBootReceiversFile() { 11035 File dataDir = Environment.getDataDirectory(); 11036 File systemDir = new File(dataDir, "system"); 11037 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11038 return fname; 11039 } 11040 11041 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11042 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11043 File file = getCalledPreBootReceiversFile(); 11044 FileInputStream fis = null; 11045 try { 11046 fis = new FileInputStream(file); 11047 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11048 int fvers = dis.readInt(); 11049 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11050 String vers = dis.readUTF(); 11051 String codename = dis.readUTF(); 11052 String build = dis.readUTF(); 11053 if (android.os.Build.VERSION.RELEASE.equals(vers) 11054 && android.os.Build.VERSION.CODENAME.equals(codename) 11055 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11056 int num = dis.readInt(); 11057 while (num > 0) { 11058 num--; 11059 String pkg = dis.readUTF(); 11060 String cls = dis.readUTF(); 11061 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11062 } 11063 } 11064 } 11065 } catch (FileNotFoundException e) { 11066 } catch (IOException e) { 11067 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11068 } finally { 11069 if (fis != null) { 11070 try { 11071 fis.close(); 11072 } catch (IOException e) { 11073 } 11074 } 11075 } 11076 return lastDoneReceivers; 11077 } 11078 11079 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11080 File file = getCalledPreBootReceiversFile(); 11081 FileOutputStream fos = null; 11082 DataOutputStream dos = null; 11083 try { 11084 fos = new FileOutputStream(file); 11085 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11086 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11087 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11088 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11089 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11090 dos.writeInt(list.size()); 11091 for (int i=0; i<list.size(); i++) { 11092 dos.writeUTF(list.get(i).getPackageName()); 11093 dos.writeUTF(list.get(i).getClassName()); 11094 } 11095 } catch (IOException e) { 11096 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11097 file.delete(); 11098 } finally { 11099 FileUtils.sync(fos); 11100 if (dos != null) { 11101 try { 11102 dos.close(); 11103 } catch (IOException e) { 11104 // TODO Auto-generated catch block 11105 e.printStackTrace(); 11106 } 11107 } 11108 } 11109 } 11110 11111 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11112 ArrayList<ComponentName> doneReceivers, int userId) { 11113 boolean waitingUpdate = false; 11114 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11115 List<ResolveInfo> ris = null; 11116 try { 11117 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11118 intent, null, 0, userId); 11119 } catch (RemoteException e) { 11120 } 11121 if (ris != null) { 11122 for (int i=ris.size()-1; i>=0; i--) { 11123 if ((ris.get(i).activityInfo.applicationInfo.flags 11124 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11125 ris.remove(i); 11126 } 11127 } 11128 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11129 11130 // For User 0, load the version number. When delivering to a new user, deliver 11131 // to all receivers. 11132 if (userId == UserHandle.USER_OWNER) { 11133 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11134 for (int i=0; i<ris.size(); i++) { 11135 ActivityInfo ai = ris.get(i).activityInfo; 11136 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11137 if (lastDoneReceivers.contains(comp)) { 11138 // We already did the pre boot receiver for this app with the current 11139 // platform version, so don't do it again... 11140 ris.remove(i); 11141 i--; 11142 // ...however, do keep it as one that has been done, so we don't 11143 // forget about it when rewriting the file of last done receivers. 11144 doneReceivers.add(comp); 11145 } 11146 } 11147 } 11148 11149 // If primary user, send broadcast to all available users, else just to userId 11150 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11151 : new int[] { userId }; 11152 for (int i = 0; i < ris.size(); i++) { 11153 ActivityInfo ai = ris.get(i).activityInfo; 11154 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11155 doneReceivers.add(comp); 11156 intent.setComponent(comp); 11157 for (int j=0; j<users.length; j++) { 11158 IIntentReceiver finisher = null; 11159 // On last receiver and user, set up a completion callback 11160 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11161 finisher = new IIntentReceiver.Stub() { 11162 public void performReceive(Intent intent, int resultCode, 11163 String data, Bundle extras, boolean ordered, 11164 boolean sticky, int sendingUser) { 11165 // The raw IIntentReceiver interface is called 11166 // with the AM lock held, so redispatch to 11167 // execute our code without the lock. 11168 mHandler.post(onFinishCallback); 11169 } 11170 }; 11171 } 11172 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11173 + " for user " + users[j]); 11174 broadcastIntentLocked(null, null, intent, null, finisher, 11175 0, null, null, null, AppOpsManager.OP_NONE, 11176 true, false, MY_PID, Process.SYSTEM_UID, 11177 users[j]); 11178 if (finisher != null) { 11179 waitingUpdate = true; 11180 } 11181 } 11182 } 11183 } 11184 11185 return waitingUpdate; 11186 } 11187 11188 public void systemReady(final Runnable goingCallback) { 11189 synchronized(this) { 11190 if (mSystemReady) { 11191 // If we're done calling all the receivers, run the next "boot phase" passed in 11192 // by the SystemServer 11193 if (goingCallback != null) { 11194 goingCallback.run(); 11195 } 11196 return; 11197 } 11198 11199 // Make sure we have the current profile info, since it is needed for 11200 // security checks. 11201 updateCurrentProfileIdsLocked(); 11202 11203 if (mRecentTasks == null) { 11204 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11205 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11206 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11207 mTaskPersister.startPersisting(); 11208 } 11209 11210 // Check to see if there are any update receivers to run. 11211 if (!mDidUpdate) { 11212 if (mWaitingUpdate) { 11213 return; 11214 } 11215 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11216 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11217 public void run() { 11218 synchronized (ActivityManagerService.this) { 11219 mDidUpdate = true; 11220 } 11221 writeLastDonePreBootReceivers(doneReceivers); 11222 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11223 false); 11224 systemReady(goingCallback); 11225 } 11226 }, doneReceivers, UserHandle.USER_OWNER); 11227 11228 if (mWaitingUpdate) { 11229 return; 11230 } 11231 mDidUpdate = true; 11232 } 11233 11234 mAppOpsService.systemReady(); 11235 mSystemReady = true; 11236 } 11237 11238 ArrayList<ProcessRecord> procsToKill = null; 11239 synchronized(mPidsSelfLocked) { 11240 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11241 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11242 if (!isAllowedWhileBooting(proc.info)){ 11243 if (procsToKill == null) { 11244 procsToKill = new ArrayList<ProcessRecord>(); 11245 } 11246 procsToKill.add(proc); 11247 } 11248 } 11249 } 11250 11251 synchronized(this) { 11252 if (procsToKill != null) { 11253 for (int i=procsToKill.size()-1; i>=0; i--) { 11254 ProcessRecord proc = procsToKill.get(i); 11255 Slog.i(TAG, "Removing system update proc: " + proc); 11256 removeProcessLocked(proc, true, false, "system update done"); 11257 } 11258 } 11259 11260 // Now that we have cleaned up any update processes, we 11261 // are ready to start launching real processes and know that 11262 // we won't trample on them any more. 11263 mProcessesReady = true; 11264 } 11265 11266 Slog.i(TAG, "System now ready"); 11267 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11268 SystemClock.uptimeMillis()); 11269 11270 synchronized(this) { 11271 // Make sure we have no pre-ready processes sitting around. 11272 11273 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11274 ResolveInfo ri = mContext.getPackageManager() 11275 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11276 STOCK_PM_FLAGS); 11277 CharSequence errorMsg = null; 11278 if (ri != null) { 11279 ActivityInfo ai = ri.activityInfo; 11280 ApplicationInfo app = ai.applicationInfo; 11281 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11282 mTopAction = Intent.ACTION_FACTORY_TEST; 11283 mTopData = null; 11284 mTopComponent = new ComponentName(app.packageName, 11285 ai.name); 11286 } else { 11287 errorMsg = mContext.getResources().getText( 11288 com.android.internal.R.string.factorytest_not_system); 11289 } 11290 } else { 11291 errorMsg = mContext.getResources().getText( 11292 com.android.internal.R.string.factorytest_no_action); 11293 } 11294 if (errorMsg != null) { 11295 mTopAction = null; 11296 mTopData = null; 11297 mTopComponent = null; 11298 Message msg = Message.obtain(); 11299 msg.what = SHOW_FACTORY_ERROR_MSG; 11300 msg.getData().putCharSequence("msg", errorMsg); 11301 mHandler.sendMessage(msg); 11302 } 11303 } 11304 } 11305 11306 retrieveSettings(); 11307 loadResourcesOnSystemReady(); 11308 11309 synchronized (this) { 11310 readGrantedUriPermissionsLocked(); 11311 } 11312 11313 if (goingCallback != null) goingCallback.run(); 11314 11315 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11316 Integer.toString(mCurrentUserId), mCurrentUserId); 11317 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11318 Integer.toString(mCurrentUserId), mCurrentUserId); 11319 mSystemServiceManager.startUser(mCurrentUserId); 11320 11321 synchronized (this) { 11322 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11323 try { 11324 List apps = AppGlobals.getPackageManager(). 11325 getPersistentApplications(STOCK_PM_FLAGS); 11326 if (apps != null) { 11327 int N = apps.size(); 11328 int i; 11329 for (i=0; i<N; i++) { 11330 ApplicationInfo info 11331 = (ApplicationInfo)apps.get(i); 11332 if (info != null && 11333 !info.packageName.equals("android")) { 11334 addAppLocked(info, false, null /* ABI override */); 11335 } 11336 } 11337 } 11338 } catch (RemoteException ex) { 11339 // pm is in same process, this will never happen. 11340 } 11341 } 11342 11343 // Start up initial activity. 11344 mBooting = true; 11345 startHomeActivityLocked(mCurrentUserId); 11346 11347 try { 11348 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11349 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11350 + " data partition or your device will be unstable."); 11351 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11352 } 11353 } catch (RemoteException e) { 11354 } 11355 11356 if (!Build.isFingerprintConsistent()) { 11357 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11358 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11359 } 11360 11361 long ident = Binder.clearCallingIdentity(); 11362 try { 11363 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11364 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11365 | Intent.FLAG_RECEIVER_FOREGROUND); 11366 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11367 broadcastIntentLocked(null, null, intent, 11368 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11369 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11370 intent = new Intent(Intent.ACTION_USER_STARTING); 11371 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11372 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11373 broadcastIntentLocked(null, null, intent, 11374 null, new IIntentReceiver.Stub() { 11375 @Override 11376 public void performReceive(Intent intent, int resultCode, String data, 11377 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11378 throws RemoteException { 11379 } 11380 }, 0, null, null, 11381 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11382 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11383 } catch (Throwable t) { 11384 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11385 } finally { 11386 Binder.restoreCallingIdentity(ident); 11387 } 11388 mStackSupervisor.resumeTopActivitiesLocked(); 11389 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11390 } 11391 } 11392 11393 private boolean makeAppCrashingLocked(ProcessRecord app, 11394 String shortMsg, String longMsg, String stackTrace) { 11395 app.crashing = true; 11396 app.crashingReport = generateProcessError(app, 11397 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11398 startAppProblemLocked(app); 11399 app.stopFreezingAllLocked(); 11400 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11401 } 11402 11403 private void makeAppNotRespondingLocked(ProcessRecord app, 11404 String activity, String shortMsg, String longMsg) { 11405 app.notResponding = true; 11406 app.notRespondingReport = generateProcessError(app, 11407 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11408 activity, shortMsg, longMsg, null); 11409 startAppProblemLocked(app); 11410 app.stopFreezingAllLocked(); 11411 } 11412 11413 /** 11414 * Generate a process error record, suitable for attachment to a ProcessRecord. 11415 * 11416 * @param app The ProcessRecord in which the error occurred. 11417 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11418 * ActivityManager.AppErrorStateInfo 11419 * @param activity The activity associated with the crash, if known. 11420 * @param shortMsg Short message describing the crash. 11421 * @param longMsg Long message describing the crash. 11422 * @param stackTrace Full crash stack trace, may be null. 11423 * 11424 * @return Returns a fully-formed AppErrorStateInfo record. 11425 */ 11426 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11427 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11428 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11429 11430 report.condition = condition; 11431 report.processName = app.processName; 11432 report.pid = app.pid; 11433 report.uid = app.info.uid; 11434 report.tag = activity; 11435 report.shortMsg = shortMsg; 11436 report.longMsg = longMsg; 11437 report.stackTrace = stackTrace; 11438 11439 return report; 11440 } 11441 11442 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11443 synchronized (this) { 11444 app.crashing = false; 11445 app.crashingReport = null; 11446 app.notResponding = false; 11447 app.notRespondingReport = null; 11448 if (app.anrDialog == fromDialog) { 11449 app.anrDialog = null; 11450 } 11451 if (app.waitDialog == fromDialog) { 11452 app.waitDialog = null; 11453 } 11454 if (app.pid > 0 && app.pid != MY_PID) { 11455 handleAppCrashLocked(app, null, null, null); 11456 app.kill("user request after error", true); 11457 } 11458 } 11459 } 11460 11461 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11462 String stackTrace) { 11463 long now = SystemClock.uptimeMillis(); 11464 11465 Long crashTime; 11466 if (!app.isolated) { 11467 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11468 } else { 11469 crashTime = null; 11470 } 11471 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11472 // This process loses! 11473 Slog.w(TAG, "Process " + app.info.processName 11474 + " has crashed too many times: killing!"); 11475 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11476 app.userId, app.info.processName, app.uid); 11477 mStackSupervisor.handleAppCrashLocked(app); 11478 if (!app.persistent) { 11479 // We don't want to start this process again until the user 11480 // explicitly does so... but for persistent process, we really 11481 // need to keep it running. If a persistent process is actually 11482 // repeatedly crashing, then badness for everyone. 11483 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11484 app.info.processName); 11485 if (!app.isolated) { 11486 // XXX We don't have a way to mark isolated processes 11487 // as bad, since they don't have a peristent identity. 11488 mBadProcesses.put(app.info.processName, app.uid, 11489 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11490 mProcessCrashTimes.remove(app.info.processName, app.uid); 11491 } 11492 app.bad = true; 11493 app.removed = true; 11494 // Don't let services in this process be restarted and potentially 11495 // annoy the user repeatedly. Unless it is persistent, since those 11496 // processes run critical code. 11497 removeProcessLocked(app, false, false, "crash"); 11498 mStackSupervisor.resumeTopActivitiesLocked(); 11499 return false; 11500 } 11501 mStackSupervisor.resumeTopActivitiesLocked(); 11502 } else { 11503 mStackSupervisor.finishTopRunningActivityLocked(app); 11504 } 11505 11506 // Bump up the crash count of any services currently running in the proc. 11507 for (int i=app.services.size()-1; i>=0; i--) { 11508 // Any services running in the application need to be placed 11509 // back in the pending list. 11510 ServiceRecord sr = app.services.valueAt(i); 11511 sr.crashCount++; 11512 } 11513 11514 // If the crashing process is what we consider to be the "home process" and it has been 11515 // replaced by a third-party app, clear the package preferred activities from packages 11516 // with a home activity running in the process to prevent a repeatedly crashing app 11517 // from blocking the user to manually clear the list. 11518 final ArrayList<ActivityRecord> activities = app.activities; 11519 if (app == mHomeProcess && activities.size() > 0 11520 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11521 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11522 final ActivityRecord r = activities.get(activityNdx); 11523 if (r.isHomeActivity()) { 11524 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11525 try { 11526 ActivityThread.getPackageManager() 11527 .clearPackagePreferredActivities(r.packageName); 11528 } catch (RemoteException c) { 11529 // pm is in same process, this will never happen. 11530 } 11531 } 11532 } 11533 } 11534 11535 if (!app.isolated) { 11536 // XXX Can't keep track of crash times for isolated processes, 11537 // because they don't have a perisistent identity. 11538 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11539 } 11540 11541 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11542 return true; 11543 } 11544 11545 void startAppProblemLocked(ProcessRecord app) { 11546 // If this app is not running under the current user, then we 11547 // can't give it a report button because that would require 11548 // launching the report UI under a different user. 11549 app.errorReportReceiver = null; 11550 11551 for (int userId : mCurrentProfileIds) { 11552 if (app.userId == userId) { 11553 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11554 mContext, app.info.packageName, app.info.flags); 11555 } 11556 } 11557 skipCurrentReceiverLocked(app); 11558 } 11559 11560 void skipCurrentReceiverLocked(ProcessRecord app) { 11561 for (BroadcastQueue queue : mBroadcastQueues) { 11562 queue.skipCurrentReceiverLocked(app); 11563 } 11564 } 11565 11566 /** 11567 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11568 * The application process will exit immediately after this call returns. 11569 * @param app object of the crashing app, null for the system server 11570 * @param crashInfo describing the exception 11571 */ 11572 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11573 ProcessRecord r = findAppProcess(app, "Crash"); 11574 final String processName = app == null ? "system_server" 11575 : (r == null ? "unknown" : r.processName); 11576 11577 handleApplicationCrashInner("crash", r, processName, crashInfo); 11578 } 11579 11580 /* Native crash reporting uses this inner version because it needs to be somewhat 11581 * decoupled from the AM-managed cleanup lifecycle 11582 */ 11583 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11584 ApplicationErrorReport.CrashInfo crashInfo) { 11585 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11586 UserHandle.getUserId(Binder.getCallingUid()), processName, 11587 r == null ? -1 : r.info.flags, 11588 crashInfo.exceptionClassName, 11589 crashInfo.exceptionMessage, 11590 crashInfo.throwFileName, 11591 crashInfo.throwLineNumber); 11592 11593 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11594 11595 crashApplication(r, crashInfo); 11596 } 11597 11598 public void handleApplicationStrictModeViolation( 11599 IBinder app, 11600 int violationMask, 11601 StrictMode.ViolationInfo info) { 11602 ProcessRecord r = findAppProcess(app, "StrictMode"); 11603 if (r == null) { 11604 return; 11605 } 11606 11607 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11608 Integer stackFingerprint = info.hashCode(); 11609 boolean logIt = true; 11610 synchronized (mAlreadyLoggedViolatedStacks) { 11611 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11612 logIt = false; 11613 // TODO: sub-sample into EventLog for these, with 11614 // the info.durationMillis? Then we'd get 11615 // the relative pain numbers, without logging all 11616 // the stack traces repeatedly. We'd want to do 11617 // likewise in the client code, which also does 11618 // dup suppression, before the Binder call. 11619 } else { 11620 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11621 mAlreadyLoggedViolatedStacks.clear(); 11622 } 11623 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11624 } 11625 } 11626 if (logIt) { 11627 logStrictModeViolationToDropBox(r, info); 11628 } 11629 } 11630 11631 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11632 AppErrorResult result = new AppErrorResult(); 11633 synchronized (this) { 11634 final long origId = Binder.clearCallingIdentity(); 11635 11636 Message msg = Message.obtain(); 11637 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11638 HashMap<String, Object> data = new HashMap<String, Object>(); 11639 data.put("result", result); 11640 data.put("app", r); 11641 data.put("violationMask", violationMask); 11642 data.put("info", info); 11643 msg.obj = data; 11644 mHandler.sendMessage(msg); 11645 11646 Binder.restoreCallingIdentity(origId); 11647 } 11648 int res = result.get(); 11649 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11650 } 11651 } 11652 11653 // Depending on the policy in effect, there could be a bunch of 11654 // these in quick succession so we try to batch these together to 11655 // minimize disk writes, number of dropbox entries, and maximize 11656 // compression, by having more fewer, larger records. 11657 private void logStrictModeViolationToDropBox( 11658 ProcessRecord process, 11659 StrictMode.ViolationInfo info) { 11660 if (info == null) { 11661 return; 11662 } 11663 final boolean isSystemApp = process == null || 11664 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11665 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11666 final String processName = process == null ? "unknown" : process.processName; 11667 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11668 final DropBoxManager dbox = (DropBoxManager) 11669 mContext.getSystemService(Context.DROPBOX_SERVICE); 11670 11671 // Exit early if the dropbox isn't configured to accept this report type. 11672 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11673 11674 boolean bufferWasEmpty; 11675 boolean needsFlush; 11676 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11677 synchronized (sb) { 11678 bufferWasEmpty = sb.length() == 0; 11679 appendDropBoxProcessHeaders(process, processName, sb); 11680 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11681 sb.append("System-App: ").append(isSystemApp).append("\n"); 11682 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11683 if (info.violationNumThisLoop != 0) { 11684 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11685 } 11686 if (info.numAnimationsRunning != 0) { 11687 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11688 } 11689 if (info.broadcastIntentAction != null) { 11690 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11691 } 11692 if (info.durationMillis != -1) { 11693 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11694 } 11695 if (info.numInstances != -1) { 11696 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11697 } 11698 if (info.tags != null) { 11699 for (String tag : info.tags) { 11700 sb.append("Span-Tag: ").append(tag).append("\n"); 11701 } 11702 } 11703 sb.append("\n"); 11704 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11705 sb.append(info.crashInfo.stackTrace); 11706 } 11707 sb.append("\n"); 11708 11709 // Only buffer up to ~64k. Various logging bits truncate 11710 // things at 128k. 11711 needsFlush = (sb.length() > 64 * 1024); 11712 } 11713 11714 // Flush immediately if the buffer's grown too large, or this 11715 // is a non-system app. Non-system apps are isolated with a 11716 // different tag & policy and not batched. 11717 // 11718 // Batching is useful during internal testing with 11719 // StrictMode settings turned up high. Without batching, 11720 // thousands of separate files could be created on boot. 11721 if (!isSystemApp || needsFlush) { 11722 new Thread("Error dump: " + dropboxTag) { 11723 @Override 11724 public void run() { 11725 String report; 11726 synchronized (sb) { 11727 report = sb.toString(); 11728 sb.delete(0, sb.length()); 11729 sb.trimToSize(); 11730 } 11731 if (report.length() != 0) { 11732 dbox.addText(dropboxTag, report); 11733 } 11734 } 11735 }.start(); 11736 return; 11737 } 11738 11739 // System app batching: 11740 if (!bufferWasEmpty) { 11741 // An existing dropbox-writing thread is outstanding, so 11742 // we don't need to start it up. The existing thread will 11743 // catch the buffer appends we just did. 11744 return; 11745 } 11746 11747 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11748 // (After this point, we shouldn't access AMS internal data structures.) 11749 new Thread("Error dump: " + dropboxTag) { 11750 @Override 11751 public void run() { 11752 // 5 second sleep to let stacks arrive and be batched together 11753 try { 11754 Thread.sleep(5000); // 5 seconds 11755 } catch (InterruptedException e) {} 11756 11757 String errorReport; 11758 synchronized (mStrictModeBuffer) { 11759 errorReport = mStrictModeBuffer.toString(); 11760 if (errorReport.length() == 0) { 11761 return; 11762 } 11763 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11764 mStrictModeBuffer.trimToSize(); 11765 } 11766 dbox.addText(dropboxTag, errorReport); 11767 } 11768 }.start(); 11769 } 11770 11771 /** 11772 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11773 * @param app object of the crashing app, null for the system server 11774 * @param tag reported by the caller 11775 * @param system whether this wtf is coming from the system 11776 * @param crashInfo describing the context of the error 11777 * @return true if the process should exit immediately (WTF is fatal) 11778 */ 11779 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11780 final ApplicationErrorReport.CrashInfo crashInfo) { 11781 final int callingUid = Binder.getCallingUid(); 11782 final int callingPid = Binder.getCallingPid(); 11783 11784 if (system) { 11785 // If this is coming from the system, we could very well have low-level 11786 // system locks held, so we want to do this all asynchronously. And we 11787 // never want this to become fatal, so there is that too. 11788 mHandler.post(new Runnable() { 11789 @Override public void run() { 11790 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11791 } 11792 }); 11793 return false; 11794 } 11795 11796 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11797 crashInfo); 11798 11799 if (r != null && r.pid != Process.myPid() && 11800 Settings.Global.getInt(mContext.getContentResolver(), 11801 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11802 crashApplication(r, crashInfo); 11803 return true; 11804 } else { 11805 return false; 11806 } 11807 } 11808 11809 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11810 final ApplicationErrorReport.CrashInfo crashInfo) { 11811 final ProcessRecord r = findAppProcess(app, "WTF"); 11812 final String processName = app == null ? "system_server" 11813 : (r == null ? "unknown" : r.processName); 11814 11815 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11816 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11817 11818 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11819 11820 return r; 11821 } 11822 11823 /** 11824 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11825 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11826 */ 11827 private ProcessRecord findAppProcess(IBinder app, String reason) { 11828 if (app == null) { 11829 return null; 11830 } 11831 11832 synchronized (this) { 11833 final int NP = mProcessNames.getMap().size(); 11834 for (int ip=0; ip<NP; ip++) { 11835 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11836 final int NA = apps.size(); 11837 for (int ia=0; ia<NA; ia++) { 11838 ProcessRecord p = apps.valueAt(ia); 11839 if (p.thread != null && p.thread.asBinder() == app) { 11840 return p; 11841 } 11842 } 11843 } 11844 11845 Slog.w(TAG, "Can't find mystery application for " + reason 11846 + " from pid=" + Binder.getCallingPid() 11847 + " uid=" + Binder.getCallingUid() + ": " + app); 11848 return null; 11849 } 11850 } 11851 11852 /** 11853 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11854 * to append various headers to the dropbox log text. 11855 */ 11856 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11857 StringBuilder sb) { 11858 // Watchdog thread ends up invoking this function (with 11859 // a null ProcessRecord) to add the stack file to dropbox. 11860 // Do not acquire a lock on this (am) in such cases, as it 11861 // could cause a potential deadlock, if and when watchdog 11862 // is invoked due to unavailability of lock on am and it 11863 // would prevent watchdog from killing system_server. 11864 if (process == null) { 11865 sb.append("Process: ").append(processName).append("\n"); 11866 return; 11867 } 11868 // Note: ProcessRecord 'process' is guarded by the service 11869 // instance. (notably process.pkgList, which could otherwise change 11870 // concurrently during execution of this method) 11871 synchronized (this) { 11872 sb.append("Process: ").append(processName).append("\n"); 11873 int flags = process.info.flags; 11874 IPackageManager pm = AppGlobals.getPackageManager(); 11875 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11876 for (int ip=0; ip<process.pkgList.size(); ip++) { 11877 String pkg = process.pkgList.keyAt(ip); 11878 sb.append("Package: ").append(pkg); 11879 try { 11880 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11881 if (pi != null) { 11882 sb.append(" v").append(pi.versionCode); 11883 if (pi.versionName != null) { 11884 sb.append(" (").append(pi.versionName).append(")"); 11885 } 11886 } 11887 } catch (RemoteException e) { 11888 Slog.e(TAG, "Error getting package info: " + pkg, e); 11889 } 11890 sb.append("\n"); 11891 } 11892 } 11893 } 11894 11895 private static String processClass(ProcessRecord process) { 11896 if (process == null || process.pid == MY_PID) { 11897 return "system_server"; 11898 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11899 return "system_app"; 11900 } else { 11901 return "data_app"; 11902 } 11903 } 11904 11905 /** 11906 * Write a description of an error (crash, WTF, ANR) to the drop box. 11907 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11908 * @param process which caused the error, null means the system server 11909 * @param activity which triggered the error, null if unknown 11910 * @param parent activity related to the error, null if unknown 11911 * @param subject line related to the error, null if absent 11912 * @param report in long form describing the error, null if absent 11913 * @param logFile to include in the report, null if none 11914 * @param crashInfo giving an application stack trace, null if absent 11915 */ 11916 public void addErrorToDropBox(String eventType, 11917 ProcessRecord process, String processName, ActivityRecord activity, 11918 ActivityRecord parent, String subject, 11919 final String report, final File logFile, 11920 final ApplicationErrorReport.CrashInfo crashInfo) { 11921 // NOTE -- this must never acquire the ActivityManagerService lock, 11922 // otherwise the watchdog may be prevented from resetting the system. 11923 11924 final String dropboxTag = processClass(process) + "_" + eventType; 11925 final DropBoxManager dbox = (DropBoxManager) 11926 mContext.getSystemService(Context.DROPBOX_SERVICE); 11927 11928 // Exit early if the dropbox isn't configured to accept this report type. 11929 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11930 11931 final StringBuilder sb = new StringBuilder(1024); 11932 appendDropBoxProcessHeaders(process, processName, sb); 11933 if (activity != null) { 11934 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11935 } 11936 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11937 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11938 } 11939 if (parent != null && parent != activity) { 11940 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11941 } 11942 if (subject != null) { 11943 sb.append("Subject: ").append(subject).append("\n"); 11944 } 11945 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11946 if (Debug.isDebuggerConnected()) { 11947 sb.append("Debugger: Connected\n"); 11948 } 11949 sb.append("\n"); 11950 11951 // Do the rest in a worker thread to avoid blocking the caller on I/O 11952 // (After this point, we shouldn't access AMS internal data structures.) 11953 Thread worker = new Thread("Error dump: " + dropboxTag) { 11954 @Override 11955 public void run() { 11956 if (report != null) { 11957 sb.append(report); 11958 } 11959 if (logFile != null) { 11960 try { 11961 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11962 "\n\n[[TRUNCATED]]")); 11963 } catch (IOException e) { 11964 Slog.e(TAG, "Error reading " + logFile, e); 11965 } 11966 } 11967 if (crashInfo != null && crashInfo.stackTrace != null) { 11968 sb.append(crashInfo.stackTrace); 11969 } 11970 11971 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11972 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11973 if (lines > 0) { 11974 sb.append("\n"); 11975 11976 // Merge several logcat streams, and take the last N lines 11977 InputStreamReader input = null; 11978 try { 11979 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11980 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11981 "-b", "crash", 11982 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11983 11984 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11985 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11986 input = new InputStreamReader(logcat.getInputStream()); 11987 11988 int num; 11989 char[] buf = new char[8192]; 11990 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11991 } catch (IOException e) { 11992 Slog.e(TAG, "Error running logcat", e); 11993 } finally { 11994 if (input != null) try { input.close(); } catch (IOException e) {} 11995 } 11996 } 11997 11998 dbox.addText(dropboxTag, sb.toString()); 11999 } 12000 }; 12001 12002 if (process == null) { 12003 // If process is null, we are being called from some internal code 12004 // and may be about to die -- run this synchronously. 12005 worker.run(); 12006 } else { 12007 worker.start(); 12008 } 12009 } 12010 12011 /** 12012 * Bring up the "unexpected error" dialog box for a crashing app. 12013 * Deal with edge cases (intercepts from instrumented applications, 12014 * ActivityController, error intent receivers, that sort of thing). 12015 * @param r the application crashing 12016 * @param crashInfo describing the failure 12017 */ 12018 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12019 long timeMillis = System.currentTimeMillis(); 12020 String shortMsg = crashInfo.exceptionClassName; 12021 String longMsg = crashInfo.exceptionMessage; 12022 String stackTrace = crashInfo.stackTrace; 12023 if (shortMsg != null && longMsg != null) { 12024 longMsg = shortMsg + ": " + longMsg; 12025 } else if (shortMsg != null) { 12026 longMsg = shortMsg; 12027 } 12028 12029 AppErrorResult result = new AppErrorResult(); 12030 synchronized (this) { 12031 if (mController != null) { 12032 try { 12033 String name = r != null ? r.processName : null; 12034 int pid = r != null ? r.pid : Binder.getCallingPid(); 12035 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12036 if (!mController.appCrashed(name, pid, 12037 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12038 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12039 && "Native crash".equals(crashInfo.exceptionClassName)) { 12040 Slog.w(TAG, "Skip killing native crashed app " + name 12041 + "(" + pid + ") during testing"); 12042 } else { 12043 Slog.w(TAG, "Force-killing crashed app " + name 12044 + " at watcher's request"); 12045 if (r != null) { 12046 r.kill("crash", true); 12047 } else { 12048 // Huh. 12049 Process.killProcess(pid); 12050 Process.killProcessGroup(uid, pid); 12051 } 12052 } 12053 return; 12054 } 12055 } catch (RemoteException e) { 12056 mController = null; 12057 Watchdog.getInstance().setActivityController(null); 12058 } 12059 } 12060 12061 final long origId = Binder.clearCallingIdentity(); 12062 12063 // If this process is running instrumentation, finish it. 12064 if (r != null && r.instrumentationClass != null) { 12065 Slog.w(TAG, "Error in app " + r.processName 12066 + " running instrumentation " + r.instrumentationClass + ":"); 12067 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12068 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12069 Bundle info = new Bundle(); 12070 info.putString("shortMsg", shortMsg); 12071 info.putString("longMsg", longMsg); 12072 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12073 Binder.restoreCallingIdentity(origId); 12074 return; 12075 } 12076 12077 // Log crash in battery stats. 12078 if (r != null) { 12079 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12080 } 12081 12082 // If we can't identify the process or it's already exceeded its crash quota, 12083 // quit right away without showing a crash dialog. 12084 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12085 Binder.restoreCallingIdentity(origId); 12086 return; 12087 } 12088 12089 Message msg = Message.obtain(); 12090 msg.what = SHOW_ERROR_MSG; 12091 HashMap data = new HashMap(); 12092 data.put("result", result); 12093 data.put("app", r); 12094 msg.obj = data; 12095 mHandler.sendMessage(msg); 12096 12097 Binder.restoreCallingIdentity(origId); 12098 } 12099 12100 int res = result.get(); 12101 12102 Intent appErrorIntent = null; 12103 synchronized (this) { 12104 if (r != null && !r.isolated) { 12105 // XXX Can't keep track of crash time for isolated processes, 12106 // since they don't have a persistent identity. 12107 mProcessCrashTimes.put(r.info.processName, r.uid, 12108 SystemClock.uptimeMillis()); 12109 } 12110 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12111 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12112 } 12113 } 12114 12115 if (appErrorIntent != null) { 12116 try { 12117 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12118 } catch (ActivityNotFoundException e) { 12119 Slog.w(TAG, "bug report receiver dissappeared", e); 12120 } 12121 } 12122 } 12123 12124 Intent createAppErrorIntentLocked(ProcessRecord r, 12125 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12126 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12127 if (report == null) { 12128 return null; 12129 } 12130 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12131 result.setComponent(r.errorReportReceiver); 12132 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12133 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12134 return result; 12135 } 12136 12137 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12138 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12139 if (r.errorReportReceiver == null) { 12140 return null; 12141 } 12142 12143 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12144 return null; 12145 } 12146 12147 ApplicationErrorReport report = new ApplicationErrorReport(); 12148 report.packageName = r.info.packageName; 12149 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12150 report.processName = r.processName; 12151 report.time = timeMillis; 12152 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12153 12154 if (r.crashing || r.forceCrashReport) { 12155 report.type = ApplicationErrorReport.TYPE_CRASH; 12156 report.crashInfo = crashInfo; 12157 } else if (r.notResponding) { 12158 report.type = ApplicationErrorReport.TYPE_ANR; 12159 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12160 12161 report.anrInfo.activity = r.notRespondingReport.tag; 12162 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12163 report.anrInfo.info = r.notRespondingReport.longMsg; 12164 } 12165 12166 return report; 12167 } 12168 12169 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12170 enforceNotIsolatedCaller("getProcessesInErrorState"); 12171 // assume our apps are happy - lazy create the list 12172 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12173 12174 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12175 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12176 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12177 12178 synchronized (this) { 12179 12180 // iterate across all processes 12181 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12182 ProcessRecord app = mLruProcesses.get(i); 12183 if (!allUsers && app.userId != userId) { 12184 continue; 12185 } 12186 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12187 // This one's in trouble, so we'll generate a report for it 12188 // crashes are higher priority (in case there's a crash *and* an anr) 12189 ActivityManager.ProcessErrorStateInfo report = null; 12190 if (app.crashing) { 12191 report = app.crashingReport; 12192 } else if (app.notResponding) { 12193 report = app.notRespondingReport; 12194 } 12195 12196 if (report != null) { 12197 if (errList == null) { 12198 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12199 } 12200 errList.add(report); 12201 } else { 12202 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12203 " crashing = " + app.crashing + 12204 " notResponding = " + app.notResponding); 12205 } 12206 } 12207 } 12208 } 12209 12210 return errList; 12211 } 12212 12213 static int procStateToImportance(int procState, int memAdj, 12214 ActivityManager.RunningAppProcessInfo currApp) { 12215 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12216 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12217 currApp.lru = memAdj; 12218 } else { 12219 currApp.lru = 0; 12220 } 12221 return imp; 12222 } 12223 12224 private void fillInProcMemInfo(ProcessRecord app, 12225 ActivityManager.RunningAppProcessInfo outInfo) { 12226 outInfo.pid = app.pid; 12227 outInfo.uid = app.info.uid; 12228 if (mHeavyWeightProcess == app) { 12229 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12230 } 12231 if (app.persistent) { 12232 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12233 } 12234 if (app.activities.size() > 0) { 12235 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12236 } 12237 outInfo.lastTrimLevel = app.trimMemoryLevel; 12238 int adj = app.curAdj; 12239 int procState = app.curProcState; 12240 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12241 outInfo.importanceReasonCode = app.adjTypeCode; 12242 outInfo.processState = app.curProcState; 12243 } 12244 12245 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12246 enforceNotIsolatedCaller("getRunningAppProcesses"); 12247 // Lazy instantiation of list 12248 List<ActivityManager.RunningAppProcessInfo> runList = null; 12249 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12250 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12251 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12252 synchronized (this) { 12253 // Iterate across all processes 12254 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12255 ProcessRecord app = mLruProcesses.get(i); 12256 if (!allUsers && app.userId != userId) { 12257 continue; 12258 } 12259 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12260 // Generate process state info for running application 12261 ActivityManager.RunningAppProcessInfo currApp = 12262 new ActivityManager.RunningAppProcessInfo(app.processName, 12263 app.pid, app.getPackageList()); 12264 fillInProcMemInfo(app, currApp); 12265 if (app.adjSource instanceof ProcessRecord) { 12266 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12267 currApp.importanceReasonImportance = 12268 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12269 app.adjSourceProcState); 12270 } else if (app.adjSource instanceof ActivityRecord) { 12271 ActivityRecord r = (ActivityRecord)app.adjSource; 12272 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12273 } 12274 if (app.adjTarget instanceof ComponentName) { 12275 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12276 } 12277 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12278 // + " lru=" + currApp.lru); 12279 if (runList == null) { 12280 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12281 } 12282 runList.add(currApp); 12283 } 12284 } 12285 } 12286 return runList; 12287 } 12288 12289 public List<ApplicationInfo> getRunningExternalApplications() { 12290 enforceNotIsolatedCaller("getRunningExternalApplications"); 12291 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12292 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12293 if (runningApps != null && runningApps.size() > 0) { 12294 Set<String> extList = new HashSet<String>(); 12295 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12296 if (app.pkgList != null) { 12297 for (String pkg : app.pkgList) { 12298 extList.add(pkg); 12299 } 12300 } 12301 } 12302 IPackageManager pm = AppGlobals.getPackageManager(); 12303 for (String pkg : extList) { 12304 try { 12305 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12306 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12307 retList.add(info); 12308 } 12309 } catch (RemoteException e) { 12310 } 12311 } 12312 } 12313 return retList; 12314 } 12315 12316 @Override 12317 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12318 enforceNotIsolatedCaller("getMyMemoryState"); 12319 synchronized (this) { 12320 ProcessRecord proc; 12321 synchronized (mPidsSelfLocked) { 12322 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12323 } 12324 fillInProcMemInfo(proc, outInfo); 12325 } 12326 } 12327 12328 @Override 12329 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12330 if (checkCallingPermission(android.Manifest.permission.DUMP) 12331 != PackageManager.PERMISSION_GRANTED) { 12332 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12333 + Binder.getCallingPid() 12334 + ", uid=" + Binder.getCallingUid() 12335 + " without permission " 12336 + android.Manifest.permission.DUMP); 12337 return; 12338 } 12339 12340 boolean dumpAll = false; 12341 boolean dumpClient = false; 12342 String dumpPackage = null; 12343 12344 int opti = 0; 12345 while (opti < args.length) { 12346 String opt = args[opti]; 12347 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12348 break; 12349 } 12350 opti++; 12351 if ("-a".equals(opt)) { 12352 dumpAll = true; 12353 } else if ("-c".equals(opt)) { 12354 dumpClient = true; 12355 } else if ("-p".equals(opt)) { 12356 if (opti < args.length) { 12357 dumpPackage = args[opti]; 12358 opti++; 12359 } else { 12360 pw.println("Error: -p option requires package argument"); 12361 return; 12362 } 12363 dumpClient = true; 12364 } else if ("-h".equals(opt)) { 12365 pw.println("Activity manager dump options:"); 12366 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12367 pw.println(" cmd may be one of:"); 12368 pw.println(" a[ctivities]: activity stack state"); 12369 pw.println(" r[recents]: recent activities state"); 12370 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12371 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12372 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12373 pw.println(" o[om]: out of memory management"); 12374 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12375 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12376 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12377 pw.println(" as[sociations]: tracked app associations"); 12378 pw.println(" service [COMP_SPEC]: service client-side state"); 12379 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12380 pw.println(" all: dump all activities"); 12381 pw.println(" top: dump the top activity"); 12382 pw.println(" write: write all pending state to storage"); 12383 pw.println(" track-associations: enable association tracking"); 12384 pw.println(" untrack-associations: disable and clear association tracking"); 12385 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12386 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12387 pw.println(" a partial substring in a component name, a"); 12388 pw.println(" hex object identifier."); 12389 pw.println(" -a: include all available server state."); 12390 pw.println(" -c: include client state."); 12391 pw.println(" -p: limit output to given package."); 12392 return; 12393 } else { 12394 pw.println("Unknown argument: " + opt + "; use -h for help"); 12395 } 12396 } 12397 12398 long origId = Binder.clearCallingIdentity(); 12399 boolean more = false; 12400 // Is the caller requesting to dump a particular piece of data? 12401 if (opti < args.length) { 12402 String cmd = args[opti]; 12403 opti++; 12404 if ("activities".equals(cmd) || "a".equals(cmd)) { 12405 synchronized (this) { 12406 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12407 } 12408 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12409 synchronized (this) { 12410 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12411 } 12412 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12413 String[] newArgs; 12414 String name; 12415 if (opti >= args.length) { 12416 name = null; 12417 newArgs = EMPTY_STRING_ARRAY; 12418 } else { 12419 dumpPackage = args[opti]; 12420 opti++; 12421 newArgs = new String[args.length - opti]; 12422 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12423 args.length - opti); 12424 } 12425 synchronized (this) { 12426 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12427 } 12428 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12429 String[] newArgs; 12430 String name; 12431 if (opti >= args.length) { 12432 name = null; 12433 newArgs = EMPTY_STRING_ARRAY; 12434 } else { 12435 dumpPackage = args[opti]; 12436 opti++; 12437 newArgs = new String[args.length - opti]; 12438 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12439 args.length - opti); 12440 } 12441 synchronized (this) { 12442 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12443 } 12444 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12445 String[] newArgs; 12446 String name; 12447 if (opti >= args.length) { 12448 name = null; 12449 newArgs = EMPTY_STRING_ARRAY; 12450 } else { 12451 dumpPackage = args[opti]; 12452 opti++; 12453 newArgs = new String[args.length - opti]; 12454 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12455 args.length - opti); 12456 } 12457 synchronized (this) { 12458 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12459 } 12460 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12461 synchronized (this) { 12462 dumpOomLocked(fd, pw, args, opti, true); 12463 } 12464 } else if ("provider".equals(cmd)) { 12465 String[] newArgs; 12466 String name; 12467 if (opti >= args.length) { 12468 name = null; 12469 newArgs = EMPTY_STRING_ARRAY; 12470 } else { 12471 name = args[opti]; 12472 opti++; 12473 newArgs = new String[args.length - opti]; 12474 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12475 } 12476 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12477 pw.println("No providers match: " + name); 12478 pw.println("Use -h for help."); 12479 } 12480 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12481 synchronized (this) { 12482 dumpProvidersLocked(fd, pw, args, opti, true, null); 12483 } 12484 } else if ("service".equals(cmd)) { 12485 String[] newArgs; 12486 String name; 12487 if (opti >= args.length) { 12488 name = null; 12489 newArgs = EMPTY_STRING_ARRAY; 12490 } else { 12491 name = args[opti]; 12492 opti++; 12493 newArgs = new String[args.length - opti]; 12494 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12495 args.length - opti); 12496 } 12497 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12498 pw.println("No services match: " + name); 12499 pw.println("Use -h for help."); 12500 } 12501 } else if ("package".equals(cmd)) { 12502 String[] newArgs; 12503 if (opti >= args.length) { 12504 pw.println("package: no package name specified"); 12505 pw.println("Use -h for help."); 12506 } else { 12507 dumpPackage = args[opti]; 12508 opti++; 12509 newArgs = new String[args.length - opti]; 12510 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12511 args.length - opti); 12512 args = newArgs; 12513 opti = 0; 12514 more = true; 12515 } 12516 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12517 synchronized (this) { 12518 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12519 } 12520 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12521 synchronized (this) { 12522 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12523 } 12524 } else if ("write".equals(cmd)) { 12525 mTaskPersister.flush(); 12526 pw.println("All tasks persisted."); 12527 return; 12528 } else if ("track-associations".equals(cmd)) { 12529 synchronized (this) { 12530 if (!mTrackingAssociations) { 12531 mTrackingAssociations = true; 12532 pw.println("Association tracking started."); 12533 } else { 12534 pw.println("Association tracking already enabled."); 12535 } 12536 } 12537 return; 12538 } else if ("untrack-associations".equals(cmd)) { 12539 synchronized (this) { 12540 if (mTrackingAssociations) { 12541 mTrackingAssociations = false; 12542 mAssociations.clear(); 12543 pw.println("Association tracking stopped."); 12544 } else { 12545 pw.println("Association tracking not running."); 12546 } 12547 } 12548 return; 12549 } else { 12550 // Dumping a single activity? 12551 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12552 pw.println("Bad activity command, or no activities match: " + cmd); 12553 pw.println("Use -h for help."); 12554 } 12555 } 12556 if (!more) { 12557 Binder.restoreCallingIdentity(origId); 12558 return; 12559 } 12560 } 12561 12562 // No piece of data specified, dump everything. 12563 synchronized (this) { 12564 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12565 pw.println(); 12566 if (dumpAll) { 12567 pw.println("-------------------------------------------------------------------------------"); 12568 } 12569 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12570 pw.println(); 12571 if (dumpAll) { 12572 pw.println("-------------------------------------------------------------------------------"); 12573 } 12574 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12575 pw.println(); 12576 if (dumpAll) { 12577 pw.println("-------------------------------------------------------------------------------"); 12578 } 12579 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12580 pw.println(); 12581 if (dumpAll) { 12582 pw.println("-------------------------------------------------------------------------------"); 12583 } 12584 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12585 pw.println(); 12586 if (dumpAll) { 12587 pw.println("-------------------------------------------------------------------------------"); 12588 } 12589 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12590 if (mAssociations.size() > 0) { 12591 pw.println(); 12592 if (dumpAll) { 12593 pw.println("-------------------------------------------------------------------------------"); 12594 } 12595 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12596 } 12597 pw.println(); 12598 if (dumpAll) { 12599 pw.println("-------------------------------------------------------------------------------"); 12600 } 12601 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12602 } 12603 Binder.restoreCallingIdentity(origId); 12604 } 12605 12606 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12607 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12608 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12609 12610 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12611 dumpPackage); 12612 boolean needSep = printedAnything; 12613 12614 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12615 dumpPackage, needSep, " mFocusedActivity: "); 12616 if (printed) { 12617 printedAnything = true; 12618 needSep = false; 12619 } 12620 12621 if (dumpPackage == null) { 12622 if (needSep) { 12623 pw.println(); 12624 } 12625 needSep = true; 12626 printedAnything = true; 12627 mStackSupervisor.dump(pw, " "); 12628 } 12629 12630 if (!printedAnything) { 12631 pw.println(" (nothing)"); 12632 } 12633 } 12634 12635 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12636 int opti, boolean dumpAll, String dumpPackage) { 12637 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12638 12639 boolean printedAnything = false; 12640 12641 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12642 boolean printedHeader = false; 12643 12644 final int N = mRecentTasks.size(); 12645 for (int i=0; i<N; i++) { 12646 TaskRecord tr = mRecentTasks.get(i); 12647 if (dumpPackage != null) { 12648 if (tr.realActivity == null || 12649 !dumpPackage.equals(tr.realActivity)) { 12650 continue; 12651 } 12652 } 12653 if (!printedHeader) { 12654 pw.println(" Recent tasks:"); 12655 printedHeader = true; 12656 printedAnything = true; 12657 } 12658 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12659 pw.println(tr); 12660 if (dumpAll) { 12661 mRecentTasks.get(i).dump(pw, " "); 12662 } 12663 } 12664 } 12665 12666 if (!printedAnything) { 12667 pw.println(" (nothing)"); 12668 } 12669 } 12670 12671 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12672 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12673 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12674 12675 int dumpUid = 0; 12676 if (dumpPackage != null) { 12677 IPackageManager pm = AppGlobals.getPackageManager(); 12678 try { 12679 dumpUid = pm.getPackageUid(dumpPackage, 0); 12680 } catch (RemoteException e) { 12681 } 12682 } 12683 12684 boolean printedAnything = false; 12685 12686 final long now = SystemClock.uptimeMillis(); 12687 12688 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12689 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12690 = mAssociations.valueAt(i1); 12691 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12692 SparseArray<ArrayMap<String, Association>> sourceUids 12693 = targetComponents.valueAt(i2); 12694 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12695 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12696 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12697 Association ass = sourceProcesses.valueAt(i4); 12698 if (dumpPackage != null) { 12699 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12700 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12701 continue; 12702 } 12703 } 12704 printedAnything = true; 12705 pw.print(" "); 12706 pw.print(ass.mTargetProcess); 12707 pw.print("/"); 12708 UserHandle.formatUid(pw, ass.mTargetUid); 12709 pw.print(" <- "); 12710 pw.print(ass.mSourceProcess); 12711 pw.print("/"); 12712 UserHandle.formatUid(pw, ass.mSourceUid); 12713 pw.println(); 12714 pw.print(" via "); 12715 pw.print(ass.mTargetComponent.flattenToShortString()); 12716 pw.println(); 12717 pw.print(" "); 12718 long dur = ass.mTime; 12719 if (ass.mNesting > 0) { 12720 dur += now - ass.mStartTime; 12721 } 12722 TimeUtils.formatDuration(dur, pw); 12723 pw.print(" ("); 12724 pw.print(ass.mCount); 12725 pw.println(" times)"); 12726 if (ass.mNesting > 0) { 12727 pw.print(" "); 12728 pw.print(" Currently active: "); 12729 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12730 pw.println(); 12731 } 12732 } 12733 } 12734 } 12735 12736 } 12737 12738 if (!printedAnything) { 12739 pw.println(" (nothing)"); 12740 } 12741 } 12742 12743 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12744 int opti, boolean dumpAll, String dumpPackage) { 12745 boolean needSep = false; 12746 boolean printedAnything = false; 12747 int numPers = 0; 12748 12749 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12750 12751 if (dumpAll) { 12752 final int NP = mProcessNames.getMap().size(); 12753 for (int ip=0; ip<NP; ip++) { 12754 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12755 final int NA = procs.size(); 12756 for (int ia=0; ia<NA; ia++) { 12757 ProcessRecord r = procs.valueAt(ia); 12758 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12759 continue; 12760 } 12761 if (!needSep) { 12762 pw.println(" All known processes:"); 12763 needSep = true; 12764 printedAnything = true; 12765 } 12766 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12767 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12768 pw.print(" "); pw.println(r); 12769 r.dump(pw, " "); 12770 if (r.persistent) { 12771 numPers++; 12772 } 12773 } 12774 } 12775 } 12776 12777 if (mIsolatedProcesses.size() > 0) { 12778 boolean printed = false; 12779 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12780 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12781 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12782 continue; 12783 } 12784 if (!printed) { 12785 if (needSep) { 12786 pw.println(); 12787 } 12788 pw.println(" Isolated process list (sorted by uid):"); 12789 printedAnything = true; 12790 printed = true; 12791 needSep = true; 12792 } 12793 pw.println(String.format("%sIsolated #%2d: %s", 12794 " ", i, r.toString())); 12795 } 12796 } 12797 12798 if (mLruProcesses.size() > 0) { 12799 if (needSep) { 12800 pw.println(); 12801 } 12802 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12803 pw.print(" total, non-act at "); 12804 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12805 pw.print(", non-svc at "); 12806 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12807 pw.println("):"); 12808 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12809 needSep = true; 12810 printedAnything = true; 12811 } 12812 12813 if (dumpAll || dumpPackage != null) { 12814 synchronized (mPidsSelfLocked) { 12815 boolean printed = false; 12816 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12817 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12818 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12819 continue; 12820 } 12821 if (!printed) { 12822 if (needSep) pw.println(); 12823 needSep = true; 12824 pw.println(" PID mappings:"); 12825 printed = true; 12826 printedAnything = true; 12827 } 12828 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12829 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12830 } 12831 } 12832 } 12833 12834 if (mForegroundProcesses.size() > 0) { 12835 synchronized (mPidsSelfLocked) { 12836 boolean printed = false; 12837 for (int i=0; i<mForegroundProcesses.size(); i++) { 12838 ProcessRecord r = mPidsSelfLocked.get( 12839 mForegroundProcesses.valueAt(i).pid); 12840 if (dumpPackage != null && (r == null 12841 || !r.pkgList.containsKey(dumpPackage))) { 12842 continue; 12843 } 12844 if (!printed) { 12845 if (needSep) pw.println(); 12846 needSep = true; 12847 pw.println(" Foreground Processes:"); 12848 printed = true; 12849 printedAnything = true; 12850 } 12851 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12852 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12853 } 12854 } 12855 } 12856 12857 if (mPersistentStartingProcesses.size() > 0) { 12858 if (needSep) pw.println(); 12859 needSep = true; 12860 printedAnything = true; 12861 pw.println(" Persisent processes that are starting:"); 12862 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12863 "Starting Norm", "Restarting PERS", dumpPackage); 12864 } 12865 12866 if (mRemovedProcesses.size() > 0) { 12867 if (needSep) pw.println(); 12868 needSep = true; 12869 printedAnything = true; 12870 pw.println(" Processes that are being removed:"); 12871 dumpProcessList(pw, this, mRemovedProcesses, " ", 12872 "Removed Norm", "Removed PERS", dumpPackage); 12873 } 12874 12875 if (mProcessesOnHold.size() > 0) { 12876 if (needSep) pw.println(); 12877 needSep = true; 12878 printedAnything = true; 12879 pw.println(" Processes that are on old until the system is ready:"); 12880 dumpProcessList(pw, this, mProcessesOnHold, " ", 12881 "OnHold Norm", "OnHold PERS", dumpPackage); 12882 } 12883 12884 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12885 12886 if (mProcessCrashTimes.getMap().size() > 0) { 12887 boolean printed = false; 12888 long now = SystemClock.uptimeMillis(); 12889 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12890 final int NP = pmap.size(); 12891 for (int ip=0; ip<NP; ip++) { 12892 String pname = pmap.keyAt(ip); 12893 SparseArray<Long> uids = pmap.valueAt(ip); 12894 final int N = uids.size(); 12895 for (int i=0; i<N; i++) { 12896 int puid = uids.keyAt(i); 12897 ProcessRecord r = mProcessNames.get(pname, puid); 12898 if (dumpPackage != null && (r == null 12899 || !r.pkgList.containsKey(dumpPackage))) { 12900 continue; 12901 } 12902 if (!printed) { 12903 if (needSep) pw.println(); 12904 needSep = true; 12905 pw.println(" Time since processes crashed:"); 12906 printed = true; 12907 printedAnything = true; 12908 } 12909 pw.print(" Process "); pw.print(pname); 12910 pw.print(" uid "); pw.print(puid); 12911 pw.print(": last crashed "); 12912 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12913 pw.println(" ago"); 12914 } 12915 } 12916 } 12917 12918 if (mBadProcesses.getMap().size() > 0) { 12919 boolean printed = false; 12920 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12921 final int NP = pmap.size(); 12922 for (int ip=0; ip<NP; ip++) { 12923 String pname = pmap.keyAt(ip); 12924 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12925 final int N = uids.size(); 12926 for (int i=0; i<N; i++) { 12927 int puid = uids.keyAt(i); 12928 ProcessRecord r = mProcessNames.get(pname, puid); 12929 if (dumpPackage != null && (r == null 12930 || !r.pkgList.containsKey(dumpPackage))) { 12931 continue; 12932 } 12933 if (!printed) { 12934 if (needSep) pw.println(); 12935 needSep = true; 12936 pw.println(" Bad processes:"); 12937 printedAnything = true; 12938 } 12939 BadProcessInfo info = uids.valueAt(i); 12940 pw.print(" Bad process "); pw.print(pname); 12941 pw.print(" uid "); pw.print(puid); 12942 pw.print(": crashed at time "); pw.println(info.time); 12943 if (info.shortMsg != null) { 12944 pw.print(" Short msg: "); pw.println(info.shortMsg); 12945 } 12946 if (info.longMsg != null) { 12947 pw.print(" Long msg: "); pw.println(info.longMsg); 12948 } 12949 if (info.stack != null) { 12950 pw.println(" Stack:"); 12951 int lastPos = 0; 12952 for (int pos=0; pos<info.stack.length(); pos++) { 12953 if (info.stack.charAt(pos) == '\n') { 12954 pw.print(" "); 12955 pw.write(info.stack, lastPos, pos-lastPos); 12956 pw.println(); 12957 lastPos = pos+1; 12958 } 12959 } 12960 if (lastPos < info.stack.length()) { 12961 pw.print(" "); 12962 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12963 pw.println(); 12964 } 12965 } 12966 } 12967 } 12968 } 12969 12970 if (dumpPackage == null) { 12971 pw.println(); 12972 needSep = false; 12973 pw.println(" mStartedUsers:"); 12974 for (int i=0; i<mStartedUsers.size(); i++) { 12975 UserStartedState uss = mStartedUsers.valueAt(i); 12976 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12977 pw.print(": "); uss.dump("", pw); 12978 } 12979 pw.print(" mStartedUserArray: ["); 12980 for (int i=0; i<mStartedUserArray.length; i++) { 12981 if (i > 0) pw.print(", "); 12982 pw.print(mStartedUserArray[i]); 12983 } 12984 pw.println("]"); 12985 pw.print(" mUserLru: ["); 12986 for (int i=0; i<mUserLru.size(); i++) { 12987 if (i > 0) pw.print(", "); 12988 pw.print(mUserLru.get(i)); 12989 } 12990 pw.println("]"); 12991 if (dumpAll) { 12992 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12993 } 12994 synchronized (mUserProfileGroupIdsSelfLocked) { 12995 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12996 pw.println(" mUserProfileGroupIds:"); 12997 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12998 pw.print(" User #"); 12999 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 13000 pw.print(" -> profile #"); 13001 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 13002 } 13003 } 13004 } 13005 } 13006 if (mHomeProcess != null && (dumpPackage == null 13007 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13008 if (needSep) { 13009 pw.println(); 13010 needSep = false; 13011 } 13012 pw.println(" mHomeProcess: " + mHomeProcess); 13013 } 13014 if (mPreviousProcess != null && (dumpPackage == null 13015 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13016 if (needSep) { 13017 pw.println(); 13018 needSep = false; 13019 } 13020 pw.println(" mPreviousProcess: " + mPreviousProcess); 13021 } 13022 if (dumpAll) { 13023 StringBuilder sb = new StringBuilder(128); 13024 sb.append(" mPreviousProcessVisibleTime: "); 13025 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13026 pw.println(sb); 13027 } 13028 if (mHeavyWeightProcess != null && (dumpPackage == null 13029 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13030 if (needSep) { 13031 pw.println(); 13032 needSep = false; 13033 } 13034 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13035 } 13036 if (dumpPackage == null) { 13037 pw.println(" mConfiguration: " + mConfiguration); 13038 } 13039 if (dumpAll) { 13040 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13041 if (mCompatModePackages.getPackages().size() > 0) { 13042 boolean printed = false; 13043 for (Map.Entry<String, Integer> entry 13044 : mCompatModePackages.getPackages().entrySet()) { 13045 String pkg = entry.getKey(); 13046 int mode = entry.getValue(); 13047 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13048 continue; 13049 } 13050 if (!printed) { 13051 pw.println(" mScreenCompatPackages:"); 13052 printed = true; 13053 } 13054 pw.print(" "); pw.print(pkg); pw.print(": "); 13055 pw.print(mode); pw.println(); 13056 } 13057 } 13058 } 13059 if (dumpPackage == null) { 13060 pw.println(" mWakefulness=" 13061 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13062 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13063 + lockScreenShownToString()); 13064 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13065 + " mTestPssMode=" + mTestPssMode); 13066 } 13067 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13068 || mOrigWaitForDebugger) { 13069 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13070 || dumpPackage.equals(mOrigDebugApp)) { 13071 if (needSep) { 13072 pw.println(); 13073 needSep = false; 13074 } 13075 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13076 + " mDebugTransient=" + mDebugTransient 13077 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13078 } 13079 } 13080 if (mOpenGlTraceApp != null) { 13081 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13082 if (needSep) { 13083 pw.println(); 13084 needSep = false; 13085 } 13086 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13087 } 13088 } 13089 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13090 || mProfileFd != null) { 13091 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13092 if (needSep) { 13093 pw.println(); 13094 needSep = false; 13095 } 13096 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13097 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13098 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13099 + mAutoStopProfiler); 13100 pw.println(" mProfileType=" + mProfileType); 13101 } 13102 } 13103 if (dumpPackage == null) { 13104 if (mAlwaysFinishActivities || mController != null) { 13105 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13106 + " mController=" + mController); 13107 } 13108 if (dumpAll) { 13109 pw.println(" Total persistent processes: " + numPers); 13110 pw.println(" mProcessesReady=" + mProcessesReady 13111 + " mSystemReady=" + mSystemReady 13112 + " mBooted=" + mBooted 13113 + " mFactoryTest=" + mFactoryTest); 13114 pw.println(" mBooting=" + mBooting 13115 + " mCallFinishBooting=" + mCallFinishBooting 13116 + " mBootAnimationComplete=" + mBootAnimationComplete); 13117 pw.print(" mLastPowerCheckRealtime="); 13118 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13119 pw.println(""); 13120 pw.print(" mLastPowerCheckUptime="); 13121 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13122 pw.println(""); 13123 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13124 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13125 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13126 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13127 + " (" + mLruProcesses.size() + " total)" 13128 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13129 + " mNumServiceProcs=" + mNumServiceProcs 13130 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13131 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13132 + " mLastMemoryLevel" + mLastMemoryLevel 13133 + " mLastNumProcesses" + mLastNumProcesses); 13134 long now = SystemClock.uptimeMillis(); 13135 pw.print(" mLastIdleTime="); 13136 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13137 pw.print(" mLowRamSinceLastIdle="); 13138 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13139 pw.println(); 13140 } 13141 } 13142 13143 if (!printedAnything) { 13144 pw.println(" (nothing)"); 13145 } 13146 } 13147 13148 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13149 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13150 if (mProcessesToGc.size() > 0) { 13151 boolean printed = false; 13152 long now = SystemClock.uptimeMillis(); 13153 for (int i=0; i<mProcessesToGc.size(); i++) { 13154 ProcessRecord proc = mProcessesToGc.get(i); 13155 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13156 continue; 13157 } 13158 if (!printed) { 13159 if (needSep) pw.println(); 13160 needSep = true; 13161 pw.println(" Processes that are waiting to GC:"); 13162 printed = true; 13163 } 13164 pw.print(" Process "); pw.println(proc); 13165 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13166 pw.print(", last gced="); 13167 pw.print(now-proc.lastRequestedGc); 13168 pw.print(" ms ago, last lowMem="); 13169 pw.print(now-proc.lastLowMemory); 13170 pw.println(" ms ago"); 13171 13172 } 13173 } 13174 return needSep; 13175 } 13176 13177 void printOomLevel(PrintWriter pw, String name, int adj) { 13178 pw.print(" "); 13179 if (adj >= 0) { 13180 pw.print(' '); 13181 if (adj < 10) pw.print(' '); 13182 } else { 13183 if (adj > -10) pw.print(' '); 13184 } 13185 pw.print(adj); 13186 pw.print(": "); 13187 pw.print(name); 13188 pw.print(" ("); 13189 pw.print(mProcessList.getMemLevel(adj)/1024); 13190 pw.println(" kB)"); 13191 } 13192 13193 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13194 int opti, boolean dumpAll) { 13195 boolean needSep = false; 13196 13197 if (mLruProcesses.size() > 0) { 13198 if (needSep) pw.println(); 13199 needSep = true; 13200 pw.println(" OOM levels:"); 13201 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13202 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13203 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13204 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13205 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13206 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13207 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13208 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13209 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13210 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13211 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13212 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13213 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13214 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13215 13216 if (needSep) pw.println(); 13217 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13218 pw.print(" total, non-act at "); 13219 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13220 pw.print(", non-svc at "); 13221 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13222 pw.println("):"); 13223 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13224 needSep = true; 13225 } 13226 13227 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13228 13229 pw.println(); 13230 pw.println(" mHomeProcess: " + mHomeProcess); 13231 pw.println(" mPreviousProcess: " + mPreviousProcess); 13232 if (mHeavyWeightProcess != null) { 13233 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13234 } 13235 13236 return true; 13237 } 13238 13239 /** 13240 * There are three ways to call this: 13241 * - no provider specified: dump all the providers 13242 * - a flattened component name that matched an existing provider was specified as the 13243 * first arg: dump that one provider 13244 * - the first arg isn't the flattened component name of an existing provider: 13245 * dump all providers whose component contains the first arg as a substring 13246 */ 13247 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13248 int opti, boolean dumpAll) { 13249 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13250 } 13251 13252 static class ItemMatcher { 13253 ArrayList<ComponentName> components; 13254 ArrayList<String> strings; 13255 ArrayList<Integer> objects; 13256 boolean all; 13257 13258 ItemMatcher() { 13259 all = true; 13260 } 13261 13262 void build(String name) { 13263 ComponentName componentName = ComponentName.unflattenFromString(name); 13264 if (componentName != null) { 13265 if (components == null) { 13266 components = new ArrayList<ComponentName>(); 13267 } 13268 components.add(componentName); 13269 all = false; 13270 } else { 13271 int objectId = 0; 13272 // Not a '/' separated full component name; maybe an object ID? 13273 try { 13274 objectId = Integer.parseInt(name, 16); 13275 if (objects == null) { 13276 objects = new ArrayList<Integer>(); 13277 } 13278 objects.add(objectId); 13279 all = false; 13280 } catch (RuntimeException e) { 13281 // Not an integer; just do string match. 13282 if (strings == null) { 13283 strings = new ArrayList<String>(); 13284 } 13285 strings.add(name); 13286 all = false; 13287 } 13288 } 13289 } 13290 13291 int build(String[] args, int opti) { 13292 for (; opti<args.length; opti++) { 13293 String name = args[opti]; 13294 if ("--".equals(name)) { 13295 return opti+1; 13296 } 13297 build(name); 13298 } 13299 return opti; 13300 } 13301 13302 boolean match(Object object, ComponentName comp) { 13303 if (all) { 13304 return true; 13305 } 13306 if (components != null) { 13307 for (int i=0; i<components.size(); i++) { 13308 if (components.get(i).equals(comp)) { 13309 return true; 13310 } 13311 } 13312 } 13313 if (objects != null) { 13314 for (int i=0; i<objects.size(); i++) { 13315 if (System.identityHashCode(object) == objects.get(i)) { 13316 return true; 13317 } 13318 } 13319 } 13320 if (strings != null) { 13321 String flat = comp.flattenToString(); 13322 for (int i=0; i<strings.size(); i++) { 13323 if (flat.contains(strings.get(i))) { 13324 return true; 13325 } 13326 } 13327 } 13328 return false; 13329 } 13330 } 13331 13332 /** 13333 * There are three things that cmd can be: 13334 * - a flattened component name that matches an existing activity 13335 * - the cmd arg isn't the flattened component name of an existing activity: 13336 * dump all activity whose component contains the cmd as a substring 13337 * - A hex number of the ActivityRecord object instance. 13338 */ 13339 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13340 int opti, boolean dumpAll) { 13341 ArrayList<ActivityRecord> activities; 13342 13343 synchronized (this) { 13344 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13345 } 13346 13347 if (activities.size() <= 0) { 13348 return false; 13349 } 13350 13351 String[] newArgs = new String[args.length - opti]; 13352 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13353 13354 TaskRecord lastTask = null; 13355 boolean needSep = false; 13356 for (int i=activities.size()-1; i>=0; i--) { 13357 ActivityRecord r = activities.get(i); 13358 if (needSep) { 13359 pw.println(); 13360 } 13361 needSep = true; 13362 synchronized (this) { 13363 if (lastTask != r.task) { 13364 lastTask = r.task; 13365 pw.print("TASK "); pw.print(lastTask.affinity); 13366 pw.print(" id="); pw.println(lastTask.taskId); 13367 if (dumpAll) { 13368 lastTask.dump(pw, " "); 13369 } 13370 } 13371 } 13372 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13373 } 13374 return true; 13375 } 13376 13377 /** 13378 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13379 * there is a thread associated with the activity. 13380 */ 13381 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13382 final ActivityRecord r, String[] args, boolean dumpAll) { 13383 String innerPrefix = prefix + " "; 13384 synchronized (this) { 13385 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13386 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13387 pw.print(" pid="); 13388 if (r.app != null) pw.println(r.app.pid); 13389 else pw.println("(not running)"); 13390 if (dumpAll) { 13391 r.dump(pw, innerPrefix); 13392 } 13393 } 13394 if (r.app != null && r.app.thread != null) { 13395 // flush anything that is already in the PrintWriter since the thread is going 13396 // to write to the file descriptor directly 13397 pw.flush(); 13398 try { 13399 TransferPipe tp = new TransferPipe(); 13400 try { 13401 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13402 r.appToken, innerPrefix, args); 13403 tp.go(fd); 13404 } finally { 13405 tp.kill(); 13406 } 13407 } catch (IOException e) { 13408 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13409 } catch (RemoteException e) { 13410 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13411 } 13412 } 13413 } 13414 13415 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13416 int opti, boolean dumpAll, String dumpPackage) { 13417 boolean needSep = false; 13418 boolean onlyHistory = false; 13419 boolean printedAnything = false; 13420 13421 if ("history".equals(dumpPackage)) { 13422 if (opti < args.length && "-s".equals(args[opti])) { 13423 dumpAll = false; 13424 } 13425 onlyHistory = true; 13426 dumpPackage = null; 13427 } 13428 13429 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13430 if (!onlyHistory && dumpAll) { 13431 if (mRegisteredReceivers.size() > 0) { 13432 boolean printed = false; 13433 Iterator it = mRegisteredReceivers.values().iterator(); 13434 while (it.hasNext()) { 13435 ReceiverList r = (ReceiverList)it.next(); 13436 if (dumpPackage != null && (r.app == null || 13437 !dumpPackage.equals(r.app.info.packageName))) { 13438 continue; 13439 } 13440 if (!printed) { 13441 pw.println(" Registered Receivers:"); 13442 needSep = true; 13443 printed = true; 13444 printedAnything = true; 13445 } 13446 pw.print(" * "); pw.println(r); 13447 r.dump(pw, " "); 13448 } 13449 } 13450 13451 if (mReceiverResolver.dump(pw, needSep ? 13452 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13453 " ", dumpPackage, false, false)) { 13454 needSep = true; 13455 printedAnything = true; 13456 } 13457 } 13458 13459 for (BroadcastQueue q : mBroadcastQueues) { 13460 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13461 printedAnything |= needSep; 13462 } 13463 13464 needSep = true; 13465 13466 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13467 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13468 if (needSep) { 13469 pw.println(); 13470 } 13471 needSep = true; 13472 printedAnything = true; 13473 pw.print(" Sticky broadcasts for user "); 13474 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13475 StringBuilder sb = new StringBuilder(128); 13476 for (Map.Entry<String, ArrayList<Intent>> ent 13477 : mStickyBroadcasts.valueAt(user).entrySet()) { 13478 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13479 if (dumpAll) { 13480 pw.println(":"); 13481 ArrayList<Intent> intents = ent.getValue(); 13482 final int N = intents.size(); 13483 for (int i=0; i<N; i++) { 13484 sb.setLength(0); 13485 sb.append(" Intent: "); 13486 intents.get(i).toShortString(sb, false, true, false, false); 13487 pw.println(sb.toString()); 13488 Bundle bundle = intents.get(i).getExtras(); 13489 if (bundle != null) { 13490 pw.print(" "); 13491 pw.println(bundle.toString()); 13492 } 13493 } 13494 } else { 13495 pw.println(""); 13496 } 13497 } 13498 } 13499 } 13500 13501 if (!onlyHistory && dumpAll) { 13502 pw.println(); 13503 for (BroadcastQueue queue : mBroadcastQueues) { 13504 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13505 + queue.mBroadcastsScheduled); 13506 } 13507 pw.println(" mHandler:"); 13508 mHandler.dump(new PrintWriterPrinter(pw), " "); 13509 needSep = true; 13510 printedAnything = true; 13511 } 13512 13513 if (!printedAnything) { 13514 pw.println(" (nothing)"); 13515 } 13516 } 13517 13518 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13519 int opti, boolean dumpAll, String dumpPackage) { 13520 boolean needSep; 13521 boolean printedAnything = false; 13522 13523 ItemMatcher matcher = new ItemMatcher(); 13524 matcher.build(args, opti); 13525 13526 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13527 13528 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13529 printedAnything |= needSep; 13530 13531 if (mLaunchingProviders.size() > 0) { 13532 boolean printed = false; 13533 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13534 ContentProviderRecord r = mLaunchingProviders.get(i); 13535 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13536 continue; 13537 } 13538 if (!printed) { 13539 if (needSep) pw.println(); 13540 needSep = true; 13541 pw.println(" Launching content providers:"); 13542 printed = true; 13543 printedAnything = true; 13544 } 13545 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13546 pw.println(r); 13547 } 13548 } 13549 13550 if (mGrantedUriPermissions.size() > 0) { 13551 boolean printed = false; 13552 int dumpUid = -2; 13553 if (dumpPackage != null) { 13554 try { 13555 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13556 } catch (NameNotFoundException e) { 13557 dumpUid = -1; 13558 } 13559 } 13560 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13561 int uid = mGrantedUriPermissions.keyAt(i); 13562 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13563 continue; 13564 } 13565 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13566 if (!printed) { 13567 if (needSep) pw.println(); 13568 needSep = true; 13569 pw.println(" Granted Uri Permissions:"); 13570 printed = true; 13571 printedAnything = true; 13572 } 13573 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13574 for (UriPermission perm : perms.values()) { 13575 pw.print(" "); pw.println(perm); 13576 if (dumpAll) { 13577 perm.dump(pw, " "); 13578 } 13579 } 13580 } 13581 } 13582 13583 if (!printedAnything) { 13584 pw.println(" (nothing)"); 13585 } 13586 } 13587 13588 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13589 int opti, boolean dumpAll, String dumpPackage) { 13590 boolean printed = false; 13591 13592 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13593 13594 if (mIntentSenderRecords.size() > 0) { 13595 Iterator<WeakReference<PendingIntentRecord>> it 13596 = mIntentSenderRecords.values().iterator(); 13597 while (it.hasNext()) { 13598 WeakReference<PendingIntentRecord> ref = it.next(); 13599 PendingIntentRecord rec = ref != null ? ref.get(): null; 13600 if (dumpPackage != null && (rec == null 13601 || !dumpPackage.equals(rec.key.packageName))) { 13602 continue; 13603 } 13604 printed = true; 13605 if (rec != null) { 13606 pw.print(" * "); pw.println(rec); 13607 if (dumpAll) { 13608 rec.dump(pw, " "); 13609 } 13610 } else { 13611 pw.print(" * "); pw.println(ref); 13612 } 13613 } 13614 } 13615 13616 if (!printed) { 13617 pw.println(" (nothing)"); 13618 } 13619 } 13620 13621 private static final int dumpProcessList(PrintWriter pw, 13622 ActivityManagerService service, List list, 13623 String prefix, String normalLabel, String persistentLabel, 13624 String dumpPackage) { 13625 int numPers = 0; 13626 final int N = list.size()-1; 13627 for (int i=N; i>=0; i--) { 13628 ProcessRecord r = (ProcessRecord)list.get(i); 13629 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13630 continue; 13631 } 13632 pw.println(String.format("%s%s #%2d: %s", 13633 prefix, (r.persistent ? persistentLabel : normalLabel), 13634 i, r.toString())); 13635 if (r.persistent) { 13636 numPers++; 13637 } 13638 } 13639 return numPers; 13640 } 13641 13642 private static final boolean dumpProcessOomList(PrintWriter pw, 13643 ActivityManagerService service, List<ProcessRecord> origList, 13644 String prefix, String normalLabel, String persistentLabel, 13645 boolean inclDetails, String dumpPackage) { 13646 13647 ArrayList<Pair<ProcessRecord, Integer>> list 13648 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13649 for (int i=0; i<origList.size(); i++) { 13650 ProcessRecord r = origList.get(i); 13651 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13652 continue; 13653 } 13654 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13655 } 13656 13657 if (list.size() <= 0) { 13658 return false; 13659 } 13660 13661 Comparator<Pair<ProcessRecord, Integer>> comparator 13662 = new Comparator<Pair<ProcessRecord, Integer>>() { 13663 @Override 13664 public int compare(Pair<ProcessRecord, Integer> object1, 13665 Pair<ProcessRecord, Integer> object2) { 13666 if (object1.first.setAdj != object2.first.setAdj) { 13667 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13668 } 13669 if (object1.second.intValue() != object2.second.intValue()) { 13670 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13671 } 13672 return 0; 13673 } 13674 }; 13675 13676 Collections.sort(list, comparator); 13677 13678 final long curRealtime = SystemClock.elapsedRealtime(); 13679 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13680 final long curUptime = SystemClock.uptimeMillis(); 13681 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13682 13683 for (int i=list.size()-1; i>=0; i--) { 13684 ProcessRecord r = list.get(i).first; 13685 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13686 char schedGroup; 13687 switch (r.setSchedGroup) { 13688 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13689 schedGroup = 'B'; 13690 break; 13691 case Process.THREAD_GROUP_DEFAULT: 13692 schedGroup = 'F'; 13693 break; 13694 default: 13695 schedGroup = '?'; 13696 break; 13697 } 13698 char foreground; 13699 if (r.foregroundActivities) { 13700 foreground = 'A'; 13701 } else if (r.foregroundServices) { 13702 foreground = 'S'; 13703 } else { 13704 foreground = ' '; 13705 } 13706 String procState = ProcessList.makeProcStateString(r.curProcState); 13707 pw.print(prefix); 13708 pw.print(r.persistent ? persistentLabel : normalLabel); 13709 pw.print(" #"); 13710 int num = (origList.size()-1)-list.get(i).second; 13711 if (num < 10) pw.print(' '); 13712 pw.print(num); 13713 pw.print(": "); 13714 pw.print(oomAdj); 13715 pw.print(' '); 13716 pw.print(schedGroup); 13717 pw.print('/'); 13718 pw.print(foreground); 13719 pw.print('/'); 13720 pw.print(procState); 13721 pw.print(" trm:"); 13722 if (r.trimMemoryLevel < 10) pw.print(' '); 13723 pw.print(r.trimMemoryLevel); 13724 pw.print(' '); 13725 pw.print(r.toShortString()); 13726 pw.print(" ("); 13727 pw.print(r.adjType); 13728 pw.println(')'); 13729 if (r.adjSource != null || r.adjTarget != null) { 13730 pw.print(prefix); 13731 pw.print(" "); 13732 if (r.adjTarget instanceof ComponentName) { 13733 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13734 } else if (r.adjTarget != null) { 13735 pw.print(r.adjTarget.toString()); 13736 } else { 13737 pw.print("{null}"); 13738 } 13739 pw.print("<="); 13740 if (r.adjSource instanceof ProcessRecord) { 13741 pw.print("Proc{"); 13742 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13743 pw.println("}"); 13744 } else if (r.adjSource != null) { 13745 pw.println(r.adjSource.toString()); 13746 } else { 13747 pw.println("{null}"); 13748 } 13749 } 13750 if (inclDetails) { 13751 pw.print(prefix); 13752 pw.print(" "); 13753 pw.print("oom: max="); pw.print(r.maxAdj); 13754 pw.print(" curRaw="); pw.print(r.curRawAdj); 13755 pw.print(" setRaw="); pw.print(r.setRawAdj); 13756 pw.print(" cur="); pw.print(r.curAdj); 13757 pw.print(" set="); pw.println(r.setAdj); 13758 pw.print(prefix); 13759 pw.print(" "); 13760 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13761 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13762 pw.print(" lastPss="); pw.print(r.lastPss); 13763 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13764 pw.print(prefix); 13765 pw.print(" "); 13766 pw.print("cached="); pw.print(r.cached); 13767 pw.print(" empty="); pw.print(r.empty); 13768 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13769 13770 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13771 if (r.lastWakeTime != 0) { 13772 long wtime; 13773 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13774 synchronized (stats) { 13775 wtime = stats.getProcessWakeTime(r.info.uid, 13776 r.pid, curRealtime); 13777 } 13778 long timeUsed = wtime - r.lastWakeTime; 13779 pw.print(prefix); 13780 pw.print(" "); 13781 pw.print("keep awake over "); 13782 TimeUtils.formatDuration(realtimeSince, pw); 13783 pw.print(" used "); 13784 TimeUtils.formatDuration(timeUsed, pw); 13785 pw.print(" ("); 13786 pw.print((timeUsed*100)/realtimeSince); 13787 pw.println("%)"); 13788 } 13789 if (r.lastCpuTime != 0) { 13790 long timeUsed = r.curCpuTime - r.lastCpuTime; 13791 pw.print(prefix); 13792 pw.print(" "); 13793 pw.print("run cpu over "); 13794 TimeUtils.formatDuration(uptimeSince, pw); 13795 pw.print(" used "); 13796 TimeUtils.formatDuration(timeUsed, pw); 13797 pw.print(" ("); 13798 pw.print((timeUsed*100)/uptimeSince); 13799 pw.println("%)"); 13800 } 13801 } 13802 } 13803 } 13804 return true; 13805 } 13806 13807 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13808 String[] args) { 13809 ArrayList<ProcessRecord> procs; 13810 synchronized (this) { 13811 if (args != null && args.length > start 13812 && args[start].charAt(0) != '-') { 13813 procs = new ArrayList<ProcessRecord>(); 13814 int pid = -1; 13815 try { 13816 pid = Integer.parseInt(args[start]); 13817 } catch (NumberFormatException e) { 13818 } 13819 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13820 ProcessRecord proc = mLruProcesses.get(i); 13821 if (proc.pid == pid) { 13822 procs.add(proc); 13823 } else if (allPkgs && proc.pkgList != null 13824 && proc.pkgList.containsKey(args[start])) { 13825 procs.add(proc); 13826 } else if (proc.processName.equals(args[start])) { 13827 procs.add(proc); 13828 } 13829 } 13830 if (procs.size() <= 0) { 13831 return null; 13832 } 13833 } else { 13834 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13835 } 13836 } 13837 return procs; 13838 } 13839 13840 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13841 PrintWriter pw, String[] args) { 13842 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13843 if (procs == null) { 13844 pw.println("No process found for: " + args[0]); 13845 return; 13846 } 13847 13848 long uptime = SystemClock.uptimeMillis(); 13849 long realtime = SystemClock.elapsedRealtime(); 13850 pw.println("Applications Graphics Acceleration Info:"); 13851 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13852 13853 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13854 ProcessRecord r = procs.get(i); 13855 if (r.thread != null) { 13856 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13857 pw.flush(); 13858 try { 13859 TransferPipe tp = new TransferPipe(); 13860 try { 13861 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13862 tp.go(fd); 13863 } finally { 13864 tp.kill(); 13865 } 13866 } catch (IOException e) { 13867 pw.println("Failure while dumping the app: " + r); 13868 pw.flush(); 13869 } catch (RemoteException e) { 13870 pw.println("Got a RemoteException while dumping the app " + r); 13871 pw.flush(); 13872 } 13873 } 13874 } 13875 } 13876 13877 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13878 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13879 if (procs == null) { 13880 pw.println("No process found for: " + args[0]); 13881 return; 13882 } 13883 13884 pw.println("Applications Database Info:"); 13885 13886 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13887 ProcessRecord r = procs.get(i); 13888 if (r.thread != null) { 13889 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13890 pw.flush(); 13891 try { 13892 TransferPipe tp = new TransferPipe(); 13893 try { 13894 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13895 tp.go(fd); 13896 } finally { 13897 tp.kill(); 13898 } 13899 } catch (IOException e) { 13900 pw.println("Failure while dumping the app: " + r); 13901 pw.flush(); 13902 } catch (RemoteException e) { 13903 pw.println("Got a RemoteException while dumping the app " + r); 13904 pw.flush(); 13905 } 13906 } 13907 } 13908 } 13909 13910 final static class MemItem { 13911 final boolean isProc; 13912 final String label; 13913 final String shortLabel; 13914 final long pss; 13915 final int id; 13916 final boolean hasActivities; 13917 ArrayList<MemItem> subitems; 13918 13919 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13920 boolean _hasActivities) { 13921 isProc = true; 13922 label = _label; 13923 shortLabel = _shortLabel; 13924 pss = _pss; 13925 id = _id; 13926 hasActivities = _hasActivities; 13927 } 13928 13929 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13930 isProc = false; 13931 label = _label; 13932 shortLabel = _shortLabel; 13933 pss = _pss; 13934 id = _id; 13935 hasActivities = false; 13936 } 13937 } 13938 13939 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13940 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13941 if (sort && !isCompact) { 13942 Collections.sort(items, new Comparator<MemItem>() { 13943 @Override 13944 public int compare(MemItem lhs, MemItem rhs) { 13945 if (lhs.pss < rhs.pss) { 13946 return 1; 13947 } else if (lhs.pss > rhs.pss) { 13948 return -1; 13949 } 13950 return 0; 13951 } 13952 }); 13953 } 13954 13955 for (int i=0; i<items.size(); i++) { 13956 MemItem mi = items.get(i); 13957 if (!isCompact) { 13958 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13959 } else if (mi.isProc) { 13960 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13961 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13962 pw.println(mi.hasActivities ? ",a" : ",e"); 13963 } else { 13964 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13965 pw.println(mi.pss); 13966 } 13967 if (mi.subitems != null) { 13968 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13969 true, isCompact); 13970 } 13971 } 13972 } 13973 13974 // These are in KB. 13975 static final long[] DUMP_MEM_BUCKETS = new long[] { 13976 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13977 120*1024, 160*1024, 200*1024, 13978 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13979 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13980 }; 13981 13982 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13983 boolean stackLike) { 13984 int start = label.lastIndexOf('.'); 13985 if (start >= 0) start++; 13986 else start = 0; 13987 int end = label.length(); 13988 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13989 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13990 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13991 out.append(bucket); 13992 out.append(stackLike ? "MB." : "MB "); 13993 out.append(label, start, end); 13994 return; 13995 } 13996 } 13997 out.append(memKB/1024); 13998 out.append(stackLike ? "MB." : "MB "); 13999 out.append(label, start, end); 14000 } 14001 14002 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 14003 ProcessList.NATIVE_ADJ, 14004 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 14005 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14006 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14007 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14008 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14009 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14010 }; 14011 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14012 "Native", 14013 "System", "Persistent", "Persistent Service", "Foreground", 14014 "Visible", "Perceptible", 14015 "Heavy Weight", "Backup", 14016 "A Services", "Home", 14017 "Previous", "B Services", "Cached" 14018 }; 14019 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14020 "native", 14021 "sys", "pers", "persvc", "fore", 14022 "vis", "percept", 14023 "heavy", "backup", 14024 "servicea", "home", 14025 "prev", "serviceb", "cached" 14026 }; 14027 14028 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14029 long realtime, boolean isCheckinRequest, boolean isCompact) { 14030 if (isCheckinRequest || isCompact) { 14031 // short checkin version 14032 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14033 } else { 14034 pw.println("Applications Memory Usage (kB):"); 14035 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14036 } 14037 } 14038 14039 private static final int KSM_SHARED = 0; 14040 private static final int KSM_SHARING = 1; 14041 private static final int KSM_UNSHARED = 2; 14042 private static final int KSM_VOLATILE = 3; 14043 14044 private final long[] getKsmInfo() { 14045 long[] longOut = new long[4]; 14046 final int[] SINGLE_LONG_FORMAT = new int[] { 14047 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14048 }; 14049 long[] longTmp = new long[1]; 14050 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14051 SINGLE_LONG_FORMAT, null, longTmp, null); 14052 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14053 longTmp[0] = 0; 14054 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14055 SINGLE_LONG_FORMAT, null, longTmp, null); 14056 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14057 longTmp[0] = 0; 14058 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14059 SINGLE_LONG_FORMAT, null, longTmp, null); 14060 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14061 longTmp[0] = 0; 14062 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14063 SINGLE_LONG_FORMAT, null, longTmp, null); 14064 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14065 return longOut; 14066 } 14067 14068 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14069 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14070 boolean dumpDetails = false; 14071 boolean dumpFullDetails = false; 14072 boolean dumpDalvik = false; 14073 boolean oomOnly = false; 14074 boolean isCompact = false; 14075 boolean localOnly = false; 14076 boolean packages = false; 14077 14078 int opti = 0; 14079 while (opti < args.length) { 14080 String opt = args[opti]; 14081 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14082 break; 14083 } 14084 opti++; 14085 if ("-a".equals(opt)) { 14086 dumpDetails = true; 14087 dumpFullDetails = true; 14088 dumpDalvik = true; 14089 } else if ("-d".equals(opt)) { 14090 dumpDalvik = true; 14091 } else if ("-c".equals(opt)) { 14092 isCompact = true; 14093 } else if ("--oom".equals(opt)) { 14094 oomOnly = true; 14095 } else if ("--local".equals(opt)) { 14096 localOnly = true; 14097 } else if ("--package".equals(opt)) { 14098 packages = true; 14099 } else if ("-h".equals(opt)) { 14100 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14101 pw.println(" -a: include all available information for each process."); 14102 pw.println(" -d: include dalvik details when dumping process details."); 14103 pw.println(" -c: dump in a compact machine-parseable representation."); 14104 pw.println(" --oom: only show processes organized by oom adj."); 14105 pw.println(" --local: only collect details locally, don't call process."); 14106 pw.println(" --package: interpret process arg as package, dumping all"); 14107 pw.println(" processes that have loaded that package."); 14108 pw.println("If [process] is specified it can be the name or "); 14109 pw.println("pid of a specific process to dump."); 14110 return; 14111 } else { 14112 pw.println("Unknown argument: " + opt + "; use -h for help"); 14113 } 14114 } 14115 14116 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14117 long uptime = SystemClock.uptimeMillis(); 14118 long realtime = SystemClock.elapsedRealtime(); 14119 final long[] tmpLong = new long[1]; 14120 14121 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14122 if (procs == null) { 14123 // No Java processes. Maybe they want to print a native process. 14124 if (args != null && args.length > opti 14125 && args[opti].charAt(0) != '-') { 14126 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14127 = new ArrayList<ProcessCpuTracker.Stats>(); 14128 updateCpuStatsNow(); 14129 int findPid = -1; 14130 try { 14131 findPid = Integer.parseInt(args[opti]); 14132 } catch (NumberFormatException e) { 14133 } 14134 synchronized (mProcessCpuTracker) { 14135 final int N = mProcessCpuTracker.countStats(); 14136 for (int i=0; i<N; i++) { 14137 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14138 if (st.pid == findPid || (st.baseName != null 14139 && st.baseName.equals(args[opti]))) { 14140 nativeProcs.add(st); 14141 } 14142 } 14143 } 14144 if (nativeProcs.size() > 0) { 14145 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14146 isCompact); 14147 Debug.MemoryInfo mi = null; 14148 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14149 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14150 final int pid = r.pid; 14151 if (!isCheckinRequest && dumpDetails) { 14152 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14153 } 14154 if (mi == null) { 14155 mi = new Debug.MemoryInfo(); 14156 } 14157 if (dumpDetails || (!brief && !oomOnly)) { 14158 Debug.getMemoryInfo(pid, mi); 14159 } else { 14160 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14161 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14162 } 14163 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14164 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14165 if (isCheckinRequest) { 14166 pw.println(); 14167 } 14168 } 14169 return; 14170 } 14171 } 14172 pw.println("No process found for: " + args[opti]); 14173 return; 14174 } 14175 14176 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14177 dumpDetails = true; 14178 } 14179 14180 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14181 14182 String[] innerArgs = new String[args.length-opti]; 14183 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14184 14185 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14186 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14187 long nativePss = 0; 14188 long dalvikPss = 0; 14189 long otherPss = 0; 14190 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14191 14192 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14193 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14194 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14195 14196 long totalPss = 0; 14197 long cachedPss = 0; 14198 14199 Debug.MemoryInfo mi = null; 14200 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14201 final ProcessRecord r = procs.get(i); 14202 final IApplicationThread thread; 14203 final int pid; 14204 final int oomAdj; 14205 final boolean hasActivities; 14206 synchronized (this) { 14207 thread = r.thread; 14208 pid = r.pid; 14209 oomAdj = r.getSetAdjWithServices(); 14210 hasActivities = r.activities.size() > 0; 14211 } 14212 if (thread != null) { 14213 if (!isCheckinRequest && dumpDetails) { 14214 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14215 } 14216 if (mi == null) { 14217 mi = new Debug.MemoryInfo(); 14218 } 14219 if (dumpDetails || (!brief && !oomOnly)) { 14220 Debug.getMemoryInfo(pid, mi); 14221 } else { 14222 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14223 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14224 } 14225 if (dumpDetails) { 14226 if (localOnly) { 14227 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14228 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14229 if (isCheckinRequest) { 14230 pw.println(); 14231 } 14232 } else { 14233 try { 14234 pw.flush(); 14235 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14236 dumpDalvik, innerArgs); 14237 } catch (RemoteException e) { 14238 if (!isCheckinRequest) { 14239 pw.println("Got RemoteException!"); 14240 pw.flush(); 14241 } 14242 } 14243 } 14244 } 14245 14246 final long myTotalPss = mi.getTotalPss(); 14247 final long myTotalUss = mi.getTotalUss(); 14248 14249 synchronized (this) { 14250 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14251 // Record this for posterity if the process has been stable. 14252 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14253 } 14254 } 14255 14256 if (!isCheckinRequest && mi != null) { 14257 totalPss += myTotalPss; 14258 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14259 (hasActivities ? " / activities)" : ")"), 14260 r.processName, myTotalPss, pid, hasActivities); 14261 procMems.add(pssItem); 14262 procMemsMap.put(pid, pssItem); 14263 14264 nativePss += mi.nativePss; 14265 dalvikPss += mi.dalvikPss; 14266 otherPss += mi.otherPss; 14267 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14268 long mem = mi.getOtherPss(j); 14269 miscPss[j] += mem; 14270 otherPss -= mem; 14271 } 14272 14273 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14274 cachedPss += myTotalPss; 14275 } 14276 14277 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14278 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14279 || oomIndex == (oomPss.length-1)) { 14280 oomPss[oomIndex] += myTotalPss; 14281 if (oomProcs[oomIndex] == null) { 14282 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14283 } 14284 oomProcs[oomIndex].add(pssItem); 14285 break; 14286 } 14287 } 14288 } 14289 } 14290 } 14291 14292 long nativeProcTotalPss = 0; 14293 14294 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14295 // If we are showing aggregations, also look for native processes to 14296 // include so that our aggregations are more accurate. 14297 updateCpuStatsNow(); 14298 mi = null; 14299 synchronized (mProcessCpuTracker) { 14300 final int N = mProcessCpuTracker.countStats(); 14301 for (int i=0; i<N; i++) { 14302 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14303 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14304 if (mi == null) { 14305 mi = new Debug.MemoryInfo(); 14306 } 14307 if (!brief && !oomOnly) { 14308 Debug.getMemoryInfo(st.pid, mi); 14309 } else { 14310 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14311 mi.nativePrivateDirty = (int)tmpLong[0]; 14312 } 14313 14314 final long myTotalPss = mi.getTotalPss(); 14315 totalPss += myTotalPss; 14316 nativeProcTotalPss += myTotalPss; 14317 14318 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14319 st.name, myTotalPss, st.pid, false); 14320 procMems.add(pssItem); 14321 14322 nativePss += mi.nativePss; 14323 dalvikPss += mi.dalvikPss; 14324 otherPss += mi.otherPss; 14325 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14326 long mem = mi.getOtherPss(j); 14327 miscPss[j] += mem; 14328 otherPss -= mem; 14329 } 14330 oomPss[0] += myTotalPss; 14331 if (oomProcs[0] == null) { 14332 oomProcs[0] = new ArrayList<MemItem>(); 14333 } 14334 oomProcs[0].add(pssItem); 14335 } 14336 } 14337 } 14338 14339 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14340 14341 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14342 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14343 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14344 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14345 String label = Debug.MemoryInfo.getOtherLabel(j); 14346 catMems.add(new MemItem(label, label, miscPss[j], j)); 14347 } 14348 14349 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14350 for (int j=0; j<oomPss.length; j++) { 14351 if (oomPss[j] != 0) { 14352 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14353 : DUMP_MEM_OOM_LABEL[j]; 14354 MemItem item = new MemItem(label, label, oomPss[j], 14355 DUMP_MEM_OOM_ADJ[j]); 14356 item.subitems = oomProcs[j]; 14357 oomMems.add(item); 14358 } 14359 } 14360 14361 if (!brief && !oomOnly && !isCompact) { 14362 pw.println(); 14363 pw.println("Total PSS by process:"); 14364 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14365 pw.println(); 14366 } 14367 if (!isCompact) { 14368 pw.println("Total PSS by OOM adjustment:"); 14369 } 14370 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14371 if (!brief && !oomOnly) { 14372 PrintWriter out = categoryPw != null ? categoryPw : pw; 14373 if (!isCompact) { 14374 out.println(); 14375 out.println("Total PSS by category:"); 14376 } 14377 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14378 } 14379 if (!isCompact) { 14380 pw.println(); 14381 } 14382 MemInfoReader memInfo = new MemInfoReader(); 14383 memInfo.readMemInfo(); 14384 if (nativeProcTotalPss > 0) { 14385 synchronized (this) { 14386 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14387 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14388 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14389 } 14390 } 14391 if (!brief) { 14392 if (!isCompact) { 14393 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14394 pw.print(" kB (status "); 14395 switch (mLastMemoryLevel) { 14396 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14397 pw.println("normal)"); 14398 break; 14399 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14400 pw.println("moderate)"); 14401 break; 14402 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14403 pw.println("low)"); 14404 break; 14405 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14406 pw.println("critical)"); 14407 break; 14408 default: 14409 pw.print(mLastMemoryLevel); 14410 pw.println(")"); 14411 break; 14412 } 14413 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14414 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14415 pw.print(cachedPss); pw.print(" cached pss + "); 14416 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14417 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14418 } else { 14419 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14420 pw.print(cachedPss + memInfo.getCachedSizeKb() 14421 + memInfo.getFreeSizeKb()); pw.print(","); 14422 pw.println(totalPss - cachedPss); 14423 } 14424 } 14425 if (!isCompact) { 14426 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14427 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14428 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14429 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14430 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14431 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14432 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14433 } 14434 if (!brief) { 14435 if (memInfo.getZramTotalSizeKb() != 0) { 14436 if (!isCompact) { 14437 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14438 pw.print(" kB physical used for "); 14439 pw.print(memInfo.getSwapTotalSizeKb() 14440 - memInfo.getSwapFreeSizeKb()); 14441 pw.print(" kB in swap ("); 14442 pw.print(memInfo.getSwapTotalSizeKb()); 14443 pw.println(" kB total swap)"); 14444 } else { 14445 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14446 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14447 pw.println(memInfo.getSwapFreeSizeKb()); 14448 } 14449 } 14450 final long[] ksm = getKsmInfo(); 14451 if (!isCompact) { 14452 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14453 || ksm[KSM_VOLATILE] != 0) { 14454 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14455 pw.print(" kB saved from shared "); 14456 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14457 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14458 pw.print(" kB unshared; "); 14459 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14460 } 14461 pw.print(" Tuning: "); 14462 pw.print(ActivityManager.staticGetMemoryClass()); 14463 pw.print(" (large "); 14464 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14465 pw.print("), oom "); 14466 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14467 pw.print(" kB"); 14468 pw.print(", restore limit "); 14469 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14470 pw.print(" kB"); 14471 if (ActivityManager.isLowRamDeviceStatic()) { 14472 pw.print(" (low-ram)"); 14473 } 14474 if (ActivityManager.isHighEndGfx()) { 14475 pw.print(" (high-end-gfx)"); 14476 } 14477 pw.println(); 14478 } else { 14479 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14480 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14481 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14482 pw.print("tuning,"); 14483 pw.print(ActivityManager.staticGetMemoryClass()); 14484 pw.print(','); 14485 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14486 pw.print(','); 14487 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14488 if (ActivityManager.isLowRamDeviceStatic()) { 14489 pw.print(",low-ram"); 14490 } 14491 if (ActivityManager.isHighEndGfx()) { 14492 pw.print(",high-end-gfx"); 14493 } 14494 pw.println(); 14495 } 14496 } 14497 } 14498 } 14499 14500 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14501 long memtrack, String name) { 14502 sb.append(" "); 14503 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14504 sb.append(' '); 14505 sb.append(ProcessList.makeProcStateString(procState)); 14506 sb.append(' '); 14507 ProcessList.appendRamKb(sb, pss); 14508 sb.append(" kB: "); 14509 sb.append(name); 14510 if (memtrack > 0) { 14511 sb.append(" ("); 14512 sb.append(memtrack); 14513 sb.append(" kB memtrack)"); 14514 } 14515 } 14516 14517 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14518 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14519 sb.append(" (pid "); 14520 sb.append(mi.pid); 14521 sb.append(") "); 14522 sb.append(mi.adjType); 14523 sb.append('\n'); 14524 if (mi.adjReason != null) { 14525 sb.append(" "); 14526 sb.append(mi.adjReason); 14527 sb.append('\n'); 14528 } 14529 } 14530 14531 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14532 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14533 for (int i=0, N=memInfos.size(); i<N; i++) { 14534 ProcessMemInfo mi = memInfos.get(i); 14535 infoMap.put(mi.pid, mi); 14536 } 14537 updateCpuStatsNow(); 14538 long[] memtrackTmp = new long[1]; 14539 synchronized (mProcessCpuTracker) { 14540 final int N = mProcessCpuTracker.countStats(); 14541 for (int i=0; i<N; i++) { 14542 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14543 if (st.vsize > 0) { 14544 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14545 if (pss > 0) { 14546 if (infoMap.indexOfKey(st.pid) < 0) { 14547 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14548 ProcessList.NATIVE_ADJ, -1, "native", null); 14549 mi.pss = pss; 14550 mi.memtrack = memtrackTmp[0]; 14551 memInfos.add(mi); 14552 } 14553 } 14554 } 14555 } 14556 } 14557 14558 long totalPss = 0; 14559 long totalMemtrack = 0; 14560 for (int i=0, N=memInfos.size(); i<N; i++) { 14561 ProcessMemInfo mi = memInfos.get(i); 14562 if (mi.pss == 0) { 14563 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14564 mi.memtrack = memtrackTmp[0]; 14565 } 14566 totalPss += mi.pss; 14567 totalMemtrack += mi.memtrack; 14568 } 14569 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14570 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14571 if (lhs.oomAdj != rhs.oomAdj) { 14572 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14573 } 14574 if (lhs.pss != rhs.pss) { 14575 return lhs.pss < rhs.pss ? 1 : -1; 14576 } 14577 return 0; 14578 } 14579 }); 14580 14581 StringBuilder tag = new StringBuilder(128); 14582 StringBuilder stack = new StringBuilder(128); 14583 tag.append("Low on memory -- "); 14584 appendMemBucket(tag, totalPss, "total", false); 14585 appendMemBucket(stack, totalPss, "total", true); 14586 14587 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14588 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14589 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14590 14591 boolean firstLine = true; 14592 int lastOomAdj = Integer.MIN_VALUE; 14593 long extraNativeRam = 0; 14594 long extraNativeMemtrack = 0; 14595 long cachedPss = 0; 14596 for (int i=0, N=memInfos.size(); i<N; i++) { 14597 ProcessMemInfo mi = memInfos.get(i); 14598 14599 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14600 cachedPss += mi.pss; 14601 } 14602 14603 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14604 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14605 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14606 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14607 if (lastOomAdj != mi.oomAdj) { 14608 lastOomAdj = mi.oomAdj; 14609 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14610 tag.append(" / "); 14611 } 14612 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14613 if (firstLine) { 14614 stack.append(":"); 14615 firstLine = false; 14616 } 14617 stack.append("\n\t at "); 14618 } else { 14619 stack.append("$"); 14620 } 14621 } else { 14622 tag.append(" "); 14623 stack.append("$"); 14624 } 14625 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14626 appendMemBucket(tag, mi.pss, mi.name, false); 14627 } 14628 appendMemBucket(stack, mi.pss, mi.name, true); 14629 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14630 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14631 stack.append("("); 14632 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14633 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14634 stack.append(DUMP_MEM_OOM_LABEL[k]); 14635 stack.append(":"); 14636 stack.append(DUMP_MEM_OOM_ADJ[k]); 14637 } 14638 } 14639 stack.append(")"); 14640 } 14641 } 14642 14643 appendMemInfo(fullNativeBuilder, mi); 14644 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14645 // The short form only has native processes that are >= 512K. 14646 if (mi.pss >= 512) { 14647 appendMemInfo(shortNativeBuilder, mi); 14648 } else { 14649 extraNativeRam += mi.pss; 14650 extraNativeMemtrack += mi.memtrack; 14651 } 14652 } else { 14653 // Short form has all other details, but if we have collected RAM 14654 // from smaller native processes let's dump a summary of that. 14655 if (extraNativeRam > 0) { 14656 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14657 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14658 shortNativeBuilder.append('\n'); 14659 extraNativeRam = 0; 14660 } 14661 appendMemInfo(fullJavaBuilder, mi); 14662 } 14663 } 14664 14665 fullJavaBuilder.append(" "); 14666 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14667 fullJavaBuilder.append(" kB: TOTAL"); 14668 if (totalMemtrack > 0) { 14669 fullJavaBuilder.append(" ("); 14670 fullJavaBuilder.append(totalMemtrack); 14671 fullJavaBuilder.append(" kB memtrack)"); 14672 } else { 14673 } 14674 fullJavaBuilder.append("\n"); 14675 14676 MemInfoReader memInfo = new MemInfoReader(); 14677 memInfo.readMemInfo(); 14678 final long[] infos = memInfo.getRawInfo(); 14679 14680 StringBuilder memInfoBuilder = new StringBuilder(1024); 14681 Debug.getMemInfo(infos); 14682 memInfoBuilder.append(" MemInfo: "); 14683 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14684 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14685 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14686 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14687 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14688 memInfoBuilder.append(" "); 14689 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14690 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14691 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14692 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14693 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14694 memInfoBuilder.append(" ZRAM: "); 14695 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14696 memInfoBuilder.append(" kB RAM, "); 14697 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14698 memInfoBuilder.append(" kB swap total, "); 14699 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14700 memInfoBuilder.append(" kB swap free\n"); 14701 } 14702 final long[] ksm = getKsmInfo(); 14703 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14704 || ksm[KSM_VOLATILE] != 0) { 14705 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14706 memInfoBuilder.append(" kB saved from shared "); 14707 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14708 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14709 memInfoBuilder.append(" kB unshared; "); 14710 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14711 } 14712 memInfoBuilder.append(" Free RAM: "); 14713 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14714 + memInfo.getFreeSizeKb()); 14715 memInfoBuilder.append(" kB\n"); 14716 memInfoBuilder.append(" Used RAM: "); 14717 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14718 memInfoBuilder.append(" kB\n"); 14719 memInfoBuilder.append(" Lost RAM: "); 14720 memInfoBuilder.append(memInfo.getTotalSizeKb() 14721 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14722 - memInfo.getKernelUsedSizeKb()); 14723 memInfoBuilder.append(" kB\n"); 14724 Slog.i(TAG, "Low on memory:"); 14725 Slog.i(TAG, shortNativeBuilder.toString()); 14726 Slog.i(TAG, fullJavaBuilder.toString()); 14727 Slog.i(TAG, memInfoBuilder.toString()); 14728 14729 StringBuilder dropBuilder = new StringBuilder(1024); 14730 /* 14731 StringWriter oomSw = new StringWriter(); 14732 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14733 StringWriter catSw = new StringWriter(); 14734 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14735 String[] emptyArgs = new String[] { }; 14736 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14737 oomPw.flush(); 14738 String oomString = oomSw.toString(); 14739 */ 14740 dropBuilder.append("Low on memory:"); 14741 dropBuilder.append(stack); 14742 dropBuilder.append('\n'); 14743 dropBuilder.append(fullNativeBuilder); 14744 dropBuilder.append(fullJavaBuilder); 14745 dropBuilder.append('\n'); 14746 dropBuilder.append(memInfoBuilder); 14747 dropBuilder.append('\n'); 14748 /* 14749 dropBuilder.append(oomString); 14750 dropBuilder.append('\n'); 14751 */ 14752 StringWriter catSw = new StringWriter(); 14753 synchronized (ActivityManagerService.this) { 14754 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14755 String[] emptyArgs = new String[] { }; 14756 catPw.println(); 14757 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14758 catPw.println(); 14759 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14760 false, false, null); 14761 catPw.println(); 14762 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14763 catPw.flush(); 14764 } 14765 dropBuilder.append(catSw.toString()); 14766 addErrorToDropBox("lowmem", null, "system_server", null, 14767 null, tag.toString(), dropBuilder.toString(), null, null); 14768 //Slog.i(TAG, "Sent to dropbox:"); 14769 //Slog.i(TAG, dropBuilder.toString()); 14770 synchronized (ActivityManagerService.this) { 14771 long now = SystemClock.uptimeMillis(); 14772 if (mLastMemUsageReportTime < now) { 14773 mLastMemUsageReportTime = now; 14774 } 14775 } 14776 } 14777 14778 /** 14779 * Searches array of arguments for the specified string 14780 * @param args array of argument strings 14781 * @param value value to search for 14782 * @return true if the value is contained in the array 14783 */ 14784 private static boolean scanArgs(String[] args, String value) { 14785 if (args != null) { 14786 for (String arg : args) { 14787 if (value.equals(arg)) { 14788 return true; 14789 } 14790 } 14791 } 14792 return false; 14793 } 14794 14795 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14796 ContentProviderRecord cpr, boolean always) { 14797 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14798 14799 if (!inLaunching || always) { 14800 synchronized (cpr) { 14801 cpr.launchingApp = null; 14802 cpr.notifyAll(); 14803 } 14804 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14805 String names[] = cpr.info.authority.split(";"); 14806 for (int j = 0; j < names.length; j++) { 14807 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14808 } 14809 } 14810 14811 for (int i=0; i<cpr.connections.size(); i++) { 14812 ContentProviderConnection conn = cpr.connections.get(i); 14813 if (conn.waiting) { 14814 // If this connection is waiting for the provider, then we don't 14815 // need to mess with its process unless we are always removing 14816 // or for some reason the provider is not currently launching. 14817 if (inLaunching && !always) { 14818 continue; 14819 } 14820 } 14821 ProcessRecord capp = conn.client; 14822 conn.dead = true; 14823 if (conn.stableCount > 0) { 14824 if (!capp.persistent && capp.thread != null 14825 && capp.pid != 0 14826 && capp.pid != MY_PID) { 14827 capp.kill("depends on provider " 14828 + cpr.name.flattenToShortString() 14829 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14830 } 14831 } else if (capp.thread != null && conn.provider.provider != null) { 14832 try { 14833 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14834 } catch (RemoteException e) { 14835 } 14836 // In the protocol here, we don't expect the client to correctly 14837 // clean up this connection, we'll just remove it. 14838 cpr.connections.remove(i); 14839 if (conn.client.conProviders.remove(conn)) { 14840 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14841 } 14842 } 14843 } 14844 14845 if (inLaunching && always) { 14846 mLaunchingProviders.remove(cpr); 14847 } 14848 return inLaunching; 14849 } 14850 14851 /** 14852 * Main code for cleaning up a process when it has gone away. This is 14853 * called both as a result of the process dying, or directly when stopping 14854 * a process when running in single process mode. 14855 * 14856 * @return Returns true if the given process has been restarted, so the 14857 * app that was passed in must remain on the process lists. 14858 */ 14859 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14860 boolean restarting, boolean allowRestart, int index) { 14861 if (index >= 0) { 14862 removeLruProcessLocked(app); 14863 ProcessList.remove(app.pid); 14864 } 14865 14866 mProcessesToGc.remove(app); 14867 mPendingPssProcesses.remove(app); 14868 14869 // Dismiss any open dialogs. 14870 if (app.crashDialog != null && !app.forceCrashReport) { 14871 app.crashDialog.dismiss(); 14872 app.crashDialog = null; 14873 } 14874 if (app.anrDialog != null) { 14875 app.anrDialog.dismiss(); 14876 app.anrDialog = null; 14877 } 14878 if (app.waitDialog != null) { 14879 app.waitDialog.dismiss(); 14880 app.waitDialog = null; 14881 } 14882 14883 app.crashing = false; 14884 app.notResponding = false; 14885 14886 app.resetPackageList(mProcessStats); 14887 app.unlinkDeathRecipient(); 14888 app.makeInactive(mProcessStats); 14889 app.waitingToKill = null; 14890 app.forcingToForeground = null; 14891 updateProcessForegroundLocked(app, false, false); 14892 app.foregroundActivities = false; 14893 app.hasShownUi = false; 14894 app.treatLikeActivity = false; 14895 app.hasAboveClient = false; 14896 app.hasClientActivities = false; 14897 14898 mServices.killServicesLocked(app, allowRestart); 14899 14900 boolean restart = false; 14901 14902 // Remove published content providers. 14903 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14904 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14905 final boolean always = app.bad || !allowRestart; 14906 if (removeDyingProviderLocked(app, cpr, always) || always) { 14907 // We left the provider in the launching list, need to 14908 // restart it. 14909 restart = true; 14910 } 14911 14912 cpr.provider = null; 14913 cpr.proc = null; 14914 } 14915 app.pubProviders.clear(); 14916 14917 // Take care of any launching providers waiting for this process. 14918 if (checkAppInLaunchingProvidersLocked(app, false)) { 14919 restart = true; 14920 } 14921 14922 // Unregister from connected content providers. 14923 if (!app.conProviders.isEmpty()) { 14924 for (int i=0; i<app.conProviders.size(); i++) { 14925 ContentProviderConnection conn = app.conProviders.get(i); 14926 conn.provider.connections.remove(conn); 14927 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14928 conn.provider.name); 14929 } 14930 app.conProviders.clear(); 14931 } 14932 14933 // At this point there may be remaining entries in mLaunchingProviders 14934 // where we were the only one waiting, so they are no longer of use. 14935 // Look for these and clean up if found. 14936 // XXX Commented out for now. Trying to figure out a way to reproduce 14937 // the actual situation to identify what is actually going on. 14938 if (false) { 14939 for (int i=0; i<mLaunchingProviders.size(); i++) { 14940 ContentProviderRecord cpr = (ContentProviderRecord) 14941 mLaunchingProviders.get(i); 14942 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14943 synchronized (cpr) { 14944 cpr.launchingApp = null; 14945 cpr.notifyAll(); 14946 } 14947 } 14948 } 14949 } 14950 14951 skipCurrentReceiverLocked(app); 14952 14953 // Unregister any receivers. 14954 for (int i=app.receivers.size()-1; i>=0; i--) { 14955 removeReceiverLocked(app.receivers.valueAt(i)); 14956 } 14957 app.receivers.clear(); 14958 14959 // If the app is undergoing backup, tell the backup manager about it 14960 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14961 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14962 + mBackupTarget.appInfo + " died during backup"); 14963 try { 14964 IBackupManager bm = IBackupManager.Stub.asInterface( 14965 ServiceManager.getService(Context.BACKUP_SERVICE)); 14966 bm.agentDisconnected(app.info.packageName); 14967 } catch (RemoteException e) { 14968 // can't happen; backup manager is local 14969 } 14970 } 14971 14972 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14973 ProcessChangeItem item = mPendingProcessChanges.get(i); 14974 if (item.pid == app.pid) { 14975 mPendingProcessChanges.remove(i); 14976 mAvailProcessChanges.add(item); 14977 } 14978 } 14979 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14980 14981 // If the caller is restarting this app, then leave it in its 14982 // current lists and let the caller take care of it. 14983 if (restarting) { 14984 return false; 14985 } 14986 14987 if (!app.persistent || app.isolated) { 14988 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14989 "Removing non-persistent process during cleanup: " + app); 14990 mProcessNames.remove(app.processName, app.uid); 14991 mIsolatedProcesses.remove(app.uid); 14992 if (mHeavyWeightProcess == app) { 14993 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14994 mHeavyWeightProcess.userId, 0)); 14995 mHeavyWeightProcess = null; 14996 } 14997 } else if (!app.removed) { 14998 // This app is persistent, so we need to keep its record around. 14999 // If it is not already on the pending app list, add it there 15000 // and start a new process for it. 15001 if (mPersistentStartingProcesses.indexOf(app) < 0) { 15002 mPersistentStartingProcesses.add(app); 15003 restart = true; 15004 } 15005 } 15006 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15007 "Clean-up removing on hold: " + app); 15008 mProcessesOnHold.remove(app); 15009 15010 if (app == mHomeProcess) { 15011 mHomeProcess = null; 15012 } 15013 if (app == mPreviousProcess) { 15014 mPreviousProcess = null; 15015 } 15016 15017 if (restart && !app.isolated) { 15018 // We have components that still need to be running in the 15019 // process, so re-launch it. 15020 if (index < 0) { 15021 ProcessList.remove(app.pid); 15022 } 15023 mProcessNames.put(app.processName, app.uid, app); 15024 startProcessLocked(app, "restart", app.processName); 15025 return true; 15026 } else if (app.pid > 0 && app.pid != MY_PID) { 15027 // Goodbye! 15028 boolean removed; 15029 synchronized (mPidsSelfLocked) { 15030 mPidsSelfLocked.remove(app.pid); 15031 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15032 } 15033 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15034 if (app.isolated) { 15035 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15036 } 15037 app.setPid(0); 15038 } 15039 return false; 15040 } 15041 15042 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15043 // Look through the content providers we are waiting to have launched, 15044 // and if any run in this process then either schedule a restart of 15045 // the process or kill the client waiting for it if this process has 15046 // gone bad. 15047 int NL = mLaunchingProviders.size(); 15048 boolean restart = false; 15049 for (int i=0; i<NL; i++) { 15050 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15051 if (cpr.launchingApp == app) { 15052 if (!alwaysBad && !app.bad) { 15053 restart = true; 15054 } else { 15055 removeDyingProviderLocked(app, cpr, true); 15056 // cpr should have been removed from mLaunchingProviders 15057 NL = mLaunchingProviders.size(); 15058 i--; 15059 } 15060 } 15061 } 15062 return restart; 15063 } 15064 15065 // ========================================================= 15066 // SERVICES 15067 // ========================================================= 15068 15069 @Override 15070 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15071 int flags) { 15072 enforceNotIsolatedCaller("getServices"); 15073 synchronized (this) { 15074 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15075 } 15076 } 15077 15078 @Override 15079 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15080 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15081 synchronized (this) { 15082 return mServices.getRunningServiceControlPanelLocked(name); 15083 } 15084 } 15085 15086 @Override 15087 public ComponentName startService(IApplicationThread caller, Intent service, 15088 String resolvedType, int userId) { 15089 enforceNotIsolatedCaller("startService"); 15090 // Refuse possible leaked file descriptors 15091 if (service != null && service.hasFileDescriptors() == true) { 15092 throw new IllegalArgumentException("File descriptors passed in Intent"); 15093 } 15094 15095 if (DEBUG_SERVICE) 15096 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15097 synchronized(this) { 15098 final int callingPid = Binder.getCallingPid(); 15099 final int callingUid = Binder.getCallingUid(); 15100 final long origId = Binder.clearCallingIdentity(); 15101 ComponentName res = mServices.startServiceLocked(caller, service, 15102 resolvedType, callingPid, callingUid, userId); 15103 Binder.restoreCallingIdentity(origId); 15104 return res; 15105 } 15106 } 15107 15108 ComponentName startServiceInPackage(int uid, 15109 Intent service, String resolvedType, int userId) { 15110 synchronized(this) { 15111 if (DEBUG_SERVICE) 15112 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15113 final long origId = Binder.clearCallingIdentity(); 15114 ComponentName res = mServices.startServiceLocked(null, service, 15115 resolvedType, -1, uid, userId); 15116 Binder.restoreCallingIdentity(origId); 15117 return res; 15118 } 15119 } 15120 15121 @Override 15122 public int stopService(IApplicationThread caller, Intent service, 15123 String resolvedType, int userId) { 15124 enforceNotIsolatedCaller("stopService"); 15125 // Refuse possible leaked file descriptors 15126 if (service != null && service.hasFileDescriptors() == true) { 15127 throw new IllegalArgumentException("File descriptors passed in Intent"); 15128 } 15129 15130 synchronized(this) { 15131 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15132 } 15133 } 15134 15135 @Override 15136 public IBinder peekService(Intent service, String resolvedType) { 15137 enforceNotIsolatedCaller("peekService"); 15138 // Refuse possible leaked file descriptors 15139 if (service != null && service.hasFileDescriptors() == true) { 15140 throw new IllegalArgumentException("File descriptors passed in Intent"); 15141 } 15142 synchronized(this) { 15143 return mServices.peekServiceLocked(service, resolvedType); 15144 } 15145 } 15146 15147 @Override 15148 public boolean stopServiceToken(ComponentName className, IBinder token, 15149 int startId) { 15150 synchronized(this) { 15151 return mServices.stopServiceTokenLocked(className, token, startId); 15152 } 15153 } 15154 15155 @Override 15156 public void setServiceForeground(ComponentName className, IBinder token, 15157 int id, Notification notification, boolean removeNotification) { 15158 synchronized(this) { 15159 mServices.setServiceForegroundLocked(className, token, id, notification, 15160 removeNotification); 15161 } 15162 } 15163 15164 @Override 15165 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15166 boolean requireFull, String name, String callerPackage) { 15167 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15168 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15169 } 15170 15171 int unsafeConvertIncomingUser(int userId) { 15172 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15173 ? mCurrentUserId : userId; 15174 } 15175 15176 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15177 int allowMode, String name, String callerPackage) { 15178 final int callingUserId = UserHandle.getUserId(callingUid); 15179 if (callingUserId == userId) { 15180 return userId; 15181 } 15182 15183 // Note that we may be accessing mCurrentUserId outside of a lock... 15184 // shouldn't be a big deal, if this is being called outside 15185 // of a locked context there is intrinsically a race with 15186 // the value the caller will receive and someone else changing it. 15187 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15188 // we will switch to the calling user if access to the current user fails. 15189 int targetUserId = unsafeConvertIncomingUser(userId); 15190 15191 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15192 final boolean allow; 15193 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15194 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15195 // If the caller has this permission, they always pass go. And collect $200. 15196 allow = true; 15197 } else if (allowMode == ALLOW_FULL_ONLY) { 15198 // We require full access, sucks to be you. 15199 allow = false; 15200 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15201 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15202 // If the caller does not have either permission, they are always doomed. 15203 allow = false; 15204 } else if (allowMode == ALLOW_NON_FULL) { 15205 // We are blanket allowing non-full access, you lucky caller! 15206 allow = true; 15207 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15208 // We may or may not allow this depending on whether the two users are 15209 // in the same profile. 15210 synchronized (mUserProfileGroupIdsSelfLocked) { 15211 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15212 UserInfo.NO_PROFILE_GROUP_ID); 15213 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15214 UserInfo.NO_PROFILE_GROUP_ID); 15215 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15216 && callingProfile == targetProfile; 15217 } 15218 } else { 15219 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15220 } 15221 if (!allow) { 15222 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15223 // In this case, they would like to just execute as their 15224 // owner user instead of failing. 15225 targetUserId = callingUserId; 15226 } else { 15227 StringBuilder builder = new StringBuilder(128); 15228 builder.append("Permission Denial: "); 15229 builder.append(name); 15230 if (callerPackage != null) { 15231 builder.append(" from "); 15232 builder.append(callerPackage); 15233 } 15234 builder.append(" asks to run as user "); 15235 builder.append(userId); 15236 builder.append(" but is calling from user "); 15237 builder.append(UserHandle.getUserId(callingUid)); 15238 builder.append("; this requires "); 15239 builder.append(INTERACT_ACROSS_USERS_FULL); 15240 if (allowMode != ALLOW_FULL_ONLY) { 15241 builder.append(" or "); 15242 builder.append(INTERACT_ACROSS_USERS); 15243 } 15244 String msg = builder.toString(); 15245 Slog.w(TAG, msg); 15246 throw new SecurityException(msg); 15247 } 15248 } 15249 } 15250 if (!allowAll && targetUserId < 0) { 15251 throw new IllegalArgumentException( 15252 "Call does not support special user #" + targetUserId); 15253 } 15254 // Check shell permission 15255 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15256 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15257 targetUserId)) { 15258 throw new SecurityException("Shell does not have permission to access user " 15259 + targetUserId + "\n " + Debug.getCallers(3)); 15260 } 15261 } 15262 return targetUserId; 15263 } 15264 15265 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15266 String className, int flags) { 15267 boolean result = false; 15268 // For apps that don't have pre-defined UIDs, check for permission 15269 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15270 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15271 if (ActivityManager.checkUidPermission( 15272 INTERACT_ACROSS_USERS, 15273 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15274 ComponentName comp = new ComponentName(aInfo.packageName, className); 15275 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15276 + " requests FLAG_SINGLE_USER, but app does not hold " 15277 + INTERACT_ACROSS_USERS; 15278 Slog.w(TAG, msg); 15279 throw new SecurityException(msg); 15280 } 15281 // Permission passed 15282 result = true; 15283 } 15284 } else if ("system".equals(componentProcessName)) { 15285 result = true; 15286 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15287 // Phone app and persistent apps are allowed to export singleuser providers. 15288 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15289 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15290 } 15291 if (DEBUG_MU) { 15292 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15293 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15294 } 15295 return result; 15296 } 15297 15298 /** 15299 * Checks to see if the caller is in the same app as the singleton 15300 * component, or the component is in a special app. It allows special apps 15301 * to export singleton components but prevents exporting singleton 15302 * components for regular apps. 15303 */ 15304 boolean isValidSingletonCall(int callingUid, int componentUid) { 15305 int componentAppId = UserHandle.getAppId(componentUid); 15306 return UserHandle.isSameApp(callingUid, componentUid) 15307 || componentAppId == Process.SYSTEM_UID 15308 || componentAppId == Process.PHONE_UID 15309 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15310 == PackageManager.PERMISSION_GRANTED; 15311 } 15312 15313 public int bindService(IApplicationThread caller, IBinder token, 15314 Intent service, String resolvedType, 15315 IServiceConnection connection, int flags, int userId) { 15316 enforceNotIsolatedCaller("bindService"); 15317 15318 // Refuse possible leaked file descriptors 15319 if (service != null && service.hasFileDescriptors() == true) { 15320 throw new IllegalArgumentException("File descriptors passed in Intent"); 15321 } 15322 15323 synchronized(this) { 15324 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15325 connection, flags, userId); 15326 } 15327 } 15328 15329 public boolean unbindService(IServiceConnection connection) { 15330 synchronized (this) { 15331 return mServices.unbindServiceLocked(connection); 15332 } 15333 } 15334 15335 public void publishService(IBinder token, Intent intent, IBinder service) { 15336 // Refuse possible leaked file descriptors 15337 if (intent != null && intent.hasFileDescriptors() == true) { 15338 throw new IllegalArgumentException("File descriptors passed in Intent"); 15339 } 15340 15341 synchronized(this) { 15342 if (!(token instanceof ServiceRecord)) { 15343 throw new IllegalArgumentException("Invalid service token"); 15344 } 15345 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15346 } 15347 } 15348 15349 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15350 // Refuse possible leaked file descriptors 15351 if (intent != null && intent.hasFileDescriptors() == true) { 15352 throw new IllegalArgumentException("File descriptors passed in Intent"); 15353 } 15354 15355 synchronized(this) { 15356 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15357 } 15358 } 15359 15360 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15361 synchronized(this) { 15362 if (!(token instanceof ServiceRecord)) { 15363 throw new IllegalArgumentException("Invalid service token"); 15364 } 15365 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15366 } 15367 } 15368 15369 // ========================================================= 15370 // BACKUP AND RESTORE 15371 // ========================================================= 15372 15373 // Cause the target app to be launched if necessary and its backup agent 15374 // instantiated. The backup agent will invoke backupAgentCreated() on the 15375 // activity manager to announce its creation. 15376 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15377 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15378 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15379 15380 synchronized(this) { 15381 // !!! TODO: currently no check here that we're already bound 15382 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15383 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15384 synchronized (stats) { 15385 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15386 } 15387 15388 // Backup agent is now in use, its package can't be stopped. 15389 try { 15390 AppGlobals.getPackageManager().setPackageStoppedState( 15391 app.packageName, false, UserHandle.getUserId(app.uid)); 15392 } catch (RemoteException e) { 15393 } catch (IllegalArgumentException e) { 15394 Slog.w(TAG, "Failed trying to unstop package " 15395 + app.packageName + ": " + e); 15396 } 15397 15398 BackupRecord r = new BackupRecord(ss, app, backupMode); 15399 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15400 ? new ComponentName(app.packageName, app.backupAgentName) 15401 : new ComponentName("android", "FullBackupAgent"); 15402 // startProcessLocked() returns existing proc's record if it's already running 15403 ProcessRecord proc = startProcessLocked(app.processName, app, 15404 false, 0, "backup", hostingName, false, false, false); 15405 if (proc == null) { 15406 Slog.e(TAG, "Unable to start backup agent process " + r); 15407 return false; 15408 } 15409 15410 r.app = proc; 15411 mBackupTarget = r; 15412 mBackupAppName = app.packageName; 15413 15414 // Try not to kill the process during backup 15415 updateOomAdjLocked(proc); 15416 15417 // If the process is already attached, schedule the creation of the backup agent now. 15418 // If it is not yet live, this will be done when it attaches to the framework. 15419 if (proc.thread != null) { 15420 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15421 try { 15422 proc.thread.scheduleCreateBackupAgent(app, 15423 compatibilityInfoForPackageLocked(app), backupMode); 15424 } catch (RemoteException e) { 15425 // Will time out on the backup manager side 15426 } 15427 } else { 15428 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15429 } 15430 // Invariants: at this point, the target app process exists and the application 15431 // is either already running or in the process of coming up. mBackupTarget and 15432 // mBackupAppName describe the app, so that when it binds back to the AM we 15433 // know that it's scheduled for a backup-agent operation. 15434 } 15435 15436 return true; 15437 } 15438 15439 @Override 15440 public void clearPendingBackup() { 15441 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15442 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15443 15444 synchronized (this) { 15445 mBackupTarget = null; 15446 mBackupAppName = null; 15447 } 15448 } 15449 15450 // A backup agent has just come up 15451 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15452 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15453 + " = " + agent); 15454 15455 synchronized(this) { 15456 if (!agentPackageName.equals(mBackupAppName)) { 15457 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15458 return; 15459 } 15460 } 15461 15462 long oldIdent = Binder.clearCallingIdentity(); 15463 try { 15464 IBackupManager bm = IBackupManager.Stub.asInterface( 15465 ServiceManager.getService(Context.BACKUP_SERVICE)); 15466 bm.agentConnected(agentPackageName, agent); 15467 } catch (RemoteException e) { 15468 // can't happen; the backup manager service is local 15469 } catch (Exception e) { 15470 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15471 e.printStackTrace(); 15472 } finally { 15473 Binder.restoreCallingIdentity(oldIdent); 15474 } 15475 } 15476 15477 // done with this agent 15478 public void unbindBackupAgent(ApplicationInfo appInfo) { 15479 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15480 if (appInfo == null) { 15481 Slog.w(TAG, "unbind backup agent for null app"); 15482 return; 15483 } 15484 15485 synchronized(this) { 15486 try { 15487 if (mBackupAppName == null) { 15488 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15489 return; 15490 } 15491 15492 if (!mBackupAppName.equals(appInfo.packageName)) { 15493 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15494 return; 15495 } 15496 15497 // Not backing this app up any more; reset its OOM adjustment 15498 final ProcessRecord proc = mBackupTarget.app; 15499 updateOomAdjLocked(proc); 15500 15501 // If the app crashed during backup, 'thread' will be null here 15502 if (proc.thread != null) { 15503 try { 15504 proc.thread.scheduleDestroyBackupAgent(appInfo, 15505 compatibilityInfoForPackageLocked(appInfo)); 15506 } catch (Exception e) { 15507 Slog.e(TAG, "Exception when unbinding backup agent:"); 15508 e.printStackTrace(); 15509 } 15510 } 15511 } finally { 15512 mBackupTarget = null; 15513 mBackupAppName = null; 15514 } 15515 } 15516 } 15517 // ========================================================= 15518 // BROADCASTS 15519 // ========================================================= 15520 15521 private final List getStickiesLocked(String action, IntentFilter filter, 15522 List cur, int userId) { 15523 final ContentResolver resolver = mContext.getContentResolver(); 15524 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15525 if (stickies == null) { 15526 return cur; 15527 } 15528 final ArrayList<Intent> list = stickies.get(action); 15529 if (list == null) { 15530 return cur; 15531 } 15532 int N = list.size(); 15533 for (int i=0; i<N; i++) { 15534 Intent intent = list.get(i); 15535 if (filter.match(resolver, intent, true, TAG) >= 0) { 15536 if (cur == null) { 15537 cur = new ArrayList<Intent>(); 15538 } 15539 cur.add(intent); 15540 } 15541 } 15542 return cur; 15543 } 15544 15545 boolean isPendingBroadcastProcessLocked(int pid) { 15546 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15547 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15548 } 15549 15550 void skipPendingBroadcastLocked(int pid) { 15551 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15552 for (BroadcastQueue queue : mBroadcastQueues) { 15553 queue.skipPendingBroadcastLocked(pid); 15554 } 15555 } 15556 15557 // The app just attached; send any pending broadcasts that it should receive 15558 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15559 boolean didSomething = false; 15560 for (BroadcastQueue queue : mBroadcastQueues) { 15561 didSomething |= queue.sendPendingBroadcastsLocked(app); 15562 } 15563 return didSomething; 15564 } 15565 15566 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15567 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15568 enforceNotIsolatedCaller("registerReceiver"); 15569 int callingUid; 15570 int callingPid; 15571 synchronized(this) { 15572 ProcessRecord callerApp = null; 15573 if (caller != null) { 15574 callerApp = getRecordForAppLocked(caller); 15575 if (callerApp == null) { 15576 throw new SecurityException( 15577 "Unable to find app for caller " + caller 15578 + " (pid=" + Binder.getCallingPid() 15579 + ") when registering receiver " + receiver); 15580 } 15581 if (callerApp.info.uid != Process.SYSTEM_UID && 15582 !callerApp.pkgList.containsKey(callerPackage) && 15583 !"android".equals(callerPackage)) { 15584 throw new SecurityException("Given caller package " + callerPackage 15585 + " is not running in process " + callerApp); 15586 } 15587 callingUid = callerApp.info.uid; 15588 callingPid = callerApp.pid; 15589 } else { 15590 callerPackage = null; 15591 callingUid = Binder.getCallingUid(); 15592 callingPid = Binder.getCallingPid(); 15593 } 15594 15595 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15596 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15597 15598 List allSticky = null; 15599 15600 // Look for any matching sticky broadcasts... 15601 Iterator actions = filter.actionsIterator(); 15602 if (actions != null) { 15603 while (actions.hasNext()) { 15604 String action = (String)actions.next(); 15605 allSticky = getStickiesLocked(action, filter, allSticky, 15606 UserHandle.USER_ALL); 15607 allSticky = getStickiesLocked(action, filter, allSticky, 15608 UserHandle.getUserId(callingUid)); 15609 } 15610 } else { 15611 allSticky = getStickiesLocked(null, filter, allSticky, 15612 UserHandle.USER_ALL); 15613 allSticky = getStickiesLocked(null, filter, allSticky, 15614 UserHandle.getUserId(callingUid)); 15615 } 15616 15617 // The first sticky in the list is returned directly back to 15618 // the client. 15619 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15620 15621 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15622 + ": " + sticky); 15623 15624 if (receiver == null) { 15625 return sticky; 15626 } 15627 15628 ReceiverList rl 15629 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15630 if (rl == null) { 15631 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15632 userId, receiver); 15633 if (rl.app != null) { 15634 rl.app.receivers.add(rl); 15635 } else { 15636 try { 15637 receiver.asBinder().linkToDeath(rl, 0); 15638 } catch (RemoteException e) { 15639 return sticky; 15640 } 15641 rl.linkedToDeath = true; 15642 } 15643 mRegisteredReceivers.put(receiver.asBinder(), rl); 15644 } else if (rl.uid != callingUid) { 15645 throw new IllegalArgumentException( 15646 "Receiver requested to register for uid " + callingUid 15647 + " was previously registered for uid " + rl.uid); 15648 } else if (rl.pid != callingPid) { 15649 throw new IllegalArgumentException( 15650 "Receiver requested to register for pid " + callingPid 15651 + " was previously registered for pid " + rl.pid); 15652 } else if (rl.userId != userId) { 15653 throw new IllegalArgumentException( 15654 "Receiver requested to register for user " + userId 15655 + " was previously registered for user " + rl.userId); 15656 } 15657 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15658 permission, callingUid, userId); 15659 rl.add(bf); 15660 if (!bf.debugCheck()) { 15661 Slog.w(TAG, "==> For Dynamic broadast"); 15662 } 15663 mReceiverResolver.addFilter(bf); 15664 15665 // Enqueue broadcasts for all existing stickies that match 15666 // this filter. 15667 if (allSticky != null) { 15668 ArrayList receivers = new ArrayList(); 15669 receivers.add(bf); 15670 15671 int N = allSticky.size(); 15672 for (int i=0; i<N; i++) { 15673 Intent intent = (Intent)allSticky.get(i); 15674 BroadcastQueue queue = broadcastQueueForIntent(intent); 15675 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15676 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15677 null, null, false, true, true, -1); 15678 queue.enqueueParallelBroadcastLocked(r); 15679 queue.scheduleBroadcastsLocked(); 15680 } 15681 } 15682 15683 return sticky; 15684 } 15685 } 15686 15687 public void unregisterReceiver(IIntentReceiver receiver) { 15688 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15689 15690 final long origId = Binder.clearCallingIdentity(); 15691 try { 15692 boolean doTrim = false; 15693 15694 synchronized(this) { 15695 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15696 if (rl != null) { 15697 if (rl.curBroadcast != null) { 15698 BroadcastRecord r = rl.curBroadcast; 15699 final boolean doNext = finishReceiverLocked( 15700 receiver.asBinder(), r.resultCode, r.resultData, 15701 r.resultExtras, r.resultAbort); 15702 if (doNext) { 15703 doTrim = true; 15704 r.queue.processNextBroadcast(false); 15705 } 15706 } 15707 15708 if (rl.app != null) { 15709 rl.app.receivers.remove(rl); 15710 } 15711 removeReceiverLocked(rl); 15712 if (rl.linkedToDeath) { 15713 rl.linkedToDeath = false; 15714 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15715 } 15716 } 15717 } 15718 15719 // If we actually concluded any broadcasts, we might now be able 15720 // to trim the recipients' apps from our working set 15721 if (doTrim) { 15722 trimApplications(); 15723 return; 15724 } 15725 15726 } finally { 15727 Binder.restoreCallingIdentity(origId); 15728 } 15729 } 15730 15731 void removeReceiverLocked(ReceiverList rl) { 15732 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15733 int N = rl.size(); 15734 for (int i=0; i<N; i++) { 15735 mReceiverResolver.removeFilter(rl.get(i)); 15736 } 15737 } 15738 15739 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15740 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15741 ProcessRecord r = mLruProcesses.get(i); 15742 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15743 try { 15744 r.thread.dispatchPackageBroadcast(cmd, packages); 15745 } catch (RemoteException ex) { 15746 } 15747 } 15748 } 15749 } 15750 15751 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15752 int callingUid, int[] users) { 15753 List<ResolveInfo> receivers = null; 15754 try { 15755 HashSet<ComponentName> singleUserReceivers = null; 15756 boolean scannedFirstReceivers = false; 15757 for (int user : users) { 15758 // Skip users that have Shell restrictions 15759 if (callingUid == Process.SHELL_UID 15760 && getUserManagerLocked().hasUserRestriction( 15761 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15762 continue; 15763 } 15764 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15765 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15766 if (user != 0 && newReceivers != null) { 15767 // If this is not the primary user, we need to check for 15768 // any receivers that should be filtered out. 15769 for (int i=0; i<newReceivers.size(); i++) { 15770 ResolveInfo ri = newReceivers.get(i); 15771 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15772 newReceivers.remove(i); 15773 i--; 15774 } 15775 } 15776 } 15777 if (newReceivers != null && newReceivers.size() == 0) { 15778 newReceivers = null; 15779 } 15780 if (receivers == null) { 15781 receivers = newReceivers; 15782 } else if (newReceivers != null) { 15783 // We need to concatenate the additional receivers 15784 // found with what we have do far. This would be easy, 15785 // but we also need to de-dup any receivers that are 15786 // singleUser. 15787 if (!scannedFirstReceivers) { 15788 // Collect any single user receivers we had already retrieved. 15789 scannedFirstReceivers = true; 15790 for (int i=0; i<receivers.size(); i++) { 15791 ResolveInfo ri = receivers.get(i); 15792 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15793 ComponentName cn = new ComponentName( 15794 ri.activityInfo.packageName, ri.activityInfo.name); 15795 if (singleUserReceivers == null) { 15796 singleUserReceivers = new HashSet<ComponentName>(); 15797 } 15798 singleUserReceivers.add(cn); 15799 } 15800 } 15801 } 15802 // Add the new results to the existing results, tracking 15803 // and de-dupping single user receivers. 15804 for (int i=0; i<newReceivers.size(); i++) { 15805 ResolveInfo ri = newReceivers.get(i); 15806 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15807 ComponentName cn = new ComponentName( 15808 ri.activityInfo.packageName, ri.activityInfo.name); 15809 if (singleUserReceivers == null) { 15810 singleUserReceivers = new HashSet<ComponentName>(); 15811 } 15812 if (!singleUserReceivers.contains(cn)) { 15813 singleUserReceivers.add(cn); 15814 receivers.add(ri); 15815 } 15816 } else { 15817 receivers.add(ri); 15818 } 15819 } 15820 } 15821 } 15822 } catch (RemoteException ex) { 15823 // pm is in same process, this will never happen. 15824 } 15825 return receivers; 15826 } 15827 15828 private final int broadcastIntentLocked(ProcessRecord callerApp, 15829 String callerPackage, Intent intent, String resolvedType, 15830 IIntentReceiver resultTo, int resultCode, String resultData, 15831 Bundle map, String requiredPermission, int appOp, 15832 boolean ordered, boolean sticky, int callingPid, int callingUid, 15833 int userId) { 15834 intent = new Intent(intent); 15835 15836 // By default broadcasts do not go to stopped apps. 15837 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15838 15839 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15840 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15841 + " ordered=" + ordered + " userid=" + userId); 15842 if ((resultTo != null) && !ordered) { 15843 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15844 } 15845 15846 userId = handleIncomingUser(callingPid, callingUid, userId, 15847 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15848 15849 // Make sure that the user who is receiving this broadcast is running. 15850 // If not, we will just skip it. Make an exception for shutdown broadcasts 15851 // and upgrade steps. 15852 15853 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15854 if ((callingUid != Process.SYSTEM_UID 15855 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15856 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15857 Slog.w(TAG, "Skipping broadcast of " + intent 15858 + ": user " + userId + " is stopped"); 15859 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15860 } 15861 } 15862 15863 /* 15864 * Prevent non-system code (defined here to be non-persistent 15865 * processes) from sending protected broadcasts. 15866 */ 15867 int callingAppId = UserHandle.getAppId(callingUid); 15868 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15869 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15870 || callingAppId == Process.NFC_UID || callingUid == 0) { 15871 // Always okay. 15872 } else if (callerApp == null || !callerApp.persistent) { 15873 try { 15874 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15875 intent.getAction())) { 15876 String msg = "Permission Denial: not allowed to send broadcast " 15877 + intent.getAction() + " from pid=" 15878 + callingPid + ", uid=" + callingUid; 15879 Slog.w(TAG, msg); 15880 throw new SecurityException(msg); 15881 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15882 // Special case for compatibility: we don't want apps to send this, 15883 // but historically it has not been protected and apps may be using it 15884 // to poke their own app widget. So, instead of making it protected, 15885 // just limit it to the caller. 15886 if (callerApp == null) { 15887 String msg = "Permission Denial: not allowed to send broadcast " 15888 + intent.getAction() + " from unknown caller."; 15889 Slog.w(TAG, msg); 15890 throw new SecurityException(msg); 15891 } else if (intent.getComponent() != null) { 15892 // They are good enough to send to an explicit component... verify 15893 // it is being sent to the calling app. 15894 if (!intent.getComponent().getPackageName().equals( 15895 callerApp.info.packageName)) { 15896 String msg = "Permission Denial: not allowed to send broadcast " 15897 + intent.getAction() + " to " 15898 + intent.getComponent().getPackageName() + " from " 15899 + callerApp.info.packageName; 15900 Slog.w(TAG, msg); 15901 throw new SecurityException(msg); 15902 } 15903 } else { 15904 // Limit broadcast to their own package. 15905 intent.setPackage(callerApp.info.packageName); 15906 } 15907 } 15908 } catch (RemoteException e) { 15909 Slog.w(TAG, "Remote exception", e); 15910 return ActivityManager.BROADCAST_SUCCESS; 15911 } 15912 } 15913 15914 final String action = intent.getAction(); 15915 if (action != null) { 15916 switch (action) { 15917 case Intent.ACTION_UID_REMOVED: 15918 case Intent.ACTION_PACKAGE_REMOVED: 15919 case Intent.ACTION_PACKAGE_CHANGED: 15920 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15921 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15922 // Handle special intents: if this broadcast is from the package 15923 // manager about a package being removed, we need to remove all of 15924 // its activities from the history stack. 15925 if (checkComponentPermission( 15926 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15927 callingPid, callingUid, -1, true) 15928 != PackageManager.PERMISSION_GRANTED) { 15929 String msg = "Permission Denial: " + intent.getAction() 15930 + " broadcast from " + callerPackage + " (pid=" + callingPid 15931 + ", uid=" + callingUid + ")" 15932 + " requires " 15933 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15934 Slog.w(TAG, msg); 15935 throw new SecurityException(msg); 15936 } 15937 switch (action) { 15938 case Intent.ACTION_UID_REMOVED: 15939 final Bundle intentExtras = intent.getExtras(); 15940 final int uid = intentExtras != null 15941 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15942 if (uid >= 0) { 15943 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15944 synchronized (bs) { 15945 bs.removeUidStatsLocked(uid); 15946 } 15947 mAppOpsService.uidRemoved(uid); 15948 } 15949 break; 15950 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15951 // If resources are unavailable just force stop all those packages 15952 // and flush the attribute cache as well. 15953 String list[] = 15954 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15955 if (list != null && list.length > 0) { 15956 for (int i = 0; i < list.length; i++) { 15957 forceStopPackageLocked(list[i], -1, false, true, true, 15958 false, false, userId, "storage unmount"); 15959 } 15960 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15961 sendPackageBroadcastLocked( 15962 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15963 userId); 15964 } 15965 break; 15966 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15967 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15968 break; 15969 case Intent.ACTION_PACKAGE_REMOVED: 15970 case Intent.ACTION_PACKAGE_CHANGED: 15971 Uri data = intent.getData(); 15972 String ssp; 15973 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15974 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15975 boolean fullUninstall = removed && 15976 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15977 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15978 forceStopPackageLocked(ssp, UserHandle.getAppId( 15979 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15980 false, true, true, false, fullUninstall, userId, 15981 removed ? "pkg removed" : "pkg changed"); 15982 } 15983 if (removed) { 15984 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15985 new String[] {ssp}, userId); 15986 if (fullUninstall) { 15987 mAppOpsService.packageRemoved( 15988 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15989 15990 // Remove all permissions granted from/to this package 15991 removeUriPermissionsForPackageLocked(ssp, userId, true); 15992 15993 removeTasksByPackageNameLocked(ssp, userId); 15994 } 15995 } else { 15996 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15997 if (userId == UserHandle.USER_OWNER) { 15998 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15999 } 16000 } 16001 } 16002 break; 16003 } 16004 break; 16005 case Intent.ACTION_PACKAGE_ADDED: 16006 // Special case for adding a package: by default turn on compatibility mode. 16007 Uri data = intent.getData(); 16008 String ssp; 16009 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16010 final boolean replacing = 16011 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16012 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16013 16014 if (replacing) { 16015 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16016 } 16017 if (userId == UserHandle.USER_OWNER) { 16018 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16019 } 16020 } 16021 break; 16022 case Intent.ACTION_TIMEZONE_CHANGED: 16023 // If this is the time zone changed action, queue up a message that will reset 16024 // the timezone of all currently running processes. This message will get 16025 // queued up before the broadcast happens. 16026 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16027 break; 16028 case Intent.ACTION_TIME_CHANGED: 16029 // If the user set the time, let all running processes know. 16030 final int is24Hour = 16031 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16032 : 0; 16033 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16034 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16035 synchronized (stats) { 16036 stats.noteCurrentTimeChangedLocked(); 16037 } 16038 break; 16039 case Intent.ACTION_CLEAR_DNS_CACHE: 16040 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16041 break; 16042 case Proxy.PROXY_CHANGE_ACTION: 16043 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16044 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16045 break; 16046 } 16047 } 16048 16049 // Add to the sticky list if requested. 16050 if (sticky) { 16051 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16052 callingPid, callingUid) 16053 != PackageManager.PERMISSION_GRANTED) { 16054 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16055 + callingPid + ", uid=" + callingUid 16056 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16057 Slog.w(TAG, msg); 16058 throw new SecurityException(msg); 16059 } 16060 if (requiredPermission != null) { 16061 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16062 + " and enforce permission " + requiredPermission); 16063 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16064 } 16065 if (intent.getComponent() != null) { 16066 throw new SecurityException( 16067 "Sticky broadcasts can't target a specific component"); 16068 } 16069 // We use userId directly here, since the "all" target is maintained 16070 // as a separate set of sticky broadcasts. 16071 if (userId != UserHandle.USER_ALL) { 16072 // But first, if this is not a broadcast to all users, then 16073 // make sure it doesn't conflict with an existing broadcast to 16074 // all users. 16075 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16076 UserHandle.USER_ALL); 16077 if (stickies != null) { 16078 ArrayList<Intent> list = stickies.get(intent.getAction()); 16079 if (list != null) { 16080 int N = list.size(); 16081 int i; 16082 for (i=0; i<N; i++) { 16083 if (intent.filterEquals(list.get(i))) { 16084 throw new IllegalArgumentException( 16085 "Sticky broadcast " + intent + " for user " 16086 + userId + " conflicts with existing global broadcast"); 16087 } 16088 } 16089 } 16090 } 16091 } 16092 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16093 if (stickies == null) { 16094 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16095 mStickyBroadcasts.put(userId, stickies); 16096 } 16097 ArrayList<Intent> list = stickies.get(intent.getAction()); 16098 if (list == null) { 16099 list = new ArrayList<Intent>(); 16100 stickies.put(intent.getAction(), list); 16101 } 16102 int N = list.size(); 16103 int i; 16104 for (i=0; i<N; i++) { 16105 if (intent.filterEquals(list.get(i))) { 16106 // This sticky already exists, replace it. 16107 list.set(i, new Intent(intent)); 16108 break; 16109 } 16110 } 16111 if (i >= N) { 16112 list.add(new Intent(intent)); 16113 } 16114 } 16115 16116 int[] users; 16117 if (userId == UserHandle.USER_ALL) { 16118 // Caller wants broadcast to go to all started users. 16119 users = mStartedUserArray; 16120 } else { 16121 // Caller wants broadcast to go to one specific user. 16122 users = new int[] {userId}; 16123 } 16124 16125 // Figure out who all will receive this broadcast. 16126 List receivers = null; 16127 List<BroadcastFilter> registeredReceivers = null; 16128 // Need to resolve the intent to interested receivers... 16129 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16130 == 0) { 16131 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16132 } 16133 if (intent.getComponent() == null) { 16134 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16135 // Query one target user at a time, excluding shell-restricted users 16136 UserManagerService ums = getUserManagerLocked(); 16137 for (int i = 0; i < users.length; i++) { 16138 if (ums.hasUserRestriction( 16139 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16140 continue; 16141 } 16142 List<BroadcastFilter> registeredReceiversForUser = 16143 mReceiverResolver.queryIntent(intent, 16144 resolvedType, false, users[i]); 16145 if (registeredReceivers == null) { 16146 registeredReceivers = registeredReceiversForUser; 16147 } else if (registeredReceiversForUser != null) { 16148 registeredReceivers.addAll(registeredReceiversForUser); 16149 } 16150 } 16151 } else { 16152 registeredReceivers = mReceiverResolver.queryIntent(intent, 16153 resolvedType, false, userId); 16154 } 16155 } 16156 16157 final boolean replacePending = 16158 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16159 16160 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16161 + " replacePending=" + replacePending); 16162 16163 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16164 if (!ordered && NR > 0) { 16165 // If we are not serializing this broadcast, then send the 16166 // registered receivers separately so they don't wait for the 16167 // components to be launched. 16168 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16169 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16170 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16171 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16172 ordered, sticky, false, userId); 16173 if (DEBUG_BROADCAST) Slog.v( 16174 TAG, "Enqueueing parallel broadcast " + r); 16175 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16176 if (!replaced) { 16177 queue.enqueueParallelBroadcastLocked(r); 16178 queue.scheduleBroadcastsLocked(); 16179 } 16180 registeredReceivers = null; 16181 NR = 0; 16182 } 16183 16184 // Merge into one list. 16185 int ir = 0; 16186 if (receivers != null) { 16187 // A special case for PACKAGE_ADDED: do not allow the package 16188 // being added to see this broadcast. This prevents them from 16189 // using this as a back door to get run as soon as they are 16190 // installed. Maybe in the future we want to have a special install 16191 // broadcast or such for apps, but we'd like to deliberately make 16192 // this decision. 16193 String skipPackages[] = null; 16194 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16195 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16196 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16197 Uri data = intent.getData(); 16198 if (data != null) { 16199 String pkgName = data.getSchemeSpecificPart(); 16200 if (pkgName != null) { 16201 skipPackages = new String[] { pkgName }; 16202 } 16203 } 16204 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16205 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16206 } 16207 if (skipPackages != null && (skipPackages.length > 0)) { 16208 for (String skipPackage : skipPackages) { 16209 if (skipPackage != null) { 16210 int NT = receivers.size(); 16211 for (int it=0; it<NT; it++) { 16212 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16213 if (curt.activityInfo.packageName.equals(skipPackage)) { 16214 receivers.remove(it); 16215 it--; 16216 NT--; 16217 } 16218 } 16219 } 16220 } 16221 } 16222 16223 int NT = receivers != null ? receivers.size() : 0; 16224 int it = 0; 16225 ResolveInfo curt = null; 16226 BroadcastFilter curr = null; 16227 while (it < NT && ir < NR) { 16228 if (curt == null) { 16229 curt = (ResolveInfo)receivers.get(it); 16230 } 16231 if (curr == null) { 16232 curr = registeredReceivers.get(ir); 16233 } 16234 if (curr.getPriority() >= curt.priority) { 16235 // Insert this broadcast record into the final list. 16236 receivers.add(it, curr); 16237 ir++; 16238 curr = null; 16239 it++; 16240 NT++; 16241 } else { 16242 // Skip to the next ResolveInfo in the final list. 16243 it++; 16244 curt = null; 16245 } 16246 } 16247 } 16248 while (ir < NR) { 16249 if (receivers == null) { 16250 receivers = new ArrayList(); 16251 } 16252 receivers.add(registeredReceivers.get(ir)); 16253 ir++; 16254 } 16255 16256 if ((receivers != null && receivers.size() > 0) 16257 || resultTo != null) { 16258 BroadcastQueue queue = broadcastQueueForIntent(intent); 16259 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16260 callerPackage, callingPid, callingUid, resolvedType, 16261 requiredPermission, appOp, receivers, resultTo, resultCode, 16262 resultData, map, ordered, sticky, false, userId); 16263 if (DEBUG_BROADCAST) Slog.v( 16264 TAG, "Enqueueing ordered broadcast " + r 16265 + ": prev had " + queue.mOrderedBroadcasts.size()); 16266 if (DEBUG_BROADCAST) { 16267 int seq = r.intent.getIntExtra("seq", -1); 16268 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16269 } 16270 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16271 if (!replaced) { 16272 queue.enqueueOrderedBroadcastLocked(r); 16273 queue.scheduleBroadcastsLocked(); 16274 } 16275 } 16276 16277 return ActivityManager.BROADCAST_SUCCESS; 16278 } 16279 16280 final Intent verifyBroadcastLocked(Intent intent) { 16281 // Refuse possible leaked file descriptors 16282 if (intent != null && intent.hasFileDescriptors() == true) { 16283 throw new IllegalArgumentException("File descriptors passed in Intent"); 16284 } 16285 16286 int flags = intent.getFlags(); 16287 16288 if (!mProcessesReady) { 16289 // if the caller really truly claims to know what they're doing, go 16290 // ahead and allow the broadcast without launching any receivers 16291 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16292 intent = new Intent(intent); 16293 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16294 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16295 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16296 + " before boot completion"); 16297 throw new IllegalStateException("Cannot broadcast before boot completed"); 16298 } 16299 } 16300 16301 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16302 throw new IllegalArgumentException( 16303 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16304 } 16305 16306 return intent; 16307 } 16308 16309 public final int broadcastIntent(IApplicationThread caller, 16310 Intent intent, String resolvedType, IIntentReceiver resultTo, 16311 int resultCode, String resultData, Bundle map, 16312 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16313 enforceNotIsolatedCaller("broadcastIntent"); 16314 synchronized(this) { 16315 intent = verifyBroadcastLocked(intent); 16316 16317 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16318 final int callingPid = Binder.getCallingPid(); 16319 final int callingUid = Binder.getCallingUid(); 16320 final long origId = Binder.clearCallingIdentity(); 16321 int res = broadcastIntentLocked(callerApp, 16322 callerApp != null ? callerApp.info.packageName : null, 16323 intent, resolvedType, resultTo, 16324 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16325 callingPid, callingUid, userId); 16326 Binder.restoreCallingIdentity(origId); 16327 return res; 16328 } 16329 } 16330 16331 int broadcastIntentInPackage(String packageName, int uid, 16332 Intent intent, String resolvedType, IIntentReceiver resultTo, 16333 int resultCode, String resultData, Bundle map, 16334 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16335 synchronized(this) { 16336 intent = verifyBroadcastLocked(intent); 16337 16338 final long origId = Binder.clearCallingIdentity(); 16339 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16340 resultTo, resultCode, resultData, map, requiredPermission, 16341 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16342 Binder.restoreCallingIdentity(origId); 16343 return res; 16344 } 16345 } 16346 16347 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16348 // Refuse possible leaked file descriptors 16349 if (intent != null && intent.hasFileDescriptors() == true) { 16350 throw new IllegalArgumentException("File descriptors passed in Intent"); 16351 } 16352 16353 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16354 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16355 16356 synchronized(this) { 16357 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16358 != PackageManager.PERMISSION_GRANTED) { 16359 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16360 + Binder.getCallingPid() 16361 + ", uid=" + Binder.getCallingUid() 16362 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16363 Slog.w(TAG, msg); 16364 throw new SecurityException(msg); 16365 } 16366 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16367 if (stickies != null) { 16368 ArrayList<Intent> list = stickies.get(intent.getAction()); 16369 if (list != null) { 16370 int N = list.size(); 16371 int i; 16372 for (i=0; i<N; i++) { 16373 if (intent.filterEquals(list.get(i))) { 16374 list.remove(i); 16375 break; 16376 } 16377 } 16378 if (list.size() <= 0) { 16379 stickies.remove(intent.getAction()); 16380 } 16381 } 16382 if (stickies.size() <= 0) { 16383 mStickyBroadcasts.remove(userId); 16384 } 16385 } 16386 } 16387 } 16388 16389 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16390 String resultData, Bundle resultExtras, boolean resultAbort) { 16391 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16392 if (r == null) { 16393 Slog.w(TAG, "finishReceiver called but not found on queue"); 16394 return false; 16395 } 16396 16397 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16398 } 16399 16400 void backgroundServicesFinishedLocked(int userId) { 16401 for (BroadcastQueue queue : mBroadcastQueues) { 16402 queue.backgroundServicesFinishedLocked(userId); 16403 } 16404 } 16405 16406 public void finishReceiver(IBinder who, int resultCode, String resultData, 16407 Bundle resultExtras, boolean resultAbort) { 16408 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16409 16410 // Refuse possible leaked file descriptors 16411 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16412 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16413 } 16414 16415 final long origId = Binder.clearCallingIdentity(); 16416 try { 16417 boolean doNext = false; 16418 BroadcastRecord r; 16419 16420 synchronized(this) { 16421 r = broadcastRecordForReceiverLocked(who); 16422 if (r != null) { 16423 doNext = r.queue.finishReceiverLocked(r, resultCode, 16424 resultData, resultExtras, resultAbort, true); 16425 } 16426 } 16427 16428 if (doNext) { 16429 r.queue.processNextBroadcast(false); 16430 } 16431 trimApplications(); 16432 } finally { 16433 Binder.restoreCallingIdentity(origId); 16434 } 16435 } 16436 16437 // ========================================================= 16438 // INSTRUMENTATION 16439 // ========================================================= 16440 16441 public boolean startInstrumentation(ComponentName className, 16442 String profileFile, int flags, Bundle arguments, 16443 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16444 int userId, String abiOverride) { 16445 enforceNotIsolatedCaller("startInstrumentation"); 16446 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16447 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16448 // Refuse possible leaked file descriptors 16449 if (arguments != null && arguments.hasFileDescriptors()) { 16450 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16451 } 16452 16453 synchronized(this) { 16454 InstrumentationInfo ii = null; 16455 ApplicationInfo ai = null; 16456 try { 16457 ii = mContext.getPackageManager().getInstrumentationInfo( 16458 className, STOCK_PM_FLAGS); 16459 ai = AppGlobals.getPackageManager().getApplicationInfo( 16460 ii.targetPackage, STOCK_PM_FLAGS, userId); 16461 } catch (PackageManager.NameNotFoundException e) { 16462 } catch (RemoteException e) { 16463 } 16464 if (ii == null) { 16465 reportStartInstrumentationFailure(watcher, className, 16466 "Unable to find instrumentation info for: " + className); 16467 return false; 16468 } 16469 if (ai == null) { 16470 reportStartInstrumentationFailure(watcher, className, 16471 "Unable to find instrumentation target package: " + ii.targetPackage); 16472 return false; 16473 } 16474 16475 int match = mContext.getPackageManager().checkSignatures( 16476 ii.targetPackage, ii.packageName); 16477 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16478 String msg = "Permission Denial: starting instrumentation " 16479 + className + " from pid=" 16480 + Binder.getCallingPid() 16481 + ", uid=" + Binder.getCallingPid() 16482 + " not allowed because package " + ii.packageName 16483 + " does not have a signature matching the target " 16484 + ii.targetPackage; 16485 reportStartInstrumentationFailure(watcher, className, msg); 16486 throw new SecurityException(msg); 16487 } 16488 16489 final long origId = Binder.clearCallingIdentity(); 16490 // Instrumentation can kill and relaunch even persistent processes 16491 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16492 "start instr"); 16493 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16494 app.instrumentationClass = className; 16495 app.instrumentationInfo = ai; 16496 app.instrumentationProfileFile = profileFile; 16497 app.instrumentationArguments = arguments; 16498 app.instrumentationWatcher = watcher; 16499 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16500 app.instrumentationResultClass = className; 16501 Binder.restoreCallingIdentity(origId); 16502 } 16503 16504 return true; 16505 } 16506 16507 /** 16508 * Report errors that occur while attempting to start Instrumentation. Always writes the 16509 * error to the logs, but if somebody is watching, send the report there too. This enables 16510 * the "am" command to report errors with more information. 16511 * 16512 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16513 * @param cn The component name of the instrumentation. 16514 * @param report The error report. 16515 */ 16516 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16517 ComponentName cn, String report) { 16518 Slog.w(TAG, report); 16519 try { 16520 if (watcher != null) { 16521 Bundle results = new Bundle(); 16522 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16523 results.putString("Error", report); 16524 watcher.instrumentationStatus(cn, -1, results); 16525 } 16526 } catch (RemoteException e) { 16527 Slog.w(TAG, e); 16528 } 16529 } 16530 16531 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16532 if (app.instrumentationWatcher != null) { 16533 try { 16534 // NOTE: IInstrumentationWatcher *must* be oneway here 16535 app.instrumentationWatcher.instrumentationFinished( 16536 app.instrumentationClass, 16537 resultCode, 16538 results); 16539 } catch (RemoteException e) { 16540 } 16541 } 16542 if (app.instrumentationUiAutomationConnection != null) { 16543 try { 16544 app.instrumentationUiAutomationConnection.shutdown(); 16545 } catch (RemoteException re) { 16546 /* ignore */ 16547 } 16548 // Only a UiAutomation can set this flag and now that 16549 // it is finished we make sure it is reset to its default. 16550 mUserIsMonkey = false; 16551 } 16552 app.instrumentationWatcher = null; 16553 app.instrumentationUiAutomationConnection = null; 16554 app.instrumentationClass = null; 16555 app.instrumentationInfo = null; 16556 app.instrumentationProfileFile = null; 16557 app.instrumentationArguments = null; 16558 16559 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16560 "finished inst"); 16561 } 16562 16563 public void finishInstrumentation(IApplicationThread target, 16564 int resultCode, Bundle results) { 16565 int userId = UserHandle.getCallingUserId(); 16566 // Refuse possible leaked file descriptors 16567 if (results != null && results.hasFileDescriptors()) { 16568 throw new IllegalArgumentException("File descriptors passed in Intent"); 16569 } 16570 16571 synchronized(this) { 16572 ProcessRecord app = getRecordForAppLocked(target); 16573 if (app == null) { 16574 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16575 return; 16576 } 16577 final long origId = Binder.clearCallingIdentity(); 16578 finishInstrumentationLocked(app, resultCode, results); 16579 Binder.restoreCallingIdentity(origId); 16580 } 16581 } 16582 16583 // ========================================================= 16584 // CONFIGURATION 16585 // ========================================================= 16586 16587 public ConfigurationInfo getDeviceConfigurationInfo() { 16588 ConfigurationInfo config = new ConfigurationInfo(); 16589 synchronized (this) { 16590 config.reqTouchScreen = mConfiguration.touchscreen; 16591 config.reqKeyboardType = mConfiguration.keyboard; 16592 config.reqNavigation = mConfiguration.navigation; 16593 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16594 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16595 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16596 } 16597 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16598 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16599 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16600 } 16601 config.reqGlEsVersion = GL_ES_VERSION; 16602 } 16603 return config; 16604 } 16605 16606 ActivityStack getFocusedStack() { 16607 return mStackSupervisor.getFocusedStack(); 16608 } 16609 16610 public Configuration getConfiguration() { 16611 Configuration ci; 16612 synchronized(this) { 16613 ci = new Configuration(mConfiguration); 16614 } 16615 return ci; 16616 } 16617 16618 public void updatePersistentConfiguration(Configuration values) { 16619 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16620 "updateConfiguration()"); 16621 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16622 "updateConfiguration()"); 16623 if (values == null) { 16624 throw new NullPointerException("Configuration must not be null"); 16625 } 16626 16627 synchronized(this) { 16628 final long origId = Binder.clearCallingIdentity(); 16629 updateConfigurationLocked(values, null, true, false); 16630 Binder.restoreCallingIdentity(origId); 16631 } 16632 } 16633 16634 public void updateConfiguration(Configuration values) { 16635 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16636 "updateConfiguration()"); 16637 16638 synchronized(this) { 16639 if (values == null && mWindowManager != null) { 16640 // sentinel: fetch the current configuration from the window manager 16641 values = mWindowManager.computeNewConfiguration(); 16642 } 16643 16644 if (mWindowManager != null) { 16645 mProcessList.applyDisplaySize(mWindowManager); 16646 } 16647 16648 final long origId = Binder.clearCallingIdentity(); 16649 if (values != null) { 16650 Settings.System.clearConfiguration(values); 16651 } 16652 updateConfigurationLocked(values, null, false, false); 16653 Binder.restoreCallingIdentity(origId); 16654 } 16655 } 16656 16657 /** 16658 * Do either or both things: (1) change the current configuration, and (2) 16659 * make sure the given activity is running with the (now) current 16660 * configuration. Returns true if the activity has been left running, or 16661 * false if <var>starting</var> is being destroyed to match the new 16662 * configuration. 16663 * @param persistent TODO 16664 */ 16665 boolean updateConfigurationLocked(Configuration values, 16666 ActivityRecord starting, boolean persistent, boolean initLocale) { 16667 int changes = 0; 16668 16669 if (values != null) { 16670 Configuration newConfig = new Configuration(mConfiguration); 16671 changes = newConfig.updateFrom(values); 16672 if (changes != 0) { 16673 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16674 Slog.i(TAG, "Updating configuration to: " + values); 16675 } 16676 16677 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16678 16679 if (values.locale != null && !initLocale) { 16680 saveLocaleLocked(values.locale, 16681 !values.locale.equals(mConfiguration.locale), 16682 values.userSetLocale); 16683 } 16684 16685 mConfigurationSeq++; 16686 if (mConfigurationSeq <= 0) { 16687 mConfigurationSeq = 1; 16688 } 16689 newConfig.seq = mConfigurationSeq; 16690 mConfiguration = newConfig; 16691 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16692 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16693 //mUsageStatsService.noteStartConfig(newConfig); 16694 16695 final Configuration configCopy = new Configuration(mConfiguration); 16696 16697 // TODO: If our config changes, should we auto dismiss any currently 16698 // showing dialogs? 16699 mShowDialogs = shouldShowDialogs(newConfig); 16700 16701 AttributeCache ac = AttributeCache.instance(); 16702 if (ac != null) { 16703 ac.updateConfiguration(configCopy); 16704 } 16705 16706 // Make sure all resources in our process are updated 16707 // right now, so that anyone who is going to retrieve 16708 // resource values after we return will be sure to get 16709 // the new ones. This is especially important during 16710 // boot, where the first config change needs to guarantee 16711 // all resources have that config before following boot 16712 // code is executed. 16713 mSystemThread.applyConfigurationToResources(configCopy); 16714 16715 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16716 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16717 msg.obj = new Configuration(configCopy); 16718 mHandler.sendMessage(msg); 16719 } 16720 16721 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16722 ProcessRecord app = mLruProcesses.get(i); 16723 try { 16724 if (app.thread != null) { 16725 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16726 + app.processName + " new config " + mConfiguration); 16727 app.thread.scheduleConfigurationChanged(configCopy); 16728 } 16729 } catch (Exception e) { 16730 } 16731 } 16732 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16733 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16734 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16735 | Intent.FLAG_RECEIVER_FOREGROUND); 16736 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16737 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16738 Process.SYSTEM_UID, UserHandle.USER_ALL); 16739 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16740 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16741 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16742 broadcastIntentLocked(null, null, intent, 16743 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16744 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16745 } 16746 } 16747 } 16748 16749 boolean kept = true; 16750 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16751 // mainStack is null during startup. 16752 if (mainStack != null) { 16753 if (changes != 0 && starting == null) { 16754 // If the configuration changed, and the caller is not already 16755 // in the process of starting an activity, then find the top 16756 // activity to check if its configuration needs to change. 16757 starting = mainStack.topRunningActivityLocked(null); 16758 } 16759 16760 if (starting != null) { 16761 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16762 // And we need to make sure at this point that all other activities 16763 // are made visible with the correct configuration. 16764 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16765 } 16766 } 16767 16768 if (values != null && mWindowManager != null) { 16769 mWindowManager.setNewConfiguration(mConfiguration); 16770 } 16771 16772 return kept; 16773 } 16774 16775 /** 16776 * Decide based on the configuration whether we should shouw the ANR, 16777 * crash, etc dialogs. The idea is that if there is no affordnace to 16778 * press the on-screen buttons, we shouldn't show the dialog. 16779 * 16780 * A thought: SystemUI might also want to get told about this, the Power 16781 * dialog / global actions also might want different behaviors. 16782 */ 16783 private static final boolean shouldShowDialogs(Configuration config) { 16784 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16785 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16786 } 16787 16788 /** 16789 * Save the locale. You must be inside a synchronized (this) block. 16790 */ 16791 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16792 if(isDiff) { 16793 SystemProperties.set("user.language", l.getLanguage()); 16794 SystemProperties.set("user.region", l.getCountry()); 16795 } 16796 16797 if(isPersist) { 16798 SystemProperties.set("persist.sys.language", l.getLanguage()); 16799 SystemProperties.set("persist.sys.country", l.getCountry()); 16800 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16801 16802 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16803 } 16804 } 16805 16806 @Override 16807 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16808 synchronized (this) { 16809 ActivityRecord srec = ActivityRecord.forToken(token); 16810 if (srec.task != null && srec.task.stack != null) { 16811 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16812 } 16813 } 16814 return false; 16815 } 16816 16817 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16818 Intent resultData) { 16819 16820 synchronized (this) { 16821 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16822 if (stack != null) { 16823 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16824 } 16825 return false; 16826 } 16827 } 16828 16829 public int getLaunchedFromUid(IBinder activityToken) { 16830 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16831 if (srec == null) { 16832 return -1; 16833 } 16834 return srec.launchedFromUid; 16835 } 16836 16837 public String getLaunchedFromPackage(IBinder activityToken) { 16838 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16839 if (srec == null) { 16840 return null; 16841 } 16842 return srec.launchedFromPackage; 16843 } 16844 16845 // ========================================================= 16846 // LIFETIME MANAGEMENT 16847 // ========================================================= 16848 16849 // Returns which broadcast queue the app is the current [or imminent] receiver 16850 // on, or 'null' if the app is not an active broadcast recipient. 16851 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16852 BroadcastRecord r = app.curReceiver; 16853 if (r != null) { 16854 return r.queue; 16855 } 16856 16857 // It's not the current receiver, but it might be starting up to become one 16858 synchronized (this) { 16859 for (BroadcastQueue queue : mBroadcastQueues) { 16860 r = queue.mPendingBroadcast; 16861 if (r != null && r.curApp == app) { 16862 // found it; report which queue it's in 16863 return queue; 16864 } 16865 } 16866 } 16867 16868 return null; 16869 } 16870 16871 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16872 ComponentName targetComponent, String targetProcess) { 16873 if (!mTrackingAssociations) { 16874 return null; 16875 } 16876 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16877 = mAssociations.get(targetUid); 16878 if (components == null) { 16879 components = new ArrayMap<>(); 16880 mAssociations.put(targetUid, components); 16881 } 16882 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16883 if (sourceUids == null) { 16884 sourceUids = new SparseArray<>(); 16885 components.put(targetComponent, sourceUids); 16886 } 16887 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16888 if (sourceProcesses == null) { 16889 sourceProcesses = new ArrayMap<>(); 16890 sourceUids.put(sourceUid, sourceProcesses); 16891 } 16892 Association ass = sourceProcesses.get(sourceProcess); 16893 if (ass == null) { 16894 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16895 targetProcess); 16896 sourceProcesses.put(sourceProcess, ass); 16897 } 16898 ass.mCount++; 16899 ass.mNesting++; 16900 if (ass.mNesting == 1) { 16901 ass.mStartTime = SystemClock.uptimeMillis(); 16902 } 16903 return ass; 16904 } 16905 16906 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16907 ComponentName targetComponent) { 16908 if (!mTrackingAssociations) { 16909 return; 16910 } 16911 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16912 = mAssociations.get(targetUid); 16913 if (components == null) { 16914 return; 16915 } 16916 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16917 if (sourceUids == null) { 16918 return; 16919 } 16920 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16921 if (sourceProcesses == null) { 16922 return; 16923 } 16924 Association ass = sourceProcesses.get(sourceProcess); 16925 if (ass == null || ass.mNesting <= 0) { 16926 return; 16927 } 16928 ass.mNesting--; 16929 if (ass.mNesting == 0) { 16930 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16931 } 16932 } 16933 16934 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16935 boolean doingAll, long now) { 16936 if (mAdjSeq == app.adjSeq) { 16937 // This adjustment has already been computed. 16938 return app.curRawAdj; 16939 } 16940 16941 if (app.thread == null) { 16942 app.adjSeq = mAdjSeq; 16943 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16944 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16945 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16946 } 16947 16948 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16949 app.adjSource = null; 16950 app.adjTarget = null; 16951 app.empty = false; 16952 app.cached = false; 16953 16954 final int activitiesSize = app.activities.size(); 16955 16956 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16957 // The max adjustment doesn't allow this app to be anything 16958 // below foreground, so it is not worth doing work for it. 16959 app.adjType = "fixed"; 16960 app.adjSeq = mAdjSeq; 16961 app.curRawAdj = app.maxAdj; 16962 app.foregroundActivities = false; 16963 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16964 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16965 // System processes can do UI, and when they do we want to have 16966 // them trim their memory after the user leaves the UI. To 16967 // facilitate this, here we need to determine whether or not it 16968 // is currently showing UI. 16969 app.systemNoUi = true; 16970 if (app == TOP_APP) { 16971 app.systemNoUi = false; 16972 } else if (activitiesSize > 0) { 16973 for (int j = 0; j < activitiesSize; j++) { 16974 final ActivityRecord r = app.activities.get(j); 16975 if (r.visible) { 16976 app.systemNoUi = false; 16977 } 16978 } 16979 } 16980 if (!app.systemNoUi) { 16981 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16982 } 16983 return (app.curAdj=app.maxAdj); 16984 } 16985 16986 app.systemNoUi = false; 16987 16988 // Determine the importance of the process, starting with most 16989 // important to least, and assign an appropriate OOM adjustment. 16990 int adj; 16991 int schedGroup; 16992 int procState; 16993 boolean foregroundActivities = false; 16994 BroadcastQueue queue; 16995 if (app == TOP_APP) { 16996 // The last app on the list is the foreground app. 16997 adj = ProcessList.FOREGROUND_APP_ADJ; 16998 schedGroup = Process.THREAD_GROUP_DEFAULT; 16999 app.adjType = "top-activity"; 17000 foregroundActivities = true; 17001 procState = ActivityManager.PROCESS_STATE_TOP; 17002 } else if (app.instrumentationClass != null) { 17003 // Don't want to kill running instrumentation. 17004 adj = ProcessList.FOREGROUND_APP_ADJ; 17005 schedGroup = Process.THREAD_GROUP_DEFAULT; 17006 app.adjType = "instrumentation"; 17007 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17008 } else if ((queue = isReceivingBroadcast(app)) != null) { 17009 // An app that is currently receiving a broadcast also 17010 // counts as being in the foreground for OOM killer purposes. 17011 // It's placed in a sched group based on the nature of the 17012 // broadcast as reflected by which queue it's active in. 17013 adj = ProcessList.FOREGROUND_APP_ADJ; 17014 schedGroup = (queue == mFgBroadcastQueue) 17015 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17016 app.adjType = "broadcast"; 17017 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17018 } else if (app.executingServices.size() > 0) { 17019 // An app that is currently executing a service callback also 17020 // counts as being in the foreground. 17021 adj = ProcessList.FOREGROUND_APP_ADJ; 17022 schedGroup = app.execServicesFg ? 17023 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17024 app.adjType = "exec-service"; 17025 procState = ActivityManager.PROCESS_STATE_SERVICE; 17026 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17027 } else { 17028 // As far as we know the process is empty. We may change our mind later. 17029 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17030 // At this point we don't actually know the adjustment. Use the cached adj 17031 // value that the caller wants us to. 17032 adj = cachedAdj; 17033 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17034 app.cached = true; 17035 app.empty = true; 17036 app.adjType = "cch-empty"; 17037 } 17038 17039 // Examine all activities if not already foreground. 17040 if (!foregroundActivities && activitiesSize > 0) { 17041 for (int j = 0; j < activitiesSize; j++) { 17042 final ActivityRecord r = app.activities.get(j); 17043 if (r.app != app) { 17044 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17045 + app + "?!?"); 17046 continue; 17047 } 17048 if (r.visible) { 17049 // App has a visible activity; only upgrade adjustment. 17050 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17051 adj = ProcessList.VISIBLE_APP_ADJ; 17052 app.adjType = "visible"; 17053 } 17054 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17055 procState = ActivityManager.PROCESS_STATE_TOP; 17056 } 17057 schedGroup = Process.THREAD_GROUP_DEFAULT; 17058 app.cached = false; 17059 app.empty = false; 17060 foregroundActivities = true; 17061 break; 17062 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17063 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17064 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17065 app.adjType = "pausing"; 17066 } 17067 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17068 procState = ActivityManager.PROCESS_STATE_TOP; 17069 } 17070 schedGroup = Process.THREAD_GROUP_DEFAULT; 17071 app.cached = false; 17072 app.empty = false; 17073 foregroundActivities = true; 17074 } else if (r.state == ActivityState.STOPPING) { 17075 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17076 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17077 app.adjType = "stopping"; 17078 } 17079 // For the process state, we will at this point consider the 17080 // process to be cached. It will be cached either as an activity 17081 // or empty depending on whether the activity is finishing. We do 17082 // this so that we can treat the process as cached for purposes of 17083 // memory trimming (determing current memory level, trim command to 17084 // send to process) since there can be an arbitrary number of stopping 17085 // processes and they should soon all go into the cached state. 17086 if (!r.finishing) { 17087 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17088 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17089 } 17090 } 17091 app.cached = false; 17092 app.empty = false; 17093 foregroundActivities = true; 17094 } else { 17095 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17096 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17097 app.adjType = "cch-act"; 17098 } 17099 } 17100 } 17101 } 17102 17103 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17104 if (app.foregroundServices) { 17105 // The user is aware of this app, so make it visible. 17106 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17107 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17108 app.cached = false; 17109 app.adjType = "fg-service"; 17110 schedGroup = Process.THREAD_GROUP_DEFAULT; 17111 } else if (app.forcingToForeground != null) { 17112 // The user is aware of this app, so make it visible. 17113 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17114 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17115 app.cached = false; 17116 app.adjType = "force-fg"; 17117 app.adjSource = app.forcingToForeground; 17118 schedGroup = Process.THREAD_GROUP_DEFAULT; 17119 } 17120 } 17121 17122 if (app == mHeavyWeightProcess) { 17123 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17124 // We don't want to kill the current heavy-weight process. 17125 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17126 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17127 app.cached = false; 17128 app.adjType = "heavy"; 17129 } 17130 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17131 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17132 } 17133 } 17134 17135 if (app == mHomeProcess) { 17136 if (adj > ProcessList.HOME_APP_ADJ) { 17137 // This process is hosting what we currently consider to be the 17138 // home app, so we don't want to let it go into the background. 17139 adj = ProcessList.HOME_APP_ADJ; 17140 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17141 app.cached = false; 17142 app.adjType = "home"; 17143 } 17144 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17145 procState = ActivityManager.PROCESS_STATE_HOME; 17146 } 17147 } 17148 17149 if (app == mPreviousProcess && app.activities.size() > 0) { 17150 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17151 // This was the previous process that showed UI to the user. 17152 // We want to try to keep it around more aggressively, to give 17153 // a good experience around switching between two apps. 17154 adj = ProcessList.PREVIOUS_APP_ADJ; 17155 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17156 app.cached = false; 17157 app.adjType = "previous"; 17158 } 17159 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17160 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17161 } 17162 } 17163 17164 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17165 + " reason=" + app.adjType); 17166 17167 // By default, we use the computed adjustment. It may be changed if 17168 // there are applications dependent on our services or providers, but 17169 // this gives us a baseline and makes sure we don't get into an 17170 // infinite recursion. 17171 app.adjSeq = mAdjSeq; 17172 app.curRawAdj = adj; 17173 app.hasStartedServices = false; 17174 17175 if (mBackupTarget != null && app == mBackupTarget.app) { 17176 // If possible we want to avoid killing apps while they're being backed up 17177 if (adj > ProcessList.BACKUP_APP_ADJ) { 17178 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17179 adj = ProcessList.BACKUP_APP_ADJ; 17180 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17181 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17182 } 17183 app.adjType = "backup"; 17184 app.cached = false; 17185 } 17186 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17187 procState = ActivityManager.PROCESS_STATE_BACKUP; 17188 } 17189 } 17190 17191 boolean mayBeTop = false; 17192 17193 for (int is = app.services.size()-1; 17194 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17195 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17196 || procState > ActivityManager.PROCESS_STATE_TOP); 17197 is--) { 17198 ServiceRecord s = app.services.valueAt(is); 17199 if (s.startRequested) { 17200 app.hasStartedServices = true; 17201 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17202 procState = ActivityManager.PROCESS_STATE_SERVICE; 17203 } 17204 if (app.hasShownUi && app != mHomeProcess) { 17205 // If this process has shown some UI, let it immediately 17206 // go to the LRU list because it may be pretty heavy with 17207 // UI stuff. We'll tag it with a label just to help 17208 // debug and understand what is going on. 17209 if (adj > ProcessList.SERVICE_ADJ) { 17210 app.adjType = "cch-started-ui-services"; 17211 } 17212 } else { 17213 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17214 // This service has seen some activity within 17215 // recent memory, so we will keep its process ahead 17216 // of the background processes. 17217 if (adj > ProcessList.SERVICE_ADJ) { 17218 adj = ProcessList.SERVICE_ADJ; 17219 app.adjType = "started-services"; 17220 app.cached = false; 17221 } 17222 } 17223 // If we have let the service slide into the background 17224 // state, still have some text describing what it is doing 17225 // even though the service no longer has an impact. 17226 if (adj > ProcessList.SERVICE_ADJ) { 17227 app.adjType = "cch-started-services"; 17228 } 17229 } 17230 } 17231 for (int conni = s.connections.size()-1; 17232 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17233 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17234 || procState > ActivityManager.PROCESS_STATE_TOP); 17235 conni--) { 17236 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17237 for (int i = 0; 17238 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17239 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17240 || procState > ActivityManager.PROCESS_STATE_TOP); 17241 i++) { 17242 // XXX should compute this based on the max of 17243 // all connected clients. 17244 ConnectionRecord cr = clist.get(i); 17245 if (cr.binding.client == app) { 17246 // Binding to ourself is not interesting. 17247 continue; 17248 } 17249 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17250 ProcessRecord client = cr.binding.client; 17251 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17252 TOP_APP, doingAll, now); 17253 int clientProcState = client.curProcState; 17254 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17255 // If the other app is cached for any reason, for purposes here 17256 // we are going to consider it empty. The specific cached state 17257 // doesn't propagate except under certain conditions. 17258 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17259 } 17260 String adjType = null; 17261 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17262 // Not doing bind OOM management, so treat 17263 // this guy more like a started service. 17264 if (app.hasShownUi && app != mHomeProcess) { 17265 // If this process has shown some UI, let it immediately 17266 // go to the LRU list because it may be pretty heavy with 17267 // UI stuff. We'll tag it with a label just to help 17268 // debug and understand what is going on. 17269 if (adj > clientAdj) { 17270 adjType = "cch-bound-ui-services"; 17271 } 17272 app.cached = false; 17273 clientAdj = adj; 17274 clientProcState = procState; 17275 } else { 17276 if (now >= (s.lastActivity 17277 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17278 // This service has not seen activity within 17279 // recent memory, so allow it to drop to the 17280 // LRU list if there is no other reason to keep 17281 // it around. We'll also tag it with a label just 17282 // to help debug and undertand what is going on. 17283 if (adj > clientAdj) { 17284 adjType = "cch-bound-services"; 17285 } 17286 clientAdj = adj; 17287 } 17288 } 17289 } 17290 if (adj > clientAdj) { 17291 // If this process has recently shown UI, and 17292 // the process that is binding to it is less 17293 // important than being visible, then we don't 17294 // care about the binding as much as we care 17295 // about letting this process get into the LRU 17296 // list to be killed and restarted if needed for 17297 // memory. 17298 if (app.hasShownUi && app != mHomeProcess 17299 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17300 adjType = "cch-bound-ui-services"; 17301 } else { 17302 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17303 |Context.BIND_IMPORTANT)) != 0) { 17304 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17305 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17306 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17307 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17308 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17309 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17310 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17311 adj = clientAdj; 17312 } else { 17313 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17314 adj = ProcessList.VISIBLE_APP_ADJ; 17315 } 17316 } 17317 if (!client.cached) { 17318 app.cached = false; 17319 } 17320 adjType = "service"; 17321 } 17322 } 17323 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17324 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17325 schedGroup = Process.THREAD_GROUP_DEFAULT; 17326 } 17327 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17328 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17329 // Special handling of clients who are in the top state. 17330 // We *may* want to consider this process to be in the 17331 // top state as well, but only if there is not another 17332 // reason for it to be running. Being on the top is a 17333 // special state, meaning you are specifically running 17334 // for the current top app. If the process is already 17335 // running in the background for some other reason, it 17336 // is more important to continue considering it to be 17337 // in the background state. 17338 mayBeTop = true; 17339 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17340 } else { 17341 // Special handling for above-top states (persistent 17342 // processes). These should not bring the current process 17343 // into the top state, since they are not on top. Instead 17344 // give them the best state after that. 17345 clientProcState = 17346 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17347 } 17348 } 17349 } else { 17350 if (clientProcState < 17351 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17352 clientProcState = 17353 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17354 } 17355 } 17356 if (procState > clientProcState) { 17357 procState = clientProcState; 17358 } 17359 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17360 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17361 app.pendingUiClean = true; 17362 } 17363 if (adjType != null) { 17364 app.adjType = adjType; 17365 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17366 .REASON_SERVICE_IN_USE; 17367 app.adjSource = cr.binding.client; 17368 app.adjSourceProcState = clientProcState; 17369 app.adjTarget = s.name; 17370 } 17371 } 17372 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17373 app.treatLikeActivity = true; 17374 } 17375 final ActivityRecord a = cr.activity; 17376 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17377 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17378 (a.visible || a.state == ActivityState.RESUMED 17379 || a.state == ActivityState.PAUSING)) { 17380 adj = ProcessList.FOREGROUND_APP_ADJ; 17381 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17382 schedGroup = Process.THREAD_GROUP_DEFAULT; 17383 } 17384 app.cached = false; 17385 app.adjType = "service"; 17386 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17387 .REASON_SERVICE_IN_USE; 17388 app.adjSource = a; 17389 app.adjSourceProcState = procState; 17390 app.adjTarget = s.name; 17391 } 17392 } 17393 } 17394 } 17395 } 17396 17397 for (int provi = app.pubProviders.size()-1; 17398 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17399 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17400 || procState > ActivityManager.PROCESS_STATE_TOP); 17401 provi--) { 17402 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17403 for (int i = cpr.connections.size()-1; 17404 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17405 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17406 || procState > ActivityManager.PROCESS_STATE_TOP); 17407 i--) { 17408 ContentProviderConnection conn = cpr.connections.get(i); 17409 ProcessRecord client = conn.client; 17410 if (client == app) { 17411 // Being our own client is not interesting. 17412 continue; 17413 } 17414 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17415 int clientProcState = client.curProcState; 17416 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17417 // If the other app is cached for any reason, for purposes here 17418 // we are going to consider it empty. 17419 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17420 } 17421 if (adj > clientAdj) { 17422 if (app.hasShownUi && app != mHomeProcess 17423 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17424 app.adjType = "cch-ui-provider"; 17425 } else { 17426 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17427 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17428 app.adjType = "provider"; 17429 } 17430 app.cached &= client.cached; 17431 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17432 .REASON_PROVIDER_IN_USE; 17433 app.adjSource = client; 17434 app.adjSourceProcState = clientProcState; 17435 app.adjTarget = cpr.name; 17436 } 17437 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17438 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17439 // Special handling of clients who are in the top state. 17440 // We *may* want to consider this process to be in the 17441 // top state as well, but only if there is not another 17442 // reason for it to be running. Being on the top is a 17443 // special state, meaning you are specifically running 17444 // for the current top app. If the process is already 17445 // running in the background for some other reason, it 17446 // is more important to continue considering it to be 17447 // in the background state. 17448 mayBeTop = true; 17449 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17450 } else { 17451 // Special handling for above-top states (persistent 17452 // processes). These should not bring the current process 17453 // into the top state, since they are not on top. Instead 17454 // give them the best state after that. 17455 clientProcState = 17456 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17457 } 17458 } 17459 if (procState > clientProcState) { 17460 procState = clientProcState; 17461 } 17462 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17463 schedGroup = Process.THREAD_GROUP_DEFAULT; 17464 } 17465 } 17466 // If the provider has external (non-framework) process 17467 // dependencies, ensure that its adjustment is at least 17468 // FOREGROUND_APP_ADJ. 17469 if (cpr.hasExternalProcessHandles()) { 17470 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17471 adj = ProcessList.FOREGROUND_APP_ADJ; 17472 schedGroup = Process.THREAD_GROUP_DEFAULT; 17473 app.cached = false; 17474 app.adjType = "provider"; 17475 app.adjTarget = cpr.name; 17476 } 17477 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17478 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17479 } 17480 } 17481 } 17482 17483 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17484 // A client of one of our services or providers is in the top state. We 17485 // *may* want to be in the top state, but not if we are already running in 17486 // the background for some other reason. For the decision here, we are going 17487 // to pick out a few specific states that we want to remain in when a client 17488 // is top (states that tend to be longer-term) and otherwise allow it to go 17489 // to the top state. 17490 switch (procState) { 17491 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17492 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17493 case ActivityManager.PROCESS_STATE_SERVICE: 17494 // These all are longer-term states, so pull them up to the top 17495 // of the background states, but not all the way to the top state. 17496 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17497 break; 17498 default: 17499 // Otherwise, top is a better choice, so take it. 17500 procState = ActivityManager.PROCESS_STATE_TOP; 17501 break; 17502 } 17503 } 17504 17505 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17506 if (app.hasClientActivities) { 17507 // This is a cached process, but with client activities. Mark it so. 17508 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17509 app.adjType = "cch-client-act"; 17510 } else if (app.treatLikeActivity) { 17511 // This is a cached process, but somebody wants us to treat it like it has 17512 // an activity, okay! 17513 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17514 app.adjType = "cch-as-act"; 17515 } 17516 } 17517 17518 if (adj == ProcessList.SERVICE_ADJ) { 17519 if (doingAll) { 17520 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17521 mNewNumServiceProcs++; 17522 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17523 if (!app.serviceb) { 17524 // This service isn't far enough down on the LRU list to 17525 // normally be a B service, but if we are low on RAM and it 17526 // is large we want to force it down since we would prefer to 17527 // keep launcher over it. 17528 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17529 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17530 app.serviceHighRam = true; 17531 app.serviceb = true; 17532 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17533 } else { 17534 mNewNumAServiceProcs++; 17535 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17536 } 17537 } else { 17538 app.serviceHighRam = false; 17539 } 17540 } 17541 if (app.serviceb) { 17542 adj = ProcessList.SERVICE_B_ADJ; 17543 } 17544 } 17545 17546 app.curRawAdj = adj; 17547 17548 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17549 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17550 if (adj > app.maxAdj) { 17551 adj = app.maxAdj; 17552 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17553 schedGroup = Process.THREAD_GROUP_DEFAULT; 17554 } 17555 } 17556 17557 // Do final modification to adj. Everything we do between here and applying 17558 // the final setAdj must be done in this function, because we will also use 17559 // it when computing the final cached adj later. Note that we don't need to 17560 // worry about this for max adj above, since max adj will always be used to 17561 // keep it out of the cached vaues. 17562 app.curAdj = app.modifyRawOomAdj(adj); 17563 app.curSchedGroup = schedGroup; 17564 app.curProcState = procState; 17565 app.foregroundActivities = foregroundActivities; 17566 17567 return app.curRawAdj; 17568 } 17569 17570 /** 17571 * Record new PSS sample for a process. 17572 */ 17573 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17574 proc.lastPssTime = now; 17575 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17576 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17577 + ": " + pss + " lastPss=" + proc.lastPss 17578 + " state=" + ProcessList.makeProcStateString(procState)); 17579 if (proc.initialIdlePss == 0) { 17580 proc.initialIdlePss = pss; 17581 } 17582 proc.lastPss = pss; 17583 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17584 proc.lastCachedPss = pss; 17585 } 17586 } 17587 17588 /** 17589 * Schedule PSS collection of a process. 17590 */ 17591 void requestPssLocked(ProcessRecord proc, int procState) { 17592 if (mPendingPssProcesses.contains(proc)) { 17593 return; 17594 } 17595 if (mPendingPssProcesses.size() == 0) { 17596 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17597 } 17598 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17599 proc.pssProcState = procState; 17600 mPendingPssProcesses.add(proc); 17601 } 17602 17603 /** 17604 * Schedule PSS collection of all processes. 17605 */ 17606 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17607 if (!always) { 17608 if (now < (mLastFullPssTime + 17609 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17610 return; 17611 } 17612 } 17613 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17614 mLastFullPssTime = now; 17615 mFullPssPending = true; 17616 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17617 mPendingPssProcesses.clear(); 17618 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17619 ProcessRecord app = mLruProcesses.get(i); 17620 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17621 app.pssProcState = app.setProcState; 17622 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17623 mTestPssMode, isSleeping(), now); 17624 mPendingPssProcesses.add(app); 17625 } 17626 } 17627 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17628 } 17629 17630 public void setTestPssMode(boolean enabled) { 17631 synchronized (this) { 17632 mTestPssMode = enabled; 17633 if (enabled) { 17634 // Whenever we enable the mode, we want to take a snapshot all of current 17635 // process mem use. 17636 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17637 } 17638 } 17639 } 17640 17641 /** 17642 * Ask a given process to GC right now. 17643 */ 17644 final void performAppGcLocked(ProcessRecord app) { 17645 try { 17646 app.lastRequestedGc = SystemClock.uptimeMillis(); 17647 if (app.thread != null) { 17648 if (app.reportLowMemory) { 17649 app.reportLowMemory = false; 17650 app.thread.scheduleLowMemory(); 17651 } else { 17652 app.thread.processInBackground(); 17653 } 17654 } 17655 } catch (Exception e) { 17656 // whatever. 17657 } 17658 } 17659 17660 /** 17661 * Returns true if things are idle enough to perform GCs. 17662 */ 17663 private final boolean canGcNowLocked() { 17664 boolean processingBroadcasts = false; 17665 for (BroadcastQueue q : mBroadcastQueues) { 17666 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17667 processingBroadcasts = true; 17668 } 17669 } 17670 return !processingBroadcasts 17671 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17672 } 17673 17674 /** 17675 * Perform GCs on all processes that are waiting for it, but only 17676 * if things are idle. 17677 */ 17678 final void performAppGcsLocked() { 17679 final int N = mProcessesToGc.size(); 17680 if (N <= 0) { 17681 return; 17682 } 17683 if (canGcNowLocked()) { 17684 while (mProcessesToGc.size() > 0) { 17685 ProcessRecord proc = mProcessesToGc.remove(0); 17686 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17687 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17688 <= SystemClock.uptimeMillis()) { 17689 // To avoid spamming the system, we will GC processes one 17690 // at a time, waiting a few seconds between each. 17691 performAppGcLocked(proc); 17692 scheduleAppGcsLocked(); 17693 return; 17694 } else { 17695 // It hasn't been long enough since we last GCed this 17696 // process... put it in the list to wait for its time. 17697 addProcessToGcListLocked(proc); 17698 break; 17699 } 17700 } 17701 } 17702 17703 scheduleAppGcsLocked(); 17704 } 17705 } 17706 17707 /** 17708 * If all looks good, perform GCs on all processes waiting for them. 17709 */ 17710 final void performAppGcsIfAppropriateLocked() { 17711 if (canGcNowLocked()) { 17712 performAppGcsLocked(); 17713 return; 17714 } 17715 // Still not idle, wait some more. 17716 scheduleAppGcsLocked(); 17717 } 17718 17719 /** 17720 * Schedule the execution of all pending app GCs. 17721 */ 17722 final void scheduleAppGcsLocked() { 17723 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17724 17725 if (mProcessesToGc.size() > 0) { 17726 // Schedule a GC for the time to the next process. 17727 ProcessRecord proc = mProcessesToGc.get(0); 17728 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17729 17730 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17731 long now = SystemClock.uptimeMillis(); 17732 if (when < (now+GC_TIMEOUT)) { 17733 when = now + GC_TIMEOUT; 17734 } 17735 mHandler.sendMessageAtTime(msg, when); 17736 } 17737 } 17738 17739 /** 17740 * Add a process to the array of processes waiting to be GCed. Keeps the 17741 * list in sorted order by the last GC time. The process can't already be 17742 * on the list. 17743 */ 17744 final void addProcessToGcListLocked(ProcessRecord proc) { 17745 boolean added = false; 17746 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17747 if (mProcessesToGc.get(i).lastRequestedGc < 17748 proc.lastRequestedGc) { 17749 added = true; 17750 mProcessesToGc.add(i+1, proc); 17751 break; 17752 } 17753 } 17754 if (!added) { 17755 mProcessesToGc.add(0, proc); 17756 } 17757 } 17758 17759 /** 17760 * Set up to ask a process to GC itself. This will either do it 17761 * immediately, or put it on the list of processes to gc the next 17762 * time things are idle. 17763 */ 17764 final void scheduleAppGcLocked(ProcessRecord app) { 17765 long now = SystemClock.uptimeMillis(); 17766 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17767 return; 17768 } 17769 if (!mProcessesToGc.contains(app)) { 17770 addProcessToGcListLocked(app); 17771 scheduleAppGcsLocked(); 17772 } 17773 } 17774 17775 final void checkExcessivePowerUsageLocked(boolean doKills) { 17776 updateCpuStatsNow(); 17777 17778 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17779 boolean doWakeKills = doKills; 17780 boolean doCpuKills = doKills; 17781 if (mLastPowerCheckRealtime == 0) { 17782 doWakeKills = false; 17783 } 17784 if (mLastPowerCheckUptime == 0) { 17785 doCpuKills = false; 17786 } 17787 if (stats.isScreenOn()) { 17788 doWakeKills = false; 17789 } 17790 final long curRealtime = SystemClock.elapsedRealtime(); 17791 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17792 final long curUptime = SystemClock.uptimeMillis(); 17793 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17794 mLastPowerCheckRealtime = curRealtime; 17795 mLastPowerCheckUptime = curUptime; 17796 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17797 doWakeKills = false; 17798 } 17799 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17800 doCpuKills = false; 17801 } 17802 int i = mLruProcesses.size(); 17803 while (i > 0) { 17804 i--; 17805 ProcessRecord app = mLruProcesses.get(i); 17806 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17807 long wtime; 17808 synchronized (stats) { 17809 wtime = stats.getProcessWakeTime(app.info.uid, 17810 app.pid, curRealtime); 17811 } 17812 long wtimeUsed = wtime - app.lastWakeTime; 17813 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17814 if (DEBUG_POWER) { 17815 StringBuilder sb = new StringBuilder(128); 17816 sb.append("Wake for "); 17817 app.toShortString(sb); 17818 sb.append(": over "); 17819 TimeUtils.formatDuration(realtimeSince, sb); 17820 sb.append(" used "); 17821 TimeUtils.formatDuration(wtimeUsed, sb); 17822 sb.append(" ("); 17823 sb.append((wtimeUsed*100)/realtimeSince); 17824 sb.append("%)"); 17825 Slog.i(TAG, sb.toString()); 17826 sb.setLength(0); 17827 sb.append("CPU for "); 17828 app.toShortString(sb); 17829 sb.append(": over "); 17830 TimeUtils.formatDuration(uptimeSince, sb); 17831 sb.append(" used "); 17832 TimeUtils.formatDuration(cputimeUsed, sb); 17833 sb.append(" ("); 17834 sb.append((cputimeUsed*100)/uptimeSince); 17835 sb.append("%)"); 17836 Slog.i(TAG, sb.toString()); 17837 } 17838 // If a process has held a wake lock for more 17839 // than 50% of the time during this period, 17840 // that sounds bad. Kill! 17841 if (doWakeKills && realtimeSince > 0 17842 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17843 synchronized (stats) { 17844 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17845 realtimeSince, wtimeUsed); 17846 } 17847 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17848 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17849 } else if (doCpuKills && uptimeSince > 0 17850 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17851 synchronized (stats) { 17852 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17853 uptimeSince, cputimeUsed); 17854 } 17855 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17856 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17857 } else { 17858 app.lastWakeTime = wtime; 17859 app.lastCpuTime = app.curCpuTime; 17860 } 17861 } 17862 } 17863 } 17864 17865 private final boolean applyOomAdjLocked(ProcessRecord app, 17866 ProcessRecord TOP_APP, boolean doingAll, long now) { 17867 boolean success = true; 17868 17869 if (app.curRawAdj != app.setRawAdj) { 17870 app.setRawAdj = app.curRawAdj; 17871 } 17872 17873 int changes = 0; 17874 17875 if (app.curAdj != app.setAdj) { 17876 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17877 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17878 TAG, "Set " + app.pid + " " + app.processName + 17879 " adj " + app.curAdj + ": " + app.adjType); 17880 app.setAdj = app.curAdj; 17881 } 17882 17883 if (app.setSchedGroup != app.curSchedGroup) { 17884 app.setSchedGroup = app.curSchedGroup; 17885 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17886 "Setting process group of " + app.processName 17887 + " to " + app.curSchedGroup); 17888 if (app.waitingToKill != null && 17889 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17890 app.kill(app.waitingToKill, true); 17891 success = false; 17892 } else { 17893 if (true) { 17894 long oldId = Binder.clearCallingIdentity(); 17895 try { 17896 Process.setProcessGroup(app.pid, app.curSchedGroup); 17897 } catch (Exception e) { 17898 Slog.w(TAG, "Failed setting process group of " + app.pid 17899 + " to " + app.curSchedGroup); 17900 e.printStackTrace(); 17901 } finally { 17902 Binder.restoreCallingIdentity(oldId); 17903 } 17904 } else { 17905 if (app.thread != null) { 17906 try { 17907 app.thread.setSchedulingGroup(app.curSchedGroup); 17908 } catch (RemoteException e) { 17909 } 17910 } 17911 } 17912 Process.setSwappiness(app.pid, 17913 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17914 } 17915 } 17916 if (app.repForegroundActivities != app.foregroundActivities) { 17917 app.repForegroundActivities = app.foregroundActivities; 17918 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17919 } 17920 if (app.repProcState != app.curProcState) { 17921 app.repProcState = app.curProcState; 17922 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17923 if (app.thread != null) { 17924 try { 17925 if (false) { 17926 //RuntimeException h = new RuntimeException("here"); 17927 Slog.i(TAG, "Sending new process state " + app.repProcState 17928 + " to " + app /*, h*/); 17929 } 17930 app.thread.setProcessState(app.repProcState); 17931 } catch (RemoteException e) { 17932 } 17933 } 17934 } 17935 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17936 app.setProcState)) { 17937 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17938 // Experimental code to more aggressively collect pss while 17939 // running test... the problem is that this tends to collect 17940 // the data right when a process is transitioning between process 17941 // states, which well tend to give noisy data. 17942 long start = SystemClock.uptimeMillis(); 17943 long pss = Debug.getPss(app.pid, mTmpLong, null); 17944 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17945 mPendingPssProcesses.remove(app); 17946 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17947 + " to " + app.curProcState + ": " 17948 + (SystemClock.uptimeMillis()-start) + "ms"); 17949 } 17950 app.lastStateTime = now; 17951 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17952 mTestPssMode, isSleeping(), now); 17953 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17954 + ProcessList.makeProcStateString(app.setProcState) + " to " 17955 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17956 + (app.nextPssTime-now) + ": " + app); 17957 } else { 17958 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17959 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17960 mTestPssMode)))) { 17961 requestPssLocked(app, app.setProcState); 17962 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17963 mTestPssMode, isSleeping(), now); 17964 } else if (false && DEBUG_PSS) { 17965 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17966 } 17967 } 17968 if (app.setProcState != app.curProcState) { 17969 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17970 "Proc state change of " + app.processName 17971 + " to " + app.curProcState); 17972 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17973 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17974 if (setImportant && !curImportant) { 17975 // This app is no longer something we consider important enough to allow to 17976 // use arbitrary amounts of battery power. Note 17977 // its current wake lock time to later know to kill it if 17978 // it is not behaving well. 17979 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17980 synchronized (stats) { 17981 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17982 app.pid, SystemClock.elapsedRealtime()); 17983 } 17984 app.lastCpuTime = app.curCpuTime; 17985 17986 } 17987 app.setProcState = app.curProcState; 17988 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17989 app.notCachedSinceIdle = false; 17990 } 17991 if (!doingAll) { 17992 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17993 } else { 17994 app.procStateChanged = true; 17995 } 17996 } 17997 17998 if (changes != 0) { 17999 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 18000 int i = mPendingProcessChanges.size()-1; 18001 ProcessChangeItem item = null; 18002 while (i >= 0) { 18003 item = mPendingProcessChanges.get(i); 18004 if (item.pid == app.pid) { 18005 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18006 break; 18007 } 18008 i--; 18009 } 18010 if (i < 0) { 18011 // No existing item in pending changes; need a new one. 18012 final int NA = mAvailProcessChanges.size(); 18013 if (NA > 0) { 18014 item = mAvailProcessChanges.remove(NA-1); 18015 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18016 } else { 18017 item = new ProcessChangeItem(); 18018 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18019 } 18020 item.changes = 0; 18021 item.pid = app.pid; 18022 item.uid = app.info.uid; 18023 if (mPendingProcessChanges.size() == 0) { 18024 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18025 "*** Enqueueing dispatch processes changed!"); 18026 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18027 } 18028 mPendingProcessChanges.add(item); 18029 } 18030 item.changes |= changes; 18031 item.processState = app.repProcState; 18032 item.foregroundActivities = app.repForegroundActivities; 18033 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18034 + Integer.toHexString(System.identityHashCode(item)) 18035 + " " + app.toShortString() + ": changes=" + item.changes 18036 + " procState=" + item.processState 18037 + " foreground=" + item.foregroundActivities 18038 + " type=" + app.adjType + " source=" + app.adjSource 18039 + " target=" + app.adjTarget); 18040 } 18041 18042 return success; 18043 } 18044 18045 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18046 if (proc.thread != null) { 18047 if (proc.baseProcessTracker != null) { 18048 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18049 } 18050 if (proc.repProcState >= 0) { 18051 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18052 proc.repProcState); 18053 } 18054 } 18055 } 18056 18057 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18058 ProcessRecord TOP_APP, boolean doingAll, long now) { 18059 if (app.thread == null) { 18060 return false; 18061 } 18062 18063 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18064 18065 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18066 } 18067 18068 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18069 boolean oomAdj) { 18070 if (isForeground != proc.foregroundServices) { 18071 proc.foregroundServices = isForeground; 18072 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18073 proc.info.uid); 18074 if (isForeground) { 18075 if (curProcs == null) { 18076 curProcs = new ArrayList<ProcessRecord>(); 18077 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18078 } 18079 if (!curProcs.contains(proc)) { 18080 curProcs.add(proc); 18081 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18082 proc.info.packageName, proc.info.uid); 18083 } 18084 } else { 18085 if (curProcs != null) { 18086 if (curProcs.remove(proc)) { 18087 mBatteryStatsService.noteEvent( 18088 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18089 proc.info.packageName, proc.info.uid); 18090 if (curProcs.size() <= 0) { 18091 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18092 } 18093 } 18094 } 18095 } 18096 if (oomAdj) { 18097 updateOomAdjLocked(); 18098 } 18099 } 18100 } 18101 18102 private final ActivityRecord resumedAppLocked() { 18103 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18104 String pkg; 18105 int uid; 18106 if (act != null) { 18107 pkg = act.packageName; 18108 uid = act.info.applicationInfo.uid; 18109 } else { 18110 pkg = null; 18111 uid = -1; 18112 } 18113 // Has the UID or resumed package name changed? 18114 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18115 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18116 if (mCurResumedPackage != null) { 18117 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18118 mCurResumedPackage, mCurResumedUid); 18119 } 18120 mCurResumedPackage = pkg; 18121 mCurResumedUid = uid; 18122 if (mCurResumedPackage != null) { 18123 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18124 mCurResumedPackage, mCurResumedUid); 18125 } 18126 } 18127 return act; 18128 } 18129 18130 final boolean updateOomAdjLocked(ProcessRecord app) { 18131 final ActivityRecord TOP_ACT = resumedAppLocked(); 18132 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18133 final boolean wasCached = app.cached; 18134 18135 mAdjSeq++; 18136 18137 // This is the desired cached adjusment we want to tell it to use. 18138 // If our app is currently cached, we know it, and that is it. Otherwise, 18139 // we don't know it yet, and it needs to now be cached we will then 18140 // need to do a complete oom adj. 18141 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18142 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18143 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18144 SystemClock.uptimeMillis()); 18145 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18146 // Changed to/from cached state, so apps after it in the LRU 18147 // list may also be changed. 18148 updateOomAdjLocked(); 18149 } 18150 return success; 18151 } 18152 18153 final void updateOomAdjLocked() { 18154 final ActivityRecord TOP_ACT = resumedAppLocked(); 18155 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18156 final long now = SystemClock.uptimeMillis(); 18157 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18158 final int N = mLruProcesses.size(); 18159 18160 if (false) { 18161 RuntimeException e = new RuntimeException(); 18162 e.fillInStackTrace(); 18163 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18164 } 18165 18166 mAdjSeq++; 18167 mNewNumServiceProcs = 0; 18168 mNewNumAServiceProcs = 0; 18169 18170 final int emptyProcessLimit; 18171 final int cachedProcessLimit; 18172 if (mProcessLimit <= 0) { 18173 emptyProcessLimit = cachedProcessLimit = 0; 18174 } else if (mProcessLimit == 1) { 18175 emptyProcessLimit = 1; 18176 cachedProcessLimit = 0; 18177 } else { 18178 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18179 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18180 } 18181 18182 // Let's determine how many processes we have running vs. 18183 // how many slots we have for background processes; we may want 18184 // to put multiple processes in a slot of there are enough of 18185 // them. 18186 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18187 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18188 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18189 if (numEmptyProcs > cachedProcessLimit) { 18190 // If there are more empty processes than our limit on cached 18191 // processes, then use the cached process limit for the factor. 18192 // This ensures that the really old empty processes get pushed 18193 // down to the bottom, so if we are running low on memory we will 18194 // have a better chance at keeping around more cached processes 18195 // instead of a gazillion empty processes. 18196 numEmptyProcs = cachedProcessLimit; 18197 } 18198 int emptyFactor = numEmptyProcs/numSlots; 18199 if (emptyFactor < 1) emptyFactor = 1; 18200 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18201 if (cachedFactor < 1) cachedFactor = 1; 18202 int stepCached = 0; 18203 int stepEmpty = 0; 18204 int numCached = 0; 18205 int numEmpty = 0; 18206 int numTrimming = 0; 18207 18208 mNumNonCachedProcs = 0; 18209 mNumCachedHiddenProcs = 0; 18210 18211 // First update the OOM adjustment for each of the 18212 // application processes based on their current state. 18213 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18214 int nextCachedAdj = curCachedAdj+1; 18215 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18216 int nextEmptyAdj = curEmptyAdj+2; 18217 for (int i=N-1; i>=0; i--) { 18218 ProcessRecord app = mLruProcesses.get(i); 18219 if (!app.killedByAm && app.thread != null) { 18220 app.procStateChanged = false; 18221 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18222 18223 // If we haven't yet assigned the final cached adj 18224 // to the process, do that now. 18225 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18226 switch (app.curProcState) { 18227 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18228 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18229 // This process is a cached process holding activities... 18230 // assign it the next cached value for that type, and then 18231 // step that cached level. 18232 app.curRawAdj = curCachedAdj; 18233 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18234 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18235 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18236 + ")"); 18237 if (curCachedAdj != nextCachedAdj) { 18238 stepCached++; 18239 if (stepCached >= cachedFactor) { 18240 stepCached = 0; 18241 curCachedAdj = nextCachedAdj; 18242 nextCachedAdj += 2; 18243 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18244 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18245 } 18246 } 18247 } 18248 break; 18249 default: 18250 // For everything else, assign next empty cached process 18251 // level and bump that up. Note that this means that 18252 // long-running services that have dropped down to the 18253 // cached level will be treated as empty (since their process 18254 // state is still as a service), which is what we want. 18255 app.curRawAdj = curEmptyAdj; 18256 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18257 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18258 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18259 + ")"); 18260 if (curEmptyAdj != nextEmptyAdj) { 18261 stepEmpty++; 18262 if (stepEmpty >= emptyFactor) { 18263 stepEmpty = 0; 18264 curEmptyAdj = nextEmptyAdj; 18265 nextEmptyAdj += 2; 18266 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18267 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18268 } 18269 } 18270 } 18271 break; 18272 } 18273 } 18274 18275 applyOomAdjLocked(app, TOP_APP, true, now); 18276 18277 // Count the number of process types. 18278 switch (app.curProcState) { 18279 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18280 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18281 mNumCachedHiddenProcs++; 18282 numCached++; 18283 if (numCached > cachedProcessLimit) { 18284 app.kill("cached #" + numCached, true); 18285 } 18286 break; 18287 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18288 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18289 && app.lastActivityTime < oldTime) { 18290 app.kill("empty for " 18291 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18292 / 1000) + "s", true); 18293 } else { 18294 numEmpty++; 18295 if (numEmpty > emptyProcessLimit) { 18296 app.kill("empty #" + numEmpty, true); 18297 } 18298 } 18299 break; 18300 default: 18301 mNumNonCachedProcs++; 18302 break; 18303 } 18304 18305 if (app.isolated && app.services.size() <= 0) { 18306 // If this is an isolated process, and there are no 18307 // services running in it, then the process is no longer 18308 // needed. We agressively kill these because we can by 18309 // definition not re-use the same process again, and it is 18310 // good to avoid having whatever code was running in them 18311 // left sitting around after no longer needed. 18312 app.kill("isolated not needed", true); 18313 } 18314 18315 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18316 && !app.killedByAm) { 18317 numTrimming++; 18318 } 18319 } 18320 } 18321 18322 mNumServiceProcs = mNewNumServiceProcs; 18323 18324 // Now determine the memory trimming level of background processes. 18325 // Unfortunately we need to start at the back of the list to do this 18326 // properly. We only do this if the number of background apps we 18327 // are managing to keep around is less than half the maximum we desire; 18328 // if we are keeping a good number around, we'll let them use whatever 18329 // memory they want. 18330 final int numCachedAndEmpty = numCached + numEmpty; 18331 int memFactor; 18332 if (numCached <= ProcessList.TRIM_CACHED_APPS 18333 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18334 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18335 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18336 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18337 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18338 } else { 18339 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18340 } 18341 } else { 18342 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18343 } 18344 // We always allow the memory level to go up (better). We only allow it to go 18345 // down if we are in a state where that is allowed, *and* the total number of processes 18346 // has gone down since last time. 18347 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18348 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18349 + " last=" + mLastNumProcesses); 18350 if (memFactor > mLastMemoryLevel) { 18351 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18352 memFactor = mLastMemoryLevel; 18353 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18354 } 18355 } 18356 mLastMemoryLevel = memFactor; 18357 mLastNumProcesses = mLruProcesses.size(); 18358 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18359 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18360 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18361 if (mLowRamStartTime == 0) { 18362 mLowRamStartTime = now; 18363 } 18364 int step = 0; 18365 int fgTrimLevel; 18366 switch (memFactor) { 18367 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18368 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18369 break; 18370 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18371 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18372 break; 18373 default: 18374 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18375 break; 18376 } 18377 int factor = numTrimming/3; 18378 int minFactor = 2; 18379 if (mHomeProcess != null) minFactor++; 18380 if (mPreviousProcess != null) minFactor++; 18381 if (factor < minFactor) factor = minFactor; 18382 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18383 for (int i=N-1; i>=0; i--) { 18384 ProcessRecord app = mLruProcesses.get(i); 18385 if (allChanged || app.procStateChanged) { 18386 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18387 app.procStateChanged = false; 18388 } 18389 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18390 && !app.killedByAm) { 18391 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18392 try { 18393 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18394 "Trimming memory of " + app.processName 18395 + " to " + curLevel); 18396 app.thread.scheduleTrimMemory(curLevel); 18397 } catch (RemoteException e) { 18398 } 18399 if (false) { 18400 // For now we won't do this; our memory trimming seems 18401 // to be good enough at this point that destroying 18402 // activities causes more harm than good. 18403 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18404 && app != mHomeProcess && app != mPreviousProcess) { 18405 // Need to do this on its own message because the stack may not 18406 // be in a consistent state at this point. 18407 // For these apps we will also finish their activities 18408 // to help them free memory. 18409 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18410 } 18411 } 18412 } 18413 app.trimMemoryLevel = curLevel; 18414 step++; 18415 if (step >= factor) { 18416 step = 0; 18417 switch (curLevel) { 18418 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18419 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18420 break; 18421 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18422 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18423 break; 18424 } 18425 } 18426 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18427 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18428 && app.thread != null) { 18429 try { 18430 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18431 "Trimming memory of heavy-weight " + app.processName 18432 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18433 app.thread.scheduleTrimMemory( 18434 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18435 } catch (RemoteException e) { 18436 } 18437 } 18438 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18439 } else { 18440 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18441 || app.systemNoUi) && app.pendingUiClean) { 18442 // If this application is now in the background and it 18443 // had done UI, then give it the special trim level to 18444 // have it free UI resources. 18445 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18446 if (app.trimMemoryLevel < level && app.thread != null) { 18447 try { 18448 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18449 "Trimming memory of bg-ui " + app.processName 18450 + " to " + level); 18451 app.thread.scheduleTrimMemory(level); 18452 } catch (RemoteException e) { 18453 } 18454 } 18455 app.pendingUiClean = false; 18456 } 18457 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18458 try { 18459 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18460 "Trimming memory of fg " + app.processName 18461 + " to " + fgTrimLevel); 18462 app.thread.scheduleTrimMemory(fgTrimLevel); 18463 } catch (RemoteException e) { 18464 } 18465 } 18466 app.trimMemoryLevel = fgTrimLevel; 18467 } 18468 } 18469 } else { 18470 if (mLowRamStartTime != 0) { 18471 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18472 mLowRamStartTime = 0; 18473 } 18474 for (int i=N-1; i>=0; i--) { 18475 ProcessRecord app = mLruProcesses.get(i); 18476 if (allChanged || app.procStateChanged) { 18477 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18478 app.procStateChanged = false; 18479 } 18480 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18481 || app.systemNoUi) && app.pendingUiClean) { 18482 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18483 && app.thread != null) { 18484 try { 18485 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18486 "Trimming memory of ui hidden " + app.processName 18487 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18488 app.thread.scheduleTrimMemory( 18489 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18490 } catch (RemoteException e) { 18491 } 18492 } 18493 app.pendingUiClean = false; 18494 } 18495 app.trimMemoryLevel = 0; 18496 } 18497 } 18498 18499 if (mAlwaysFinishActivities) { 18500 // Need to do this on its own message because the stack may not 18501 // be in a consistent state at this point. 18502 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18503 } 18504 18505 if (allChanged) { 18506 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18507 } 18508 18509 if (mProcessStats.shouldWriteNowLocked(now)) { 18510 mHandler.post(new Runnable() { 18511 @Override public void run() { 18512 synchronized (ActivityManagerService.this) { 18513 mProcessStats.writeStateAsyncLocked(); 18514 } 18515 } 18516 }); 18517 } 18518 18519 if (DEBUG_OOM_ADJ) { 18520 if (false) { 18521 RuntimeException here = new RuntimeException("here"); 18522 here.fillInStackTrace(); 18523 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18524 } else { 18525 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18526 } 18527 } 18528 } 18529 18530 final void trimApplications() { 18531 synchronized (this) { 18532 int i; 18533 18534 // First remove any unused application processes whose package 18535 // has been removed. 18536 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18537 final ProcessRecord app = mRemovedProcesses.get(i); 18538 if (app.activities.size() == 0 18539 && app.curReceiver == null && app.services.size() == 0) { 18540 Slog.i( 18541 TAG, "Exiting empty application process " 18542 + app.processName + " (" 18543 + (app.thread != null ? app.thread.asBinder() : null) 18544 + ")\n"); 18545 if (app.pid > 0 && app.pid != MY_PID) { 18546 app.kill("empty", false); 18547 } else { 18548 try { 18549 app.thread.scheduleExit(); 18550 } catch (Exception e) { 18551 // Ignore exceptions. 18552 } 18553 } 18554 cleanUpApplicationRecordLocked(app, false, true, -1); 18555 mRemovedProcesses.remove(i); 18556 18557 if (app.persistent) { 18558 addAppLocked(app.info, false, null /* ABI override */); 18559 } 18560 } 18561 } 18562 18563 // Now update the oom adj for all processes. 18564 updateOomAdjLocked(); 18565 } 18566 } 18567 18568 /** This method sends the specified signal to each of the persistent apps */ 18569 public void signalPersistentProcesses(int sig) throws RemoteException { 18570 if (sig != Process.SIGNAL_USR1) { 18571 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18572 } 18573 18574 synchronized (this) { 18575 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18576 != PackageManager.PERMISSION_GRANTED) { 18577 throw new SecurityException("Requires permission " 18578 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18579 } 18580 18581 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18582 ProcessRecord r = mLruProcesses.get(i); 18583 if (r.thread != null && r.persistent) { 18584 Process.sendSignal(r.pid, sig); 18585 } 18586 } 18587 } 18588 } 18589 18590 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18591 if (proc == null || proc == mProfileProc) { 18592 proc = mProfileProc; 18593 profileType = mProfileType; 18594 clearProfilerLocked(); 18595 } 18596 if (proc == null) { 18597 return; 18598 } 18599 try { 18600 proc.thread.profilerControl(false, null, profileType); 18601 } catch (RemoteException e) { 18602 throw new IllegalStateException("Process disappeared"); 18603 } 18604 } 18605 18606 private void clearProfilerLocked() { 18607 if (mProfileFd != null) { 18608 try { 18609 mProfileFd.close(); 18610 } catch (IOException e) { 18611 } 18612 } 18613 mProfileApp = null; 18614 mProfileProc = null; 18615 mProfileFile = null; 18616 mProfileType = 0; 18617 mAutoStopProfiler = false; 18618 mSamplingInterval = 0; 18619 } 18620 18621 public boolean profileControl(String process, int userId, boolean start, 18622 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18623 18624 try { 18625 synchronized (this) { 18626 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18627 // its own permission. 18628 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18629 != PackageManager.PERMISSION_GRANTED) { 18630 throw new SecurityException("Requires permission " 18631 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18632 } 18633 18634 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18635 throw new IllegalArgumentException("null profile info or fd"); 18636 } 18637 18638 ProcessRecord proc = null; 18639 if (process != null) { 18640 proc = findProcessLocked(process, userId, "profileControl"); 18641 } 18642 18643 if (start && (proc == null || proc.thread == null)) { 18644 throw new IllegalArgumentException("Unknown process: " + process); 18645 } 18646 18647 if (start) { 18648 stopProfilerLocked(null, 0); 18649 setProfileApp(proc.info, proc.processName, profilerInfo); 18650 mProfileProc = proc; 18651 mProfileType = profileType; 18652 ParcelFileDescriptor fd = profilerInfo.profileFd; 18653 try { 18654 fd = fd.dup(); 18655 } catch (IOException e) { 18656 fd = null; 18657 } 18658 profilerInfo.profileFd = fd; 18659 proc.thread.profilerControl(start, profilerInfo, profileType); 18660 fd = null; 18661 mProfileFd = null; 18662 } else { 18663 stopProfilerLocked(proc, profileType); 18664 if (profilerInfo != null && profilerInfo.profileFd != null) { 18665 try { 18666 profilerInfo.profileFd.close(); 18667 } catch (IOException e) { 18668 } 18669 } 18670 } 18671 18672 return true; 18673 } 18674 } catch (RemoteException e) { 18675 throw new IllegalStateException("Process disappeared"); 18676 } finally { 18677 if (profilerInfo != null && profilerInfo.profileFd != null) { 18678 try { 18679 profilerInfo.profileFd.close(); 18680 } catch (IOException e) { 18681 } 18682 } 18683 } 18684 } 18685 18686 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18687 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18688 userId, true, ALLOW_FULL_ONLY, callName, null); 18689 ProcessRecord proc = null; 18690 try { 18691 int pid = Integer.parseInt(process); 18692 synchronized (mPidsSelfLocked) { 18693 proc = mPidsSelfLocked.get(pid); 18694 } 18695 } catch (NumberFormatException e) { 18696 } 18697 18698 if (proc == null) { 18699 ArrayMap<String, SparseArray<ProcessRecord>> all 18700 = mProcessNames.getMap(); 18701 SparseArray<ProcessRecord> procs = all.get(process); 18702 if (procs != null && procs.size() > 0) { 18703 proc = procs.valueAt(0); 18704 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18705 for (int i=1; i<procs.size(); i++) { 18706 ProcessRecord thisProc = procs.valueAt(i); 18707 if (thisProc.userId == userId) { 18708 proc = thisProc; 18709 break; 18710 } 18711 } 18712 } 18713 } 18714 } 18715 18716 return proc; 18717 } 18718 18719 public boolean dumpHeap(String process, int userId, boolean managed, 18720 String path, ParcelFileDescriptor fd) throws RemoteException { 18721 18722 try { 18723 synchronized (this) { 18724 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18725 // its own permission (same as profileControl). 18726 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18727 != PackageManager.PERMISSION_GRANTED) { 18728 throw new SecurityException("Requires permission " 18729 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18730 } 18731 18732 if (fd == null) { 18733 throw new IllegalArgumentException("null fd"); 18734 } 18735 18736 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18737 if (proc == null || proc.thread == null) { 18738 throw new IllegalArgumentException("Unknown process: " + process); 18739 } 18740 18741 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18742 if (!isDebuggable) { 18743 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18744 throw new SecurityException("Process not debuggable: " + proc); 18745 } 18746 } 18747 18748 proc.thread.dumpHeap(managed, path, fd); 18749 fd = null; 18750 return true; 18751 } 18752 } catch (RemoteException e) { 18753 throw new IllegalStateException("Process disappeared"); 18754 } finally { 18755 if (fd != null) { 18756 try { 18757 fd.close(); 18758 } catch (IOException e) { 18759 } 18760 } 18761 } 18762 } 18763 18764 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18765 public void monitor() { 18766 synchronized (this) { } 18767 } 18768 18769 void onCoreSettingsChange(Bundle settings) { 18770 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18771 ProcessRecord processRecord = mLruProcesses.get(i); 18772 try { 18773 if (processRecord.thread != null) { 18774 processRecord.thread.setCoreSettings(settings); 18775 } 18776 } catch (RemoteException re) { 18777 /* ignore */ 18778 } 18779 } 18780 } 18781 18782 // Multi-user methods 18783 18784 /** 18785 * Start user, if its not already running, but don't bring it to foreground. 18786 */ 18787 @Override 18788 public boolean startUserInBackground(final int userId) { 18789 return startUser(userId, /* foreground */ false); 18790 } 18791 18792 /** 18793 * Start user, if its not already running, and bring it to foreground. 18794 */ 18795 boolean startUserInForeground(final int userId, Dialog dlg) { 18796 boolean result = startUser(userId, /* foreground */ true); 18797 dlg.dismiss(); 18798 return result; 18799 } 18800 18801 /** 18802 * Refreshes the list of users related to the current user when either a 18803 * user switch happens or when a new related user is started in the 18804 * background. 18805 */ 18806 private void updateCurrentProfileIdsLocked() { 18807 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18808 mCurrentUserId, false /* enabledOnly */); 18809 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18810 for (int i = 0; i < currentProfileIds.length; i++) { 18811 currentProfileIds[i] = profiles.get(i).id; 18812 } 18813 mCurrentProfileIds = currentProfileIds; 18814 18815 synchronized (mUserProfileGroupIdsSelfLocked) { 18816 mUserProfileGroupIdsSelfLocked.clear(); 18817 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18818 for (int i = 0; i < users.size(); i++) { 18819 UserInfo user = users.get(i); 18820 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18821 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18822 } 18823 } 18824 } 18825 } 18826 18827 private Set getProfileIdsLocked(int userId) { 18828 Set userIds = new HashSet<Integer>(); 18829 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18830 userId, false /* enabledOnly */); 18831 for (UserInfo user : profiles) { 18832 userIds.add(Integer.valueOf(user.id)); 18833 } 18834 return userIds; 18835 } 18836 18837 @Override 18838 public boolean switchUser(final int userId) { 18839 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18840 String userName; 18841 synchronized (this) { 18842 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18843 if (userInfo == null) { 18844 Slog.w(TAG, "No user info for user #" + userId); 18845 return false; 18846 } 18847 if (userInfo.isManagedProfile()) { 18848 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18849 return false; 18850 } 18851 userName = userInfo.name; 18852 mTargetUserId = userId; 18853 } 18854 mHandler.removeMessages(START_USER_SWITCH_MSG); 18855 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18856 return true; 18857 } 18858 18859 private void showUserSwitchDialog(int userId, String userName) { 18860 // The dialog will show and then initiate the user switch by calling startUserInForeground 18861 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18862 true /* above system */); 18863 d.show(); 18864 } 18865 18866 private boolean startUser(final int userId, final boolean foreground) { 18867 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18868 != PackageManager.PERMISSION_GRANTED) { 18869 String msg = "Permission Denial: switchUser() from pid=" 18870 + Binder.getCallingPid() 18871 + ", uid=" + Binder.getCallingUid() 18872 + " requires " + INTERACT_ACROSS_USERS_FULL; 18873 Slog.w(TAG, msg); 18874 throw new SecurityException(msg); 18875 } 18876 18877 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18878 18879 final long ident = Binder.clearCallingIdentity(); 18880 try { 18881 synchronized (this) { 18882 final int oldUserId = mCurrentUserId; 18883 if (oldUserId == userId) { 18884 return true; 18885 } 18886 18887 mStackSupervisor.setLockTaskModeLocked(null, false); 18888 18889 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18890 if (userInfo == null) { 18891 Slog.w(TAG, "No user info for user #" + userId); 18892 return false; 18893 } 18894 if (foreground && userInfo.isManagedProfile()) { 18895 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18896 return false; 18897 } 18898 18899 if (foreground) { 18900 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18901 R.anim.screen_user_enter); 18902 } 18903 18904 boolean needStart = false; 18905 18906 // If the user we are switching to is not currently started, then 18907 // we need to start it now. 18908 if (mStartedUsers.get(userId) == null) { 18909 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18910 updateStartedUserArrayLocked(); 18911 needStart = true; 18912 } 18913 18914 final Integer userIdInt = Integer.valueOf(userId); 18915 mUserLru.remove(userIdInt); 18916 mUserLru.add(userIdInt); 18917 18918 if (foreground) { 18919 mCurrentUserId = userId; 18920 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18921 updateCurrentProfileIdsLocked(); 18922 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18923 // Once the internal notion of the active user has switched, we lock the device 18924 // with the option to show the user switcher on the keyguard. 18925 mWindowManager.lockNow(null); 18926 } else { 18927 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18928 updateCurrentProfileIdsLocked(); 18929 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18930 mUserLru.remove(currentUserIdInt); 18931 mUserLru.add(currentUserIdInt); 18932 } 18933 18934 final UserStartedState uss = mStartedUsers.get(userId); 18935 18936 // Make sure user is in the started state. If it is currently 18937 // stopping, we need to knock that off. 18938 if (uss.mState == UserStartedState.STATE_STOPPING) { 18939 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18940 // so we can just fairly silently bring the user back from 18941 // the almost-dead. 18942 uss.mState = UserStartedState.STATE_RUNNING; 18943 updateStartedUserArrayLocked(); 18944 needStart = true; 18945 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18946 // This means ACTION_SHUTDOWN has been sent, so we will 18947 // need to treat this as a new boot of the user. 18948 uss.mState = UserStartedState.STATE_BOOTING; 18949 updateStartedUserArrayLocked(); 18950 needStart = true; 18951 } 18952 18953 if (uss.mState == UserStartedState.STATE_BOOTING) { 18954 // Booting up a new user, need to tell system services about it. 18955 // Note that this is on the same handler as scheduling of broadcasts, 18956 // which is important because it needs to go first. 18957 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18958 } 18959 18960 if (foreground) { 18961 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18962 oldUserId)); 18963 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18964 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18965 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18966 oldUserId, userId, uss)); 18967 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18968 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18969 } 18970 18971 if (needStart) { 18972 // Send USER_STARTED broadcast 18973 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18974 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18975 | Intent.FLAG_RECEIVER_FOREGROUND); 18976 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18977 broadcastIntentLocked(null, null, intent, 18978 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18979 false, false, MY_PID, Process.SYSTEM_UID, userId); 18980 } 18981 18982 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18983 if (userId != UserHandle.USER_OWNER) { 18984 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18985 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18986 broadcastIntentLocked(null, null, intent, null, 18987 new IIntentReceiver.Stub() { 18988 public void performReceive(Intent intent, int resultCode, 18989 String data, Bundle extras, boolean ordered, 18990 boolean sticky, int sendingUser) { 18991 onUserInitialized(uss, foreground, oldUserId, userId); 18992 } 18993 }, 0, null, null, null, AppOpsManager.OP_NONE, 18994 true, false, MY_PID, Process.SYSTEM_UID, 18995 userId); 18996 uss.initializing = true; 18997 } else { 18998 getUserManagerLocked().makeInitialized(userInfo.id); 18999 } 19000 } 19001 19002 if (foreground) { 19003 if (!uss.initializing) { 19004 moveUserToForeground(uss, oldUserId, userId); 19005 } 19006 } else { 19007 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19008 } 19009 19010 if (needStart) { 19011 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19012 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19013 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19014 broadcastIntentLocked(null, null, intent, 19015 null, new IIntentReceiver.Stub() { 19016 @Override 19017 public void performReceive(Intent intent, int resultCode, String data, 19018 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19019 throws RemoteException { 19020 } 19021 }, 0, null, null, 19022 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19023 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19024 } 19025 } 19026 } finally { 19027 Binder.restoreCallingIdentity(ident); 19028 } 19029 19030 return true; 19031 } 19032 19033 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19034 long ident = Binder.clearCallingIdentity(); 19035 try { 19036 Intent intent; 19037 if (oldUserId >= 0) { 19038 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19039 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19040 int count = profiles.size(); 19041 for (int i = 0; i < count; i++) { 19042 int profileUserId = profiles.get(i).id; 19043 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19044 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19045 | Intent.FLAG_RECEIVER_FOREGROUND); 19046 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19047 broadcastIntentLocked(null, null, intent, 19048 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19049 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19050 } 19051 } 19052 if (newUserId >= 0) { 19053 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19054 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19055 int count = profiles.size(); 19056 for (int i = 0; i < count; i++) { 19057 int profileUserId = profiles.get(i).id; 19058 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19059 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19060 | Intent.FLAG_RECEIVER_FOREGROUND); 19061 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19062 broadcastIntentLocked(null, null, intent, 19063 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19064 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19065 } 19066 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19067 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19068 | Intent.FLAG_RECEIVER_FOREGROUND); 19069 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19070 broadcastIntentLocked(null, null, intent, 19071 null, null, 0, null, null, 19072 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19073 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19074 } 19075 } finally { 19076 Binder.restoreCallingIdentity(ident); 19077 } 19078 } 19079 19080 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19081 final int newUserId) { 19082 final int N = mUserSwitchObservers.beginBroadcast(); 19083 if (N > 0) { 19084 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19085 int mCount = 0; 19086 @Override 19087 public void sendResult(Bundle data) throws RemoteException { 19088 synchronized (ActivityManagerService.this) { 19089 if (mCurUserSwitchCallback == this) { 19090 mCount++; 19091 if (mCount == N) { 19092 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19093 } 19094 } 19095 } 19096 } 19097 }; 19098 synchronized (this) { 19099 uss.switching = true; 19100 mCurUserSwitchCallback = callback; 19101 } 19102 for (int i=0; i<N; i++) { 19103 try { 19104 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19105 newUserId, callback); 19106 } catch (RemoteException e) { 19107 } 19108 } 19109 } else { 19110 synchronized (this) { 19111 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19112 } 19113 } 19114 mUserSwitchObservers.finishBroadcast(); 19115 } 19116 19117 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19118 synchronized (this) { 19119 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19120 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19121 } 19122 } 19123 19124 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19125 mCurUserSwitchCallback = null; 19126 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19127 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19128 oldUserId, newUserId, uss)); 19129 } 19130 19131 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19132 synchronized (this) { 19133 if (foreground) { 19134 moveUserToForeground(uss, oldUserId, newUserId); 19135 } 19136 } 19137 19138 completeSwitchAndInitalize(uss, newUserId, true, false); 19139 } 19140 19141 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19142 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19143 if (homeInFront) { 19144 startHomeActivityLocked(newUserId); 19145 } else { 19146 mStackSupervisor.resumeTopActivitiesLocked(); 19147 } 19148 EventLogTags.writeAmSwitchUser(newUserId); 19149 getUserManagerLocked().userForeground(newUserId); 19150 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19151 } 19152 19153 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19154 completeSwitchAndInitalize(uss, newUserId, false, true); 19155 } 19156 19157 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19158 boolean clearInitializing, boolean clearSwitching) { 19159 boolean unfrozen = false; 19160 synchronized (this) { 19161 if (clearInitializing) { 19162 uss.initializing = false; 19163 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19164 } 19165 if (clearSwitching) { 19166 uss.switching = false; 19167 } 19168 if (!uss.switching && !uss.initializing) { 19169 mWindowManager.stopFreezingScreen(); 19170 unfrozen = true; 19171 } 19172 } 19173 if (unfrozen) { 19174 final int N = mUserSwitchObservers.beginBroadcast(); 19175 for (int i=0; i<N; i++) { 19176 try { 19177 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19178 } catch (RemoteException e) { 19179 } 19180 } 19181 mUserSwitchObservers.finishBroadcast(); 19182 } 19183 stopGuestUserIfBackground(); 19184 } 19185 19186 /** 19187 * Stops the guest user if it has gone to the background. 19188 */ 19189 private void stopGuestUserIfBackground() { 19190 synchronized (this) { 19191 final int num = mUserLru.size(); 19192 for (int i = 0; i < num; i++) { 19193 Integer oldUserId = mUserLru.get(i); 19194 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19195 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19196 || oldUss.mState == UserStartedState.STATE_STOPPING 19197 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19198 continue; 19199 } 19200 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19201 if (userInfo.isGuest()) { 19202 // This is a user to be stopped. 19203 stopUserLocked(oldUserId, null); 19204 break; 19205 } 19206 } 19207 } 19208 } 19209 19210 void scheduleStartProfilesLocked() { 19211 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19212 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19213 DateUtils.SECOND_IN_MILLIS); 19214 } 19215 } 19216 19217 void startProfilesLocked() { 19218 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19219 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19220 mCurrentUserId, false /* enabledOnly */); 19221 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19222 for (UserInfo user : profiles) { 19223 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19224 && user.id != mCurrentUserId) { 19225 toStart.add(user); 19226 } 19227 } 19228 final int n = toStart.size(); 19229 int i = 0; 19230 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19231 startUserInBackground(toStart.get(i).id); 19232 } 19233 if (i < n) { 19234 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19235 } 19236 } 19237 19238 void finishUserBoot(UserStartedState uss) { 19239 synchronized (this) { 19240 if (uss.mState == UserStartedState.STATE_BOOTING 19241 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19242 uss.mState = UserStartedState.STATE_RUNNING; 19243 final int userId = uss.mHandle.getIdentifier(); 19244 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19245 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19246 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19247 broadcastIntentLocked(null, null, intent, 19248 null, null, 0, null, null, 19249 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19250 true, false, MY_PID, Process.SYSTEM_UID, userId); 19251 } 19252 } 19253 } 19254 19255 void finishUserSwitch(UserStartedState uss) { 19256 synchronized (this) { 19257 finishUserBoot(uss); 19258 19259 startProfilesLocked(); 19260 19261 int num = mUserLru.size(); 19262 int i = 0; 19263 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19264 Integer oldUserId = mUserLru.get(i); 19265 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19266 if (oldUss == null) { 19267 // Shouldn't happen, but be sane if it does. 19268 mUserLru.remove(i); 19269 num--; 19270 continue; 19271 } 19272 if (oldUss.mState == UserStartedState.STATE_STOPPING 19273 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19274 // This user is already stopping, doesn't count. 19275 num--; 19276 i++; 19277 continue; 19278 } 19279 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19280 // Owner and current can't be stopped, but count as running. 19281 i++; 19282 continue; 19283 } 19284 // This is a user to be stopped. 19285 stopUserLocked(oldUserId, null); 19286 num--; 19287 i++; 19288 } 19289 } 19290 } 19291 19292 @Override 19293 public int stopUser(final int userId, final IStopUserCallback callback) { 19294 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19295 != PackageManager.PERMISSION_GRANTED) { 19296 String msg = "Permission Denial: switchUser() from pid=" 19297 + Binder.getCallingPid() 19298 + ", uid=" + Binder.getCallingUid() 19299 + " requires " + INTERACT_ACROSS_USERS_FULL; 19300 Slog.w(TAG, msg); 19301 throw new SecurityException(msg); 19302 } 19303 if (userId <= 0) { 19304 throw new IllegalArgumentException("Can't stop primary user " + userId); 19305 } 19306 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19307 synchronized (this) { 19308 return stopUserLocked(userId, callback); 19309 } 19310 } 19311 19312 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19313 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19314 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19315 return ActivityManager.USER_OP_IS_CURRENT; 19316 } 19317 19318 final UserStartedState uss = mStartedUsers.get(userId); 19319 if (uss == null) { 19320 // User is not started, nothing to do... but we do need to 19321 // callback if requested. 19322 if (callback != null) { 19323 mHandler.post(new Runnable() { 19324 @Override 19325 public void run() { 19326 try { 19327 callback.userStopped(userId); 19328 } catch (RemoteException e) { 19329 } 19330 } 19331 }); 19332 } 19333 return ActivityManager.USER_OP_SUCCESS; 19334 } 19335 19336 if (callback != null) { 19337 uss.mStopCallbacks.add(callback); 19338 } 19339 19340 if (uss.mState != UserStartedState.STATE_STOPPING 19341 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19342 uss.mState = UserStartedState.STATE_STOPPING; 19343 updateStartedUserArrayLocked(); 19344 19345 long ident = Binder.clearCallingIdentity(); 19346 try { 19347 // We are going to broadcast ACTION_USER_STOPPING and then 19348 // once that is done send a final ACTION_SHUTDOWN and then 19349 // stop the user. 19350 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19351 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19352 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19353 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19354 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19355 // This is the result receiver for the final shutdown broadcast. 19356 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19357 @Override 19358 public void performReceive(Intent intent, int resultCode, String data, 19359 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19360 finishUserStop(uss); 19361 } 19362 }; 19363 // This is the result receiver for the initial stopping broadcast. 19364 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19365 @Override 19366 public void performReceive(Intent intent, int resultCode, String data, 19367 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19368 // On to the next. 19369 synchronized (ActivityManagerService.this) { 19370 if (uss.mState != UserStartedState.STATE_STOPPING) { 19371 // Whoops, we are being started back up. Abort, abort! 19372 return; 19373 } 19374 uss.mState = UserStartedState.STATE_SHUTDOWN; 19375 } 19376 mBatteryStatsService.noteEvent( 19377 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19378 Integer.toString(userId), userId); 19379 mSystemServiceManager.stopUser(userId); 19380 broadcastIntentLocked(null, null, shutdownIntent, 19381 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19382 true, false, MY_PID, Process.SYSTEM_UID, userId); 19383 } 19384 }; 19385 // Kick things off. 19386 broadcastIntentLocked(null, null, stoppingIntent, 19387 null, stoppingReceiver, 0, null, null, 19388 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19389 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19390 } finally { 19391 Binder.restoreCallingIdentity(ident); 19392 } 19393 } 19394 19395 return ActivityManager.USER_OP_SUCCESS; 19396 } 19397 19398 void finishUserStop(UserStartedState uss) { 19399 final int userId = uss.mHandle.getIdentifier(); 19400 boolean stopped; 19401 ArrayList<IStopUserCallback> callbacks; 19402 synchronized (this) { 19403 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19404 if (mStartedUsers.get(userId) != uss) { 19405 stopped = false; 19406 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19407 stopped = false; 19408 } else { 19409 stopped = true; 19410 // User can no longer run. 19411 mStartedUsers.remove(userId); 19412 mUserLru.remove(Integer.valueOf(userId)); 19413 updateStartedUserArrayLocked(); 19414 19415 // Clean up all state and processes associated with the user. 19416 // Kill all the processes for the user. 19417 forceStopUserLocked(userId, "finish user"); 19418 } 19419 19420 // Explicitly remove the old information in mRecentTasks. 19421 removeRecentTasksForUserLocked(userId); 19422 } 19423 19424 for (int i=0; i<callbacks.size(); i++) { 19425 try { 19426 if (stopped) callbacks.get(i).userStopped(userId); 19427 else callbacks.get(i).userStopAborted(userId); 19428 } catch (RemoteException e) { 19429 } 19430 } 19431 19432 if (stopped) { 19433 mSystemServiceManager.cleanupUser(userId); 19434 synchronized (this) { 19435 mStackSupervisor.removeUserLocked(userId); 19436 } 19437 } 19438 } 19439 19440 @Override 19441 public UserInfo getCurrentUser() { 19442 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19443 != PackageManager.PERMISSION_GRANTED) && ( 19444 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19445 != PackageManager.PERMISSION_GRANTED)) { 19446 String msg = "Permission Denial: getCurrentUser() from pid=" 19447 + Binder.getCallingPid() 19448 + ", uid=" + Binder.getCallingUid() 19449 + " requires " + INTERACT_ACROSS_USERS; 19450 Slog.w(TAG, msg); 19451 throw new SecurityException(msg); 19452 } 19453 synchronized (this) { 19454 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19455 return getUserManagerLocked().getUserInfo(userId); 19456 } 19457 } 19458 19459 int getCurrentUserIdLocked() { 19460 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19461 } 19462 19463 @Override 19464 public boolean isUserRunning(int userId, boolean orStopped) { 19465 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19466 != PackageManager.PERMISSION_GRANTED) { 19467 String msg = "Permission Denial: isUserRunning() from pid=" 19468 + Binder.getCallingPid() 19469 + ", uid=" + Binder.getCallingUid() 19470 + " requires " + INTERACT_ACROSS_USERS; 19471 Slog.w(TAG, msg); 19472 throw new SecurityException(msg); 19473 } 19474 synchronized (this) { 19475 return isUserRunningLocked(userId, orStopped); 19476 } 19477 } 19478 19479 boolean isUserRunningLocked(int userId, boolean orStopped) { 19480 UserStartedState state = mStartedUsers.get(userId); 19481 if (state == null) { 19482 return false; 19483 } 19484 if (orStopped) { 19485 return true; 19486 } 19487 return state.mState != UserStartedState.STATE_STOPPING 19488 && state.mState != UserStartedState.STATE_SHUTDOWN; 19489 } 19490 19491 @Override 19492 public int[] getRunningUserIds() { 19493 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19494 != PackageManager.PERMISSION_GRANTED) { 19495 String msg = "Permission Denial: isUserRunning() from pid=" 19496 + Binder.getCallingPid() 19497 + ", uid=" + Binder.getCallingUid() 19498 + " requires " + INTERACT_ACROSS_USERS; 19499 Slog.w(TAG, msg); 19500 throw new SecurityException(msg); 19501 } 19502 synchronized (this) { 19503 return mStartedUserArray; 19504 } 19505 } 19506 19507 private void updateStartedUserArrayLocked() { 19508 int num = 0; 19509 for (int i=0; i<mStartedUsers.size(); i++) { 19510 UserStartedState uss = mStartedUsers.valueAt(i); 19511 // This list does not include stopping users. 19512 if (uss.mState != UserStartedState.STATE_STOPPING 19513 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19514 num++; 19515 } 19516 } 19517 mStartedUserArray = new int[num]; 19518 num = 0; 19519 for (int i=0; i<mStartedUsers.size(); i++) { 19520 UserStartedState uss = mStartedUsers.valueAt(i); 19521 if (uss.mState != UserStartedState.STATE_STOPPING 19522 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19523 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19524 num++; 19525 } 19526 } 19527 } 19528 19529 @Override 19530 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19531 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19532 != PackageManager.PERMISSION_GRANTED) { 19533 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19534 + Binder.getCallingPid() 19535 + ", uid=" + Binder.getCallingUid() 19536 + " requires " + INTERACT_ACROSS_USERS_FULL; 19537 Slog.w(TAG, msg); 19538 throw new SecurityException(msg); 19539 } 19540 19541 mUserSwitchObservers.register(observer); 19542 } 19543 19544 @Override 19545 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19546 mUserSwitchObservers.unregister(observer); 19547 } 19548 19549 private boolean userExists(int userId) { 19550 if (userId == 0) { 19551 return true; 19552 } 19553 UserManagerService ums = getUserManagerLocked(); 19554 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19555 } 19556 19557 int[] getUsersLocked() { 19558 UserManagerService ums = getUserManagerLocked(); 19559 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19560 } 19561 19562 UserManagerService getUserManagerLocked() { 19563 if (mUserManager == null) { 19564 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19565 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19566 } 19567 return mUserManager; 19568 } 19569 19570 private int applyUserId(int uid, int userId) { 19571 return UserHandle.getUid(userId, uid); 19572 } 19573 19574 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19575 if (info == null) return null; 19576 ApplicationInfo newInfo = new ApplicationInfo(info); 19577 newInfo.uid = applyUserId(info.uid, userId); 19578 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19579 + info.packageName; 19580 return newInfo; 19581 } 19582 19583 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19584 if (aInfo == null 19585 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19586 return aInfo; 19587 } 19588 19589 ActivityInfo info = new ActivityInfo(aInfo); 19590 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19591 return info; 19592 } 19593 19594 private final class LocalService extends ActivityManagerInternal { 19595 @Override 19596 public void onWakefulnessChanged(int wakefulness) { 19597 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19598 } 19599 19600 @Override 19601 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19602 String processName, String abiOverride, int uid, Runnable crashHandler) { 19603 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19604 processName, abiOverride, uid, crashHandler); 19605 } 19606 } 19607 19608 /** 19609 * An implementation of IAppTask, that allows an app to manage its own tasks via 19610 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19611 * only the process that calls getAppTasks() can call the AppTask methods. 19612 */ 19613 class AppTaskImpl extends IAppTask.Stub { 19614 private int mTaskId; 19615 private int mCallingUid; 19616 19617 public AppTaskImpl(int taskId, int callingUid) { 19618 mTaskId = taskId; 19619 mCallingUid = callingUid; 19620 } 19621 19622 private void checkCaller() { 19623 if (mCallingUid != Binder.getCallingUid()) { 19624 throw new SecurityException("Caller " + mCallingUid 19625 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19626 } 19627 } 19628 19629 @Override 19630 public void finishAndRemoveTask() { 19631 checkCaller(); 19632 19633 synchronized (ActivityManagerService.this) { 19634 long origId = Binder.clearCallingIdentity(); 19635 try { 19636 if (!removeTaskByIdLocked(mTaskId, false)) { 19637 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19638 } 19639 } finally { 19640 Binder.restoreCallingIdentity(origId); 19641 } 19642 } 19643 } 19644 19645 @Override 19646 public ActivityManager.RecentTaskInfo getTaskInfo() { 19647 checkCaller(); 19648 19649 synchronized (ActivityManagerService.this) { 19650 long origId = Binder.clearCallingIdentity(); 19651 try { 19652 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19653 if (tr == null) { 19654 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19655 } 19656 return createRecentTaskInfoFromTaskRecord(tr); 19657 } finally { 19658 Binder.restoreCallingIdentity(origId); 19659 } 19660 } 19661 } 19662 19663 @Override 19664 public void moveToFront() { 19665 checkCaller(); 19666 19667 final TaskRecord tr; 19668 synchronized (ActivityManagerService.this) { 19669 tr = recentTaskForIdLocked(mTaskId); 19670 if (tr == null) { 19671 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19672 } 19673 if (tr.getRootActivity() != null) { 19674 moveTaskToFrontLocked(tr.taskId, 0, null); 19675 return; 19676 } 19677 } 19678 19679 startActivityFromRecentsInner(tr.taskId, null); 19680 } 19681 19682 @Override 19683 public int startActivity(IBinder whoThread, String callingPackage, 19684 Intent intent, String resolvedType, Bundle options) { 19685 checkCaller(); 19686 19687 int callingUser = UserHandle.getCallingUserId(); 19688 TaskRecord tr; 19689 IApplicationThread appThread; 19690 synchronized (ActivityManagerService.this) { 19691 tr = recentTaskForIdLocked(mTaskId); 19692 if (tr == null) { 19693 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19694 } 19695 appThread = ApplicationThreadNative.asInterface(whoThread); 19696 if (appThread == null) { 19697 throw new IllegalArgumentException("Bad app thread " + appThread); 19698 } 19699 } 19700 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19701 resolvedType, null, null, null, null, 0, 0, null, null, 19702 null, options, callingUser, null, tr); 19703 } 19704 19705 @Override 19706 public void setExcludeFromRecents(boolean exclude) { 19707 checkCaller(); 19708 19709 synchronized (ActivityManagerService.this) { 19710 long origId = Binder.clearCallingIdentity(); 19711 try { 19712 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19713 if (tr == null) { 19714 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19715 } 19716 Intent intent = tr.getBaseIntent(); 19717 if (exclude) { 19718 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19719 } else { 19720 intent.setFlags(intent.getFlags() 19721 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19722 } 19723 } finally { 19724 Binder.restoreCallingIdentity(origId); 19725 } 19726 } 19727 } 19728 } 19729} 19730