ActivityManagerService.java revision 9987b6e867d862c27cd1339d7fa8135b75d565f1
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 android.view.Display; 61import com.android.internal.R; 62import com.android.internal.annotations.GuardedBy; 63import com.android.internal.app.IAppOpsService; 64import com.android.internal.app.IVoiceInteractor; 65import com.android.internal.app.ProcessMap; 66import com.android.internal.app.ProcessStats; 67import com.android.internal.os.BackgroundThread; 68import com.android.internal.os.BatteryStatsImpl; 69import com.android.internal.os.ProcessCpuTracker; 70import com.android.internal.os.TransferPipe; 71import com.android.internal.os.Zygote; 72import com.android.internal.util.FastPrintWriter; 73import com.android.internal.util.FastXmlSerializer; 74import com.android.internal.util.MemInfoReader; 75import com.android.internal.util.Preconditions; 76import com.android.server.AppOpsService; 77import com.android.server.AttributeCache; 78import com.android.server.IntentResolver; 79import com.android.server.LocalServices; 80import com.android.server.ServiceThread; 81import com.android.server.SystemService; 82import com.android.server.SystemServiceManager; 83import com.android.server.Watchdog; 84import com.android.server.am.ActivityStack.ActivityState; 85import com.android.server.firewall.IntentFirewall; 86import com.android.server.pm.Installer; 87import com.android.server.pm.UserManagerService; 88import com.android.server.statusbar.StatusBarManagerInternal; 89import com.android.server.wm.AppTransition; 90import com.android.server.wm.WindowManagerService; 91import com.google.android.collect.Lists; 92import com.google.android.collect.Maps; 93 94import libcore.io.IoUtils; 95 96import org.xmlpull.v1.XmlPullParser; 97import org.xmlpull.v1.XmlPullParserException; 98import org.xmlpull.v1.XmlSerializer; 99 100import android.app.Activity; 101import android.app.ActivityManager; 102import android.app.ActivityManager.RunningTaskInfo; 103import android.app.ActivityManager.StackInfo; 104import android.app.ActivityManagerInternal; 105import android.app.ActivityManagerNative; 106import android.app.ActivityOptions; 107import android.app.ActivityThread; 108import android.app.AlertDialog; 109import android.app.AppGlobals; 110import android.app.ApplicationErrorReport; 111import android.app.Dialog; 112import android.app.IActivityController; 113import android.app.IApplicationThread; 114import android.app.IInstrumentationWatcher; 115import android.app.INotificationManager; 116import android.app.IProcessObserver; 117import android.app.IServiceConnection; 118import android.app.IStopUserCallback; 119import android.app.IUiAutomationConnection; 120import android.app.IUserSwitchObserver; 121import android.app.Instrumentation; 122import android.app.Notification; 123import android.app.NotificationManager; 124import android.app.PendingIntent; 125import android.app.backup.IBackupManager; 126import android.content.ActivityNotFoundException; 127import android.content.BroadcastReceiver; 128import android.content.ClipData; 129import android.content.ComponentCallbacks2; 130import android.content.ComponentName; 131import android.content.ContentProvider; 132import android.content.ContentResolver; 133import android.content.Context; 134import android.content.DialogInterface; 135import android.content.IContentProvider; 136import android.content.IIntentReceiver; 137import android.content.IIntentSender; 138import android.content.Intent; 139import android.content.IntentFilter; 140import android.content.IntentSender; 141import android.content.pm.ActivityInfo; 142import android.content.pm.ApplicationInfo; 143import android.content.pm.ConfigurationInfo; 144import android.content.pm.IPackageDataObserver; 145import android.content.pm.IPackageManager; 146import android.content.pm.InstrumentationInfo; 147import android.content.pm.PackageInfo; 148import android.content.pm.PackageManager; 149import android.content.pm.ParceledListSlice; 150import android.content.pm.UserInfo; 151import android.content.pm.PackageManager.NameNotFoundException; 152import android.content.pm.PathPermission; 153import android.content.pm.ProviderInfo; 154import android.content.pm.ResolveInfo; 155import android.content.pm.ServiceInfo; 156import android.content.res.CompatibilityInfo; 157import android.content.res.Configuration; 158import android.net.Proxy; 159import android.net.ProxyInfo; 160import android.net.Uri; 161import android.os.Binder; 162import android.os.Build; 163import android.os.Bundle; 164import android.os.Debug; 165import android.os.DropBoxManager; 166import android.os.Environment; 167import android.os.FactoryTest; 168import android.os.FileObserver; 169import android.os.FileUtils; 170import android.os.Handler; 171import android.os.IBinder; 172import android.os.IPermissionController; 173import android.os.IProcessInfoService; 174import android.os.IRemoteCallback; 175import android.os.IUserManager; 176import android.os.Looper; 177import android.os.Message; 178import android.os.Parcel; 179import android.os.ParcelFileDescriptor; 180import android.os.PowerManagerInternal; 181import android.os.Process; 182import android.os.RemoteCallbackList; 183import android.os.RemoteException; 184import android.os.SELinux; 185import android.os.ServiceManager; 186import android.os.StrictMode; 187import android.os.SystemClock; 188import android.os.SystemProperties; 189import android.os.UpdateLock; 190import android.os.UserHandle; 191import android.os.UserManager; 192import android.provider.Settings; 193import android.text.format.DateUtils; 194import android.text.format.Time; 195import android.util.AtomicFile; 196import android.util.EventLog; 197import android.util.Log; 198import android.util.Pair; 199import android.util.PrintWriterPrinter; 200import android.util.Slog; 201import android.util.SparseArray; 202import android.util.TimeUtils; 203import android.util.Xml; 204import android.view.Gravity; 205import android.view.LayoutInflater; 206import android.view.View; 207import android.view.WindowManager; 208 209import dalvik.system.VMRuntime; 210 211import java.io.BufferedInputStream; 212import java.io.BufferedOutputStream; 213import java.io.DataInputStream; 214import java.io.DataOutputStream; 215import java.io.File; 216import java.io.FileDescriptor; 217import java.io.FileInputStream; 218import java.io.FileNotFoundException; 219import java.io.FileOutputStream; 220import java.io.IOException; 221import java.io.InputStreamReader; 222import java.io.PrintWriter; 223import java.io.StringWriter; 224import java.lang.ref.WeakReference; 225import java.util.ArrayList; 226import java.util.Arrays; 227import java.util.Collections; 228import java.util.Comparator; 229import java.util.HashMap; 230import java.util.HashSet; 231import java.util.Iterator; 232import java.util.List; 233import java.util.Locale; 234import java.util.Map; 235import java.util.Set; 236import java.util.concurrent.atomic.AtomicBoolean; 237import java.util.concurrent.atomic.AtomicLong; 238 239public final class ActivityManagerService extends ActivityManagerNative 240 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 241 242 private static final String USER_DATA_DIR = "/data/user/"; 243 // File that stores last updated system version and called preboot receivers 244 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 245 246 static final String TAG = "ActivityManager"; 247 static final String TAG_MU = "ActivityManagerServiceMU"; 248 static final boolean DEBUG = false; 249 static final boolean localLOGV = DEBUG; 250 static final boolean DEBUG_BACKUP = localLOGV || false; 251 static final boolean DEBUG_BROADCAST = localLOGV || false; 252 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 253 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 254 static final boolean DEBUG_CLEANUP = localLOGV || false; 255 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 256 static final boolean DEBUG_FOCUS = false; 257 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 258 static final boolean DEBUG_MU = localLOGV || false; 259 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 260 static final boolean DEBUG_LRU = localLOGV || false; 261 static final boolean DEBUG_PAUSE = localLOGV || false; 262 static final boolean DEBUG_POWER = localLOGV || false; 263 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 264 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 265 static final boolean DEBUG_PROCESSES = localLOGV || false; 266 static final boolean DEBUG_PROVIDER = localLOGV || false; 267 static final boolean DEBUG_RESULTS = localLOGV || false; 268 static final boolean DEBUG_SERVICE = localLOGV || false; 269 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 270 static final boolean DEBUG_STACK = localLOGV || false; 271 static final boolean DEBUG_SWITCH = localLOGV || false; 272 static final boolean DEBUG_TASKS = localLOGV || false; 273 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 274 static final boolean DEBUG_TRANSITION = localLOGV || false; 275 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 276 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 277 static final boolean DEBUG_VISBILITY = localLOGV || false; 278 static final boolean DEBUG_PSS = localLOGV || false; 279 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 280 static final boolean DEBUG_RECENTS = localLOGV || false; 281 static final boolean VALIDATE_TOKENS = false; 282 static final boolean SHOW_ACTIVITY_START_TIME = true; 283 284 // Control over CPU and battery monitoring. 285 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 286 static final boolean MONITOR_CPU_USAGE = true; 287 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 288 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 289 static final boolean MONITOR_THREAD_CPU_USAGE = false; 290 291 // The flags that are set for all calls we make to the package manager. 292 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 293 294 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 295 296 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 297 298 // Maximum number recent bitmaps to keep in memory. 299 static final int MAX_RECENT_BITMAPS = 3; 300 301 // Amount of time after a call to stopAppSwitches() during which we will 302 // prevent further untrusted switches from happening. 303 static final long APP_SWITCH_DELAY_TIME = 5*1000; 304 305 // How long we wait for a launched process to attach to the activity manager 306 // before we decide it's never going to come up for real. 307 static final int PROC_START_TIMEOUT = 10*1000; 308 309 // How long we wait for a launched process to attach to the activity manager 310 // before we decide it's never going to come up for real, when the process was 311 // started with a wrapper for instrumentation (such as Valgrind) because it 312 // could take much longer than usual. 313 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 314 315 // How long to wait after going idle before forcing apps to GC. 316 static final int GC_TIMEOUT = 5*1000; 317 318 // The minimum amount of time between successive GC requests for a process. 319 static final int GC_MIN_INTERVAL = 60*1000; 320 321 // The minimum amount of time between successive PSS requests for a process. 322 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 323 324 // The minimum amount of time between successive PSS requests for a process 325 // when the request is due to the memory state being lowered. 326 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 327 328 // The rate at which we check for apps using excessive power -- 15 mins. 329 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 330 331 // The minimum sample duration we will allow before deciding we have 332 // enough data on wake locks to start killing things. 333 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 334 335 // The minimum sample duration we will allow before deciding we have 336 // enough data on CPU usage to start killing things. 337 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 338 339 // How long we allow a receiver to run before giving up on it. 340 static final int BROADCAST_FG_TIMEOUT = 10*1000; 341 static final int BROADCAST_BG_TIMEOUT = 60*1000; 342 343 // How long we wait until we timeout on key dispatching. 344 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 345 346 // How long we wait until we timeout on key dispatching during instrumentation. 347 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 348 349 // Amount of time we wait for observers to handle a user switch before 350 // giving up on them and unfreezing the screen. 351 static final int USER_SWITCH_TIMEOUT = 2*1000; 352 353 // Maximum number of users we allow to be running at a time. 354 static final int MAX_RUNNING_USERS = 3; 355 356 // How long to wait in getAssistContextExtras for the activity and foreground services 357 // to respond with the result. 358 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 359 360 // Maximum number of persisted Uri grants a package is allowed 361 static final int MAX_PERSISTED_URI_GRANTS = 128; 362 363 static final int MY_PID = Process.myPid(); 364 365 static final String[] EMPTY_STRING_ARRAY = new String[0]; 366 367 // How many bytes to write into the dropbox log before truncating 368 static final int DROPBOX_MAX_SIZE = 256 * 1024; 369 370 // Access modes for handleIncomingUser. 371 static final int ALLOW_NON_FULL = 0; 372 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 373 static final int ALLOW_FULL_ONLY = 2; 374 375 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 376 377 // Delay in notifying task stack change listeners (in millis) 378 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 379 380 /** All system services */ 381 SystemServiceManager mSystemServiceManager; 382 383 private Installer mInstaller; 384 385 /** Run all ActivityStacks through this */ 386 ActivityStackSupervisor mStackSupervisor; 387 388 /** Task stack change listeners. */ 389 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 390 new RemoteCallbackList<ITaskStackListener>(); 391 392 public IntentFirewall mIntentFirewall; 393 394 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 395 // default actuion automatically. Important for devices without direct input 396 // devices. 397 private boolean mShowDialogs = true; 398 399 BroadcastQueue mFgBroadcastQueue; 400 BroadcastQueue mBgBroadcastQueue; 401 // Convenient for easy iteration over the queues. Foreground is first 402 // so that dispatch of foreground broadcasts gets precedence. 403 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 404 405 BroadcastQueue broadcastQueueForIntent(Intent intent) { 406 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 407 if (DEBUG_BACKGROUND_BROADCAST) { 408 Slog.i(TAG, "Broadcast intent " + intent + " on " 409 + (isFg ? "foreground" : "background") 410 + " queue"); 411 } 412 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 413 } 414 415 /** 416 * Activity we have told the window manager to have key focus. 417 */ 418 ActivityRecord mFocusedActivity = null; 419 420 /** 421 * List of intents that were used to start the most recent tasks. 422 */ 423 ArrayList<TaskRecord> mRecentTasks; 424 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 425 426 /** 427 * For addAppTask: cached of the last activity component that was added. 428 */ 429 ComponentName mLastAddedTaskComponent; 430 431 /** 432 * For addAppTask: cached of the last activity uid that was added. 433 */ 434 int mLastAddedTaskUid; 435 436 /** 437 * For addAppTask: cached of the last ActivityInfo that was added. 438 */ 439 ActivityInfo mLastAddedTaskActivity; 440 441 public class PendingAssistExtras extends Binder implements Runnable { 442 public final ActivityRecord activity; 443 public final Bundle extras; 444 public final Intent intent; 445 public final String hint; 446 public final int userHandle; 447 public boolean haveResult = false; 448 public Bundle result = null; 449 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 450 String _hint, int _userHandle) { 451 activity = _activity; 452 extras = _extras; 453 intent = _intent; 454 hint = _hint; 455 userHandle = _userHandle; 456 } 457 @Override 458 public void run() { 459 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 460 synchronized (this) { 461 haveResult = true; 462 notifyAll(); 463 } 464 } 465 } 466 467 final ArrayList<PendingAssistExtras> mPendingAssistExtras 468 = new ArrayList<PendingAssistExtras>(); 469 470 /** 471 * Process management. 472 */ 473 final ProcessList mProcessList = new ProcessList(); 474 475 /** 476 * All of the applications we currently have running organized by name. 477 * The keys are strings of the application package name (as 478 * returned by the package manager), and the keys are ApplicationRecord 479 * objects. 480 */ 481 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 482 483 /** 484 * Tracking long-term execution of processes to look for abuse and other 485 * bad app behavior. 486 */ 487 final ProcessStatsService mProcessStats; 488 489 /** 490 * The currently running isolated processes. 491 */ 492 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 493 494 /** 495 * Counter for assigning isolated process uids, to avoid frequently reusing the 496 * same ones. 497 */ 498 int mNextIsolatedProcessUid = 0; 499 500 /** 501 * The currently running heavy-weight process, if any. 502 */ 503 ProcessRecord mHeavyWeightProcess = null; 504 505 /** 506 * The last time that various processes have crashed. 507 */ 508 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 509 510 /** 511 * Information about a process that is currently marked as bad. 512 */ 513 static final class BadProcessInfo { 514 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 515 this.time = time; 516 this.shortMsg = shortMsg; 517 this.longMsg = longMsg; 518 this.stack = stack; 519 } 520 521 final long time; 522 final String shortMsg; 523 final String longMsg; 524 final String stack; 525 } 526 527 /** 528 * Set of applications that we consider to be bad, and will reject 529 * incoming broadcasts from (which the user has no control over). 530 * Processes are added to this set when they have crashed twice within 531 * a minimum amount of time; they are removed from it when they are 532 * later restarted (hopefully due to some user action). The value is the 533 * time it was added to the list. 534 */ 535 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 536 537 /** 538 * All of the processes we currently have running organized by pid. 539 * The keys are the pid running the application. 540 * 541 * <p>NOTE: This object is protected by its own lock, NOT the global 542 * activity manager lock! 543 */ 544 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 545 546 /** 547 * All of the processes that have been forced to be foreground. The key 548 * is the pid of the caller who requested it (we hold a death 549 * link on it). 550 */ 551 abstract class ForegroundToken implements IBinder.DeathRecipient { 552 int pid; 553 IBinder token; 554 } 555 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 556 557 /** 558 * List of records for processes that someone had tried to start before the 559 * system was ready. We don't start them at that point, but ensure they 560 * are started by the time booting is complete. 561 */ 562 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 563 564 /** 565 * List of persistent applications that are in the process 566 * of being started. 567 */ 568 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 569 570 /** 571 * Processes that are being forcibly torn down. 572 */ 573 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * List of running applications, sorted by recent usage. 577 * The first entry in the list is the least recently used. 578 */ 579 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 580 581 /** 582 * Where in mLruProcesses that the processes hosting activities start. 583 */ 584 int mLruProcessActivityStart = 0; 585 586 /** 587 * Where in mLruProcesses that the processes hosting services start. 588 * This is after (lower index) than mLruProcessesActivityStart. 589 */ 590 int mLruProcessServiceStart = 0; 591 592 /** 593 * List of processes that should gc as soon as things are idle. 594 */ 595 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 596 597 /** 598 * Processes we want to collect PSS data from. 599 */ 600 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 601 602 /** 603 * Last time we requested PSS data of all processes. 604 */ 605 long mLastFullPssTime = SystemClock.uptimeMillis(); 606 607 /** 608 * If set, the next time we collect PSS data we should do a full collection 609 * with data from native processes and the kernel. 610 */ 611 boolean mFullPssPending = false; 612 613 /** 614 * This is the process holding what we currently consider to be 615 * the "home" activity. 616 */ 617 ProcessRecord mHomeProcess; 618 619 /** 620 * This is the process holding the activity the user last visited that 621 * is in a different process from the one they are currently in. 622 */ 623 ProcessRecord mPreviousProcess; 624 625 /** 626 * The time at which the previous process was last visible. 627 */ 628 long mPreviousProcessVisibleTime; 629 630 /** 631 * Which uses have been started, so are allowed to run code. 632 */ 633 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 634 635 /** 636 * LRU list of history of current users. Most recently current is at the end. 637 */ 638 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 639 640 /** 641 * Constant array of the users that are currently started. 642 */ 643 int[] mStartedUserArray = new int[] { 0 }; 644 645 /** 646 * Registered observers of the user switching mechanics. 647 */ 648 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 649 = new RemoteCallbackList<IUserSwitchObserver>(); 650 651 /** 652 * Currently active user switch. 653 */ 654 Object mCurUserSwitchCallback; 655 656 /** 657 * Packages that the user has asked to have run in screen size 658 * compatibility mode instead of filling the screen. 659 */ 660 final CompatModePackages mCompatModePackages; 661 662 /** 663 * Set of IntentSenderRecord objects that are currently active. 664 */ 665 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 666 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 667 668 /** 669 * Fingerprints (hashCode()) of stack traces that we've 670 * already logged DropBox entries for. Guarded by itself. If 671 * something (rogue user app) forces this over 672 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 673 */ 674 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 675 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 676 677 /** 678 * Strict Mode background batched logging state. 679 * 680 * The string buffer is guarded by itself, and its lock is also 681 * used to determine if another batched write is already 682 * in-flight. 683 */ 684 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 685 686 /** 687 * Keeps track of all IIntentReceivers that have been registered for 688 * broadcasts. Hash keys are the receiver IBinder, hash value is 689 * a ReceiverList. 690 */ 691 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 692 new HashMap<IBinder, ReceiverList>(); 693 694 /** 695 * Resolver for broadcast intents to registered receivers. 696 * Holds BroadcastFilter (subclass of IntentFilter). 697 */ 698 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 699 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 700 @Override 701 protected boolean allowFilterResult( 702 BroadcastFilter filter, List<BroadcastFilter> dest) { 703 IBinder target = filter.receiverList.receiver.asBinder(); 704 for (int i=dest.size()-1; i>=0; i--) { 705 if (dest.get(i).receiverList.receiver.asBinder() == target) { 706 return false; 707 } 708 } 709 return true; 710 } 711 712 @Override 713 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 714 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 715 || userId == filter.owningUserId) { 716 return super.newResult(filter, match, userId); 717 } 718 return null; 719 } 720 721 @Override 722 protected BroadcastFilter[] newArray(int size) { 723 return new BroadcastFilter[size]; 724 } 725 726 @Override 727 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 728 return packageName.equals(filter.packageName); 729 } 730 }; 731 732 /** 733 * State of all active sticky broadcasts per user. Keys are the action of the 734 * sticky Intent, values are an ArrayList of all broadcasted intents with 735 * that action (which should usually be one). The SparseArray is keyed 736 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 737 * for stickies that are sent to all users. 738 */ 739 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 740 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 741 742 final ActiveServices mServices; 743 744 final static class Association { 745 final int mSourceUid; 746 final String mSourceProcess; 747 final int mTargetUid; 748 final ComponentName mTargetComponent; 749 final String mTargetProcess; 750 751 int mCount; 752 long mTime; 753 754 int mNesting; 755 long mStartTime; 756 757 Association(int sourceUid, String sourceProcess, int targetUid, 758 ComponentName targetComponent, String targetProcess) { 759 mSourceUid = sourceUid; 760 mSourceProcess = sourceProcess; 761 mTargetUid = targetUid; 762 mTargetComponent = targetComponent; 763 mTargetProcess = targetProcess; 764 } 765 } 766 767 /** 768 * When service association tracking is enabled, this is all of the associations we 769 * have seen. Mapping is target uid -> target component -> source uid -> source process name 770 * -> association data. 771 */ 772 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 773 mAssociations = new SparseArray<>(); 774 boolean mTrackingAssociations; 775 776 /** 777 * Backup/restore process management 778 */ 779 String mBackupAppName = null; 780 BackupRecord mBackupTarget = null; 781 782 final ProviderMap mProviderMap; 783 784 /** 785 * List of content providers who have clients waiting for them. The 786 * application is currently being launched and the provider will be 787 * removed from this list once it is published. 788 */ 789 final ArrayList<ContentProviderRecord> mLaunchingProviders 790 = new ArrayList<ContentProviderRecord>(); 791 792 /** 793 * File storing persisted {@link #mGrantedUriPermissions}. 794 */ 795 private final AtomicFile mGrantFile; 796 797 /** XML constants used in {@link #mGrantFile} */ 798 private static final String TAG_URI_GRANTS = "uri-grants"; 799 private static final String TAG_URI_GRANT = "uri-grant"; 800 private static final String ATTR_USER_HANDLE = "userHandle"; 801 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 802 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 803 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 804 private static final String ATTR_TARGET_PKG = "targetPkg"; 805 private static final String ATTR_URI = "uri"; 806 private static final String ATTR_MODE_FLAGS = "modeFlags"; 807 private static final String ATTR_CREATED_TIME = "createdTime"; 808 private static final String ATTR_PREFIX = "prefix"; 809 810 /** 811 * Global set of specific {@link Uri} permissions that have been granted. 812 * This optimized lookup structure maps from {@link UriPermission#targetUid} 813 * to {@link UriPermission#uri} to {@link UriPermission}. 814 */ 815 @GuardedBy("this") 816 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 817 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 818 819 public static class GrantUri { 820 public final int sourceUserId; 821 public final Uri uri; 822 public boolean prefix; 823 824 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 825 this.sourceUserId = sourceUserId; 826 this.uri = uri; 827 this.prefix = prefix; 828 } 829 830 @Override 831 public int hashCode() { 832 int hashCode = 1; 833 hashCode = 31 * hashCode + sourceUserId; 834 hashCode = 31 * hashCode + uri.hashCode(); 835 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 836 return hashCode; 837 } 838 839 @Override 840 public boolean equals(Object o) { 841 if (o instanceof GrantUri) { 842 GrantUri other = (GrantUri) o; 843 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 844 && prefix == other.prefix; 845 } 846 return false; 847 } 848 849 @Override 850 public String toString() { 851 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 852 if (prefix) result += " [prefix]"; 853 return result; 854 } 855 856 public String toSafeString() { 857 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 858 if (prefix) result += " [prefix]"; 859 return result; 860 } 861 862 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 863 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 864 ContentProvider.getUriWithoutUserId(uri), false); 865 } 866 } 867 868 CoreSettingsObserver mCoreSettingsObserver; 869 870 /** 871 * Thread-local storage used to carry caller permissions over through 872 * indirect content-provider access. 873 */ 874 private class Identity { 875 public final IBinder token; 876 public final int pid; 877 public final int uid; 878 879 Identity(IBinder _token, int _pid, int _uid) { 880 token = _token; 881 pid = _pid; 882 uid = _uid; 883 } 884 } 885 886 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 887 888 /** 889 * All information we have collected about the runtime performance of 890 * any user id that can impact battery performance. 891 */ 892 final BatteryStatsService mBatteryStatsService; 893 894 /** 895 * Information about component usage 896 */ 897 UsageStatsManagerInternal mUsageStatsService; 898 899 /** 900 * Information about and control over application operations 901 */ 902 final AppOpsService mAppOpsService; 903 904 /** 905 * Save recent tasks information across reboots. 906 */ 907 final TaskPersister mTaskPersister; 908 909 /** 910 * Current configuration information. HistoryRecord objects are given 911 * a reference to this object to indicate which configuration they are 912 * currently running in, so this object must be kept immutable. 913 */ 914 Configuration mConfiguration = new Configuration(); 915 916 /** 917 * Current sequencing integer of the configuration, for skipping old 918 * configurations. 919 */ 920 int mConfigurationSeq = 0; 921 922 /** 923 * Hardware-reported OpenGLES version. 924 */ 925 final int GL_ES_VERSION; 926 927 /** 928 * List of initialization arguments to pass to all processes when binding applications to them. 929 * For example, references to the commonly used services. 930 */ 931 HashMap<String, IBinder> mAppBindArgs; 932 933 /** 934 * Temporary to avoid allocations. Protected by main lock. 935 */ 936 final StringBuilder mStringBuilder = new StringBuilder(256); 937 938 /** 939 * Used to control how we initialize the service. 940 */ 941 ComponentName mTopComponent; 942 String mTopAction = Intent.ACTION_MAIN; 943 String mTopData; 944 boolean mProcessesReady = false; 945 boolean mSystemReady = false; 946 boolean mBooting = false; 947 boolean mCallFinishBooting = false; 948 boolean mBootAnimationComplete = false; 949 boolean mWaitingUpdate = false; 950 boolean mDidUpdate = false; 951 boolean mOnBattery = false; 952 boolean mLaunchWarningShown = false; 953 954 Context mContext; 955 956 int mFactoryTest; 957 958 boolean mCheckedForSetup; 959 960 /** 961 * The time at which we will allow normal application switches again, 962 * after a call to {@link #stopAppSwitches()}. 963 */ 964 long mAppSwitchesAllowedTime; 965 966 /** 967 * This is set to true after the first switch after mAppSwitchesAllowedTime 968 * is set; any switches after that will clear the time. 969 */ 970 boolean mDidAppSwitch; 971 972 /** 973 * Last time (in realtime) at which we checked for power usage. 974 */ 975 long mLastPowerCheckRealtime; 976 977 /** 978 * Last time (in uptime) at which we checked for power usage. 979 */ 980 long mLastPowerCheckUptime; 981 982 /** 983 * Set while we are wanting to sleep, to prevent any 984 * activities from being started/resumed. 985 */ 986 private boolean mSleeping = false; 987 988 /** 989 * Set while we are running a voice interaction. This overrides 990 * sleeping while it is active. 991 */ 992 private boolean mRunningVoice = false; 993 994 /** 995 * State of external calls telling us if the device is awake or asleep. 996 */ 997 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 998 999 static final int LOCK_SCREEN_HIDDEN = 0; 1000 static final int LOCK_SCREEN_LEAVING = 1; 1001 static final int LOCK_SCREEN_SHOWN = 2; 1002 /** 1003 * State of external call telling us if the lock screen is shown. 1004 */ 1005 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 1006 1007 /** 1008 * Set if we are shutting down the system, similar to sleeping. 1009 */ 1010 boolean mShuttingDown = false; 1011 1012 /** 1013 * Current sequence id for oom_adj computation traversal. 1014 */ 1015 int mAdjSeq = 0; 1016 1017 /** 1018 * Current sequence id for process LRU updating. 1019 */ 1020 int mLruSeq = 0; 1021 1022 /** 1023 * Keep track of the non-cached/empty process we last found, to help 1024 * determine how to distribute cached/empty processes next time. 1025 */ 1026 int mNumNonCachedProcs = 0; 1027 1028 /** 1029 * Keep track of the number of cached hidden procs, to balance oom adj 1030 * distribution between those and empty procs. 1031 */ 1032 int mNumCachedHiddenProcs = 0; 1033 1034 /** 1035 * Keep track of the number of service processes we last found, to 1036 * determine on the next iteration which should be B services. 1037 */ 1038 int mNumServiceProcs = 0; 1039 int mNewNumAServiceProcs = 0; 1040 int mNewNumServiceProcs = 0; 1041 1042 /** 1043 * Allow the current computed overall memory level of the system to go down? 1044 * This is set to false when we are killing processes for reasons other than 1045 * memory management, so that the now smaller process list will not be taken as 1046 * an indication that memory is tighter. 1047 */ 1048 boolean mAllowLowerMemLevel = false; 1049 1050 /** 1051 * The last computed memory level, for holding when we are in a state that 1052 * processes are going away for other reasons. 1053 */ 1054 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1055 1056 /** 1057 * The last total number of process we have, to determine if changes actually look 1058 * like a shrinking number of process due to lower RAM. 1059 */ 1060 int mLastNumProcesses; 1061 1062 /** 1063 * The uptime of the last time we performed idle maintenance. 1064 */ 1065 long mLastIdleTime = SystemClock.uptimeMillis(); 1066 1067 /** 1068 * Total time spent with RAM that has been added in the past since the last idle time. 1069 */ 1070 long mLowRamTimeSinceLastIdle = 0; 1071 1072 /** 1073 * If RAM is currently low, when that horrible situation started. 1074 */ 1075 long mLowRamStartTime = 0; 1076 1077 /** 1078 * For reporting to battery stats the current top application. 1079 */ 1080 private String mCurResumedPackage = null; 1081 private int mCurResumedUid = -1; 1082 1083 /** 1084 * For reporting to battery stats the apps currently running foreground 1085 * service. The ProcessMap is package/uid tuples; each of these contain 1086 * an array of the currently foreground processes. 1087 */ 1088 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1089 = new ProcessMap<ArrayList<ProcessRecord>>(); 1090 1091 /** 1092 * This is set if we had to do a delayed dexopt of an app before launching 1093 * it, to increase the ANR timeouts in that case. 1094 */ 1095 boolean mDidDexOpt; 1096 1097 /** 1098 * Set if the systemServer made a call to enterSafeMode. 1099 */ 1100 boolean mSafeMode; 1101 1102 /** 1103 * If true, we are running under a test environment so will sample PSS from processes 1104 * much more rapidly to try to collect better data when the tests are rapidly 1105 * running through apps. 1106 */ 1107 boolean mTestPssMode = false; 1108 1109 String mDebugApp = null; 1110 boolean mWaitForDebugger = false; 1111 boolean mDebugTransient = false; 1112 String mOrigDebugApp = null; 1113 boolean mOrigWaitForDebugger = false; 1114 boolean mAlwaysFinishActivities = false; 1115 IActivityController mController = null; 1116 String mProfileApp = null; 1117 ProcessRecord mProfileProc = null; 1118 String mProfileFile; 1119 ParcelFileDescriptor mProfileFd; 1120 int mSamplingInterval = 0; 1121 boolean mAutoStopProfiler = false; 1122 int mProfileType = 0; 1123 String mOpenGlTraceApp = null; 1124 1125 final long[] mTmpLong = new long[1]; 1126 1127 static class ProcessChangeItem { 1128 static final int CHANGE_ACTIVITIES = 1<<0; 1129 static final int CHANGE_PROCESS_STATE = 1<<1; 1130 int changes; 1131 int uid; 1132 int pid; 1133 int processState; 1134 boolean foregroundActivities; 1135 } 1136 1137 final RemoteCallbackList<IProcessObserver> mProcessObservers 1138 = new RemoteCallbackList<IProcessObserver>(); 1139 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1140 1141 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1142 = new ArrayList<ProcessChangeItem>(); 1143 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1144 = new ArrayList<ProcessChangeItem>(); 1145 1146 /** 1147 * Runtime CPU use collection thread. This object's lock is used to 1148 * perform synchronization with the thread (notifying it to run). 1149 */ 1150 final Thread mProcessCpuThread; 1151 1152 /** 1153 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1154 * Must acquire this object's lock when accessing it. 1155 * NOTE: this lock will be held while doing long operations (trawling 1156 * through all processes in /proc), so it should never be acquired by 1157 * any critical paths such as when holding the main activity manager lock. 1158 */ 1159 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1160 MONITOR_THREAD_CPU_USAGE); 1161 final AtomicLong mLastCpuTime = new AtomicLong(0); 1162 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1163 1164 long mLastWriteTime = 0; 1165 1166 /** 1167 * Used to retain an update lock when the foreground activity is in 1168 * immersive mode. 1169 */ 1170 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1171 1172 /** 1173 * Set to true after the system has finished booting. 1174 */ 1175 boolean mBooted = false; 1176 1177 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1178 int mProcessLimitOverride = -1; 1179 1180 WindowManagerService mWindowManager; 1181 1182 final ActivityThread mSystemThread; 1183 1184 // Holds the current foreground user's id 1185 int mCurrentUserId = 0; 1186 // Holds the target user's id during a user switch 1187 int mTargetUserId = UserHandle.USER_NULL; 1188 // If there are multiple profiles for the current user, their ids are here 1189 // Currently only the primary user can have managed profiles 1190 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1191 1192 /** 1193 * Mapping from each known user ID to the profile group ID it is associated with. 1194 */ 1195 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1196 1197 private UserManagerService mUserManager; 1198 1199 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1200 final ProcessRecord mApp; 1201 final int mPid; 1202 final IApplicationThread mAppThread; 1203 1204 AppDeathRecipient(ProcessRecord app, int pid, 1205 IApplicationThread thread) { 1206 if (localLOGV) Slog.v( 1207 TAG, "New death recipient " + this 1208 + " for thread " + thread.asBinder()); 1209 mApp = app; 1210 mPid = pid; 1211 mAppThread = thread; 1212 } 1213 1214 @Override 1215 public void binderDied() { 1216 if (localLOGV) Slog.v( 1217 TAG, "Death received in " + this 1218 + " for thread " + mAppThread.asBinder()); 1219 synchronized(ActivityManagerService.this) { 1220 appDiedLocked(mApp, mPid, mAppThread, true); 1221 } 1222 } 1223 } 1224 1225 static final int SHOW_ERROR_MSG = 1; 1226 static final int SHOW_NOT_RESPONDING_MSG = 2; 1227 static final int SHOW_FACTORY_ERROR_MSG = 3; 1228 static final int UPDATE_CONFIGURATION_MSG = 4; 1229 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1230 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1231 static final int SERVICE_TIMEOUT_MSG = 12; 1232 static final int UPDATE_TIME_ZONE = 13; 1233 static final int SHOW_UID_ERROR_MSG = 14; 1234 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1235 static final int PROC_START_TIMEOUT_MSG = 20; 1236 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1237 static final int KILL_APPLICATION_MSG = 22; 1238 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1239 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1240 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1241 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1242 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1243 static final int CLEAR_DNS_CACHE_MSG = 28; 1244 static final int UPDATE_HTTP_PROXY_MSG = 29; 1245 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1246 static final int DISPATCH_PROCESSES_CHANGED = 31; 1247 static final int DISPATCH_PROCESS_DIED = 32; 1248 static final int REPORT_MEM_USAGE_MSG = 33; 1249 static final int REPORT_USER_SWITCH_MSG = 34; 1250 static final int CONTINUE_USER_SWITCH_MSG = 35; 1251 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1252 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1253 static final int PERSIST_URI_GRANTS_MSG = 38; 1254 static final int REQUEST_ALL_PSS_MSG = 39; 1255 static final int START_PROFILES_MSG = 40; 1256 static final int UPDATE_TIME = 41; 1257 static final int SYSTEM_USER_START_MSG = 42; 1258 static final int SYSTEM_USER_CURRENT_MSG = 43; 1259 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1260 static final int FINISH_BOOTING_MSG = 45; 1261 static final int START_USER_SWITCH_MSG = 46; 1262 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1263 static final int DISMISS_DIALOG_MSG = 48; 1264 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1265 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50; 1266 1267 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1268 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1269 static final int FIRST_COMPAT_MODE_MSG = 300; 1270 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1271 1272 CompatModeDialog mCompatModeDialog; 1273 long mLastMemUsageReportTime = 0; 1274 1275 /** 1276 * Flag whether the current user is a "monkey", i.e. whether 1277 * the UI is driven by a UI automation tool. 1278 */ 1279 private boolean mUserIsMonkey; 1280 1281 /** Flag whether the device has a Recents UI */ 1282 boolean mHasRecents; 1283 1284 /** The dimensions of the thumbnails in the Recents UI. */ 1285 int mThumbnailWidth; 1286 int mThumbnailHeight; 1287 1288 final ServiceThread mHandlerThread; 1289 final MainHandler mHandler; 1290 1291 final class MainHandler extends Handler { 1292 public MainHandler(Looper looper) { 1293 super(looper, null, true); 1294 } 1295 1296 @Override 1297 public void handleMessage(Message msg) { 1298 switch (msg.what) { 1299 case SHOW_ERROR_MSG: { 1300 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1301 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1302 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1303 synchronized (ActivityManagerService.this) { 1304 ProcessRecord proc = (ProcessRecord)data.get("app"); 1305 AppErrorResult res = (AppErrorResult) data.get("result"); 1306 if (proc != null && proc.crashDialog != null) { 1307 Slog.e(TAG, "App already has crash dialog: " + proc); 1308 if (res != null) { 1309 res.set(0); 1310 } 1311 return; 1312 } 1313 boolean isBackground = (UserHandle.getAppId(proc.uid) 1314 >= Process.FIRST_APPLICATION_UID 1315 && proc.pid != MY_PID); 1316 for (int userId : mCurrentProfileIds) { 1317 isBackground &= (proc.userId != userId); 1318 } 1319 if (isBackground && !showBackground) { 1320 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1321 if (res != null) { 1322 res.set(0); 1323 } 1324 return; 1325 } 1326 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1327 Dialog d = new AppErrorDialog(mContext, 1328 ActivityManagerService.this, res, proc); 1329 d.show(); 1330 proc.crashDialog = d; 1331 } else { 1332 // The device is asleep, so just pretend that the user 1333 // saw a crash dialog and hit "force quit". 1334 if (res != null) { 1335 res.set(0); 1336 } 1337 } 1338 } 1339 1340 ensureBootCompleted(); 1341 } break; 1342 case SHOW_NOT_RESPONDING_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1345 ProcessRecord proc = (ProcessRecord)data.get("app"); 1346 if (proc != null && proc.anrDialog != null) { 1347 Slog.e(TAG, "App already has anr dialog: " + proc); 1348 return; 1349 } 1350 1351 Intent intent = new Intent("android.intent.action.ANR"); 1352 if (!mProcessesReady) { 1353 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1354 | Intent.FLAG_RECEIVER_FOREGROUND); 1355 } 1356 broadcastIntentLocked(null, null, intent, 1357 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1358 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1359 1360 if (mShowDialogs) { 1361 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1362 mContext, proc, (ActivityRecord)data.get("activity"), 1363 msg.arg1 != 0); 1364 d.show(); 1365 proc.anrDialog = d; 1366 } else { 1367 // Just kill the app if there is no dialog to be shown. 1368 killAppAtUsersRequest(proc, null); 1369 } 1370 } 1371 1372 ensureBootCompleted(); 1373 } break; 1374 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1375 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1376 synchronized (ActivityManagerService.this) { 1377 ProcessRecord proc = (ProcessRecord) data.get("app"); 1378 if (proc == null) { 1379 Slog.e(TAG, "App not found when showing strict mode dialog."); 1380 break; 1381 } 1382 if (proc.crashDialog != null) { 1383 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1384 return; 1385 } 1386 AppErrorResult res = (AppErrorResult) data.get("result"); 1387 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1388 Dialog d = new StrictModeViolationDialog(mContext, 1389 ActivityManagerService.this, res, proc); 1390 d.show(); 1391 proc.crashDialog = d; 1392 } else { 1393 // The device is asleep, so just pretend that the user 1394 // saw a crash dialog and hit "force quit". 1395 res.set(0); 1396 } 1397 } 1398 ensureBootCompleted(); 1399 } break; 1400 case SHOW_FACTORY_ERROR_MSG: { 1401 Dialog d = new FactoryErrorDialog( 1402 mContext, msg.getData().getCharSequence("msg")); 1403 d.show(); 1404 ensureBootCompleted(); 1405 } break; 1406 case UPDATE_CONFIGURATION_MSG: { 1407 final ContentResolver resolver = mContext.getContentResolver(); 1408 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1409 } break; 1410 case GC_BACKGROUND_PROCESSES_MSG: { 1411 synchronized (ActivityManagerService.this) { 1412 performAppGcsIfAppropriateLocked(); 1413 } 1414 } break; 1415 case WAIT_FOR_DEBUGGER_MSG: { 1416 synchronized (ActivityManagerService.this) { 1417 ProcessRecord app = (ProcessRecord)msg.obj; 1418 if (msg.arg1 != 0) { 1419 if (!app.waitedForDebugger) { 1420 Dialog d = new AppWaitingForDebuggerDialog( 1421 ActivityManagerService.this, 1422 mContext, app); 1423 app.waitDialog = d; 1424 app.waitedForDebugger = true; 1425 d.show(); 1426 } 1427 } else { 1428 if (app.waitDialog != null) { 1429 app.waitDialog.dismiss(); 1430 app.waitDialog = null; 1431 } 1432 } 1433 } 1434 } break; 1435 case SERVICE_TIMEOUT_MSG: { 1436 if (mDidDexOpt) { 1437 mDidDexOpt = false; 1438 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1439 nmsg.obj = msg.obj; 1440 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1441 return; 1442 } 1443 mServices.serviceTimeout((ProcessRecord)msg.obj); 1444 } break; 1445 case UPDATE_TIME_ZONE: { 1446 synchronized (ActivityManagerService.this) { 1447 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1448 ProcessRecord r = mLruProcesses.get(i); 1449 if (r.thread != null) { 1450 try { 1451 r.thread.updateTimeZone(); 1452 } catch (RemoteException ex) { 1453 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1454 } 1455 } 1456 } 1457 } 1458 } break; 1459 case CLEAR_DNS_CACHE_MSG: { 1460 synchronized (ActivityManagerService.this) { 1461 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1462 ProcessRecord r = mLruProcesses.get(i); 1463 if (r.thread != null) { 1464 try { 1465 r.thread.clearDnsCache(); 1466 } catch (RemoteException ex) { 1467 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1468 } 1469 } 1470 } 1471 } 1472 } break; 1473 case UPDATE_HTTP_PROXY_MSG: { 1474 ProxyInfo proxy = (ProxyInfo)msg.obj; 1475 String host = ""; 1476 String port = ""; 1477 String exclList = ""; 1478 Uri pacFileUrl = Uri.EMPTY; 1479 if (proxy != null) { 1480 host = proxy.getHost(); 1481 port = Integer.toString(proxy.getPort()); 1482 exclList = proxy.getExclusionListAsString(); 1483 pacFileUrl = proxy.getPacFileUrl(); 1484 } 1485 synchronized (ActivityManagerService.this) { 1486 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1487 ProcessRecord r = mLruProcesses.get(i); 1488 if (r.thread != null) { 1489 try { 1490 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1491 } catch (RemoteException ex) { 1492 Slog.w(TAG, "Failed to update http proxy for: " + 1493 r.info.processName); 1494 } 1495 } 1496 } 1497 } 1498 } break; 1499 case SHOW_UID_ERROR_MSG: { 1500 if (mShowDialogs) { 1501 AlertDialog d = new BaseErrorDialog(mContext); 1502 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1503 d.setCancelable(false); 1504 d.setTitle(mContext.getText(R.string.android_system_label)); 1505 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1506 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1507 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1508 d.show(); 1509 } 1510 } break; 1511 case SHOW_FINGERPRINT_ERROR_MSG: { 1512 if (mShowDialogs) { 1513 AlertDialog d = new BaseErrorDialog(mContext); 1514 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1515 d.setCancelable(false); 1516 d.setTitle(mContext.getText(R.string.android_system_label)); 1517 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1518 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1519 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1520 d.show(); 1521 } 1522 } break; 1523 case PROC_START_TIMEOUT_MSG: { 1524 if (mDidDexOpt) { 1525 mDidDexOpt = false; 1526 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1527 nmsg.obj = msg.obj; 1528 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1529 return; 1530 } 1531 ProcessRecord app = (ProcessRecord)msg.obj; 1532 synchronized (ActivityManagerService.this) { 1533 processStartTimedOutLocked(app); 1534 } 1535 } break; 1536 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1537 synchronized (ActivityManagerService.this) { 1538 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1539 } 1540 } break; 1541 case KILL_APPLICATION_MSG: { 1542 synchronized (ActivityManagerService.this) { 1543 int appid = msg.arg1; 1544 boolean restart = (msg.arg2 == 1); 1545 Bundle bundle = (Bundle)msg.obj; 1546 String pkg = bundle.getString("pkg"); 1547 String reason = bundle.getString("reason"); 1548 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1549 false, UserHandle.USER_ALL, reason); 1550 } 1551 } break; 1552 case FINALIZE_PENDING_INTENT_MSG: { 1553 ((PendingIntentRecord)msg.obj).completeFinalize(); 1554 } break; 1555 case POST_HEAVY_NOTIFICATION_MSG: { 1556 INotificationManager inm = NotificationManager.getService(); 1557 if (inm == null) { 1558 return; 1559 } 1560 1561 ActivityRecord root = (ActivityRecord)msg.obj; 1562 ProcessRecord process = root.app; 1563 if (process == null) { 1564 return; 1565 } 1566 1567 try { 1568 Context context = mContext.createPackageContext(process.info.packageName, 0); 1569 String text = mContext.getString(R.string.heavy_weight_notification, 1570 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1571 Notification notification = new Notification(); 1572 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1573 notification.when = 0; 1574 notification.flags = Notification.FLAG_ONGOING_EVENT; 1575 notification.tickerText = text; 1576 notification.defaults = 0; // please be quiet 1577 notification.sound = null; 1578 notification.vibrate = null; 1579 notification.color = mContext.getResources().getColor( 1580 com.android.internal.R.color.system_notification_accent_color); 1581 notification.setLatestEventInfo(context, text, 1582 mContext.getText(R.string.heavy_weight_notification_detail), 1583 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1584 PendingIntent.FLAG_CANCEL_CURRENT, null, 1585 new UserHandle(root.userId))); 1586 1587 try { 1588 int[] outId = new int[1]; 1589 inm.enqueueNotificationWithTag("android", "android", null, 1590 R.string.heavy_weight_notification, 1591 notification, outId, root.userId); 1592 } catch (RuntimeException e) { 1593 Slog.w(ActivityManagerService.TAG, 1594 "Error showing notification for heavy-weight app", e); 1595 } catch (RemoteException e) { 1596 } 1597 } catch (NameNotFoundException e) { 1598 Slog.w(TAG, "Unable to create context for heavy notification", e); 1599 } 1600 } break; 1601 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1602 INotificationManager inm = NotificationManager.getService(); 1603 if (inm == null) { 1604 return; 1605 } 1606 try { 1607 inm.cancelNotificationWithTag("android", null, 1608 R.string.heavy_weight_notification, msg.arg1); 1609 } catch (RuntimeException e) { 1610 Slog.w(ActivityManagerService.TAG, 1611 "Error canceling notification for service", e); 1612 } catch (RemoteException e) { 1613 } 1614 } break; 1615 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1616 synchronized (ActivityManagerService.this) { 1617 checkExcessivePowerUsageLocked(true); 1618 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1619 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1620 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1621 } 1622 } break; 1623 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1624 synchronized (ActivityManagerService.this) { 1625 ActivityRecord ar = (ActivityRecord)msg.obj; 1626 if (mCompatModeDialog != null) { 1627 if (mCompatModeDialog.mAppInfo.packageName.equals( 1628 ar.info.applicationInfo.packageName)) { 1629 return; 1630 } 1631 mCompatModeDialog.dismiss(); 1632 mCompatModeDialog = null; 1633 } 1634 if (ar != null && false) { 1635 if (mCompatModePackages.getPackageAskCompatModeLocked( 1636 ar.packageName)) { 1637 int mode = mCompatModePackages.computeCompatModeLocked( 1638 ar.info.applicationInfo); 1639 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1640 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1641 mCompatModeDialog = new CompatModeDialog( 1642 ActivityManagerService.this, mContext, 1643 ar.info.applicationInfo); 1644 mCompatModeDialog.show(); 1645 } 1646 } 1647 } 1648 } 1649 break; 1650 } 1651 case DISPATCH_PROCESSES_CHANGED: { 1652 dispatchProcessesChanged(); 1653 break; 1654 } 1655 case DISPATCH_PROCESS_DIED: { 1656 final int pid = msg.arg1; 1657 final int uid = msg.arg2; 1658 dispatchProcessDied(pid, uid); 1659 break; 1660 } 1661 case REPORT_MEM_USAGE_MSG: { 1662 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1663 Thread thread = new Thread() { 1664 @Override public void run() { 1665 reportMemUsage(memInfos); 1666 } 1667 }; 1668 thread.start(); 1669 break; 1670 } 1671 case START_USER_SWITCH_MSG: { 1672 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1673 break; 1674 } 1675 case REPORT_USER_SWITCH_MSG: { 1676 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1677 break; 1678 } 1679 case CONTINUE_USER_SWITCH_MSG: { 1680 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1681 break; 1682 } 1683 case USER_SWITCH_TIMEOUT_MSG: { 1684 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1685 break; 1686 } 1687 case IMMERSIVE_MODE_LOCK_MSG: { 1688 final boolean nextState = (msg.arg1 != 0); 1689 if (mUpdateLock.isHeld() != nextState) { 1690 if (DEBUG_IMMERSIVE) { 1691 final ActivityRecord r = (ActivityRecord) msg.obj; 1692 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1693 } 1694 if (nextState) { 1695 mUpdateLock.acquire(); 1696 } else { 1697 mUpdateLock.release(); 1698 } 1699 } 1700 break; 1701 } 1702 case PERSIST_URI_GRANTS_MSG: { 1703 writeGrantedUriPermissions(); 1704 break; 1705 } 1706 case REQUEST_ALL_PSS_MSG: { 1707 synchronized (ActivityManagerService.this) { 1708 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1709 } 1710 break; 1711 } 1712 case START_PROFILES_MSG: { 1713 synchronized (ActivityManagerService.this) { 1714 startProfilesLocked(); 1715 } 1716 break; 1717 } 1718 case UPDATE_TIME: { 1719 synchronized (ActivityManagerService.this) { 1720 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1721 ProcessRecord r = mLruProcesses.get(i); 1722 if (r.thread != null) { 1723 try { 1724 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1725 } catch (RemoteException ex) { 1726 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1727 } 1728 } 1729 } 1730 } 1731 break; 1732 } 1733 case SYSTEM_USER_START_MSG: { 1734 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1735 Integer.toString(msg.arg1), msg.arg1); 1736 mSystemServiceManager.startUser(msg.arg1); 1737 break; 1738 } 1739 case SYSTEM_USER_CURRENT_MSG: { 1740 mBatteryStatsService.noteEvent( 1741 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1742 Integer.toString(msg.arg2), msg.arg2); 1743 mBatteryStatsService.noteEvent( 1744 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1745 Integer.toString(msg.arg1), msg.arg1); 1746 mSystemServiceManager.switchUser(msg.arg1); 1747 break; 1748 } 1749 case ENTER_ANIMATION_COMPLETE_MSG: { 1750 synchronized (ActivityManagerService.this) { 1751 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1752 if (r != null && r.app != null && r.app.thread != null) { 1753 try { 1754 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1755 } catch (RemoteException e) { 1756 } 1757 } 1758 } 1759 break; 1760 } 1761 case FINISH_BOOTING_MSG: { 1762 if (msg.arg1 != 0) { 1763 finishBooting(); 1764 } 1765 if (msg.arg2 != 0) { 1766 enableScreenAfterBoot(); 1767 } 1768 break; 1769 } 1770 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1771 try { 1772 Locale l = (Locale) msg.obj; 1773 IBinder service = ServiceManager.getService("mount"); 1774 IMountService mountService = IMountService.Stub.asInterface(service); 1775 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1776 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1777 } catch (RemoteException e) { 1778 Log.e(TAG, "Error storing locale for decryption UI", e); 1779 } 1780 break; 1781 } 1782 case DISMISS_DIALOG_MSG: { 1783 final Dialog d = (Dialog) msg.obj; 1784 d.dismiss(); 1785 break; 1786 } 1787 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1788 synchronized (ActivityManagerService.this) { 1789 int i = mTaskStackListeners.beginBroadcast(); 1790 while (i > 0) { 1791 i--; 1792 try { 1793 // Make a one-way callback to the listener 1794 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1795 } catch (RemoteException e){ 1796 // Handled by the RemoteCallbackList 1797 } 1798 } 1799 mTaskStackListeners.finishBroadcast(); 1800 } 1801 break; 1802 } 1803 case NOTIFY_CLEARTEXT_NETWORK_MSG: { 1804 final int uid = msg.arg1; 1805 final byte[] firstPacket = (byte[]) msg.obj; 1806 1807 synchronized (mPidsSelfLocked) { 1808 for (int i = 0; i < mPidsSelfLocked.size(); i++) { 1809 final ProcessRecord p = mPidsSelfLocked.valueAt(i); 1810 if (p.uid == uid) { 1811 try { 1812 p.thread.notifyCleartextNetwork(firstPacket); 1813 } catch (RemoteException ignored) { 1814 } 1815 } 1816 } 1817 } 1818 break; 1819 } 1820 } 1821 } 1822 }; 1823 1824 static final int COLLECT_PSS_BG_MSG = 1; 1825 1826 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1827 @Override 1828 public void handleMessage(Message msg) { 1829 switch (msg.what) { 1830 case COLLECT_PSS_BG_MSG: { 1831 long start = SystemClock.uptimeMillis(); 1832 MemInfoReader memInfo = null; 1833 synchronized (ActivityManagerService.this) { 1834 if (mFullPssPending) { 1835 mFullPssPending = false; 1836 memInfo = new MemInfoReader(); 1837 } 1838 } 1839 if (memInfo != null) { 1840 updateCpuStatsNow(); 1841 long nativeTotalPss = 0; 1842 synchronized (mProcessCpuTracker) { 1843 final int N = mProcessCpuTracker.countStats(); 1844 for (int j=0; j<N; j++) { 1845 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1846 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1847 // This is definitely an application process; skip it. 1848 continue; 1849 } 1850 synchronized (mPidsSelfLocked) { 1851 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1852 // This is one of our own processes; skip it. 1853 continue; 1854 } 1855 } 1856 nativeTotalPss += Debug.getPss(st.pid, null, null); 1857 } 1858 } 1859 memInfo.readMemInfo(); 1860 synchronized (ActivityManagerService.this) { 1861 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1862 + (SystemClock.uptimeMillis()-start) + "ms"); 1863 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1864 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1865 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1866 } 1867 } 1868 1869 int num = 0; 1870 long[] tmp = new long[1]; 1871 do { 1872 ProcessRecord proc; 1873 int procState; 1874 int pid; 1875 long lastPssTime; 1876 synchronized (ActivityManagerService.this) { 1877 if (mPendingPssProcesses.size() <= 0) { 1878 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1879 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1880 mPendingPssProcesses.clear(); 1881 return; 1882 } 1883 proc = mPendingPssProcesses.remove(0); 1884 procState = proc.pssProcState; 1885 lastPssTime = proc.lastPssTime; 1886 if (proc.thread != null && procState == proc.setProcState 1887 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1888 < SystemClock.uptimeMillis()) { 1889 pid = proc.pid; 1890 } else { 1891 proc = null; 1892 pid = 0; 1893 } 1894 } 1895 if (proc != null) { 1896 long pss = Debug.getPss(pid, tmp, null); 1897 synchronized (ActivityManagerService.this) { 1898 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1899 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1900 num++; 1901 recordPssSample(proc, procState, pss, tmp[0], 1902 SystemClock.uptimeMillis()); 1903 } 1904 } 1905 } 1906 } while (true); 1907 } 1908 } 1909 } 1910 }; 1911 1912 public void setSystemProcess() { 1913 try { 1914 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1915 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1916 ServiceManager.addService("meminfo", new MemBinder(this)); 1917 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1918 ServiceManager.addService("dbinfo", new DbBinder(this)); 1919 if (MONITOR_CPU_USAGE) { 1920 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1921 } 1922 ServiceManager.addService("permission", new PermissionController(this)); 1923 ServiceManager.addService("processinfo", new ProcessInfoService(this)); 1924 1925 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1926 "android", STOCK_PM_FLAGS); 1927 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1928 1929 synchronized (this) { 1930 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1931 app.persistent = true; 1932 app.pid = MY_PID; 1933 app.maxAdj = ProcessList.SYSTEM_ADJ; 1934 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1935 mProcessNames.put(app.processName, app.uid, app); 1936 synchronized (mPidsSelfLocked) { 1937 mPidsSelfLocked.put(app.pid, app); 1938 } 1939 updateLruProcessLocked(app, false, null); 1940 updateOomAdjLocked(); 1941 } 1942 } catch (PackageManager.NameNotFoundException e) { 1943 throw new RuntimeException( 1944 "Unable to find android system package", e); 1945 } 1946 } 1947 1948 public void setWindowManager(WindowManagerService wm) { 1949 mWindowManager = wm; 1950 mStackSupervisor.setWindowManager(wm); 1951 } 1952 1953 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1954 mUsageStatsService = usageStatsManager; 1955 } 1956 1957 public void startObservingNativeCrashes() { 1958 final NativeCrashListener ncl = new NativeCrashListener(this); 1959 ncl.start(); 1960 } 1961 1962 public IAppOpsService getAppOpsService() { 1963 return mAppOpsService; 1964 } 1965 1966 static class MemBinder extends Binder { 1967 ActivityManagerService mActivityManagerService; 1968 MemBinder(ActivityManagerService activityManagerService) { 1969 mActivityManagerService = activityManagerService; 1970 } 1971 1972 @Override 1973 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1974 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1975 != PackageManager.PERMISSION_GRANTED) { 1976 pw.println("Permission Denial: can't dump meminfo from from pid=" 1977 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1978 + " without permission " + android.Manifest.permission.DUMP); 1979 return; 1980 } 1981 1982 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1983 } 1984 } 1985 1986 static class GraphicsBinder extends Binder { 1987 ActivityManagerService mActivityManagerService; 1988 GraphicsBinder(ActivityManagerService activityManagerService) { 1989 mActivityManagerService = activityManagerService; 1990 } 1991 1992 @Override 1993 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1994 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1995 != PackageManager.PERMISSION_GRANTED) { 1996 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1997 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1998 + " without permission " + android.Manifest.permission.DUMP); 1999 return; 2000 } 2001 2002 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2003 } 2004 } 2005 2006 static class DbBinder extends Binder { 2007 ActivityManagerService mActivityManagerService; 2008 DbBinder(ActivityManagerService activityManagerService) { 2009 mActivityManagerService = activityManagerService; 2010 } 2011 2012 @Override 2013 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2014 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2015 != PackageManager.PERMISSION_GRANTED) { 2016 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2017 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2018 + " without permission " + android.Manifest.permission.DUMP); 2019 return; 2020 } 2021 2022 mActivityManagerService.dumpDbInfo(fd, pw, args); 2023 } 2024 } 2025 2026 static class CpuBinder extends Binder { 2027 ActivityManagerService mActivityManagerService; 2028 CpuBinder(ActivityManagerService activityManagerService) { 2029 mActivityManagerService = activityManagerService; 2030 } 2031 2032 @Override 2033 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2034 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2035 != PackageManager.PERMISSION_GRANTED) { 2036 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2037 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2038 + " without permission " + android.Manifest.permission.DUMP); 2039 return; 2040 } 2041 2042 synchronized (mActivityManagerService.mProcessCpuTracker) { 2043 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2044 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2045 SystemClock.uptimeMillis())); 2046 } 2047 } 2048 } 2049 2050 public static final class Lifecycle extends SystemService { 2051 private final ActivityManagerService mService; 2052 2053 public Lifecycle(Context context) { 2054 super(context); 2055 mService = new ActivityManagerService(context); 2056 } 2057 2058 @Override 2059 public void onStart() { 2060 mService.start(); 2061 } 2062 2063 public ActivityManagerService getService() { 2064 return mService; 2065 } 2066 } 2067 2068 // Note: This method is invoked on the main thread but may need to attach various 2069 // handlers to other threads. So take care to be explicit about the looper. 2070 public ActivityManagerService(Context systemContext) { 2071 mContext = systemContext; 2072 mFactoryTest = FactoryTest.getMode(); 2073 mSystemThread = ActivityThread.currentActivityThread(); 2074 2075 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2076 2077 mHandlerThread = new ServiceThread(TAG, 2078 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2079 mHandlerThread.start(); 2080 mHandler = new MainHandler(mHandlerThread.getLooper()); 2081 2082 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2083 "foreground", BROADCAST_FG_TIMEOUT, false); 2084 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2085 "background", BROADCAST_BG_TIMEOUT, true); 2086 mBroadcastQueues[0] = mFgBroadcastQueue; 2087 mBroadcastQueues[1] = mBgBroadcastQueue; 2088 2089 mServices = new ActiveServices(this); 2090 mProviderMap = new ProviderMap(this); 2091 2092 // TODO: Move creation of battery stats service outside of activity manager service. 2093 File dataDir = Environment.getDataDirectory(); 2094 File systemDir = new File(dataDir, "system"); 2095 systemDir.mkdirs(); 2096 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2097 mBatteryStatsService.getActiveStatistics().readLocked(); 2098 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2099 mOnBattery = DEBUG_POWER ? true 2100 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2101 mBatteryStatsService.getActiveStatistics().setCallback(this); 2102 2103 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2104 2105 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2106 2107 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2108 2109 // User 0 is the first and only user that runs at boot. 2110 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2111 mUserLru.add(Integer.valueOf(0)); 2112 updateStartedUserArrayLocked(); 2113 2114 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2115 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2116 2117 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2118 2119 mConfiguration.setToDefaults(); 2120 mConfiguration.locale = Locale.getDefault(); 2121 2122 mConfigurationSeq = mConfiguration.seq = 1; 2123 mProcessCpuTracker.init(); 2124 2125 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2126 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2127 mStackSupervisor = new ActivityStackSupervisor(this); 2128 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2129 2130 mProcessCpuThread = new Thread("CpuTracker") { 2131 @Override 2132 public void run() { 2133 while (true) { 2134 try { 2135 try { 2136 synchronized(this) { 2137 final long now = SystemClock.uptimeMillis(); 2138 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2139 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2140 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2141 // + ", write delay=" + nextWriteDelay); 2142 if (nextWriteDelay < nextCpuDelay) { 2143 nextCpuDelay = nextWriteDelay; 2144 } 2145 if (nextCpuDelay > 0) { 2146 mProcessCpuMutexFree.set(true); 2147 this.wait(nextCpuDelay); 2148 } 2149 } 2150 } catch (InterruptedException e) { 2151 } 2152 updateCpuStatsNow(); 2153 } catch (Exception e) { 2154 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2155 } 2156 } 2157 } 2158 }; 2159 2160 Watchdog.getInstance().addMonitor(this); 2161 Watchdog.getInstance().addThread(mHandler); 2162 } 2163 2164 public void setSystemServiceManager(SystemServiceManager mgr) { 2165 mSystemServiceManager = mgr; 2166 } 2167 2168 public void setInstaller(Installer installer) { 2169 mInstaller = installer; 2170 } 2171 2172 private void start() { 2173 Process.removeAllProcessGroups(); 2174 mProcessCpuThread.start(); 2175 2176 mBatteryStatsService.publish(mContext); 2177 mAppOpsService.publish(mContext); 2178 Slog.d("AppOps", "AppOpsService published"); 2179 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2180 } 2181 2182 public void initPowerManagement() { 2183 mStackSupervisor.initPowerManagement(); 2184 mBatteryStatsService.initPowerManagement(); 2185 } 2186 2187 @Override 2188 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2189 throws RemoteException { 2190 if (code == SYSPROPS_TRANSACTION) { 2191 // We need to tell all apps about the system property change. 2192 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2193 synchronized(this) { 2194 final int NP = mProcessNames.getMap().size(); 2195 for (int ip=0; ip<NP; ip++) { 2196 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2197 final int NA = apps.size(); 2198 for (int ia=0; ia<NA; ia++) { 2199 ProcessRecord app = apps.valueAt(ia); 2200 if (app.thread != null) { 2201 procs.add(app.thread.asBinder()); 2202 } 2203 } 2204 } 2205 } 2206 2207 int N = procs.size(); 2208 for (int i=0; i<N; i++) { 2209 Parcel data2 = Parcel.obtain(); 2210 try { 2211 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2212 } catch (RemoteException e) { 2213 } 2214 data2.recycle(); 2215 } 2216 } 2217 try { 2218 return super.onTransact(code, data, reply, flags); 2219 } catch (RuntimeException e) { 2220 // The activity manager only throws security exceptions, so let's 2221 // log all others. 2222 if (!(e instanceof SecurityException)) { 2223 Slog.wtf(TAG, "Activity Manager Crash", e); 2224 } 2225 throw e; 2226 } 2227 } 2228 2229 void updateCpuStats() { 2230 final long now = SystemClock.uptimeMillis(); 2231 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2232 return; 2233 } 2234 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2235 synchronized (mProcessCpuThread) { 2236 mProcessCpuThread.notify(); 2237 } 2238 } 2239 } 2240 2241 void updateCpuStatsNow() { 2242 synchronized (mProcessCpuTracker) { 2243 mProcessCpuMutexFree.set(false); 2244 final long now = SystemClock.uptimeMillis(); 2245 boolean haveNewCpuStats = false; 2246 2247 if (MONITOR_CPU_USAGE && 2248 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2249 mLastCpuTime.set(now); 2250 haveNewCpuStats = true; 2251 mProcessCpuTracker.update(); 2252 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2253 //Slog.i(TAG, "Total CPU usage: " 2254 // + mProcessCpu.getTotalCpuPercent() + "%"); 2255 2256 // Slog the cpu usage if the property is set. 2257 if ("true".equals(SystemProperties.get("events.cpu"))) { 2258 int user = mProcessCpuTracker.getLastUserTime(); 2259 int system = mProcessCpuTracker.getLastSystemTime(); 2260 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2261 int irq = mProcessCpuTracker.getLastIrqTime(); 2262 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2263 int idle = mProcessCpuTracker.getLastIdleTime(); 2264 2265 int total = user + system + iowait + irq + softIrq + idle; 2266 if (total == 0) total = 1; 2267 2268 EventLog.writeEvent(EventLogTags.CPU, 2269 ((user+system+iowait+irq+softIrq) * 100) / total, 2270 (user * 100) / total, 2271 (system * 100) / total, 2272 (iowait * 100) / total, 2273 (irq * 100) / total, 2274 (softIrq * 100) / total); 2275 } 2276 } 2277 2278 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2279 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2280 synchronized(bstats) { 2281 synchronized(mPidsSelfLocked) { 2282 if (haveNewCpuStats) { 2283 if (mOnBattery) { 2284 int perc = bstats.startAddingCpuLocked(); 2285 int totalUTime = 0; 2286 int totalSTime = 0; 2287 final int N = mProcessCpuTracker.countStats(); 2288 for (int i=0; i<N; i++) { 2289 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2290 if (!st.working) { 2291 continue; 2292 } 2293 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2294 int otherUTime = (st.rel_utime*perc)/100; 2295 int otherSTime = (st.rel_stime*perc)/100; 2296 totalUTime += otherUTime; 2297 totalSTime += otherSTime; 2298 if (pr != null) { 2299 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2300 if (ps == null || !ps.isActive()) { 2301 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2302 pr.info.uid, pr.processName); 2303 } 2304 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2305 st.rel_stime-otherSTime); 2306 ps.addSpeedStepTimes(cpuSpeedTimes); 2307 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2308 } else { 2309 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2310 if (ps == null || !ps.isActive()) { 2311 st.batteryStats = ps = bstats.getProcessStatsLocked( 2312 bstats.mapUid(st.uid), st.name); 2313 } 2314 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2315 st.rel_stime-otherSTime); 2316 ps.addSpeedStepTimes(cpuSpeedTimes); 2317 } 2318 } 2319 bstats.finishAddingCpuLocked(perc, totalUTime, 2320 totalSTime, cpuSpeedTimes); 2321 } 2322 } 2323 } 2324 2325 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2326 mLastWriteTime = now; 2327 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2328 } 2329 } 2330 } 2331 } 2332 2333 @Override 2334 public void batteryNeedsCpuUpdate() { 2335 updateCpuStatsNow(); 2336 } 2337 2338 @Override 2339 public void batteryPowerChanged(boolean onBattery) { 2340 // When plugging in, update the CPU stats first before changing 2341 // the plug state. 2342 updateCpuStatsNow(); 2343 synchronized (this) { 2344 synchronized(mPidsSelfLocked) { 2345 mOnBattery = DEBUG_POWER ? true : onBattery; 2346 } 2347 } 2348 } 2349 2350 /** 2351 * Initialize the application bind args. These are passed to each 2352 * process when the bindApplication() IPC is sent to the process. They're 2353 * lazily setup to make sure the services are running when they're asked for. 2354 */ 2355 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2356 if (mAppBindArgs == null) { 2357 mAppBindArgs = new HashMap<>(); 2358 2359 // Isolated processes won't get this optimization, so that we don't 2360 // violate the rules about which services they have access to. 2361 if (!isolated) { 2362 // Setup the application init args 2363 mAppBindArgs.put("package", ServiceManager.getService("package")); 2364 mAppBindArgs.put("window", ServiceManager.getService("window")); 2365 mAppBindArgs.put(Context.ALARM_SERVICE, 2366 ServiceManager.getService(Context.ALARM_SERVICE)); 2367 } 2368 } 2369 return mAppBindArgs; 2370 } 2371 2372 final void setFocusedActivityLocked(ActivityRecord r, String reason) { 2373 if (mFocusedActivity != r) { 2374 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2375 mFocusedActivity = r; 2376 if (r.task != null && r.task.voiceInteractor != null) { 2377 startRunningVoiceLocked(); 2378 } else { 2379 finishRunningVoiceLocked(); 2380 } 2381 mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity"); 2382 if (r != null) { 2383 mWindowManager.setFocusedApp(r.appToken, true); 2384 } 2385 applyUpdateLockStateLocked(r); 2386 } 2387 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId, 2388 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName); 2389 } 2390 2391 final void clearFocusedActivity(ActivityRecord r) { 2392 if (mFocusedActivity == r) { 2393 mFocusedActivity = null; 2394 } 2395 } 2396 2397 @Override 2398 public void setFocusedStack(int stackId) { 2399 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2400 synchronized (ActivityManagerService.this) { 2401 ActivityStack stack = mStackSupervisor.getStack(stackId); 2402 if (stack != null) { 2403 ActivityRecord r = stack.topRunningActivityLocked(null); 2404 if (r != null) { 2405 setFocusedActivityLocked(r, "setFocusedStack"); 2406 } 2407 } 2408 } 2409 } 2410 2411 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2412 @Override 2413 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2414 synchronized (ActivityManagerService.this) { 2415 if (listener != null) { 2416 mTaskStackListeners.register(listener); 2417 } 2418 } 2419 } 2420 2421 @Override 2422 public void notifyActivityDrawn(IBinder token) { 2423 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2424 synchronized (this) { 2425 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2426 if (r != null) { 2427 r.task.stack.notifyActivityDrawnLocked(r); 2428 } 2429 } 2430 } 2431 2432 final void applyUpdateLockStateLocked(ActivityRecord r) { 2433 // Modifications to the UpdateLock state are done on our handler, outside 2434 // the activity manager's locks. The new state is determined based on the 2435 // state *now* of the relevant activity record. The object is passed to 2436 // the handler solely for logging detail, not to be consulted/modified. 2437 final boolean nextState = r != null && r.immersive; 2438 mHandler.sendMessage( 2439 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2440 } 2441 2442 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2443 Message msg = Message.obtain(); 2444 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2445 msg.obj = r.task.askedCompatMode ? null : r; 2446 mHandler.sendMessage(msg); 2447 } 2448 2449 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2450 String what, Object obj, ProcessRecord srcApp) { 2451 app.lastActivityTime = now; 2452 2453 if (app.activities.size() > 0) { 2454 // Don't want to touch dependent processes that are hosting activities. 2455 return index; 2456 } 2457 2458 int lrui = mLruProcesses.lastIndexOf(app); 2459 if (lrui < 0) { 2460 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2461 + what + " " + obj + " from " + srcApp); 2462 return index; 2463 } 2464 2465 if (lrui >= index) { 2466 // Don't want to cause this to move dependent processes *back* in the 2467 // list as if they were less frequently used. 2468 return index; 2469 } 2470 2471 if (lrui >= mLruProcessActivityStart) { 2472 // Don't want to touch dependent processes that are hosting activities. 2473 return index; 2474 } 2475 2476 mLruProcesses.remove(lrui); 2477 if (index > 0) { 2478 index--; 2479 } 2480 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2481 + " in LRU list: " + app); 2482 mLruProcesses.add(index, app); 2483 return index; 2484 } 2485 2486 final void removeLruProcessLocked(ProcessRecord app) { 2487 int lrui = mLruProcesses.lastIndexOf(app); 2488 if (lrui >= 0) { 2489 if (!app.killed) { 2490 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2491 Process.killProcessQuiet(app.pid); 2492 Process.killProcessGroup(app.info.uid, app.pid); 2493 } 2494 if (lrui <= mLruProcessActivityStart) { 2495 mLruProcessActivityStart--; 2496 } 2497 if (lrui <= mLruProcessServiceStart) { 2498 mLruProcessServiceStart--; 2499 } 2500 mLruProcesses.remove(lrui); 2501 } 2502 } 2503 2504 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2505 ProcessRecord client) { 2506 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2507 || app.treatLikeActivity; 2508 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2509 if (!activityChange && hasActivity) { 2510 // The process has activities, so we are only allowing activity-based adjustments 2511 // to move it. It should be kept in the front of the list with other 2512 // processes that have activities, and we don't want those to change their 2513 // order except due to activity operations. 2514 return; 2515 } 2516 2517 mLruSeq++; 2518 final long now = SystemClock.uptimeMillis(); 2519 app.lastActivityTime = now; 2520 2521 // First a quick reject: if the app is already at the position we will 2522 // put it, then there is nothing to do. 2523 if (hasActivity) { 2524 final int N = mLruProcesses.size(); 2525 if (N > 0 && mLruProcesses.get(N-1) == app) { 2526 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2527 return; 2528 } 2529 } else { 2530 if (mLruProcessServiceStart > 0 2531 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2532 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2533 return; 2534 } 2535 } 2536 2537 int lrui = mLruProcesses.lastIndexOf(app); 2538 2539 if (app.persistent && lrui >= 0) { 2540 // We don't care about the position of persistent processes, as long as 2541 // they are in the list. 2542 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2543 return; 2544 } 2545 2546 /* In progress: compute new position first, so we can avoid doing work 2547 if the process is not actually going to move. Not yet working. 2548 int addIndex; 2549 int nextIndex; 2550 boolean inActivity = false, inService = false; 2551 if (hasActivity) { 2552 // Process has activities, put it at the very tipsy-top. 2553 addIndex = mLruProcesses.size(); 2554 nextIndex = mLruProcessServiceStart; 2555 inActivity = true; 2556 } else if (hasService) { 2557 // Process has services, put it at the top of the service list. 2558 addIndex = mLruProcessActivityStart; 2559 nextIndex = mLruProcessServiceStart; 2560 inActivity = true; 2561 inService = true; 2562 } else { 2563 // Process not otherwise of interest, it goes to the top of the non-service area. 2564 addIndex = mLruProcessServiceStart; 2565 if (client != null) { 2566 int clientIndex = mLruProcesses.lastIndexOf(client); 2567 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2568 + app); 2569 if (clientIndex >= 0 && addIndex > clientIndex) { 2570 addIndex = clientIndex; 2571 } 2572 } 2573 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2574 } 2575 2576 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2577 + mLruProcessActivityStart + "): " + app); 2578 */ 2579 2580 if (lrui >= 0) { 2581 if (lrui < mLruProcessActivityStart) { 2582 mLruProcessActivityStart--; 2583 } 2584 if (lrui < mLruProcessServiceStart) { 2585 mLruProcessServiceStart--; 2586 } 2587 /* 2588 if (addIndex > lrui) { 2589 addIndex--; 2590 } 2591 if (nextIndex > lrui) { 2592 nextIndex--; 2593 } 2594 */ 2595 mLruProcesses.remove(lrui); 2596 } 2597 2598 /* 2599 mLruProcesses.add(addIndex, app); 2600 if (inActivity) { 2601 mLruProcessActivityStart++; 2602 } 2603 if (inService) { 2604 mLruProcessActivityStart++; 2605 } 2606 */ 2607 2608 int nextIndex; 2609 if (hasActivity) { 2610 final int N = mLruProcesses.size(); 2611 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2612 // Process doesn't have activities, but has clients with 2613 // activities... move it up, but one below the top (the top 2614 // should always have a real activity). 2615 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2616 mLruProcesses.add(N-1, app); 2617 // To keep it from spamming the LRU list (by making a bunch of clients), 2618 // we will push down any other entries owned by the app. 2619 final int uid = app.info.uid; 2620 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2621 ProcessRecord subProc = mLruProcesses.get(i); 2622 if (subProc.info.uid == uid) { 2623 // We want to push this one down the list. If the process after 2624 // it is for the same uid, however, don't do so, because we don't 2625 // want them internally to be re-ordered. 2626 if (mLruProcesses.get(i-1).info.uid != uid) { 2627 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2628 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2629 ProcessRecord tmp = mLruProcesses.get(i); 2630 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2631 mLruProcesses.set(i-1, tmp); 2632 i--; 2633 } 2634 } else { 2635 // A gap, we can stop here. 2636 break; 2637 } 2638 } 2639 } else { 2640 // Process has activities, put it at the very tipsy-top. 2641 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2642 mLruProcesses.add(app); 2643 } 2644 nextIndex = mLruProcessServiceStart; 2645 } else if (hasService) { 2646 // Process has services, put it at the top of the service list. 2647 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2648 mLruProcesses.add(mLruProcessActivityStart, app); 2649 nextIndex = mLruProcessServiceStart; 2650 mLruProcessActivityStart++; 2651 } else { 2652 // Process not otherwise of interest, it goes to the top of the non-service area. 2653 int index = mLruProcessServiceStart; 2654 if (client != null) { 2655 // If there is a client, don't allow the process to be moved up higher 2656 // in the list than that client. 2657 int clientIndex = mLruProcesses.lastIndexOf(client); 2658 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2659 + " when updating " + app); 2660 if (clientIndex <= lrui) { 2661 // Don't allow the client index restriction to push it down farther in the 2662 // list than it already is. 2663 clientIndex = lrui; 2664 } 2665 if (clientIndex >= 0 && index > clientIndex) { 2666 index = clientIndex; 2667 } 2668 } 2669 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2670 mLruProcesses.add(index, app); 2671 nextIndex = index-1; 2672 mLruProcessActivityStart++; 2673 mLruProcessServiceStart++; 2674 } 2675 2676 // If the app is currently using a content provider or service, 2677 // bump those processes as well. 2678 for (int j=app.connections.size()-1; j>=0; j--) { 2679 ConnectionRecord cr = app.connections.valueAt(j); 2680 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2681 && cr.binding.service.app != null 2682 && cr.binding.service.app.lruSeq != mLruSeq 2683 && !cr.binding.service.app.persistent) { 2684 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2685 "service connection", cr, app); 2686 } 2687 } 2688 for (int j=app.conProviders.size()-1; j>=0; j--) { 2689 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2690 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2691 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2692 "provider reference", cpr, app); 2693 } 2694 } 2695 } 2696 2697 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2698 if (uid == Process.SYSTEM_UID) { 2699 // The system gets to run in any process. If there are multiple 2700 // processes with the same uid, just pick the first (this 2701 // should never happen). 2702 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2703 if (procs == null) return null; 2704 final int N = procs.size(); 2705 for (int i = 0; i < N; i++) { 2706 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2707 } 2708 } 2709 ProcessRecord proc = mProcessNames.get(processName, uid); 2710 if (false && proc != null && !keepIfLarge 2711 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2712 && proc.lastCachedPss >= 4000) { 2713 // Turn this condition on to cause killing to happen regularly, for testing. 2714 if (proc.baseProcessTracker != null) { 2715 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2716 } 2717 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2718 } else if (proc != null && !keepIfLarge 2719 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2720 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2721 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2722 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2723 if (proc.baseProcessTracker != null) { 2724 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2725 } 2726 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2727 } 2728 } 2729 return proc; 2730 } 2731 2732 void ensurePackageDexOpt(String packageName) { 2733 IPackageManager pm = AppGlobals.getPackageManager(); 2734 try { 2735 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2736 mDidDexOpt = true; 2737 } 2738 } catch (RemoteException e) { 2739 } 2740 } 2741 2742 boolean isNextTransitionForward() { 2743 int transit = mWindowManager.getPendingAppTransition(); 2744 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2745 || transit == AppTransition.TRANSIT_TASK_OPEN 2746 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2747 } 2748 2749 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2750 String processName, String abiOverride, int uid, Runnable crashHandler) { 2751 synchronized(this) { 2752 ApplicationInfo info = new ApplicationInfo(); 2753 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2754 // For isolated processes, the former contains the parent's uid and the latter the 2755 // actual uid of the isolated process. 2756 // In the special case introduced by this method (which is, starting an isolated 2757 // process directly from the SystemServer without an actual parent app process) the 2758 // closest thing to a parent's uid is SYSTEM_UID. 2759 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2760 // the |isolated| logic in the ProcessRecord constructor. 2761 info.uid = Process.SYSTEM_UID; 2762 info.processName = processName; 2763 info.className = entryPoint; 2764 info.packageName = "android"; 2765 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2766 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2767 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2768 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2769 crashHandler); 2770 return proc != null ? proc.pid : 0; 2771 } 2772 } 2773 2774 final ProcessRecord startProcessLocked(String processName, 2775 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2776 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2777 boolean isolated, boolean keepIfLarge) { 2778 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2779 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2780 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2781 null /* crashHandler */); 2782 } 2783 2784 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2785 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2786 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2787 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2788 long startTime = SystemClock.elapsedRealtime(); 2789 ProcessRecord app; 2790 if (!isolated) { 2791 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2792 checkTime(startTime, "startProcess: after getProcessRecord"); 2793 } else { 2794 // If this is an isolated process, it can't re-use an existing process. 2795 app = null; 2796 } 2797 // We don't have to do anything more if: 2798 // (1) There is an existing application record; and 2799 // (2) The caller doesn't think it is dead, OR there is no thread 2800 // object attached to it so we know it couldn't have crashed; and 2801 // (3) There is a pid assigned to it, so it is either starting or 2802 // already running. 2803 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2804 + " app=" + app + " knownToBeDead=" + knownToBeDead 2805 + " thread=" + (app != null ? app.thread : null) 2806 + " pid=" + (app != null ? app.pid : -1)); 2807 if (app != null && app.pid > 0) { 2808 if (!knownToBeDead || app.thread == null) { 2809 // We already have the app running, or are waiting for it to 2810 // come up (we have a pid but not yet its thread), so keep it. 2811 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2812 // If this is a new package in the process, add the package to the list 2813 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2814 checkTime(startTime, "startProcess: done, added package to proc"); 2815 return app; 2816 } 2817 2818 // An application record is attached to a previous process, 2819 // clean it up now. 2820 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2821 checkTime(startTime, "startProcess: bad proc running, killing"); 2822 Process.killProcessGroup(app.info.uid, app.pid); 2823 handleAppDiedLocked(app, true, true); 2824 checkTime(startTime, "startProcess: done killing old proc"); 2825 } 2826 2827 String hostingNameStr = hostingName != null 2828 ? hostingName.flattenToShortString() : null; 2829 2830 if (!isolated) { 2831 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2832 // If we are in the background, then check to see if this process 2833 // is bad. If so, we will just silently fail. 2834 if (mBadProcesses.get(info.processName, info.uid) != null) { 2835 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2836 + "/" + info.processName); 2837 return null; 2838 } 2839 } else { 2840 // When the user is explicitly starting a process, then clear its 2841 // crash count so that we won't make it bad until they see at 2842 // least one crash dialog again, and make the process good again 2843 // if it had been bad. 2844 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2845 + "/" + info.processName); 2846 mProcessCrashTimes.remove(info.processName, info.uid); 2847 if (mBadProcesses.get(info.processName, info.uid) != null) { 2848 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2849 UserHandle.getUserId(info.uid), info.uid, 2850 info.processName); 2851 mBadProcesses.remove(info.processName, info.uid); 2852 if (app != null) { 2853 app.bad = false; 2854 } 2855 } 2856 } 2857 } 2858 2859 if (app == null) { 2860 checkTime(startTime, "startProcess: creating new process record"); 2861 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2862 if (app == null) { 2863 Slog.w(TAG, "Failed making new process record for " 2864 + processName + "/" + info.uid + " isolated=" + isolated); 2865 return null; 2866 } 2867 app.crashHandler = crashHandler; 2868 mProcessNames.put(processName, app.uid, app); 2869 if (isolated) { 2870 mIsolatedProcesses.put(app.uid, app); 2871 } 2872 checkTime(startTime, "startProcess: done creating new process record"); 2873 } else { 2874 // If this is a new package in the process, add the package to the list 2875 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2876 checkTime(startTime, "startProcess: added package to existing proc"); 2877 } 2878 2879 // If the system is not ready yet, then hold off on starting this 2880 // process until it is. 2881 if (!mProcessesReady 2882 && !isAllowedWhileBooting(info) 2883 && !allowWhileBooting) { 2884 if (!mProcessesOnHold.contains(app)) { 2885 mProcessesOnHold.add(app); 2886 } 2887 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2888 checkTime(startTime, "startProcess: returning with proc on hold"); 2889 return app; 2890 } 2891 2892 checkTime(startTime, "startProcess: stepping in to startProcess"); 2893 startProcessLocked( 2894 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2895 checkTime(startTime, "startProcess: done starting proc!"); 2896 return (app.pid != 0) ? app : null; 2897 } 2898 2899 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2900 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2901 } 2902 2903 private final void startProcessLocked(ProcessRecord app, 2904 String hostingType, String hostingNameStr) { 2905 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2906 null /* entryPoint */, null /* entryPointArgs */); 2907 } 2908 2909 private final void startProcessLocked(ProcessRecord app, String hostingType, 2910 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2911 long startTime = SystemClock.elapsedRealtime(); 2912 if (app.pid > 0 && app.pid != MY_PID) { 2913 checkTime(startTime, "startProcess: removing from pids map"); 2914 synchronized (mPidsSelfLocked) { 2915 mPidsSelfLocked.remove(app.pid); 2916 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2917 } 2918 checkTime(startTime, "startProcess: done removing from pids map"); 2919 app.setPid(0); 2920 } 2921 2922 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2923 "startProcessLocked removing on hold: " + app); 2924 mProcessesOnHold.remove(app); 2925 2926 checkTime(startTime, "startProcess: starting to update cpu stats"); 2927 updateCpuStats(); 2928 checkTime(startTime, "startProcess: done updating cpu stats"); 2929 2930 try { 2931 int uid = app.uid; 2932 2933 int[] gids = null; 2934 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2935 if (!app.isolated) { 2936 int[] permGids = null; 2937 try { 2938 checkTime(startTime, "startProcess: getting gids from package manager"); 2939 final PackageManager pm = mContext.getPackageManager(); 2940 permGids = pm.getPackageGids(app.info.packageName); 2941 2942 if (Environment.isExternalStorageEmulated()) { 2943 checkTime(startTime, "startProcess: checking external storage perm"); 2944 if (pm.checkPermission( 2945 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2946 app.info.packageName) == PERMISSION_GRANTED) { 2947 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2948 } else { 2949 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2950 } 2951 } 2952 } catch (PackageManager.NameNotFoundException e) { 2953 Slog.w(TAG, "Unable to retrieve gids", e); 2954 } 2955 2956 /* 2957 * Add shared application and profile GIDs so applications can share some 2958 * resources like shared libraries and access user-wide resources 2959 */ 2960 if (permGids == null) { 2961 gids = new int[2]; 2962 } else { 2963 gids = new int[permGids.length + 2]; 2964 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2965 } 2966 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2967 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2968 } 2969 checkTime(startTime, "startProcess: building args"); 2970 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2971 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2972 && mTopComponent != null 2973 && app.processName.equals(mTopComponent.getPackageName())) { 2974 uid = 0; 2975 } 2976 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2977 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2978 uid = 0; 2979 } 2980 } 2981 int debugFlags = 0; 2982 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2983 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2984 // Also turn on CheckJNI for debuggable apps. It's quite 2985 // awkward to turn on otherwise. 2986 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2987 } 2988 // Run the app in safe mode if its manifest requests so or the 2989 // system is booted in safe mode. 2990 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2991 mSafeMode == true) { 2992 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2993 } 2994 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2995 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2996 } 2997 String jitDebugProperty = SystemProperties.get("debug.usejit"); 2998 if ("true".equals(jitDebugProperty)) { 2999 debugFlags |= Zygote.DEBUG_ENABLE_JIT; 3000 } else if (!"false".equals(jitDebugProperty)) { 3001 // If we didn't force disable by setting false, defer to the dalvik vm options. 3002 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) { 3003 debugFlags |= Zygote.DEBUG_ENABLE_JIT; 3004 } 3005 } 3006 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3007 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3008 } 3009 if ("1".equals(SystemProperties.get("debug.assert"))) { 3010 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3011 } 3012 3013 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3014 if (requiredAbi == null) { 3015 requiredAbi = Build.SUPPORTED_ABIS[0]; 3016 } 3017 3018 String instructionSet = null; 3019 if (app.info.primaryCpuAbi != null) { 3020 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3021 } 3022 3023 app.gids = gids; 3024 app.requiredAbi = requiredAbi; 3025 app.instructionSet = instructionSet; 3026 3027 // Start the process. It will either succeed and return a result containing 3028 // the PID of the new process, or else throw a RuntimeException. 3029 boolean isActivityProcess = (entryPoint == null); 3030 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3031 checkTime(startTime, "startProcess: asking zygote to start proc"); 3032 Process.ProcessStartResult startResult = Process.start(entryPoint, 3033 app.processName, uid, uid, gids, debugFlags, mountExternal, 3034 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3035 app.info.dataDir, entryPointArgs); 3036 checkTime(startTime, "startProcess: returned from zygote!"); 3037 3038 if (app.isolated) { 3039 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3040 } 3041 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3042 checkTime(startTime, "startProcess: done updating battery stats"); 3043 3044 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3045 UserHandle.getUserId(uid), startResult.pid, uid, 3046 app.processName, hostingType, 3047 hostingNameStr != null ? hostingNameStr : ""); 3048 3049 if (app.persistent) { 3050 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3051 } 3052 3053 checkTime(startTime, "startProcess: building log message"); 3054 StringBuilder buf = mStringBuilder; 3055 buf.setLength(0); 3056 buf.append("Start proc "); 3057 buf.append(startResult.pid); 3058 buf.append(':'); 3059 buf.append(app.processName); 3060 buf.append('/'); 3061 UserHandle.formatUid(buf, uid); 3062 if (!isActivityProcess) { 3063 buf.append(" ["); 3064 buf.append(entryPoint); 3065 buf.append("]"); 3066 } 3067 buf.append(" for "); 3068 buf.append(hostingType); 3069 if (hostingNameStr != null) { 3070 buf.append(" "); 3071 buf.append(hostingNameStr); 3072 } 3073 Slog.i(TAG, buf.toString()); 3074 app.setPid(startResult.pid); 3075 app.usingWrapper = startResult.usingWrapper; 3076 app.removed = false; 3077 app.killed = false; 3078 app.killedByAm = false; 3079 checkTime(startTime, "startProcess: starting to update pids map"); 3080 synchronized (mPidsSelfLocked) { 3081 this.mPidsSelfLocked.put(startResult.pid, app); 3082 if (isActivityProcess) { 3083 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3084 msg.obj = app; 3085 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3086 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3087 } 3088 } 3089 checkTime(startTime, "startProcess: done updating pids map"); 3090 } catch (RuntimeException e) { 3091 // XXX do better error recovery. 3092 app.setPid(0); 3093 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3094 if (app.isolated) { 3095 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3096 } 3097 Slog.e(TAG, "Failure starting process " + app.processName, e); 3098 } 3099 } 3100 3101 void updateUsageStats(ActivityRecord component, boolean resumed) { 3102 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3103 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3104 if (resumed) { 3105 if (mUsageStatsService != null) { 3106 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3107 UsageEvents.Event.MOVE_TO_FOREGROUND); 3108 } 3109 synchronized (stats) { 3110 stats.noteActivityResumedLocked(component.app.uid); 3111 } 3112 } else { 3113 if (mUsageStatsService != null) { 3114 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3115 UsageEvents.Event.MOVE_TO_BACKGROUND); 3116 } 3117 synchronized (stats) { 3118 stats.noteActivityPausedLocked(component.app.uid); 3119 } 3120 } 3121 } 3122 3123 Intent getHomeIntent() { 3124 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3125 intent.setComponent(mTopComponent); 3126 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3127 intent.addCategory(Intent.CATEGORY_HOME); 3128 } 3129 return intent; 3130 } 3131 3132 boolean startHomeActivityLocked(int userId, String reason) { 3133 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3134 && mTopAction == null) { 3135 // We are running in factory test mode, but unable to find 3136 // the factory test app, so just sit around displaying the 3137 // error message and don't try to start anything. 3138 return false; 3139 } 3140 Intent intent = getHomeIntent(); 3141 ActivityInfo aInfo = 3142 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3143 if (aInfo != null) { 3144 intent.setComponent(new ComponentName( 3145 aInfo.applicationInfo.packageName, aInfo.name)); 3146 // Don't do this if the home app is currently being 3147 // instrumented. 3148 aInfo = new ActivityInfo(aInfo); 3149 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3150 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3151 aInfo.applicationInfo.uid, true); 3152 if (app == null || app.instrumentationClass == null) { 3153 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3154 mStackSupervisor.startHomeActivity(intent, aInfo, reason); 3155 } 3156 } 3157 3158 return true; 3159 } 3160 3161 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3162 ActivityInfo ai = null; 3163 ComponentName comp = intent.getComponent(); 3164 try { 3165 if (comp != null) { 3166 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3167 } else { 3168 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3169 intent, 3170 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3171 flags, userId); 3172 3173 if (info != null) { 3174 ai = info.activityInfo; 3175 } 3176 } 3177 } catch (RemoteException e) { 3178 // ignore 3179 } 3180 3181 return ai; 3182 } 3183 3184 /** 3185 * Starts the "new version setup screen" if appropriate. 3186 */ 3187 void startSetupActivityLocked() { 3188 // Only do this once per boot. 3189 if (mCheckedForSetup) { 3190 return; 3191 } 3192 3193 // We will show this screen if the current one is a different 3194 // version than the last one shown, and we are not running in 3195 // low-level factory test mode. 3196 final ContentResolver resolver = mContext.getContentResolver(); 3197 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3198 Settings.Global.getInt(resolver, 3199 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3200 mCheckedForSetup = true; 3201 3202 // See if we should be showing the platform update setup UI. 3203 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3204 List<ResolveInfo> ris = mContext.getPackageManager() 3205 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3206 3207 // We don't allow third party apps to replace this. 3208 ResolveInfo ri = null; 3209 for (int i=0; ris != null && i<ris.size(); i++) { 3210 if ((ris.get(i).activityInfo.applicationInfo.flags 3211 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3212 ri = ris.get(i); 3213 break; 3214 } 3215 } 3216 3217 if (ri != null) { 3218 String vers = ri.activityInfo.metaData != null 3219 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3220 : null; 3221 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3222 vers = ri.activityInfo.applicationInfo.metaData.getString( 3223 Intent.METADATA_SETUP_VERSION); 3224 } 3225 String lastVers = Settings.Secure.getString( 3226 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3227 if (vers != null && !vers.equals(lastVers)) { 3228 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3229 intent.setComponent(new ComponentName( 3230 ri.activityInfo.packageName, ri.activityInfo.name)); 3231 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3232 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3233 null); 3234 } 3235 } 3236 } 3237 } 3238 3239 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3240 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3241 } 3242 3243 void enforceNotIsolatedCaller(String caller) { 3244 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3245 throw new SecurityException("Isolated process not allowed to call " + caller); 3246 } 3247 } 3248 3249 void enforceShellRestriction(String restriction, int userHandle) { 3250 if (Binder.getCallingUid() == Process.SHELL_UID) { 3251 if (userHandle < 0 3252 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3253 throw new SecurityException("Shell does not have permission to access user " 3254 + userHandle); 3255 } 3256 } 3257 } 3258 3259 @Override 3260 public int getFrontActivityScreenCompatMode() { 3261 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3262 synchronized (this) { 3263 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3264 } 3265 } 3266 3267 @Override 3268 public void setFrontActivityScreenCompatMode(int mode) { 3269 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3270 "setFrontActivityScreenCompatMode"); 3271 synchronized (this) { 3272 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3273 } 3274 } 3275 3276 @Override 3277 public int getPackageScreenCompatMode(String packageName) { 3278 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3279 synchronized (this) { 3280 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3281 } 3282 } 3283 3284 @Override 3285 public void setPackageScreenCompatMode(String packageName, int mode) { 3286 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3287 "setPackageScreenCompatMode"); 3288 synchronized (this) { 3289 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3290 } 3291 } 3292 3293 @Override 3294 public boolean getPackageAskScreenCompat(String packageName) { 3295 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3296 synchronized (this) { 3297 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3298 } 3299 } 3300 3301 @Override 3302 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3303 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3304 "setPackageAskScreenCompat"); 3305 synchronized (this) { 3306 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3307 } 3308 } 3309 3310 private void dispatchProcessesChanged() { 3311 int N; 3312 synchronized (this) { 3313 N = mPendingProcessChanges.size(); 3314 if (mActiveProcessChanges.length < N) { 3315 mActiveProcessChanges = new ProcessChangeItem[N]; 3316 } 3317 mPendingProcessChanges.toArray(mActiveProcessChanges); 3318 mAvailProcessChanges.addAll(mPendingProcessChanges); 3319 mPendingProcessChanges.clear(); 3320 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3321 } 3322 3323 int i = mProcessObservers.beginBroadcast(); 3324 while (i > 0) { 3325 i--; 3326 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3327 if (observer != null) { 3328 try { 3329 for (int j=0; j<N; j++) { 3330 ProcessChangeItem item = mActiveProcessChanges[j]; 3331 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3332 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3333 + item.pid + " uid=" + item.uid + ": " 3334 + item.foregroundActivities); 3335 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3336 item.foregroundActivities); 3337 } 3338 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3339 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3340 + item.pid + " uid=" + item.uid + ": " + item.processState); 3341 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3342 } 3343 } 3344 } catch (RemoteException e) { 3345 } 3346 } 3347 } 3348 mProcessObservers.finishBroadcast(); 3349 } 3350 3351 private void dispatchProcessDied(int pid, int uid) { 3352 int i = mProcessObservers.beginBroadcast(); 3353 while (i > 0) { 3354 i--; 3355 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3356 if (observer != null) { 3357 try { 3358 observer.onProcessDied(pid, uid); 3359 } catch (RemoteException e) { 3360 } 3361 } 3362 } 3363 mProcessObservers.finishBroadcast(); 3364 } 3365 3366 @Override 3367 public final int startActivity(IApplicationThread caller, String callingPackage, 3368 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3369 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3370 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3371 resultWho, requestCode, startFlags, profilerInfo, options, 3372 UserHandle.getCallingUserId()); 3373 } 3374 3375 @Override 3376 public final int startActivityAsUser(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 enforceNotIsolatedCaller("startActivity"); 3380 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3381 false, ALLOW_FULL_ONLY, "startActivity", null); 3382 // TODO: Switch to user app stacks here. 3383 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3384 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3385 profilerInfo, null, null, options, userId, null, null); 3386 } 3387 3388 @Override 3389 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3390 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3391 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3392 3393 // This is very dangerous -- it allows you to perform a start activity (including 3394 // permission grants) as any app that may launch one of your own activities. So 3395 // we will only allow this to be done from activities that are part of the core framework, 3396 // and then only when they are running as the system. 3397 final ActivityRecord sourceRecord; 3398 final int targetUid; 3399 final String targetPackage; 3400 synchronized (this) { 3401 if (resultTo == null) { 3402 throw new SecurityException("Must be called from an activity"); 3403 } 3404 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3405 if (sourceRecord == null) { 3406 throw new SecurityException("Called with bad activity token: " + resultTo); 3407 } 3408 if (!sourceRecord.info.packageName.equals("android")) { 3409 throw new SecurityException( 3410 "Must be called from an activity that is declared in the android package"); 3411 } 3412 if (sourceRecord.app == null) { 3413 throw new SecurityException("Called without a process attached to activity"); 3414 } 3415 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3416 // This is still okay, as long as this activity is running under the 3417 // uid of the original calling activity. 3418 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3419 throw new SecurityException( 3420 "Calling activity in uid " + sourceRecord.app.uid 3421 + " must be system uid or original calling uid " 3422 + sourceRecord.launchedFromUid); 3423 } 3424 } 3425 targetUid = sourceRecord.launchedFromUid; 3426 targetPackage = sourceRecord.launchedFromPackage; 3427 } 3428 3429 if (userId == UserHandle.USER_NULL) { 3430 userId = UserHandle.getUserId(sourceRecord.app.uid); 3431 } 3432 3433 // TODO: Switch to user app stacks here. 3434 try { 3435 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3436 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3437 null, null, options, userId, null, null); 3438 return ret; 3439 } catch (SecurityException e) { 3440 // XXX need to figure out how to propagate to original app. 3441 // A SecurityException here is generally actually a fault of the original 3442 // calling activity (such as a fairly granting permissions), so propagate it 3443 // back to them. 3444 /* 3445 StringBuilder msg = new StringBuilder(); 3446 msg.append("While launching"); 3447 msg.append(intent.toString()); 3448 msg.append(": "); 3449 msg.append(e.getMessage()); 3450 */ 3451 throw e; 3452 } 3453 } 3454 3455 @Override 3456 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3457 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3458 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3459 enforceNotIsolatedCaller("startActivityAndWait"); 3460 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3461 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3462 WaitResult res = new WaitResult(); 3463 // TODO: Switch to user app stacks here. 3464 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3465 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3466 options, userId, null, null); 3467 return res; 3468 } 3469 3470 @Override 3471 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3472 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3473 int startFlags, Configuration config, Bundle options, int userId) { 3474 enforceNotIsolatedCaller("startActivityWithConfig"); 3475 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3476 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3477 // TODO: Switch to user app stacks here. 3478 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3479 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3480 null, null, config, options, userId, null, null); 3481 return ret; 3482 } 3483 3484 @Override 3485 public int startActivityIntentSender(IApplicationThread caller, 3486 IntentSender intent, Intent fillInIntent, String resolvedType, 3487 IBinder resultTo, String resultWho, int requestCode, 3488 int flagsMask, int flagsValues, Bundle options) { 3489 enforceNotIsolatedCaller("startActivityIntentSender"); 3490 // Refuse possible leaked file descriptors 3491 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3492 throw new IllegalArgumentException("File descriptors passed in Intent"); 3493 } 3494 3495 IIntentSender sender = intent.getTarget(); 3496 if (!(sender instanceof PendingIntentRecord)) { 3497 throw new IllegalArgumentException("Bad PendingIntent object"); 3498 } 3499 3500 PendingIntentRecord pir = (PendingIntentRecord)sender; 3501 3502 synchronized (this) { 3503 // If this is coming from the currently resumed activity, it is 3504 // effectively saying that app switches are allowed at this point. 3505 final ActivityStack stack = getFocusedStack(); 3506 if (stack.mResumedActivity != null && 3507 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3508 mAppSwitchesAllowedTime = 0; 3509 } 3510 } 3511 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3512 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3513 return ret; 3514 } 3515 3516 @Override 3517 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3518 Intent intent, String resolvedType, IVoiceInteractionSession session, 3519 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3520 Bundle options, int userId) { 3521 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3522 != PackageManager.PERMISSION_GRANTED) { 3523 String msg = "Permission Denial: startVoiceActivity() from pid=" 3524 + Binder.getCallingPid() 3525 + ", uid=" + Binder.getCallingUid() 3526 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3527 Slog.w(TAG, msg); 3528 throw new SecurityException(msg); 3529 } 3530 if (session == null || interactor == null) { 3531 throw new NullPointerException("null session or interactor"); 3532 } 3533 userId = handleIncomingUser(callingPid, callingUid, userId, 3534 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3535 // TODO: Switch to user app stacks here. 3536 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3537 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3538 null, options, userId, null, null); 3539 } 3540 3541 @Override 3542 public boolean startNextMatchingActivity(IBinder callingActivity, 3543 Intent intent, Bundle options) { 3544 // Refuse possible leaked file descriptors 3545 if (intent != null && intent.hasFileDescriptors() == true) { 3546 throw new IllegalArgumentException("File descriptors passed in Intent"); 3547 } 3548 3549 synchronized (this) { 3550 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3551 if (r == null) { 3552 ActivityOptions.abort(options); 3553 return false; 3554 } 3555 if (r.app == null || r.app.thread == null) { 3556 // The caller is not running... d'oh! 3557 ActivityOptions.abort(options); 3558 return false; 3559 } 3560 intent = new Intent(intent); 3561 // The caller is not allowed to change the data. 3562 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3563 // And we are resetting to find the next component... 3564 intent.setComponent(null); 3565 3566 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3567 3568 ActivityInfo aInfo = null; 3569 try { 3570 List<ResolveInfo> resolves = 3571 AppGlobals.getPackageManager().queryIntentActivities( 3572 intent, r.resolvedType, 3573 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3574 UserHandle.getCallingUserId()); 3575 3576 // Look for the original activity in the list... 3577 final int N = resolves != null ? resolves.size() : 0; 3578 for (int i=0; i<N; i++) { 3579 ResolveInfo rInfo = resolves.get(i); 3580 if (rInfo.activityInfo.packageName.equals(r.packageName) 3581 && rInfo.activityInfo.name.equals(r.info.name)) { 3582 // We found the current one... the next matching is 3583 // after it. 3584 i++; 3585 if (i<N) { 3586 aInfo = resolves.get(i).activityInfo; 3587 } 3588 if (debug) { 3589 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3590 + "/" + r.info.name); 3591 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3592 + "/" + aInfo.name); 3593 } 3594 break; 3595 } 3596 } 3597 } catch (RemoteException e) { 3598 } 3599 3600 if (aInfo == null) { 3601 // Nobody who is next! 3602 ActivityOptions.abort(options); 3603 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3604 return false; 3605 } 3606 3607 intent.setComponent(new ComponentName( 3608 aInfo.applicationInfo.packageName, aInfo.name)); 3609 intent.setFlags(intent.getFlags()&~( 3610 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3611 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3612 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3613 Intent.FLAG_ACTIVITY_NEW_TASK)); 3614 3615 // Okay now we need to start the new activity, replacing the 3616 // currently running activity. This is a little tricky because 3617 // we want to start the new one as if the current one is finished, 3618 // but not finish the current one first so that there is no flicker. 3619 // And thus... 3620 final boolean wasFinishing = r.finishing; 3621 r.finishing = true; 3622 3623 // Propagate reply information over to the new activity. 3624 final ActivityRecord resultTo = r.resultTo; 3625 final String resultWho = r.resultWho; 3626 final int requestCode = r.requestCode; 3627 r.resultTo = null; 3628 if (resultTo != null) { 3629 resultTo.removeResultsLocked(r, resultWho, requestCode); 3630 } 3631 3632 final long origId = Binder.clearCallingIdentity(); 3633 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3634 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3635 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3636 -1, r.launchedFromUid, 0, options, false, null, null, null); 3637 Binder.restoreCallingIdentity(origId); 3638 3639 r.finishing = wasFinishing; 3640 if (res != ActivityManager.START_SUCCESS) { 3641 return false; 3642 } 3643 return true; 3644 } 3645 } 3646 3647 @Override 3648 public final int startActivityFromRecents(int taskId, Bundle options) { 3649 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3650 String msg = "Permission Denial: startActivityFromRecents called without " + 3651 START_TASKS_FROM_RECENTS; 3652 Slog.w(TAG, msg); 3653 throw new SecurityException(msg); 3654 } 3655 return startActivityFromRecentsInner(taskId, options); 3656 } 3657 3658 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3659 final TaskRecord task; 3660 final int callingUid; 3661 final String callingPackage; 3662 final Intent intent; 3663 final int userId; 3664 synchronized (this) { 3665 task = recentTaskForIdLocked(taskId); 3666 if (task == null) { 3667 throw new IllegalArgumentException("Task " + taskId + " not found."); 3668 } 3669 if (task.getRootActivity() != null) { 3670 moveTaskToFrontLocked(task.taskId, 0, null); 3671 return ActivityManager.START_TASK_TO_FRONT; 3672 } 3673 callingUid = task.mCallingUid; 3674 callingPackage = task.mCallingPackage; 3675 intent = task.intent; 3676 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3677 userId = task.userId; 3678 } 3679 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3680 options, userId, null, task); 3681 } 3682 3683 final int startActivityInPackage(int uid, String callingPackage, 3684 Intent intent, String resolvedType, IBinder resultTo, 3685 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3686 IActivityContainer container, TaskRecord inTask) { 3687 3688 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3689 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3690 3691 // TODO: Switch to user app stacks here. 3692 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3693 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3694 null, null, null, options, userId, container, inTask); 3695 return ret; 3696 } 3697 3698 @Override 3699 public final int startActivities(IApplicationThread caller, String callingPackage, 3700 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3701 int userId) { 3702 enforceNotIsolatedCaller("startActivities"); 3703 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3704 false, ALLOW_FULL_ONLY, "startActivity", null); 3705 // TODO: Switch to user app stacks here. 3706 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3707 resolvedTypes, resultTo, options, userId); 3708 return ret; 3709 } 3710 3711 final int startActivitiesInPackage(int uid, String callingPackage, 3712 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3713 Bundle options, int userId) { 3714 3715 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3716 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3717 // TODO: Switch to user app stacks here. 3718 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3719 resultTo, options, userId); 3720 return ret; 3721 } 3722 3723 //explicitly remove thd old information in mRecentTasks when removing existing user. 3724 private void removeRecentTasksForUserLocked(int userId) { 3725 if(userId <= 0) { 3726 Slog.i(TAG, "Can't remove recent task on user " + userId); 3727 return; 3728 } 3729 3730 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3731 TaskRecord tr = mRecentTasks.get(i); 3732 if (tr.userId == userId) { 3733 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3734 + " when finishing user" + userId); 3735 mRecentTasks.remove(i); 3736 tr.removedFromRecents(); 3737 } 3738 } 3739 3740 // Remove tasks from persistent storage. 3741 notifyTaskPersisterLocked(null, true); 3742 } 3743 3744 // Sort by taskId 3745 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3746 @Override 3747 public int compare(TaskRecord lhs, TaskRecord rhs) { 3748 return rhs.taskId - lhs.taskId; 3749 } 3750 }; 3751 3752 // Extract the affiliates of the chain containing mRecentTasks[start]. 3753 private int processNextAffiliateChainLocked(int start) { 3754 final TaskRecord startTask = mRecentTasks.get(start); 3755 final int affiliateId = startTask.mAffiliatedTaskId; 3756 3757 // Quick identification of isolated tasks. I.e. those not launched behind. 3758 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3759 startTask.mNextAffiliate == null) { 3760 // There is still a slim chance that there are other tasks that point to this task 3761 // and that the chain is so messed up that this task no longer points to them but 3762 // the gain of this optimization outweighs the risk. 3763 startTask.inRecents = true; 3764 return start + 1; 3765 } 3766 3767 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3768 mTmpRecents.clear(); 3769 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3770 final TaskRecord task = mRecentTasks.get(i); 3771 if (task.mAffiliatedTaskId == affiliateId) { 3772 mRecentTasks.remove(i); 3773 mTmpRecents.add(task); 3774 } 3775 } 3776 3777 // Sort them all by taskId. That is the order they were create in and that order will 3778 // always be correct. 3779 Collections.sort(mTmpRecents, mTaskRecordComparator); 3780 3781 // Go through and fix up the linked list. 3782 // The first one is the end of the chain and has no next. 3783 final TaskRecord first = mTmpRecents.get(0); 3784 first.inRecents = true; 3785 if (first.mNextAffiliate != null) { 3786 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3787 first.setNextAffiliate(null); 3788 notifyTaskPersisterLocked(first, false); 3789 } 3790 // Everything in the middle is doubly linked from next to prev. 3791 final int tmpSize = mTmpRecents.size(); 3792 for (int i = 0; i < tmpSize - 1; ++i) { 3793 final TaskRecord next = mTmpRecents.get(i); 3794 final TaskRecord prev = mTmpRecents.get(i + 1); 3795 if (next.mPrevAffiliate != prev) { 3796 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3797 " setting prev=" + prev); 3798 next.setPrevAffiliate(prev); 3799 notifyTaskPersisterLocked(next, false); 3800 } 3801 if (prev.mNextAffiliate != next) { 3802 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3803 " setting next=" + next); 3804 prev.setNextAffiliate(next); 3805 notifyTaskPersisterLocked(prev, false); 3806 } 3807 prev.inRecents = true; 3808 } 3809 // The last one is the beginning of the list and has no prev. 3810 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3811 if (last.mPrevAffiliate != null) { 3812 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3813 last.setPrevAffiliate(null); 3814 notifyTaskPersisterLocked(last, false); 3815 } 3816 3817 // Insert the group back into mRecentTasks at start. 3818 mRecentTasks.addAll(start, mTmpRecents); 3819 3820 // Let the caller know where we left off. 3821 return start + tmpSize; 3822 } 3823 3824 /** 3825 * Update the recent tasks lists: make sure tasks should still be here (their 3826 * applications / activities still exist), update their availability, fixup ordering 3827 * of affiliations. 3828 */ 3829 void cleanupRecentTasksLocked(int userId) { 3830 if (mRecentTasks == null) { 3831 // Happens when called from the packagemanager broadcast before boot. 3832 return; 3833 } 3834 3835 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3836 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3837 final IPackageManager pm = AppGlobals.getPackageManager(); 3838 final ActivityInfo dummyAct = new ActivityInfo(); 3839 final ApplicationInfo dummyApp = new ApplicationInfo(); 3840 3841 int N = mRecentTasks.size(); 3842 3843 int[] users = userId == UserHandle.USER_ALL 3844 ? getUsersLocked() : new int[] { userId }; 3845 for (int user : users) { 3846 for (int i = 0; i < N; i++) { 3847 TaskRecord task = mRecentTasks.get(i); 3848 if (task.userId != user) { 3849 // Only look at tasks for the user ID of interest. 3850 continue; 3851 } 3852 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3853 // This situation is broken, and we should just get rid of it now. 3854 mRecentTasks.remove(i); 3855 task.removedFromRecents(); 3856 i--; 3857 N--; 3858 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3859 continue; 3860 } 3861 // Check whether this activity is currently available. 3862 if (task.realActivity != null) { 3863 ActivityInfo ai = availActCache.get(task.realActivity); 3864 if (ai == null) { 3865 try { 3866 ai = pm.getActivityInfo(task.realActivity, 3867 PackageManager.GET_UNINSTALLED_PACKAGES 3868 | PackageManager.GET_DISABLED_COMPONENTS, user); 3869 } catch (RemoteException e) { 3870 // Will never happen. 3871 continue; 3872 } 3873 if (ai == null) { 3874 ai = dummyAct; 3875 } 3876 availActCache.put(task.realActivity, ai); 3877 } 3878 if (ai == dummyAct) { 3879 // This could be either because the activity no longer exists, or the 3880 // app is temporarily gone. For the former we want to remove the recents 3881 // entry; for the latter we want to mark it as unavailable. 3882 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3883 if (app == null) { 3884 try { 3885 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3886 PackageManager.GET_UNINSTALLED_PACKAGES 3887 | PackageManager.GET_DISABLED_COMPONENTS, user); 3888 } catch (RemoteException e) { 3889 // Will never happen. 3890 continue; 3891 } 3892 if (app == null) { 3893 app = dummyApp; 3894 } 3895 availAppCache.put(task.realActivity.getPackageName(), app); 3896 } 3897 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3898 // Doesn't exist any more! Good-bye. 3899 mRecentTasks.remove(i); 3900 task.removedFromRecents(); 3901 i--; 3902 N--; 3903 Slog.w(TAG, "Removing no longer valid recent: " + task); 3904 continue; 3905 } else { 3906 // Otherwise just not available for now. 3907 if (task.isAvailable) { 3908 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3909 + task); 3910 } 3911 task.isAvailable = false; 3912 } 3913 } else { 3914 if (!ai.enabled || !ai.applicationInfo.enabled 3915 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3916 if (task.isAvailable) { 3917 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3918 + task + " (enabled=" + ai.enabled + "/" 3919 + ai.applicationInfo.enabled + " flags=" 3920 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3921 } 3922 task.isAvailable = false; 3923 } else { 3924 if (!task.isAvailable) { 3925 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3926 + task); 3927 } 3928 task.isAvailable = true; 3929 } 3930 } 3931 } 3932 } 3933 } 3934 3935 // Verify the affiliate chain for each task. 3936 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3937 } 3938 3939 mTmpRecents.clear(); 3940 // mRecentTasks is now in sorted, affiliated order. 3941 } 3942 3943 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3944 int N = mRecentTasks.size(); 3945 TaskRecord top = task; 3946 int topIndex = taskIndex; 3947 while (top.mNextAffiliate != null && topIndex > 0) { 3948 top = top.mNextAffiliate; 3949 topIndex--; 3950 } 3951 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3952 + topIndex + " from intial " + taskIndex); 3953 // Find the end of the chain, doing a sanity check along the way. 3954 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3955 int endIndex = topIndex; 3956 TaskRecord prev = top; 3957 while (endIndex < N) { 3958 TaskRecord cur = mRecentTasks.get(endIndex); 3959 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3960 + endIndex + " " + cur); 3961 if (cur == top) { 3962 // Verify start of the chain. 3963 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3964 Slog.wtf(TAG, "Bad chain @" + endIndex 3965 + ": first task has next affiliate: " + prev); 3966 sane = false; 3967 break; 3968 } 3969 } else { 3970 // Verify middle of the chain's next points back to the one before. 3971 if (cur.mNextAffiliate != prev 3972 || cur.mNextAffiliateTaskId != prev.taskId) { 3973 Slog.wtf(TAG, "Bad chain @" + endIndex 3974 + ": middle task " + cur + " @" + endIndex 3975 + " has bad next affiliate " 3976 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3977 + ", expected " + prev); 3978 sane = false; 3979 break; 3980 } 3981 } 3982 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3983 // Chain ends here. 3984 if (cur.mPrevAffiliate != null) { 3985 Slog.wtf(TAG, "Bad chain @" + endIndex 3986 + ": last task " + cur + " has previous affiliate " 3987 + cur.mPrevAffiliate); 3988 sane = false; 3989 } 3990 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3991 break; 3992 } else { 3993 // Verify middle of the chain's prev points to a valid item. 3994 if (cur.mPrevAffiliate == null) { 3995 Slog.wtf(TAG, "Bad chain @" + endIndex 3996 + ": task " + cur + " has previous affiliate " 3997 + cur.mPrevAffiliate + " but should be id " 3998 + cur.mPrevAffiliate); 3999 sane = false; 4000 break; 4001 } 4002 } 4003 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4004 Slog.wtf(TAG, "Bad chain @" + endIndex 4005 + ": task " + cur + " has affiliated id " 4006 + cur.mAffiliatedTaskId + " but should be " 4007 + task.mAffiliatedTaskId); 4008 sane = false; 4009 break; 4010 } 4011 prev = cur; 4012 endIndex++; 4013 if (endIndex >= N) { 4014 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4015 + ": last task " + prev); 4016 sane = false; 4017 break; 4018 } 4019 } 4020 if (sane) { 4021 if (endIndex < taskIndex) { 4022 Slog.wtf(TAG, "Bad chain @" + endIndex 4023 + ": did not extend to task " + task + " @" + taskIndex); 4024 sane = false; 4025 } 4026 } 4027 if (sane) { 4028 // All looks good, we can just move all of the affiliated tasks 4029 // to the top. 4030 for (int i=topIndex; i<=endIndex; i++) { 4031 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4032 + " from " + i + " to " + (i-topIndex)); 4033 TaskRecord cur = mRecentTasks.remove(i); 4034 mRecentTasks.add(i-topIndex, cur); 4035 } 4036 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4037 + " to " + endIndex); 4038 return true; 4039 } 4040 4041 // Whoops, couldn't do it. 4042 return false; 4043 } 4044 4045 final void addRecentTaskLocked(TaskRecord task) { 4046 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4047 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4048 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4049 4050 int N = mRecentTasks.size(); 4051 // Quick case: check if the top-most recent task is the same. 4052 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4053 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4054 return; 4055 } 4056 // Another quick case: check if this is part of a set of affiliated 4057 // tasks that are at the top. 4058 if (isAffiliated && N > 0 && task.inRecents 4059 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4060 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4061 + " at top when adding " + task); 4062 return; 4063 } 4064 // Another quick case: never add voice sessions. 4065 if (task.voiceSession != null) { 4066 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4067 return; 4068 } 4069 4070 boolean needAffiliationFix = false; 4071 4072 // Slightly less quick case: the task is already in recents, so all we need 4073 // to do is move it. 4074 if (task.inRecents) { 4075 int taskIndex = mRecentTasks.indexOf(task); 4076 if (taskIndex >= 0) { 4077 if (!isAffiliated) { 4078 // Simple case: this is not an affiliated task, so we just move it to the front. 4079 mRecentTasks.remove(taskIndex); 4080 mRecentTasks.add(0, task); 4081 notifyTaskPersisterLocked(task, false); 4082 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4083 + " from " + taskIndex); 4084 return; 4085 } else { 4086 // More complicated: need to keep all affiliated tasks together. 4087 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4088 // All went well. 4089 return; 4090 } 4091 4092 // Uh oh... something bad in the affiliation chain, try to rebuild 4093 // everything and then go through our general path of adding a new task. 4094 needAffiliationFix = true; 4095 } 4096 } else { 4097 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4098 needAffiliationFix = true; 4099 } 4100 } 4101 4102 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4103 trimRecentsForTaskLocked(task, true); 4104 4105 N = mRecentTasks.size(); 4106 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4107 final TaskRecord tr = mRecentTasks.remove(N - 1); 4108 tr.removedFromRecents(); 4109 N--; 4110 } 4111 task.inRecents = true; 4112 if (!isAffiliated || needAffiliationFix) { 4113 // If this is a simple non-affiliated task, or we had some failure trying to 4114 // handle it as part of an affilated task, then just place it at the top. 4115 mRecentTasks.add(0, task); 4116 } else if (isAffiliated) { 4117 // If this is a new affiliated task, then move all of the affiliated tasks 4118 // to the front and insert this new one. 4119 TaskRecord other = task.mNextAffiliate; 4120 if (other == null) { 4121 other = task.mPrevAffiliate; 4122 } 4123 if (other != null) { 4124 int otherIndex = mRecentTasks.indexOf(other); 4125 if (otherIndex >= 0) { 4126 // Insert new task at appropriate location. 4127 int taskIndex; 4128 if (other == task.mNextAffiliate) { 4129 // We found the index of our next affiliation, which is who is 4130 // before us in the list, so add after that point. 4131 taskIndex = otherIndex+1; 4132 } else { 4133 // We found the index of our previous affiliation, which is who is 4134 // after us in the list, so add at their position. 4135 taskIndex = otherIndex; 4136 } 4137 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4138 + taskIndex + ": " + task); 4139 mRecentTasks.add(taskIndex, task); 4140 4141 // Now move everything to the front. 4142 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4143 // All went well. 4144 return; 4145 } 4146 4147 // Uh oh... something bad in the affiliation chain, try to rebuild 4148 // everything and then go through our general path of adding a new task. 4149 needAffiliationFix = true; 4150 } else { 4151 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4152 + other); 4153 needAffiliationFix = true; 4154 } 4155 } else { 4156 if (DEBUG_RECENTS) Slog.d(TAG, 4157 "addRecent: adding affiliated task without next/prev:" + task); 4158 needAffiliationFix = true; 4159 } 4160 } 4161 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4162 4163 if (needAffiliationFix) { 4164 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4165 cleanupRecentTasksLocked(task.userId); 4166 } 4167 } 4168 4169 /** 4170 * If needed, remove oldest existing entries in recents that are for the same kind 4171 * of task as the given one. 4172 */ 4173 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4174 int N = mRecentTasks.size(); 4175 final Intent intent = task.intent; 4176 final boolean document = intent != null && intent.isDocument(); 4177 4178 int maxRecents = task.maxRecents - 1; 4179 for (int i=0; i<N; i++) { 4180 final TaskRecord tr = mRecentTasks.get(i); 4181 if (task != tr) { 4182 if (task.userId != tr.userId) { 4183 continue; 4184 } 4185 if (i > MAX_RECENT_BITMAPS) { 4186 tr.freeLastThumbnail(); 4187 } 4188 final Intent trIntent = tr.intent; 4189 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4190 (intent == null || !intent.filterEquals(trIntent))) { 4191 continue; 4192 } 4193 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4194 if (document && trIsDocument) { 4195 // These are the same document activity (not necessarily the same doc). 4196 if (maxRecents > 0) { 4197 --maxRecents; 4198 continue; 4199 } 4200 // Hit the maximum number of documents for this task. Fall through 4201 // and remove this document from recents. 4202 } else if (document || trIsDocument) { 4203 // Only one of these is a document. Not the droid we're looking for. 4204 continue; 4205 } 4206 } 4207 4208 if (!doTrim) { 4209 // If the caller is not actually asking for a trim, just tell them we reached 4210 // a point where the trim would happen. 4211 return i; 4212 } 4213 4214 // Either task and tr are the same or, their affinities match or their intents match 4215 // and neither of them is a document, or they are documents using the same activity 4216 // and their maxRecents has been reached. 4217 tr.disposeThumbnail(); 4218 mRecentTasks.remove(i); 4219 if (task != tr) { 4220 tr.removedFromRecents(); 4221 } 4222 i--; 4223 N--; 4224 if (task.intent == null) { 4225 // If the new recent task we are adding is not fully 4226 // specified, then replace it with the existing recent task. 4227 task = tr; 4228 } 4229 notifyTaskPersisterLocked(tr, false); 4230 } 4231 4232 return -1; 4233 } 4234 4235 @Override 4236 public void reportActivityFullyDrawn(IBinder token) { 4237 synchronized (this) { 4238 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4239 if (r == null) { 4240 return; 4241 } 4242 r.reportFullyDrawnLocked(); 4243 } 4244 } 4245 4246 @Override 4247 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4248 synchronized (this) { 4249 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4250 if (r == null) { 4251 return; 4252 } 4253 final long origId = Binder.clearCallingIdentity(); 4254 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4255 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4256 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4257 if (config != null) { 4258 r.frozenBeforeDestroy = true; 4259 if (!updateConfigurationLocked(config, r, false, false)) { 4260 mStackSupervisor.resumeTopActivitiesLocked(); 4261 } 4262 } 4263 Binder.restoreCallingIdentity(origId); 4264 } 4265 } 4266 4267 @Override 4268 public int getRequestedOrientation(IBinder token) { 4269 synchronized (this) { 4270 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4271 if (r == null) { 4272 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4273 } 4274 return mWindowManager.getAppOrientation(r.appToken); 4275 } 4276 } 4277 4278 /** 4279 * This is the internal entry point for handling Activity.finish(). 4280 * 4281 * @param token The Binder token referencing the Activity we want to finish. 4282 * @param resultCode Result code, if any, from this Activity. 4283 * @param resultData Result data (Intent), if any, from this Activity. 4284 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4285 * the root Activity in the task. 4286 * 4287 * @return Returns true if the activity successfully finished, or false if it is still running. 4288 */ 4289 @Override 4290 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4291 boolean finishTask) { 4292 // Refuse possible leaked file descriptors 4293 if (resultData != null && resultData.hasFileDescriptors() == true) { 4294 throw new IllegalArgumentException("File descriptors passed in Intent"); 4295 } 4296 4297 synchronized(this) { 4298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4299 if (r == null) { 4300 return true; 4301 } 4302 // Keep track of the root activity of the task before we finish it 4303 TaskRecord tr = r.task; 4304 ActivityRecord rootR = tr.getRootActivity(); 4305 if (rootR == null) { 4306 Slog.w(TAG, "Finishing task with all activities already finished"); 4307 } 4308 // Do not allow task to finish in Lock Task mode. 4309 if (tr == mStackSupervisor.mLockTaskModeTask) { 4310 if (rootR == r) { 4311 Slog.i(TAG, "Not finishing task in lock task mode"); 4312 mStackSupervisor.showLockTaskToast(); 4313 return false; 4314 } 4315 } 4316 if (mController != null) { 4317 // Find the first activity that is not finishing. 4318 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4319 if (next != null) { 4320 // ask watcher if this is allowed 4321 boolean resumeOK = true; 4322 try { 4323 resumeOK = mController.activityResuming(next.packageName); 4324 } catch (RemoteException e) { 4325 mController = null; 4326 Watchdog.getInstance().setActivityController(null); 4327 } 4328 4329 if (!resumeOK) { 4330 Slog.i(TAG, "Not finishing activity because controller resumed"); 4331 return false; 4332 } 4333 } 4334 } 4335 final long origId = Binder.clearCallingIdentity(); 4336 try { 4337 boolean res; 4338 if (finishTask && r == rootR) { 4339 // If requested, remove the task that is associated to this activity only if it 4340 // was the root activity in the task. The result code and data is ignored 4341 // because we don't support returning them across task boundaries. 4342 res = removeTaskByIdLocked(tr.taskId, false); 4343 if (!res) { 4344 Slog.i(TAG, "Removing task failed to finish activity"); 4345 } 4346 } else { 4347 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4348 resultData, "app-request", true); 4349 if (!res) { 4350 Slog.i(TAG, "Failed to finish by app-request"); 4351 } 4352 } 4353 return res; 4354 } finally { 4355 Binder.restoreCallingIdentity(origId); 4356 } 4357 } 4358 } 4359 4360 @Override 4361 public final void finishHeavyWeightApp() { 4362 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4363 != PackageManager.PERMISSION_GRANTED) { 4364 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4365 + Binder.getCallingPid() 4366 + ", uid=" + Binder.getCallingUid() 4367 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4368 Slog.w(TAG, msg); 4369 throw new SecurityException(msg); 4370 } 4371 4372 synchronized(this) { 4373 if (mHeavyWeightProcess == null) { 4374 return; 4375 } 4376 4377 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4378 mHeavyWeightProcess.activities); 4379 for (int i=0; i<activities.size(); i++) { 4380 ActivityRecord r = activities.get(i); 4381 if (!r.finishing) { 4382 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4383 null, "finish-heavy", true); 4384 } 4385 } 4386 4387 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4388 mHeavyWeightProcess.userId, 0)); 4389 mHeavyWeightProcess = null; 4390 } 4391 } 4392 4393 @Override 4394 public void crashApplication(int uid, int initialPid, String packageName, 4395 String message) { 4396 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4397 != PackageManager.PERMISSION_GRANTED) { 4398 String msg = "Permission Denial: crashApplication() from pid=" 4399 + Binder.getCallingPid() 4400 + ", uid=" + Binder.getCallingUid() 4401 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4402 Slog.w(TAG, msg); 4403 throw new SecurityException(msg); 4404 } 4405 4406 synchronized(this) { 4407 ProcessRecord proc = null; 4408 4409 // Figure out which process to kill. We don't trust that initialPid 4410 // still has any relation to current pids, so must scan through the 4411 // list. 4412 synchronized (mPidsSelfLocked) { 4413 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4414 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4415 if (p.uid != uid) { 4416 continue; 4417 } 4418 if (p.pid == initialPid) { 4419 proc = p; 4420 break; 4421 } 4422 if (p.pkgList.containsKey(packageName)) { 4423 proc = p; 4424 } 4425 } 4426 } 4427 4428 if (proc == null) { 4429 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4430 + " initialPid=" + initialPid 4431 + " packageName=" + packageName); 4432 return; 4433 } 4434 4435 if (proc.thread != null) { 4436 if (proc.pid == Process.myPid()) { 4437 Log.w(TAG, "crashApplication: trying to crash self!"); 4438 return; 4439 } 4440 long ident = Binder.clearCallingIdentity(); 4441 try { 4442 proc.thread.scheduleCrash(message); 4443 } catch (RemoteException e) { 4444 } 4445 Binder.restoreCallingIdentity(ident); 4446 } 4447 } 4448 } 4449 4450 @Override 4451 public final void finishSubActivity(IBinder token, String resultWho, 4452 int requestCode) { 4453 synchronized(this) { 4454 final long origId = Binder.clearCallingIdentity(); 4455 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4456 if (r != null) { 4457 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4458 } 4459 Binder.restoreCallingIdentity(origId); 4460 } 4461 } 4462 4463 @Override 4464 public boolean finishActivityAffinity(IBinder token) { 4465 synchronized(this) { 4466 final long origId = Binder.clearCallingIdentity(); 4467 try { 4468 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4469 4470 ActivityRecord rootR = r.task.getRootActivity(); 4471 // Do not allow task to finish in Lock Task mode. 4472 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4473 if (rootR == r) { 4474 mStackSupervisor.showLockTaskToast(); 4475 return false; 4476 } 4477 } 4478 boolean res = false; 4479 if (r != null) { 4480 res = r.task.stack.finishActivityAffinityLocked(r); 4481 } 4482 return res; 4483 } finally { 4484 Binder.restoreCallingIdentity(origId); 4485 } 4486 } 4487 } 4488 4489 @Override 4490 public void finishVoiceTask(IVoiceInteractionSession session) { 4491 synchronized(this) { 4492 final long origId = Binder.clearCallingIdentity(); 4493 try { 4494 mStackSupervisor.finishVoiceTask(session); 4495 } finally { 4496 Binder.restoreCallingIdentity(origId); 4497 } 4498 } 4499 4500 } 4501 4502 @Override 4503 public boolean releaseActivityInstance(IBinder token) { 4504 synchronized(this) { 4505 final long origId = Binder.clearCallingIdentity(); 4506 try { 4507 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4508 if (r.task == null || r.task.stack == null) { 4509 return false; 4510 } 4511 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4512 } finally { 4513 Binder.restoreCallingIdentity(origId); 4514 } 4515 } 4516 } 4517 4518 @Override 4519 public void releaseSomeActivities(IApplicationThread appInt) { 4520 synchronized(this) { 4521 final long origId = Binder.clearCallingIdentity(); 4522 try { 4523 ProcessRecord app = getRecordForAppLocked(appInt); 4524 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4525 } finally { 4526 Binder.restoreCallingIdentity(origId); 4527 } 4528 } 4529 } 4530 4531 @Override 4532 public boolean willActivityBeVisible(IBinder token) { 4533 synchronized(this) { 4534 ActivityStack stack = ActivityRecord.getStackLocked(token); 4535 if (stack != null) { 4536 return stack.willActivityBeVisibleLocked(token); 4537 } 4538 return false; 4539 } 4540 } 4541 4542 @Override 4543 public void overridePendingTransition(IBinder token, String packageName, 4544 int enterAnim, int exitAnim) { 4545 synchronized(this) { 4546 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4547 if (self == null) { 4548 return; 4549 } 4550 4551 final long origId = Binder.clearCallingIdentity(); 4552 4553 if (self.state == ActivityState.RESUMED 4554 || self.state == ActivityState.PAUSING) { 4555 mWindowManager.overridePendingAppTransition(packageName, 4556 enterAnim, exitAnim, null); 4557 } 4558 4559 Binder.restoreCallingIdentity(origId); 4560 } 4561 } 4562 4563 /** 4564 * Main function for removing an existing process from the activity manager 4565 * as a result of that process going away. Clears out all connections 4566 * to the process. 4567 */ 4568 private final void handleAppDiedLocked(ProcessRecord app, 4569 boolean restarting, boolean allowRestart) { 4570 int pid = app.pid; 4571 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4572 if (!kept && !restarting) { 4573 removeLruProcessLocked(app); 4574 if (pid > 0) { 4575 ProcessList.remove(pid); 4576 } 4577 } 4578 4579 if (mProfileProc == app) { 4580 clearProfilerLocked(); 4581 } 4582 4583 // Remove this application's activities from active lists. 4584 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4585 4586 app.activities.clear(); 4587 4588 if (app.instrumentationClass != null) { 4589 Slog.w(TAG, "Crash of app " + app.processName 4590 + " running instrumentation " + app.instrumentationClass); 4591 Bundle info = new Bundle(); 4592 info.putString("shortMsg", "Process crashed."); 4593 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4594 } 4595 4596 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) { 4597 // If there was nothing to resume, and we are not already 4598 // restarting this process, but there is a visible activity that 4599 // is hosted by the process... then make sure all visible 4600 // activities are running, taking care of restarting this 4601 // process. 4602 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4603 } 4604 } 4605 4606 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4607 IBinder threadBinder = thread.asBinder(); 4608 // Find the application record. 4609 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4610 ProcessRecord rec = mLruProcesses.get(i); 4611 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4612 return i; 4613 } 4614 } 4615 return -1; 4616 } 4617 4618 final ProcessRecord getRecordForAppLocked( 4619 IApplicationThread thread) { 4620 if (thread == null) { 4621 return null; 4622 } 4623 4624 int appIndex = getLRURecordIndexForAppLocked(thread); 4625 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4626 } 4627 4628 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4629 // If there are no longer any background processes running, 4630 // and the app that died was not running instrumentation, 4631 // then tell everyone we are now low on memory. 4632 boolean haveBg = false; 4633 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4634 ProcessRecord rec = mLruProcesses.get(i); 4635 if (rec.thread != null 4636 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4637 haveBg = true; 4638 break; 4639 } 4640 } 4641 4642 if (!haveBg) { 4643 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4644 if (doReport) { 4645 long now = SystemClock.uptimeMillis(); 4646 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4647 doReport = false; 4648 } else { 4649 mLastMemUsageReportTime = now; 4650 } 4651 } 4652 final ArrayList<ProcessMemInfo> memInfos 4653 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4654 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4655 long now = SystemClock.uptimeMillis(); 4656 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4657 ProcessRecord rec = mLruProcesses.get(i); 4658 if (rec == dyingProc || rec.thread == null) { 4659 continue; 4660 } 4661 if (doReport) { 4662 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4663 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4664 } 4665 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4666 // The low memory report is overriding any current 4667 // state for a GC request. Make sure to do 4668 // heavy/important/visible/foreground processes first. 4669 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4670 rec.lastRequestedGc = 0; 4671 } else { 4672 rec.lastRequestedGc = rec.lastLowMemory; 4673 } 4674 rec.reportLowMemory = true; 4675 rec.lastLowMemory = now; 4676 mProcessesToGc.remove(rec); 4677 addProcessToGcListLocked(rec); 4678 } 4679 } 4680 if (doReport) { 4681 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4682 mHandler.sendMessage(msg); 4683 } 4684 scheduleAppGcsLocked(); 4685 } 4686 } 4687 4688 final void appDiedLocked(ProcessRecord app) { 4689 appDiedLocked(app, app.pid, app.thread, false); 4690 } 4691 4692 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, 4693 boolean fromBinderDied) { 4694 // First check if this ProcessRecord is actually active for the pid. 4695 synchronized (mPidsSelfLocked) { 4696 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4697 if (curProc != app) { 4698 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4699 return; 4700 } 4701 } 4702 4703 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4704 synchronized (stats) { 4705 stats.noteProcessDiedLocked(app.info.uid, pid); 4706 } 4707 4708 if (!app.killed) { 4709 if (!fromBinderDied) { 4710 Process.killProcessQuiet(pid); 4711 } 4712 Process.killProcessGroup(app.info.uid, pid); 4713 app.killed = true; 4714 } 4715 4716 // Clean up already done if the process has been re-started. 4717 if (app.pid == pid && app.thread != null && 4718 app.thread.asBinder() == thread.asBinder()) { 4719 boolean doLowMem = app.instrumentationClass == null; 4720 boolean doOomAdj = doLowMem; 4721 if (!app.killedByAm) { 4722 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4723 + ") has died"); 4724 mAllowLowerMemLevel = true; 4725 } else { 4726 // Note that we always want to do oom adj to update our state with the 4727 // new number of procs. 4728 mAllowLowerMemLevel = false; 4729 doLowMem = false; 4730 } 4731 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4732 if (DEBUG_CLEANUP) Slog.v( 4733 TAG, "Dying app: " + app + ", pid: " + pid 4734 + ", thread: " + thread.asBinder()); 4735 handleAppDiedLocked(app, false, true); 4736 4737 if (doOomAdj) { 4738 updateOomAdjLocked(); 4739 } 4740 if (doLowMem) { 4741 doLowMemReportIfNeededLocked(app); 4742 } 4743 } else if (app.pid != pid) { 4744 // A new process has already been started. 4745 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4746 + ") has died and restarted (pid " + app.pid + ")."); 4747 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4748 } else if (DEBUG_PROCESSES) { 4749 Slog.d(TAG, "Received spurious death notification for thread " 4750 + thread.asBinder()); 4751 } 4752 } 4753 4754 /** 4755 * If a stack trace dump file is configured, dump process stack traces. 4756 * @param clearTraces causes the dump file to be erased prior to the new 4757 * traces being written, if true; when false, the new traces will be 4758 * appended to any existing file content. 4759 * @param firstPids of dalvik VM processes to dump stack traces for first 4760 * @param lastPids of dalvik VM processes to dump stack traces for last 4761 * @param nativeProcs optional list of native process names to dump stack crawls 4762 * @return file containing stack traces, or null if no dump file is configured 4763 */ 4764 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4765 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4766 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4767 if (tracesPath == null || tracesPath.length() == 0) { 4768 return null; 4769 } 4770 4771 File tracesFile = new File(tracesPath); 4772 try { 4773 File tracesDir = tracesFile.getParentFile(); 4774 if (!tracesDir.exists()) { 4775 tracesDir.mkdirs(); 4776 if (!SELinux.restorecon(tracesDir)) { 4777 return null; 4778 } 4779 } 4780 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4781 4782 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4783 tracesFile.createNewFile(); 4784 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4785 } catch (IOException e) { 4786 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4787 return null; 4788 } 4789 4790 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4791 return tracesFile; 4792 } 4793 4794 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4795 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4796 // Use a FileObserver to detect when traces finish writing. 4797 // The order of traces is considered important to maintain for legibility. 4798 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4799 @Override 4800 public synchronized void onEvent(int event, String path) { notify(); } 4801 }; 4802 4803 try { 4804 observer.startWatching(); 4805 4806 // First collect all of the stacks of the most important pids. 4807 if (firstPids != null) { 4808 try { 4809 int num = firstPids.size(); 4810 for (int i = 0; i < num; i++) { 4811 synchronized (observer) { 4812 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4813 observer.wait(200); // Wait for write-close, give up after 200msec 4814 } 4815 } 4816 } catch (InterruptedException e) { 4817 Slog.wtf(TAG, e); 4818 } 4819 } 4820 4821 // Next collect the stacks of the native pids 4822 if (nativeProcs != null) { 4823 int[] pids = Process.getPidsForCommands(nativeProcs); 4824 if (pids != null) { 4825 for (int pid : pids) { 4826 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4827 } 4828 } 4829 } 4830 4831 // Lastly, measure CPU usage. 4832 if (processCpuTracker != null) { 4833 processCpuTracker.init(); 4834 System.gc(); 4835 processCpuTracker.update(); 4836 try { 4837 synchronized (processCpuTracker) { 4838 processCpuTracker.wait(500); // measure over 1/2 second. 4839 } 4840 } catch (InterruptedException e) { 4841 } 4842 processCpuTracker.update(); 4843 4844 // We'll take the stack crawls of just the top apps using CPU. 4845 final int N = processCpuTracker.countWorkingStats(); 4846 int numProcs = 0; 4847 for (int i=0; i<N && numProcs<5; i++) { 4848 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4849 if (lastPids.indexOfKey(stats.pid) >= 0) { 4850 numProcs++; 4851 try { 4852 synchronized (observer) { 4853 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4854 observer.wait(200); // Wait for write-close, give up after 200msec 4855 } 4856 } catch (InterruptedException e) { 4857 Slog.wtf(TAG, e); 4858 } 4859 4860 } 4861 } 4862 } 4863 } finally { 4864 observer.stopWatching(); 4865 } 4866 } 4867 4868 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4869 if (true || IS_USER_BUILD) { 4870 return; 4871 } 4872 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4873 if (tracesPath == null || tracesPath.length() == 0) { 4874 return; 4875 } 4876 4877 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4878 StrictMode.allowThreadDiskWrites(); 4879 try { 4880 final File tracesFile = new File(tracesPath); 4881 final File tracesDir = tracesFile.getParentFile(); 4882 final File tracesTmp = new File(tracesDir, "__tmp__"); 4883 try { 4884 if (!tracesDir.exists()) { 4885 tracesDir.mkdirs(); 4886 if (!SELinux.restorecon(tracesDir.getPath())) { 4887 return; 4888 } 4889 } 4890 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4891 4892 if (tracesFile.exists()) { 4893 tracesTmp.delete(); 4894 tracesFile.renameTo(tracesTmp); 4895 } 4896 StringBuilder sb = new StringBuilder(); 4897 Time tobj = new Time(); 4898 tobj.set(System.currentTimeMillis()); 4899 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4900 sb.append(": "); 4901 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4902 sb.append(" since "); 4903 sb.append(msg); 4904 FileOutputStream fos = new FileOutputStream(tracesFile); 4905 fos.write(sb.toString().getBytes()); 4906 if (app == null) { 4907 fos.write("\n*** No application process!".getBytes()); 4908 } 4909 fos.close(); 4910 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4911 } catch (IOException e) { 4912 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4913 return; 4914 } 4915 4916 if (app != null) { 4917 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4918 firstPids.add(app.pid); 4919 dumpStackTraces(tracesPath, firstPids, null, null, null); 4920 } 4921 4922 File lastTracesFile = null; 4923 File curTracesFile = null; 4924 for (int i=9; i>=0; i--) { 4925 String name = String.format(Locale.US, "slow%02d.txt", i); 4926 curTracesFile = new File(tracesDir, name); 4927 if (curTracesFile.exists()) { 4928 if (lastTracesFile != null) { 4929 curTracesFile.renameTo(lastTracesFile); 4930 } else { 4931 curTracesFile.delete(); 4932 } 4933 } 4934 lastTracesFile = curTracesFile; 4935 } 4936 tracesFile.renameTo(curTracesFile); 4937 if (tracesTmp.exists()) { 4938 tracesTmp.renameTo(tracesFile); 4939 } 4940 } finally { 4941 StrictMode.setThreadPolicy(oldPolicy); 4942 } 4943 } 4944 4945 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4946 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4947 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4948 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4949 4950 if (mController != null) { 4951 try { 4952 // 0 == continue, -1 = kill process immediately 4953 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4954 if (res < 0 && app.pid != MY_PID) { 4955 app.kill("anr", true); 4956 } 4957 } catch (RemoteException e) { 4958 mController = null; 4959 Watchdog.getInstance().setActivityController(null); 4960 } 4961 } 4962 4963 long anrTime = SystemClock.uptimeMillis(); 4964 if (MONITOR_CPU_USAGE) { 4965 updateCpuStatsNow(); 4966 } 4967 4968 synchronized (this) { 4969 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4970 if (mShuttingDown) { 4971 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4972 return; 4973 } else if (app.notResponding) { 4974 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4975 return; 4976 } else if (app.crashing) { 4977 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4978 return; 4979 } 4980 4981 // In case we come through here for the same app before completing 4982 // this one, mark as anring now so we will bail out. 4983 app.notResponding = true; 4984 4985 // Log the ANR to the event log. 4986 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4987 app.processName, app.info.flags, annotation); 4988 4989 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4990 firstPids.add(app.pid); 4991 4992 int parentPid = app.pid; 4993 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4994 if (parentPid != app.pid) firstPids.add(parentPid); 4995 4996 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4997 4998 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4999 ProcessRecord r = mLruProcesses.get(i); 5000 if (r != null && r.thread != null) { 5001 int pid = r.pid; 5002 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5003 if (r.persistent) { 5004 firstPids.add(pid); 5005 } else { 5006 lastPids.put(pid, Boolean.TRUE); 5007 } 5008 } 5009 } 5010 } 5011 } 5012 5013 // Log the ANR to the main log. 5014 StringBuilder info = new StringBuilder(); 5015 info.setLength(0); 5016 info.append("ANR in ").append(app.processName); 5017 if (activity != null && activity.shortComponentName != null) { 5018 info.append(" (").append(activity.shortComponentName).append(")"); 5019 } 5020 info.append("\n"); 5021 info.append("PID: ").append(app.pid).append("\n"); 5022 if (annotation != null) { 5023 info.append("Reason: ").append(annotation).append("\n"); 5024 } 5025 if (parent != null && parent != activity) { 5026 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5027 } 5028 5029 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5030 5031 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5032 NATIVE_STACKS_OF_INTEREST); 5033 5034 String cpuInfo = null; 5035 if (MONITOR_CPU_USAGE) { 5036 updateCpuStatsNow(); 5037 synchronized (mProcessCpuTracker) { 5038 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5039 } 5040 info.append(processCpuTracker.printCurrentLoad()); 5041 info.append(cpuInfo); 5042 } 5043 5044 info.append(processCpuTracker.printCurrentState(anrTime)); 5045 5046 Slog.e(TAG, info.toString()); 5047 if (tracesFile == null) { 5048 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5049 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5050 } 5051 5052 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5053 cpuInfo, tracesFile, null); 5054 5055 if (mController != null) { 5056 try { 5057 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5058 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5059 if (res != 0) { 5060 if (res < 0 && app.pid != MY_PID) { 5061 app.kill("anr", true); 5062 } else { 5063 synchronized (this) { 5064 mServices.scheduleServiceTimeoutLocked(app); 5065 } 5066 } 5067 return; 5068 } 5069 } catch (RemoteException e) { 5070 mController = null; 5071 Watchdog.getInstance().setActivityController(null); 5072 } 5073 } 5074 5075 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5076 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5077 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5078 5079 synchronized (this) { 5080 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5081 5082 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5083 app.kill("bg anr", true); 5084 return; 5085 } 5086 5087 // Set the app's notResponding state, and look up the errorReportReceiver 5088 makeAppNotRespondingLocked(app, 5089 activity != null ? activity.shortComponentName : null, 5090 annotation != null ? "ANR " + annotation : "ANR", 5091 info.toString()); 5092 5093 // Bring up the infamous App Not Responding dialog 5094 Message msg = Message.obtain(); 5095 HashMap<String, Object> map = new HashMap<String, Object>(); 5096 msg.what = SHOW_NOT_RESPONDING_MSG; 5097 msg.obj = map; 5098 msg.arg1 = aboveSystem ? 1 : 0; 5099 map.put("app", app); 5100 if (activity != null) { 5101 map.put("activity", activity); 5102 } 5103 5104 mHandler.sendMessage(msg); 5105 } 5106 } 5107 5108 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5109 if (!mLaunchWarningShown) { 5110 mLaunchWarningShown = true; 5111 mHandler.post(new Runnable() { 5112 @Override 5113 public void run() { 5114 synchronized (ActivityManagerService.this) { 5115 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5116 d.show(); 5117 mHandler.postDelayed(new Runnable() { 5118 @Override 5119 public void run() { 5120 synchronized (ActivityManagerService.this) { 5121 d.dismiss(); 5122 mLaunchWarningShown = false; 5123 } 5124 } 5125 }, 4000); 5126 } 5127 } 5128 }); 5129 } 5130 } 5131 5132 @Override 5133 public boolean clearApplicationUserData(final String packageName, 5134 final IPackageDataObserver observer, int userId) { 5135 enforceNotIsolatedCaller("clearApplicationUserData"); 5136 int uid = Binder.getCallingUid(); 5137 int pid = Binder.getCallingPid(); 5138 userId = handleIncomingUser(pid, uid, 5139 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5140 long callingId = Binder.clearCallingIdentity(); 5141 try { 5142 IPackageManager pm = AppGlobals.getPackageManager(); 5143 int pkgUid = -1; 5144 synchronized(this) { 5145 try { 5146 pkgUid = pm.getPackageUid(packageName, userId); 5147 } catch (RemoteException e) { 5148 } 5149 if (pkgUid == -1) { 5150 Slog.w(TAG, "Invalid packageName: " + packageName); 5151 if (observer != null) { 5152 try { 5153 observer.onRemoveCompleted(packageName, false); 5154 } catch (RemoteException e) { 5155 Slog.i(TAG, "Observer no longer exists."); 5156 } 5157 } 5158 return false; 5159 } 5160 if (uid == pkgUid || checkComponentPermission( 5161 android.Manifest.permission.CLEAR_APP_USER_DATA, 5162 pid, uid, -1, true) 5163 == PackageManager.PERMISSION_GRANTED) { 5164 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5165 } else { 5166 throw new SecurityException("PID " + pid + " does not have permission " 5167 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5168 + " of package " + packageName); 5169 } 5170 5171 // Remove all tasks match the cleared application package and user 5172 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5173 final TaskRecord tr = mRecentTasks.get(i); 5174 final String taskPackageName = 5175 tr.getBaseIntent().getComponent().getPackageName(); 5176 if (tr.userId != userId) continue; 5177 if (!taskPackageName.equals(packageName)) continue; 5178 removeTaskByIdLocked(tr.taskId, false); 5179 } 5180 } 5181 5182 try { 5183 // Clear application user data 5184 pm.clearApplicationUserData(packageName, observer, userId); 5185 5186 synchronized(this) { 5187 // Remove all permissions granted from/to this package 5188 removeUriPermissionsForPackageLocked(packageName, userId, true); 5189 } 5190 5191 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5192 Uri.fromParts("package", packageName, null)); 5193 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5194 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5195 null, null, 0, null, null, null, false, false, userId); 5196 } catch (RemoteException e) { 5197 } 5198 } finally { 5199 Binder.restoreCallingIdentity(callingId); 5200 } 5201 return true; 5202 } 5203 5204 @Override 5205 public void killBackgroundProcesses(final String packageName, int userId) { 5206 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5207 != PackageManager.PERMISSION_GRANTED && 5208 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5209 != PackageManager.PERMISSION_GRANTED) { 5210 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5211 + Binder.getCallingPid() 5212 + ", uid=" + Binder.getCallingUid() 5213 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5214 Slog.w(TAG, msg); 5215 throw new SecurityException(msg); 5216 } 5217 5218 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5219 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5220 long callingId = Binder.clearCallingIdentity(); 5221 try { 5222 IPackageManager pm = AppGlobals.getPackageManager(); 5223 synchronized(this) { 5224 int appId = -1; 5225 try { 5226 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5227 } catch (RemoteException e) { 5228 } 5229 if (appId == -1) { 5230 Slog.w(TAG, "Invalid packageName: " + packageName); 5231 return; 5232 } 5233 killPackageProcessesLocked(packageName, appId, userId, 5234 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5235 } 5236 } finally { 5237 Binder.restoreCallingIdentity(callingId); 5238 } 5239 } 5240 5241 @Override 5242 public void killAllBackgroundProcesses() { 5243 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5244 != PackageManager.PERMISSION_GRANTED) { 5245 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5246 + Binder.getCallingPid() 5247 + ", uid=" + Binder.getCallingUid() 5248 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5249 Slog.w(TAG, msg); 5250 throw new SecurityException(msg); 5251 } 5252 5253 long callingId = Binder.clearCallingIdentity(); 5254 try { 5255 synchronized(this) { 5256 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5257 final int NP = mProcessNames.getMap().size(); 5258 for (int ip=0; ip<NP; ip++) { 5259 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5260 final int NA = apps.size(); 5261 for (int ia=0; ia<NA; ia++) { 5262 ProcessRecord app = apps.valueAt(ia); 5263 if (app.persistent) { 5264 // we don't kill persistent processes 5265 continue; 5266 } 5267 if (app.removed) { 5268 procs.add(app); 5269 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5270 app.removed = true; 5271 procs.add(app); 5272 } 5273 } 5274 } 5275 5276 int N = procs.size(); 5277 for (int i=0; i<N; i++) { 5278 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5279 } 5280 mAllowLowerMemLevel = true; 5281 updateOomAdjLocked(); 5282 doLowMemReportIfNeededLocked(null); 5283 } 5284 } finally { 5285 Binder.restoreCallingIdentity(callingId); 5286 } 5287 } 5288 5289 @Override 5290 public void forceStopPackage(final String packageName, int userId) { 5291 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5292 != PackageManager.PERMISSION_GRANTED) { 5293 String msg = "Permission Denial: forceStopPackage() from pid=" 5294 + Binder.getCallingPid() 5295 + ", uid=" + Binder.getCallingUid() 5296 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5297 Slog.w(TAG, msg); 5298 throw new SecurityException(msg); 5299 } 5300 final int callingPid = Binder.getCallingPid(); 5301 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5302 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5303 long callingId = Binder.clearCallingIdentity(); 5304 try { 5305 IPackageManager pm = AppGlobals.getPackageManager(); 5306 synchronized(this) { 5307 int[] users = userId == UserHandle.USER_ALL 5308 ? getUsersLocked() : new int[] { userId }; 5309 for (int user : users) { 5310 int pkgUid = -1; 5311 try { 5312 pkgUid = pm.getPackageUid(packageName, user); 5313 } catch (RemoteException e) { 5314 } 5315 if (pkgUid == -1) { 5316 Slog.w(TAG, "Invalid packageName: " + packageName); 5317 continue; 5318 } 5319 try { 5320 pm.setPackageStoppedState(packageName, true, user); 5321 } catch (RemoteException e) { 5322 } catch (IllegalArgumentException e) { 5323 Slog.w(TAG, "Failed trying to unstop package " 5324 + packageName + ": " + e); 5325 } 5326 if (isUserRunningLocked(user, false)) { 5327 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5328 } 5329 } 5330 } 5331 } finally { 5332 Binder.restoreCallingIdentity(callingId); 5333 } 5334 } 5335 5336 @Override 5337 public void addPackageDependency(String packageName) { 5338 synchronized (this) { 5339 int callingPid = Binder.getCallingPid(); 5340 if (callingPid == Process.myPid()) { 5341 // Yeah, um, no. 5342 return; 5343 } 5344 ProcessRecord proc; 5345 synchronized (mPidsSelfLocked) { 5346 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5347 } 5348 if (proc != null) { 5349 if (proc.pkgDeps == null) { 5350 proc.pkgDeps = new ArraySet<String>(1); 5351 } 5352 proc.pkgDeps.add(packageName); 5353 } 5354 } 5355 } 5356 5357 /* 5358 * The pkg name and app id have to be specified. 5359 */ 5360 @Override 5361 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5362 if (pkg == null) { 5363 return; 5364 } 5365 // Make sure the uid is valid. 5366 if (appid < 0) { 5367 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5368 return; 5369 } 5370 int callerUid = Binder.getCallingUid(); 5371 // Only the system server can kill an application 5372 if (callerUid == Process.SYSTEM_UID) { 5373 // Post an aysnc message to kill the application 5374 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5375 msg.arg1 = appid; 5376 msg.arg2 = 0; 5377 Bundle bundle = new Bundle(); 5378 bundle.putString("pkg", pkg); 5379 bundle.putString("reason", reason); 5380 msg.obj = bundle; 5381 mHandler.sendMessage(msg); 5382 } else { 5383 throw new SecurityException(callerUid + " cannot kill pkg: " + 5384 pkg); 5385 } 5386 } 5387 5388 @Override 5389 public void closeSystemDialogs(String reason) { 5390 enforceNotIsolatedCaller("closeSystemDialogs"); 5391 5392 final int pid = Binder.getCallingPid(); 5393 final int uid = Binder.getCallingUid(); 5394 final long origId = Binder.clearCallingIdentity(); 5395 try { 5396 synchronized (this) { 5397 // Only allow this from foreground processes, so that background 5398 // applications can't abuse it to prevent system UI from being shown. 5399 if (uid >= Process.FIRST_APPLICATION_UID) { 5400 ProcessRecord proc; 5401 synchronized (mPidsSelfLocked) { 5402 proc = mPidsSelfLocked.get(pid); 5403 } 5404 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5405 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5406 + " from background process " + proc); 5407 return; 5408 } 5409 } 5410 closeSystemDialogsLocked(reason); 5411 } 5412 } finally { 5413 Binder.restoreCallingIdentity(origId); 5414 } 5415 } 5416 5417 void closeSystemDialogsLocked(String reason) { 5418 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5419 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5420 | Intent.FLAG_RECEIVER_FOREGROUND); 5421 if (reason != null) { 5422 intent.putExtra("reason", reason); 5423 } 5424 mWindowManager.closeSystemDialogs(reason); 5425 5426 mStackSupervisor.closeSystemDialogsLocked(); 5427 5428 broadcastIntentLocked(null, null, intent, null, 5429 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5430 Process.SYSTEM_UID, UserHandle.USER_ALL); 5431 } 5432 5433 @Override 5434 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5435 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5436 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5437 for (int i=pids.length-1; i>=0; i--) { 5438 ProcessRecord proc; 5439 int oomAdj; 5440 synchronized (this) { 5441 synchronized (mPidsSelfLocked) { 5442 proc = mPidsSelfLocked.get(pids[i]); 5443 oomAdj = proc != null ? proc.setAdj : 0; 5444 } 5445 } 5446 infos[i] = new Debug.MemoryInfo(); 5447 Debug.getMemoryInfo(pids[i], infos[i]); 5448 if (proc != null) { 5449 synchronized (this) { 5450 if (proc.thread != null && proc.setAdj == oomAdj) { 5451 // Record this for posterity if the process has been stable. 5452 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5453 infos[i].getTotalUss(), false, proc.pkgList); 5454 } 5455 } 5456 } 5457 } 5458 return infos; 5459 } 5460 5461 @Override 5462 public long[] getProcessPss(int[] pids) { 5463 enforceNotIsolatedCaller("getProcessPss"); 5464 long[] pss = new long[pids.length]; 5465 for (int i=pids.length-1; i>=0; i--) { 5466 ProcessRecord proc; 5467 int oomAdj; 5468 synchronized (this) { 5469 synchronized (mPidsSelfLocked) { 5470 proc = mPidsSelfLocked.get(pids[i]); 5471 oomAdj = proc != null ? proc.setAdj : 0; 5472 } 5473 } 5474 long[] tmpUss = new long[1]; 5475 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5476 if (proc != null) { 5477 synchronized (this) { 5478 if (proc.thread != null && proc.setAdj == oomAdj) { 5479 // Record this for posterity if the process has been stable. 5480 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5481 } 5482 } 5483 } 5484 } 5485 return pss; 5486 } 5487 5488 @Override 5489 public void killApplicationProcess(String processName, int uid) { 5490 if (processName == null) { 5491 return; 5492 } 5493 5494 int callerUid = Binder.getCallingUid(); 5495 // Only the system server can kill an application 5496 if (callerUid == Process.SYSTEM_UID) { 5497 synchronized (this) { 5498 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5499 if (app != null && app.thread != null) { 5500 try { 5501 app.thread.scheduleSuicide(); 5502 } catch (RemoteException e) { 5503 // If the other end already died, then our work here is done. 5504 } 5505 } else { 5506 Slog.w(TAG, "Process/uid not found attempting kill of " 5507 + processName + " / " + uid); 5508 } 5509 } 5510 } else { 5511 throw new SecurityException(callerUid + " cannot kill app process: " + 5512 processName); 5513 } 5514 } 5515 5516 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5517 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5518 false, true, false, false, UserHandle.getUserId(uid), reason); 5519 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5520 Uri.fromParts("package", packageName, null)); 5521 if (!mProcessesReady) { 5522 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5523 | Intent.FLAG_RECEIVER_FOREGROUND); 5524 } 5525 intent.putExtra(Intent.EXTRA_UID, uid); 5526 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5527 broadcastIntentLocked(null, null, intent, 5528 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5529 false, false, 5530 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5531 } 5532 5533 private void forceStopUserLocked(int userId, String reason) { 5534 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5535 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5536 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5537 | Intent.FLAG_RECEIVER_FOREGROUND); 5538 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5539 broadcastIntentLocked(null, null, intent, 5540 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5541 false, false, 5542 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5543 } 5544 5545 private final boolean killPackageProcessesLocked(String packageName, int appId, 5546 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5547 boolean doit, boolean evenPersistent, String reason) { 5548 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5549 5550 // Remove all processes this package may have touched: all with the 5551 // same UID (except for the system or root user), and all whose name 5552 // matches the package name. 5553 final int NP = mProcessNames.getMap().size(); 5554 for (int ip=0; ip<NP; ip++) { 5555 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5556 final int NA = apps.size(); 5557 for (int ia=0; ia<NA; ia++) { 5558 ProcessRecord app = apps.valueAt(ia); 5559 if (app.persistent && !evenPersistent) { 5560 // we don't kill persistent processes 5561 continue; 5562 } 5563 if (app.removed) { 5564 if (doit) { 5565 procs.add(app); 5566 } 5567 continue; 5568 } 5569 5570 // Skip process if it doesn't meet our oom adj requirement. 5571 if (app.setAdj < minOomAdj) { 5572 continue; 5573 } 5574 5575 // If no package is specified, we call all processes under the 5576 // give user id. 5577 if (packageName == null) { 5578 if (app.userId != userId) { 5579 continue; 5580 } 5581 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5582 continue; 5583 } 5584 // Package has been specified, we want to hit all processes 5585 // that match it. We need to qualify this by the processes 5586 // that are running under the specified app and user ID. 5587 } else { 5588 final boolean isDep = app.pkgDeps != null 5589 && app.pkgDeps.contains(packageName); 5590 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5591 continue; 5592 } 5593 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5594 continue; 5595 } 5596 if (!app.pkgList.containsKey(packageName) && !isDep) { 5597 continue; 5598 } 5599 } 5600 5601 // Process has passed all conditions, kill it! 5602 if (!doit) { 5603 return true; 5604 } 5605 app.removed = true; 5606 procs.add(app); 5607 } 5608 } 5609 5610 int N = procs.size(); 5611 for (int i=0; i<N; i++) { 5612 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5613 } 5614 updateOomAdjLocked(); 5615 return N > 0; 5616 } 5617 5618 private final boolean forceStopPackageLocked(String name, int appId, 5619 boolean callerWillRestart, boolean purgeCache, boolean doit, 5620 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5621 int i; 5622 int N; 5623 5624 if (userId == UserHandle.USER_ALL && name == null) { 5625 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5626 } 5627 5628 if (appId < 0 && name != null) { 5629 try { 5630 appId = UserHandle.getAppId( 5631 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5632 } catch (RemoteException e) { 5633 } 5634 } 5635 5636 if (doit) { 5637 if (name != null) { 5638 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5639 + " user=" + userId + ": " + reason); 5640 } else { 5641 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5642 } 5643 5644 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5645 for (int ip=pmap.size()-1; ip>=0; ip--) { 5646 SparseArray<Long> ba = pmap.valueAt(ip); 5647 for (i=ba.size()-1; i>=0; i--) { 5648 boolean remove = false; 5649 final int entUid = ba.keyAt(i); 5650 if (name != null) { 5651 if (userId == UserHandle.USER_ALL) { 5652 if (UserHandle.getAppId(entUid) == appId) { 5653 remove = true; 5654 } 5655 } else { 5656 if (entUid == UserHandle.getUid(userId, appId)) { 5657 remove = true; 5658 } 5659 } 5660 } else if (UserHandle.getUserId(entUid) == userId) { 5661 remove = true; 5662 } 5663 if (remove) { 5664 ba.removeAt(i); 5665 } 5666 } 5667 if (ba.size() == 0) { 5668 pmap.removeAt(ip); 5669 } 5670 } 5671 } 5672 5673 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5674 -100, callerWillRestart, true, doit, evenPersistent, 5675 name == null ? ("stop user " + userId) : ("stop " + name)); 5676 5677 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5678 if (!doit) { 5679 return true; 5680 } 5681 didSomething = true; 5682 } 5683 5684 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5685 if (!doit) { 5686 return true; 5687 } 5688 didSomething = true; 5689 } 5690 5691 if (name == null) { 5692 // Remove all sticky broadcasts from this user. 5693 mStickyBroadcasts.remove(userId); 5694 } 5695 5696 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5697 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5698 userId, providers)) { 5699 if (!doit) { 5700 return true; 5701 } 5702 didSomething = true; 5703 } 5704 N = providers.size(); 5705 for (i=0; i<N; i++) { 5706 removeDyingProviderLocked(null, providers.get(i), true); 5707 } 5708 5709 // Remove transient permissions granted from/to this package/user 5710 removeUriPermissionsForPackageLocked(name, userId, false); 5711 5712 if (name == null || uninstalling) { 5713 // Remove pending intents. For now we only do this when force 5714 // stopping users, because we have some problems when doing this 5715 // for packages -- app widgets are not currently cleaned up for 5716 // such packages, so they can be left with bad pending intents. 5717 if (mIntentSenderRecords.size() > 0) { 5718 Iterator<WeakReference<PendingIntentRecord>> it 5719 = mIntentSenderRecords.values().iterator(); 5720 while (it.hasNext()) { 5721 WeakReference<PendingIntentRecord> wpir = it.next(); 5722 if (wpir == null) { 5723 it.remove(); 5724 continue; 5725 } 5726 PendingIntentRecord pir = wpir.get(); 5727 if (pir == null) { 5728 it.remove(); 5729 continue; 5730 } 5731 if (name == null) { 5732 // Stopping user, remove all objects for the user. 5733 if (pir.key.userId != userId) { 5734 // Not the same user, skip it. 5735 continue; 5736 } 5737 } else { 5738 if (UserHandle.getAppId(pir.uid) != appId) { 5739 // Different app id, skip it. 5740 continue; 5741 } 5742 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5743 // Different user, skip it. 5744 continue; 5745 } 5746 if (!pir.key.packageName.equals(name)) { 5747 // Different package, skip it. 5748 continue; 5749 } 5750 } 5751 if (!doit) { 5752 return true; 5753 } 5754 didSomething = true; 5755 it.remove(); 5756 pir.canceled = true; 5757 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5758 pir.key.activity.pendingResults.remove(pir.ref); 5759 } 5760 } 5761 } 5762 } 5763 5764 if (doit) { 5765 if (purgeCache && name != null) { 5766 AttributeCache ac = AttributeCache.instance(); 5767 if (ac != null) { 5768 ac.removePackage(name); 5769 } 5770 } 5771 if (mBooted) { 5772 mStackSupervisor.resumeTopActivitiesLocked(); 5773 mStackSupervisor.scheduleIdleLocked(); 5774 } 5775 } 5776 5777 return didSomething; 5778 } 5779 5780 private final boolean removeProcessLocked(ProcessRecord app, 5781 boolean callerWillRestart, boolean allowRestart, String reason) { 5782 final String name = app.processName; 5783 final int uid = app.uid; 5784 if (DEBUG_PROCESSES) Slog.d( 5785 TAG, "Force removing proc " + app.toShortString() + " (" + name 5786 + "/" + uid + ")"); 5787 5788 mProcessNames.remove(name, uid); 5789 mIsolatedProcesses.remove(app.uid); 5790 if (mHeavyWeightProcess == app) { 5791 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5792 mHeavyWeightProcess.userId, 0)); 5793 mHeavyWeightProcess = null; 5794 } 5795 boolean needRestart = false; 5796 if (app.pid > 0 && app.pid != MY_PID) { 5797 int pid = app.pid; 5798 synchronized (mPidsSelfLocked) { 5799 mPidsSelfLocked.remove(pid); 5800 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5801 } 5802 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5803 if (app.isolated) { 5804 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5805 } 5806 app.kill(reason, true); 5807 handleAppDiedLocked(app, true, allowRestart); 5808 removeLruProcessLocked(app); 5809 5810 if (app.persistent && !app.isolated) { 5811 if (!callerWillRestart) { 5812 addAppLocked(app.info, false, null /* ABI override */); 5813 } else { 5814 needRestart = true; 5815 } 5816 } 5817 } else { 5818 mRemovedProcesses.add(app); 5819 } 5820 5821 return needRestart; 5822 } 5823 5824 private final void processStartTimedOutLocked(ProcessRecord app) { 5825 final int pid = app.pid; 5826 boolean gone = false; 5827 synchronized (mPidsSelfLocked) { 5828 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5829 if (knownApp != null && knownApp.thread == null) { 5830 mPidsSelfLocked.remove(pid); 5831 gone = true; 5832 } 5833 } 5834 5835 if (gone) { 5836 Slog.w(TAG, "Process " + app + " failed to attach"); 5837 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5838 pid, app.uid, app.processName); 5839 mProcessNames.remove(app.processName, app.uid); 5840 mIsolatedProcesses.remove(app.uid); 5841 if (mHeavyWeightProcess == app) { 5842 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5843 mHeavyWeightProcess.userId, 0)); 5844 mHeavyWeightProcess = null; 5845 } 5846 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5847 if (app.isolated) { 5848 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5849 } 5850 // Take care of any launching providers waiting for this process. 5851 checkAppInLaunchingProvidersLocked(app, true); 5852 // Take care of any services that are waiting for the process. 5853 mServices.processStartTimedOutLocked(app); 5854 app.kill("start timeout", true); 5855 removeLruProcessLocked(app); 5856 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5857 Slog.w(TAG, "Unattached app died before backup, skipping"); 5858 try { 5859 IBackupManager bm = IBackupManager.Stub.asInterface( 5860 ServiceManager.getService(Context.BACKUP_SERVICE)); 5861 bm.agentDisconnected(app.info.packageName); 5862 } catch (RemoteException e) { 5863 // Can't happen; the backup manager is local 5864 } 5865 } 5866 if (isPendingBroadcastProcessLocked(pid)) { 5867 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5868 skipPendingBroadcastLocked(pid); 5869 } 5870 } else { 5871 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5872 } 5873 } 5874 5875 private final boolean attachApplicationLocked(IApplicationThread thread, 5876 int pid) { 5877 5878 // Find the application record that is being attached... either via 5879 // the pid if we are running in multiple processes, or just pull the 5880 // next app record if we are emulating process with anonymous threads. 5881 ProcessRecord app; 5882 if (pid != MY_PID && pid >= 0) { 5883 synchronized (mPidsSelfLocked) { 5884 app = mPidsSelfLocked.get(pid); 5885 } 5886 } else { 5887 app = null; 5888 } 5889 5890 if (app == null) { 5891 Slog.w(TAG, "No pending application record for pid " + pid 5892 + " (IApplicationThread " + thread + "); dropping process"); 5893 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5894 if (pid > 0 && pid != MY_PID) { 5895 Process.killProcessQuiet(pid); 5896 //TODO: Process.killProcessGroup(app.info.uid, pid); 5897 } else { 5898 try { 5899 thread.scheduleExit(); 5900 } catch (Exception e) { 5901 // Ignore exceptions. 5902 } 5903 } 5904 return false; 5905 } 5906 5907 // If this application record is still attached to a previous 5908 // process, clean it up now. 5909 if (app.thread != null) { 5910 handleAppDiedLocked(app, true, true); 5911 } 5912 5913 // Tell the process all about itself. 5914 5915 if (localLOGV) Slog.v( 5916 TAG, "Binding process pid " + pid + " to record " + app); 5917 5918 final String processName = app.processName; 5919 try { 5920 AppDeathRecipient adr = new AppDeathRecipient( 5921 app, pid, thread); 5922 thread.asBinder().linkToDeath(adr, 0); 5923 app.deathRecipient = adr; 5924 } catch (RemoteException e) { 5925 app.resetPackageList(mProcessStats); 5926 startProcessLocked(app, "link fail", processName); 5927 return false; 5928 } 5929 5930 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5931 5932 app.makeActive(thread, mProcessStats); 5933 app.curAdj = app.setAdj = -100; 5934 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5935 app.forcingToForeground = null; 5936 updateProcessForegroundLocked(app, false, false); 5937 app.hasShownUi = false; 5938 app.debugging = false; 5939 app.cached = false; 5940 app.killedByAm = false; 5941 5942 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5943 5944 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5945 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5946 5947 if (!normalMode) { 5948 Slog.i(TAG, "Launching preboot mode app: " + app); 5949 } 5950 5951 if (localLOGV) Slog.v( 5952 TAG, "New app record " + app 5953 + " thread=" + thread.asBinder() + " pid=" + pid); 5954 try { 5955 int testMode = IApplicationThread.DEBUG_OFF; 5956 if (mDebugApp != null && mDebugApp.equals(processName)) { 5957 testMode = mWaitForDebugger 5958 ? IApplicationThread.DEBUG_WAIT 5959 : IApplicationThread.DEBUG_ON; 5960 app.debugging = true; 5961 if (mDebugTransient) { 5962 mDebugApp = mOrigDebugApp; 5963 mWaitForDebugger = mOrigWaitForDebugger; 5964 } 5965 } 5966 String profileFile = app.instrumentationProfileFile; 5967 ParcelFileDescriptor profileFd = null; 5968 int samplingInterval = 0; 5969 boolean profileAutoStop = false; 5970 if (mProfileApp != null && mProfileApp.equals(processName)) { 5971 mProfileProc = app; 5972 profileFile = mProfileFile; 5973 profileFd = mProfileFd; 5974 samplingInterval = mSamplingInterval; 5975 profileAutoStop = mAutoStopProfiler; 5976 } 5977 boolean enableOpenGlTrace = false; 5978 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5979 enableOpenGlTrace = true; 5980 mOpenGlTraceApp = null; 5981 } 5982 5983 // If the app is being launched for restore or full backup, set it up specially 5984 boolean isRestrictedBackupMode = false; 5985 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5986 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5987 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5988 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5989 } 5990 5991 ensurePackageDexOpt(app.instrumentationInfo != null 5992 ? app.instrumentationInfo.packageName 5993 : app.info.packageName); 5994 if (app.instrumentationClass != null) { 5995 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5996 } 5997 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5998 + processName + " with config " + mConfiguration); 5999 ApplicationInfo appInfo = app.instrumentationInfo != null 6000 ? app.instrumentationInfo : app.info; 6001 app.compat = compatibilityInfoForPackageLocked(appInfo); 6002 if (profileFd != null) { 6003 profileFd = profileFd.dup(); 6004 } 6005 ProfilerInfo profilerInfo = profileFile == null ? null 6006 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6007 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6008 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6009 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6010 isRestrictedBackupMode || !normalMode, app.persistent, 6011 new Configuration(mConfiguration), app.compat, 6012 getCommonServicesLocked(app.isolated), 6013 mCoreSettingsObserver.getCoreSettingsLocked()); 6014 updateLruProcessLocked(app, false, null); 6015 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6016 } catch (Exception e) { 6017 // todo: Yikes! What should we do? For now we will try to 6018 // start another process, but that could easily get us in 6019 // an infinite loop of restarting processes... 6020 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6021 6022 app.resetPackageList(mProcessStats); 6023 app.unlinkDeathRecipient(); 6024 startProcessLocked(app, "bind fail", processName); 6025 return false; 6026 } 6027 6028 // Remove this record from the list of starting applications. 6029 mPersistentStartingProcesses.remove(app); 6030 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6031 "Attach application locked removing on hold: " + app); 6032 mProcessesOnHold.remove(app); 6033 6034 boolean badApp = false; 6035 boolean didSomething = false; 6036 6037 // See if the top visible activity is waiting to run in this process... 6038 if (normalMode) { 6039 try { 6040 if (mStackSupervisor.attachApplicationLocked(app)) { 6041 didSomething = true; 6042 } 6043 } catch (Exception e) { 6044 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6045 badApp = true; 6046 } 6047 } 6048 6049 // Find any services that should be running in this process... 6050 if (!badApp) { 6051 try { 6052 didSomething |= mServices.attachApplicationLocked(app, processName); 6053 } catch (Exception e) { 6054 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6055 badApp = true; 6056 } 6057 } 6058 6059 // Check if a next-broadcast receiver is in this process... 6060 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6061 try { 6062 didSomething |= sendPendingBroadcastsLocked(app); 6063 } catch (Exception e) { 6064 // If the app died trying to launch the receiver we declare it 'bad' 6065 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6066 badApp = true; 6067 } 6068 } 6069 6070 // Check whether the next backup agent is in this process... 6071 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6072 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6073 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6074 try { 6075 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6076 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6077 mBackupTarget.backupMode); 6078 } catch (Exception e) { 6079 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6080 badApp = true; 6081 } 6082 } 6083 6084 if (badApp) { 6085 app.kill("error during init", true); 6086 handleAppDiedLocked(app, false, true); 6087 return false; 6088 } 6089 6090 if (!didSomething) { 6091 updateOomAdjLocked(); 6092 } 6093 6094 return true; 6095 } 6096 6097 @Override 6098 public final void attachApplication(IApplicationThread thread) { 6099 synchronized (this) { 6100 int callingPid = Binder.getCallingPid(); 6101 final long origId = Binder.clearCallingIdentity(); 6102 attachApplicationLocked(thread, callingPid); 6103 Binder.restoreCallingIdentity(origId); 6104 } 6105 } 6106 6107 @Override 6108 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6109 final long origId = Binder.clearCallingIdentity(); 6110 synchronized (this) { 6111 ActivityStack stack = ActivityRecord.getStackLocked(token); 6112 if (stack != null) { 6113 ActivityRecord r = 6114 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6115 if (stopProfiling) { 6116 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6117 try { 6118 mProfileFd.close(); 6119 } catch (IOException e) { 6120 } 6121 clearProfilerLocked(); 6122 } 6123 } 6124 } 6125 } 6126 Binder.restoreCallingIdentity(origId); 6127 } 6128 6129 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6130 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6131 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6132 } 6133 6134 void enableScreenAfterBoot() { 6135 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6136 SystemClock.uptimeMillis()); 6137 mWindowManager.enableScreenAfterBoot(); 6138 6139 synchronized (this) { 6140 updateEventDispatchingLocked(); 6141 } 6142 } 6143 6144 @Override 6145 public void showBootMessage(final CharSequence msg, final boolean always) { 6146 enforceNotIsolatedCaller("showBootMessage"); 6147 mWindowManager.showBootMessage(msg, always); 6148 } 6149 6150 @Override 6151 public void keyguardWaitingForActivityDrawn() { 6152 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6153 final long token = Binder.clearCallingIdentity(); 6154 try { 6155 synchronized (this) { 6156 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6157 mWindowManager.keyguardWaitingForActivityDrawn(); 6158 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6159 mLockScreenShown = LOCK_SCREEN_LEAVING; 6160 updateSleepIfNeededLocked(); 6161 } 6162 } 6163 } finally { 6164 Binder.restoreCallingIdentity(token); 6165 } 6166 } 6167 6168 final void finishBooting() { 6169 synchronized (this) { 6170 if (!mBootAnimationComplete) { 6171 mCallFinishBooting = true; 6172 return; 6173 } 6174 mCallFinishBooting = false; 6175 } 6176 6177 ArraySet<String> completedIsas = new ArraySet<String>(); 6178 for (String abi : Build.SUPPORTED_ABIS) { 6179 Process.establishZygoteConnectionForAbi(abi); 6180 final String instructionSet = VMRuntime.getInstructionSet(abi); 6181 if (!completedIsas.contains(instructionSet)) { 6182 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6183 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6184 } 6185 completedIsas.add(instructionSet); 6186 } 6187 } 6188 6189 IntentFilter pkgFilter = new IntentFilter(); 6190 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6191 pkgFilter.addDataScheme("package"); 6192 mContext.registerReceiver(new BroadcastReceiver() { 6193 @Override 6194 public void onReceive(Context context, Intent intent) { 6195 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6196 if (pkgs != null) { 6197 for (String pkg : pkgs) { 6198 synchronized (ActivityManagerService.this) { 6199 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6200 0, "finished booting")) { 6201 setResultCode(Activity.RESULT_OK); 6202 return; 6203 } 6204 } 6205 } 6206 } 6207 } 6208 }, pkgFilter); 6209 6210 // Let system services know. 6211 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6212 6213 synchronized (this) { 6214 // Ensure that any processes we had put on hold are now started 6215 // up. 6216 final int NP = mProcessesOnHold.size(); 6217 if (NP > 0) { 6218 ArrayList<ProcessRecord> procs = 6219 new ArrayList<ProcessRecord>(mProcessesOnHold); 6220 for (int ip=0; ip<NP; ip++) { 6221 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6222 + procs.get(ip)); 6223 startProcessLocked(procs.get(ip), "on-hold", null); 6224 } 6225 } 6226 6227 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6228 // Start looking for apps that are abusing wake locks. 6229 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6230 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6231 // Tell anyone interested that we are done booting! 6232 SystemProperties.set("sys.boot_completed", "1"); 6233 6234 // And trigger dev.bootcomplete if we are not showing encryption progress 6235 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6236 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6237 SystemProperties.set("dev.bootcomplete", "1"); 6238 } 6239 for (int i=0; i<mStartedUsers.size(); i++) { 6240 UserStartedState uss = mStartedUsers.valueAt(i); 6241 if (uss.mState == UserStartedState.STATE_BOOTING) { 6242 uss.mState = UserStartedState.STATE_RUNNING; 6243 final int userId = mStartedUsers.keyAt(i); 6244 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6245 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6246 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6247 broadcastIntentLocked(null, null, intent, null, 6248 new IIntentReceiver.Stub() { 6249 @Override 6250 public void performReceive(Intent intent, int resultCode, 6251 String data, Bundle extras, boolean ordered, 6252 boolean sticky, int sendingUser) { 6253 synchronized (ActivityManagerService.this) { 6254 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6255 true, false); 6256 } 6257 } 6258 }, 6259 0, null, null, 6260 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6261 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6262 userId); 6263 } 6264 } 6265 scheduleStartProfilesLocked(); 6266 } 6267 } 6268 } 6269 6270 @Override 6271 public void bootAnimationComplete() { 6272 final boolean callFinishBooting; 6273 synchronized (this) { 6274 callFinishBooting = mCallFinishBooting; 6275 mBootAnimationComplete = true; 6276 } 6277 if (callFinishBooting) { 6278 finishBooting(); 6279 } 6280 } 6281 6282 @Override 6283 public void systemBackupRestored() { 6284 synchronized (this) { 6285 if (mSystemReady) { 6286 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6287 } else { 6288 Slog.w(TAG, "System backup restored before system is ready"); 6289 } 6290 } 6291 } 6292 6293 final void ensureBootCompleted() { 6294 boolean booting; 6295 boolean enableScreen; 6296 synchronized (this) { 6297 booting = mBooting; 6298 mBooting = false; 6299 enableScreen = !mBooted; 6300 mBooted = true; 6301 } 6302 6303 if (booting) { 6304 finishBooting(); 6305 } 6306 6307 if (enableScreen) { 6308 enableScreenAfterBoot(); 6309 } 6310 } 6311 6312 @Override 6313 public final void activityResumed(IBinder token) { 6314 final long origId = Binder.clearCallingIdentity(); 6315 synchronized(this) { 6316 ActivityStack stack = ActivityRecord.getStackLocked(token); 6317 if (stack != null) { 6318 ActivityRecord.activityResumedLocked(token); 6319 } 6320 } 6321 Binder.restoreCallingIdentity(origId); 6322 } 6323 6324 @Override 6325 public final void activityPaused(IBinder token) { 6326 final long origId = Binder.clearCallingIdentity(); 6327 synchronized(this) { 6328 ActivityStack stack = ActivityRecord.getStackLocked(token); 6329 if (stack != null) { 6330 stack.activityPausedLocked(token, false); 6331 } 6332 } 6333 Binder.restoreCallingIdentity(origId); 6334 } 6335 6336 @Override 6337 public final void activityStopped(IBinder token, Bundle icicle, 6338 PersistableBundle persistentState, CharSequence description) { 6339 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6340 6341 // Refuse possible leaked file descriptors 6342 if (icicle != null && icicle.hasFileDescriptors()) { 6343 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6344 } 6345 6346 final long origId = Binder.clearCallingIdentity(); 6347 6348 synchronized (this) { 6349 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6350 if (r != null) { 6351 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6352 } 6353 } 6354 6355 trimApplications(); 6356 6357 Binder.restoreCallingIdentity(origId); 6358 } 6359 6360 @Override 6361 public final void activityDestroyed(IBinder token) { 6362 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6363 synchronized (this) { 6364 ActivityStack stack = ActivityRecord.getStackLocked(token); 6365 if (stack != null) { 6366 stack.activityDestroyedLocked(token, "activityDestroyed"); 6367 } 6368 } 6369 } 6370 6371 @Override 6372 public final void backgroundResourcesReleased(IBinder token) { 6373 final long origId = Binder.clearCallingIdentity(); 6374 try { 6375 synchronized (this) { 6376 ActivityStack stack = ActivityRecord.getStackLocked(token); 6377 if (stack != null) { 6378 stack.backgroundResourcesReleased(); 6379 } 6380 } 6381 } finally { 6382 Binder.restoreCallingIdentity(origId); 6383 } 6384 } 6385 6386 @Override 6387 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6388 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6389 } 6390 6391 @Override 6392 public final void notifyEnterAnimationComplete(IBinder token) { 6393 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6394 } 6395 6396 @Override 6397 public String getCallingPackage(IBinder token) { 6398 synchronized (this) { 6399 ActivityRecord r = getCallingRecordLocked(token); 6400 return r != null ? r.info.packageName : null; 6401 } 6402 } 6403 6404 @Override 6405 public ComponentName getCallingActivity(IBinder token) { 6406 synchronized (this) { 6407 ActivityRecord r = getCallingRecordLocked(token); 6408 return r != null ? r.intent.getComponent() : null; 6409 } 6410 } 6411 6412 private ActivityRecord getCallingRecordLocked(IBinder token) { 6413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6414 if (r == null) { 6415 return null; 6416 } 6417 return r.resultTo; 6418 } 6419 6420 @Override 6421 public ComponentName getActivityClassForToken(IBinder token) { 6422 synchronized(this) { 6423 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6424 if (r == null) { 6425 return null; 6426 } 6427 return r.intent.getComponent(); 6428 } 6429 } 6430 6431 @Override 6432 public String getPackageForToken(IBinder token) { 6433 synchronized(this) { 6434 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6435 if (r == null) { 6436 return null; 6437 } 6438 return r.packageName; 6439 } 6440 } 6441 6442 @Override 6443 public IIntentSender getIntentSender(int type, 6444 String packageName, IBinder token, String resultWho, 6445 int requestCode, Intent[] intents, String[] resolvedTypes, 6446 int flags, Bundle options, int userId) { 6447 enforceNotIsolatedCaller("getIntentSender"); 6448 // Refuse possible leaked file descriptors 6449 if (intents != null) { 6450 if (intents.length < 1) { 6451 throw new IllegalArgumentException("Intents array length must be >= 1"); 6452 } 6453 for (int i=0; i<intents.length; i++) { 6454 Intent intent = intents[i]; 6455 if (intent != null) { 6456 if (intent.hasFileDescriptors()) { 6457 throw new IllegalArgumentException("File descriptors passed in Intent"); 6458 } 6459 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6460 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6461 throw new IllegalArgumentException( 6462 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6463 } 6464 intents[i] = new Intent(intent); 6465 } 6466 } 6467 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6468 throw new IllegalArgumentException( 6469 "Intent array length does not match resolvedTypes length"); 6470 } 6471 } 6472 if (options != null) { 6473 if (options.hasFileDescriptors()) { 6474 throw new IllegalArgumentException("File descriptors passed in options"); 6475 } 6476 } 6477 6478 synchronized(this) { 6479 int callingUid = Binder.getCallingUid(); 6480 int origUserId = userId; 6481 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6482 type == ActivityManager.INTENT_SENDER_BROADCAST, 6483 ALLOW_NON_FULL, "getIntentSender", null); 6484 if (origUserId == UserHandle.USER_CURRENT) { 6485 // We don't want to evaluate this until the pending intent is 6486 // actually executed. However, we do want to always do the 6487 // security checking for it above. 6488 userId = UserHandle.USER_CURRENT; 6489 } 6490 try { 6491 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6492 int uid = AppGlobals.getPackageManager() 6493 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6494 if (!UserHandle.isSameApp(callingUid, uid)) { 6495 String msg = "Permission Denial: getIntentSender() from pid=" 6496 + Binder.getCallingPid() 6497 + ", uid=" + Binder.getCallingUid() 6498 + ", (need uid=" + uid + ")" 6499 + " is not allowed to send as package " + packageName; 6500 Slog.w(TAG, msg); 6501 throw new SecurityException(msg); 6502 } 6503 } 6504 6505 return getIntentSenderLocked(type, packageName, callingUid, userId, 6506 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6507 6508 } catch (RemoteException e) { 6509 throw new SecurityException(e); 6510 } 6511 } 6512 } 6513 6514 IIntentSender getIntentSenderLocked(int type, String packageName, 6515 int callingUid, int userId, IBinder token, String resultWho, 6516 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6517 Bundle options) { 6518 if (DEBUG_MU) 6519 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6520 ActivityRecord activity = null; 6521 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6522 activity = ActivityRecord.isInStackLocked(token); 6523 if (activity == null) { 6524 return null; 6525 } 6526 if (activity.finishing) { 6527 return null; 6528 } 6529 } 6530 6531 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6532 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6533 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6534 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6535 |PendingIntent.FLAG_UPDATE_CURRENT); 6536 6537 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6538 type, packageName, activity, resultWho, 6539 requestCode, intents, resolvedTypes, flags, options, userId); 6540 WeakReference<PendingIntentRecord> ref; 6541 ref = mIntentSenderRecords.get(key); 6542 PendingIntentRecord rec = ref != null ? ref.get() : null; 6543 if (rec != null) { 6544 if (!cancelCurrent) { 6545 if (updateCurrent) { 6546 if (rec.key.requestIntent != null) { 6547 rec.key.requestIntent.replaceExtras(intents != null ? 6548 intents[intents.length - 1] : null); 6549 } 6550 if (intents != null) { 6551 intents[intents.length-1] = rec.key.requestIntent; 6552 rec.key.allIntents = intents; 6553 rec.key.allResolvedTypes = resolvedTypes; 6554 } else { 6555 rec.key.allIntents = null; 6556 rec.key.allResolvedTypes = null; 6557 } 6558 } 6559 return rec; 6560 } 6561 rec.canceled = true; 6562 mIntentSenderRecords.remove(key); 6563 } 6564 if (noCreate) { 6565 return rec; 6566 } 6567 rec = new PendingIntentRecord(this, key, callingUid); 6568 mIntentSenderRecords.put(key, rec.ref); 6569 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6570 if (activity.pendingResults == null) { 6571 activity.pendingResults 6572 = new HashSet<WeakReference<PendingIntentRecord>>(); 6573 } 6574 activity.pendingResults.add(rec.ref); 6575 } 6576 return rec; 6577 } 6578 6579 @Override 6580 public void cancelIntentSender(IIntentSender sender) { 6581 if (!(sender instanceof PendingIntentRecord)) { 6582 return; 6583 } 6584 synchronized(this) { 6585 PendingIntentRecord rec = (PendingIntentRecord)sender; 6586 try { 6587 int uid = AppGlobals.getPackageManager() 6588 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6589 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6590 String msg = "Permission Denial: cancelIntentSender() from pid=" 6591 + Binder.getCallingPid() 6592 + ", uid=" + Binder.getCallingUid() 6593 + " is not allowed to cancel packges " 6594 + rec.key.packageName; 6595 Slog.w(TAG, msg); 6596 throw new SecurityException(msg); 6597 } 6598 } catch (RemoteException e) { 6599 throw new SecurityException(e); 6600 } 6601 cancelIntentSenderLocked(rec, true); 6602 } 6603 } 6604 6605 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6606 rec.canceled = true; 6607 mIntentSenderRecords.remove(rec.key); 6608 if (cleanActivity && rec.key.activity != null) { 6609 rec.key.activity.pendingResults.remove(rec.ref); 6610 } 6611 } 6612 6613 @Override 6614 public String getPackageForIntentSender(IIntentSender pendingResult) { 6615 if (!(pendingResult instanceof PendingIntentRecord)) { 6616 return null; 6617 } 6618 try { 6619 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6620 return res.key.packageName; 6621 } catch (ClassCastException e) { 6622 } 6623 return null; 6624 } 6625 6626 @Override 6627 public int getUidForIntentSender(IIntentSender sender) { 6628 if (sender instanceof PendingIntentRecord) { 6629 try { 6630 PendingIntentRecord res = (PendingIntentRecord)sender; 6631 return res.uid; 6632 } catch (ClassCastException e) { 6633 } 6634 } 6635 return -1; 6636 } 6637 6638 @Override 6639 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6640 if (!(pendingResult instanceof PendingIntentRecord)) { 6641 return false; 6642 } 6643 try { 6644 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6645 if (res.key.allIntents == null) { 6646 return false; 6647 } 6648 for (int i=0; i<res.key.allIntents.length; i++) { 6649 Intent intent = res.key.allIntents[i]; 6650 if (intent.getPackage() != null && intent.getComponent() != null) { 6651 return false; 6652 } 6653 } 6654 return true; 6655 } catch (ClassCastException e) { 6656 } 6657 return false; 6658 } 6659 6660 @Override 6661 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6662 if (!(pendingResult instanceof PendingIntentRecord)) { 6663 return false; 6664 } 6665 try { 6666 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6667 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6668 return true; 6669 } 6670 return false; 6671 } catch (ClassCastException e) { 6672 } 6673 return false; 6674 } 6675 6676 @Override 6677 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6678 if (!(pendingResult instanceof PendingIntentRecord)) { 6679 return null; 6680 } 6681 try { 6682 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6683 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6684 } catch (ClassCastException e) { 6685 } 6686 return null; 6687 } 6688 6689 @Override 6690 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6691 if (!(pendingResult instanceof PendingIntentRecord)) { 6692 return null; 6693 } 6694 try { 6695 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6696 Intent intent = res.key.requestIntent; 6697 if (intent != null) { 6698 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6699 || res.lastTagPrefix.equals(prefix))) { 6700 return res.lastTag; 6701 } 6702 res.lastTagPrefix = prefix; 6703 StringBuilder sb = new StringBuilder(128); 6704 if (prefix != null) { 6705 sb.append(prefix); 6706 } 6707 if (intent.getAction() != null) { 6708 sb.append(intent.getAction()); 6709 } else if (intent.getComponent() != null) { 6710 intent.getComponent().appendShortString(sb); 6711 } else { 6712 sb.append("?"); 6713 } 6714 return res.lastTag = sb.toString(); 6715 } 6716 } catch (ClassCastException e) { 6717 } 6718 return null; 6719 } 6720 6721 @Override 6722 public void setProcessLimit(int max) { 6723 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6724 "setProcessLimit()"); 6725 synchronized (this) { 6726 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6727 mProcessLimitOverride = max; 6728 } 6729 trimApplications(); 6730 } 6731 6732 @Override 6733 public int getProcessLimit() { 6734 synchronized (this) { 6735 return mProcessLimitOverride; 6736 } 6737 } 6738 6739 void foregroundTokenDied(ForegroundToken token) { 6740 synchronized (ActivityManagerService.this) { 6741 synchronized (mPidsSelfLocked) { 6742 ForegroundToken cur 6743 = mForegroundProcesses.get(token.pid); 6744 if (cur != token) { 6745 return; 6746 } 6747 mForegroundProcesses.remove(token.pid); 6748 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6749 if (pr == null) { 6750 return; 6751 } 6752 pr.forcingToForeground = null; 6753 updateProcessForegroundLocked(pr, false, false); 6754 } 6755 updateOomAdjLocked(); 6756 } 6757 } 6758 6759 @Override 6760 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6761 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6762 "setProcessForeground()"); 6763 synchronized(this) { 6764 boolean changed = false; 6765 6766 synchronized (mPidsSelfLocked) { 6767 ProcessRecord pr = mPidsSelfLocked.get(pid); 6768 if (pr == null && isForeground) { 6769 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6770 return; 6771 } 6772 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6773 if (oldToken != null) { 6774 oldToken.token.unlinkToDeath(oldToken, 0); 6775 mForegroundProcesses.remove(pid); 6776 if (pr != null) { 6777 pr.forcingToForeground = null; 6778 } 6779 changed = true; 6780 } 6781 if (isForeground && token != null) { 6782 ForegroundToken newToken = new ForegroundToken() { 6783 @Override 6784 public void binderDied() { 6785 foregroundTokenDied(this); 6786 } 6787 }; 6788 newToken.pid = pid; 6789 newToken.token = token; 6790 try { 6791 token.linkToDeath(newToken, 0); 6792 mForegroundProcesses.put(pid, newToken); 6793 pr.forcingToForeground = token; 6794 changed = true; 6795 } catch (RemoteException e) { 6796 // If the process died while doing this, we will later 6797 // do the cleanup with the process death link. 6798 } 6799 } 6800 } 6801 6802 if (changed) { 6803 updateOomAdjLocked(); 6804 } 6805 } 6806 } 6807 6808 // ========================================================= 6809 // PROCESS INFO 6810 // ========================================================= 6811 6812 static class ProcessInfoService extends IProcessInfoService.Stub { 6813 final ActivityManagerService mActivityManagerService; 6814 ProcessInfoService(ActivityManagerService activityManagerService) { 6815 mActivityManagerService = activityManagerService; 6816 } 6817 6818 @Override 6819 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) { 6820 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states); 6821 } 6822 } 6823 6824 /** 6825 * For each PID in the given input array, write the current process state 6826 * for that process into the output array, or -1 to indicate that no 6827 * process with the given PID exists. 6828 */ 6829 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) { 6830 if (pids == null) { 6831 throw new NullPointerException("pids"); 6832 } else if (states == null) { 6833 throw new NullPointerException("states"); 6834 } else if (pids.length != states.length) { 6835 throw new IllegalArgumentException("input and output arrays have different lengths!"); 6836 } 6837 6838 synchronized (mPidsSelfLocked) { 6839 for (int i = 0; i < pids.length; i++) { 6840 ProcessRecord pr = mPidsSelfLocked.get(pids[i]); 6841 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT : 6842 pr.curProcState; 6843 } 6844 } 6845 } 6846 6847 // ========================================================= 6848 // PERMISSIONS 6849 // ========================================================= 6850 6851 static class PermissionController extends IPermissionController.Stub { 6852 ActivityManagerService mActivityManagerService; 6853 PermissionController(ActivityManagerService activityManagerService) { 6854 mActivityManagerService = activityManagerService; 6855 } 6856 6857 @Override 6858 public boolean checkPermission(String permission, int pid, int uid) { 6859 return mActivityManagerService.checkPermission(permission, pid, 6860 uid) == PackageManager.PERMISSION_GRANTED; 6861 } 6862 } 6863 6864 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6865 @Override 6866 public int checkComponentPermission(String permission, int pid, int uid, 6867 int owningUid, boolean exported) { 6868 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6869 owningUid, exported); 6870 } 6871 6872 @Override 6873 public Object getAMSLock() { 6874 return ActivityManagerService.this; 6875 } 6876 } 6877 6878 /** 6879 * This can be called with or without the global lock held. 6880 */ 6881 int checkComponentPermission(String permission, int pid, int uid, 6882 int owningUid, boolean exported) { 6883 if (pid == MY_PID) { 6884 return PackageManager.PERMISSION_GRANTED; 6885 } 6886 return ActivityManager.checkComponentPermission(permission, uid, 6887 owningUid, exported); 6888 } 6889 6890 /** 6891 * As the only public entry point for permissions checking, this method 6892 * can enforce the semantic that requesting a check on a null global 6893 * permission is automatically denied. (Internally a null permission 6894 * string is used when calling {@link #checkComponentPermission} in cases 6895 * when only uid-based security is needed.) 6896 * 6897 * This can be called with or without the global lock held. 6898 */ 6899 @Override 6900 public int checkPermission(String permission, int pid, int uid) { 6901 if (permission == null) { 6902 return PackageManager.PERMISSION_DENIED; 6903 } 6904 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6905 } 6906 6907 @Override 6908 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6909 if (permission == null) { 6910 return PackageManager.PERMISSION_DENIED; 6911 } 6912 6913 // We might be performing an operation on behalf of an indirect binder 6914 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6915 // client identity accordingly before proceeding. 6916 Identity tlsIdentity = sCallerIdentity.get(); 6917 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6918 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6919 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6920 uid = tlsIdentity.uid; 6921 pid = tlsIdentity.pid; 6922 } 6923 6924 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6925 } 6926 6927 /** 6928 * Binder IPC calls go through the public entry point. 6929 * This can be called with or without the global lock held. 6930 */ 6931 int checkCallingPermission(String permission) { 6932 return checkPermission(permission, 6933 Binder.getCallingPid(), 6934 UserHandle.getAppId(Binder.getCallingUid())); 6935 } 6936 6937 /** 6938 * This can be called with or without the global lock held. 6939 */ 6940 void enforceCallingPermission(String permission, String func) { 6941 if (checkCallingPermission(permission) 6942 == PackageManager.PERMISSION_GRANTED) { 6943 return; 6944 } 6945 6946 String msg = "Permission Denial: " + func + " from pid=" 6947 + Binder.getCallingPid() 6948 + ", uid=" + Binder.getCallingUid() 6949 + " requires " + permission; 6950 Slog.w(TAG, msg); 6951 throw new SecurityException(msg); 6952 } 6953 6954 /** 6955 * Determine if UID is holding permissions required to access {@link Uri} in 6956 * the given {@link ProviderInfo}. Final permission checking is always done 6957 * in {@link ContentProvider}. 6958 */ 6959 private final boolean checkHoldingPermissionsLocked( 6960 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6961 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6962 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6963 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6964 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6965 != PERMISSION_GRANTED) { 6966 return false; 6967 } 6968 } 6969 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6970 } 6971 6972 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6973 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6974 if (pi.applicationInfo.uid == uid) { 6975 return true; 6976 } else if (!pi.exported) { 6977 return false; 6978 } 6979 6980 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6981 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6982 try { 6983 // check if target holds top-level <provider> permissions 6984 if (!readMet && pi.readPermission != null && considerUidPermissions 6985 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6986 readMet = true; 6987 } 6988 if (!writeMet && pi.writePermission != null && considerUidPermissions 6989 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6990 writeMet = true; 6991 } 6992 6993 // track if unprotected read/write is allowed; any denied 6994 // <path-permission> below removes this ability 6995 boolean allowDefaultRead = pi.readPermission == null; 6996 boolean allowDefaultWrite = pi.writePermission == null; 6997 6998 // check if target holds any <path-permission> that match uri 6999 final PathPermission[] pps = pi.pathPermissions; 7000 if (pps != null) { 7001 final String path = grantUri.uri.getPath(); 7002 int i = pps.length; 7003 while (i > 0 && (!readMet || !writeMet)) { 7004 i--; 7005 PathPermission pp = pps[i]; 7006 if (pp.match(path)) { 7007 if (!readMet) { 7008 final String pprperm = pp.getReadPermission(); 7009 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7010 + pprperm + " for " + pp.getPath() 7011 + ": match=" + pp.match(path) 7012 + " check=" + pm.checkUidPermission(pprperm, uid)); 7013 if (pprperm != null) { 7014 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7015 == PERMISSION_GRANTED) { 7016 readMet = true; 7017 } else { 7018 allowDefaultRead = false; 7019 } 7020 } 7021 } 7022 if (!writeMet) { 7023 final String ppwperm = pp.getWritePermission(); 7024 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7025 + ppwperm + " for " + pp.getPath() 7026 + ": match=" + pp.match(path) 7027 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7028 if (ppwperm != null) { 7029 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7030 == PERMISSION_GRANTED) { 7031 writeMet = true; 7032 } else { 7033 allowDefaultWrite = false; 7034 } 7035 } 7036 } 7037 } 7038 } 7039 } 7040 7041 // grant unprotected <provider> read/write, if not blocked by 7042 // <path-permission> above 7043 if (allowDefaultRead) readMet = true; 7044 if (allowDefaultWrite) writeMet = true; 7045 7046 } catch (RemoteException e) { 7047 return false; 7048 } 7049 7050 return readMet && writeMet; 7051 } 7052 7053 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7054 ProviderInfo pi = null; 7055 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7056 if (cpr != null) { 7057 pi = cpr.info; 7058 } else { 7059 try { 7060 pi = AppGlobals.getPackageManager().resolveContentProvider( 7061 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7062 } catch (RemoteException ex) { 7063 } 7064 } 7065 return pi; 7066 } 7067 7068 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7069 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7070 if (targetUris != null) { 7071 return targetUris.get(grantUri); 7072 } 7073 return null; 7074 } 7075 7076 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7077 String targetPkg, int targetUid, GrantUri grantUri) { 7078 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7079 if (targetUris == null) { 7080 targetUris = Maps.newArrayMap(); 7081 mGrantedUriPermissions.put(targetUid, targetUris); 7082 } 7083 7084 UriPermission perm = targetUris.get(grantUri); 7085 if (perm == null) { 7086 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7087 targetUris.put(grantUri, perm); 7088 } 7089 7090 return perm; 7091 } 7092 7093 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7094 final int modeFlags) { 7095 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7096 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7097 : UriPermission.STRENGTH_OWNED; 7098 7099 // Root gets to do everything. 7100 if (uid == 0) { 7101 return true; 7102 } 7103 7104 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7105 if (perms == null) return false; 7106 7107 // First look for exact match 7108 final UriPermission exactPerm = perms.get(grantUri); 7109 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7110 return true; 7111 } 7112 7113 // No exact match, look for prefixes 7114 final int N = perms.size(); 7115 for (int i = 0; i < N; i++) { 7116 final UriPermission perm = perms.valueAt(i); 7117 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7118 && perm.getStrength(modeFlags) >= minStrength) { 7119 return true; 7120 } 7121 } 7122 7123 return false; 7124 } 7125 7126 /** 7127 * @param uri This uri must NOT contain an embedded userId. 7128 * @param userId The userId in which the uri is to be resolved. 7129 */ 7130 @Override 7131 public int checkUriPermission(Uri uri, int pid, int uid, 7132 final int modeFlags, int userId, IBinder callerToken) { 7133 enforceNotIsolatedCaller("checkUriPermission"); 7134 7135 // Another redirected-binder-call permissions check as in 7136 // {@link checkPermissionWithToken}. 7137 Identity tlsIdentity = sCallerIdentity.get(); 7138 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7139 uid = tlsIdentity.uid; 7140 pid = tlsIdentity.pid; 7141 } 7142 7143 // Our own process gets to do everything. 7144 if (pid == MY_PID) { 7145 return PackageManager.PERMISSION_GRANTED; 7146 } 7147 synchronized (this) { 7148 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7149 ? PackageManager.PERMISSION_GRANTED 7150 : PackageManager.PERMISSION_DENIED; 7151 } 7152 } 7153 7154 /** 7155 * Check if the targetPkg can be granted permission to access uri by 7156 * the callingUid using the given modeFlags. Throws a security exception 7157 * if callingUid is not allowed to do this. Returns the uid of the target 7158 * if the URI permission grant should be performed; returns -1 if it is not 7159 * needed (for example targetPkg already has permission to access the URI). 7160 * If you already know the uid of the target, you can supply it in 7161 * lastTargetUid else set that to -1. 7162 */ 7163 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7164 final int modeFlags, int lastTargetUid) { 7165 if (!Intent.isAccessUriMode(modeFlags)) { 7166 return -1; 7167 } 7168 7169 if (targetPkg != null) { 7170 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7171 "Checking grant " + targetPkg + " permission to " + grantUri); 7172 } 7173 7174 final IPackageManager pm = AppGlobals.getPackageManager(); 7175 7176 // If this is not a content: uri, we can't do anything with it. 7177 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7178 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7179 "Can't grant URI permission for non-content URI: " + grantUri); 7180 return -1; 7181 } 7182 7183 final String authority = grantUri.uri.getAuthority(); 7184 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7185 if (pi == null) { 7186 Slog.w(TAG, "No content provider found for permission check: " + 7187 grantUri.uri.toSafeString()); 7188 return -1; 7189 } 7190 7191 int targetUid = lastTargetUid; 7192 if (targetUid < 0 && targetPkg != null) { 7193 try { 7194 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7195 if (targetUid < 0) { 7196 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7197 "Can't grant URI permission no uid for: " + targetPkg); 7198 return -1; 7199 } 7200 } catch (RemoteException ex) { 7201 return -1; 7202 } 7203 } 7204 7205 if (targetUid >= 0) { 7206 // First... does the target actually need this permission? 7207 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7208 // No need to grant the target this permission. 7209 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7210 "Target " + targetPkg + " already has full permission to " + grantUri); 7211 return -1; 7212 } 7213 } else { 7214 // First... there is no target package, so can anyone access it? 7215 boolean allowed = pi.exported; 7216 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7217 if (pi.readPermission != null) { 7218 allowed = false; 7219 } 7220 } 7221 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7222 if (pi.writePermission != null) { 7223 allowed = false; 7224 } 7225 } 7226 if (allowed) { 7227 return -1; 7228 } 7229 } 7230 7231 /* There is a special cross user grant if: 7232 * - The target is on another user. 7233 * - Apps on the current user can access the uri without any uid permissions. 7234 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7235 * grant uri permissions. 7236 */ 7237 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7238 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7239 modeFlags, false /*without considering the uid permissions*/); 7240 7241 // Second... is the provider allowing granting of URI permissions? 7242 if (!specialCrossUserGrant) { 7243 if (!pi.grantUriPermissions) { 7244 throw new SecurityException("Provider " + pi.packageName 7245 + "/" + pi.name 7246 + " does not allow granting of Uri permissions (uri " 7247 + grantUri + ")"); 7248 } 7249 if (pi.uriPermissionPatterns != null) { 7250 final int N = pi.uriPermissionPatterns.length; 7251 boolean allowed = false; 7252 for (int i=0; i<N; i++) { 7253 if (pi.uriPermissionPatterns[i] != null 7254 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7255 allowed = true; 7256 break; 7257 } 7258 } 7259 if (!allowed) { 7260 throw new SecurityException("Provider " + pi.packageName 7261 + "/" + pi.name 7262 + " does not allow granting of permission to path of Uri " 7263 + grantUri); 7264 } 7265 } 7266 } 7267 7268 // Third... does the caller itself have permission to access 7269 // this uri? 7270 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7271 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7272 // Require they hold a strong enough Uri permission 7273 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7274 throw new SecurityException("Uid " + callingUid 7275 + " does not have permission to uri " + grantUri); 7276 } 7277 } 7278 } 7279 return targetUid; 7280 } 7281 7282 /** 7283 * @param uri This uri must NOT contain an embedded userId. 7284 * @param userId The userId in which the uri is to be resolved. 7285 */ 7286 @Override 7287 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7288 final int modeFlags, int userId) { 7289 enforceNotIsolatedCaller("checkGrantUriPermission"); 7290 synchronized(this) { 7291 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7292 new GrantUri(userId, uri, false), modeFlags, -1); 7293 } 7294 } 7295 7296 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7297 final int modeFlags, UriPermissionOwner owner) { 7298 if (!Intent.isAccessUriMode(modeFlags)) { 7299 return; 7300 } 7301 7302 // So here we are: the caller has the assumed permission 7303 // to the uri, and the target doesn't. Let's now give this to 7304 // the target. 7305 7306 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7307 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7308 7309 final String authority = grantUri.uri.getAuthority(); 7310 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7311 if (pi == null) { 7312 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7313 return; 7314 } 7315 7316 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7317 grantUri.prefix = true; 7318 } 7319 final UriPermission perm = findOrCreateUriPermissionLocked( 7320 pi.packageName, targetPkg, targetUid, grantUri); 7321 perm.grantModes(modeFlags, owner); 7322 } 7323 7324 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7325 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7326 if (targetPkg == null) { 7327 throw new NullPointerException("targetPkg"); 7328 } 7329 int targetUid; 7330 final IPackageManager pm = AppGlobals.getPackageManager(); 7331 try { 7332 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7333 } catch (RemoteException ex) { 7334 return; 7335 } 7336 7337 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7338 targetUid); 7339 if (targetUid < 0) { 7340 return; 7341 } 7342 7343 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7344 owner); 7345 } 7346 7347 static class NeededUriGrants extends ArrayList<GrantUri> { 7348 final String targetPkg; 7349 final int targetUid; 7350 final int flags; 7351 7352 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7353 this.targetPkg = targetPkg; 7354 this.targetUid = targetUid; 7355 this.flags = flags; 7356 } 7357 } 7358 7359 /** 7360 * Like checkGrantUriPermissionLocked, but takes an Intent. 7361 */ 7362 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7363 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7364 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7365 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7366 + " clip=" + (intent != null ? intent.getClipData() : null) 7367 + " from " + intent + "; flags=0x" 7368 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7369 7370 if (targetPkg == null) { 7371 throw new NullPointerException("targetPkg"); 7372 } 7373 7374 if (intent == null) { 7375 return null; 7376 } 7377 Uri data = intent.getData(); 7378 ClipData clip = intent.getClipData(); 7379 if (data == null && clip == null) { 7380 return null; 7381 } 7382 // Default userId for uris in the intent (if they don't specify it themselves) 7383 int contentUserHint = intent.getContentUserHint(); 7384 if (contentUserHint == UserHandle.USER_CURRENT) { 7385 contentUserHint = UserHandle.getUserId(callingUid); 7386 } 7387 final IPackageManager pm = AppGlobals.getPackageManager(); 7388 int targetUid; 7389 if (needed != null) { 7390 targetUid = needed.targetUid; 7391 } else { 7392 try { 7393 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7394 } catch (RemoteException ex) { 7395 return null; 7396 } 7397 if (targetUid < 0) { 7398 if (DEBUG_URI_PERMISSION) { 7399 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7400 + " on user " + targetUserId); 7401 } 7402 return null; 7403 } 7404 } 7405 if (data != null) { 7406 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7407 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7408 targetUid); 7409 if (targetUid > 0) { 7410 if (needed == null) { 7411 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7412 } 7413 needed.add(grantUri); 7414 } 7415 } 7416 if (clip != null) { 7417 for (int i=0; i<clip.getItemCount(); i++) { 7418 Uri uri = clip.getItemAt(i).getUri(); 7419 if (uri != null) { 7420 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7421 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7422 targetUid); 7423 if (targetUid > 0) { 7424 if (needed == null) { 7425 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7426 } 7427 needed.add(grantUri); 7428 } 7429 } else { 7430 Intent clipIntent = clip.getItemAt(i).getIntent(); 7431 if (clipIntent != null) { 7432 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7433 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7434 if (newNeeded != null) { 7435 needed = newNeeded; 7436 } 7437 } 7438 } 7439 } 7440 } 7441 7442 return needed; 7443 } 7444 7445 /** 7446 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7447 */ 7448 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7449 UriPermissionOwner owner) { 7450 if (needed != null) { 7451 for (int i=0; i<needed.size(); i++) { 7452 GrantUri grantUri = needed.get(i); 7453 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7454 grantUri, needed.flags, owner); 7455 } 7456 } 7457 } 7458 7459 void grantUriPermissionFromIntentLocked(int callingUid, 7460 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7461 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7462 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7463 if (needed == null) { 7464 return; 7465 } 7466 7467 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7468 } 7469 7470 /** 7471 * @param uri This uri must NOT contain an embedded userId. 7472 * @param userId The userId in which the uri is to be resolved. 7473 */ 7474 @Override 7475 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7476 final int modeFlags, int userId) { 7477 enforceNotIsolatedCaller("grantUriPermission"); 7478 GrantUri grantUri = new GrantUri(userId, uri, false); 7479 synchronized(this) { 7480 final ProcessRecord r = getRecordForAppLocked(caller); 7481 if (r == null) { 7482 throw new SecurityException("Unable to find app for caller " 7483 + caller 7484 + " when granting permission to uri " + grantUri); 7485 } 7486 if (targetPkg == null) { 7487 throw new IllegalArgumentException("null target"); 7488 } 7489 if (grantUri == null) { 7490 throw new IllegalArgumentException("null uri"); 7491 } 7492 7493 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7494 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7495 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7496 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7497 7498 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7499 UserHandle.getUserId(r.uid)); 7500 } 7501 } 7502 7503 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7504 if (perm.modeFlags == 0) { 7505 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7506 perm.targetUid); 7507 if (perms != null) { 7508 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7509 "Removing " + perm.targetUid + " permission to " + perm.uri); 7510 7511 perms.remove(perm.uri); 7512 if (perms.isEmpty()) { 7513 mGrantedUriPermissions.remove(perm.targetUid); 7514 } 7515 } 7516 } 7517 } 7518 7519 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7520 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7521 7522 final IPackageManager pm = AppGlobals.getPackageManager(); 7523 final String authority = grantUri.uri.getAuthority(); 7524 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7525 if (pi == null) { 7526 Slog.w(TAG, "No content provider found for permission revoke: " 7527 + grantUri.toSafeString()); 7528 return; 7529 } 7530 7531 // Does the caller have this permission on the URI? 7532 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7533 // If they don't have direct access to the URI, then revoke any 7534 // ownerless URI permissions that have been granted to them. 7535 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7536 if (perms != null) { 7537 boolean persistChanged = false; 7538 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7539 final UriPermission perm = it.next(); 7540 if (perm.uri.sourceUserId == grantUri.sourceUserId 7541 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7542 if (DEBUG_URI_PERMISSION) 7543 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7544 " permission to " + perm.uri); 7545 persistChanged |= perm.revokeModes( 7546 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7547 if (perm.modeFlags == 0) { 7548 it.remove(); 7549 } 7550 } 7551 } 7552 if (perms.isEmpty()) { 7553 mGrantedUriPermissions.remove(callingUid); 7554 } 7555 if (persistChanged) { 7556 schedulePersistUriGrants(); 7557 } 7558 } 7559 return; 7560 } 7561 7562 boolean persistChanged = false; 7563 7564 // Go through all of the permissions and remove any that match. 7565 int N = mGrantedUriPermissions.size(); 7566 for (int i = 0; i < N; i++) { 7567 final int targetUid = mGrantedUriPermissions.keyAt(i); 7568 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7569 7570 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7571 final UriPermission perm = it.next(); 7572 if (perm.uri.sourceUserId == grantUri.sourceUserId 7573 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7574 if (DEBUG_URI_PERMISSION) 7575 Slog.v(TAG, 7576 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7577 persistChanged |= perm.revokeModes( 7578 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7579 if (perm.modeFlags == 0) { 7580 it.remove(); 7581 } 7582 } 7583 } 7584 7585 if (perms.isEmpty()) { 7586 mGrantedUriPermissions.remove(targetUid); 7587 N--; 7588 i--; 7589 } 7590 } 7591 7592 if (persistChanged) { 7593 schedulePersistUriGrants(); 7594 } 7595 } 7596 7597 /** 7598 * @param uri This uri must NOT contain an embedded userId. 7599 * @param userId The userId in which the uri is to be resolved. 7600 */ 7601 @Override 7602 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7603 int userId) { 7604 enforceNotIsolatedCaller("revokeUriPermission"); 7605 synchronized(this) { 7606 final ProcessRecord r = getRecordForAppLocked(caller); 7607 if (r == null) { 7608 throw new SecurityException("Unable to find app for caller " 7609 + caller 7610 + " when revoking permission to uri " + uri); 7611 } 7612 if (uri == null) { 7613 Slog.w(TAG, "revokeUriPermission: null uri"); 7614 return; 7615 } 7616 7617 if (!Intent.isAccessUriMode(modeFlags)) { 7618 return; 7619 } 7620 7621 final IPackageManager pm = AppGlobals.getPackageManager(); 7622 final String authority = uri.getAuthority(); 7623 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7624 if (pi == null) { 7625 Slog.w(TAG, "No content provider found for permission revoke: " 7626 + uri.toSafeString()); 7627 return; 7628 } 7629 7630 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7631 } 7632 } 7633 7634 /** 7635 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7636 * given package. 7637 * 7638 * @param packageName Package name to match, or {@code null} to apply to all 7639 * packages. 7640 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7641 * to all users. 7642 * @param persistable If persistable grants should be removed. 7643 */ 7644 private void removeUriPermissionsForPackageLocked( 7645 String packageName, int userHandle, boolean persistable) { 7646 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7647 throw new IllegalArgumentException("Must narrow by either package or user"); 7648 } 7649 7650 boolean persistChanged = false; 7651 7652 int N = mGrantedUriPermissions.size(); 7653 for (int i = 0; i < N; i++) { 7654 final int targetUid = mGrantedUriPermissions.keyAt(i); 7655 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7656 7657 // Only inspect grants matching user 7658 if (userHandle == UserHandle.USER_ALL 7659 || userHandle == UserHandle.getUserId(targetUid)) { 7660 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7661 final UriPermission perm = it.next(); 7662 7663 // Only inspect grants matching package 7664 if (packageName == null || perm.sourcePkg.equals(packageName) 7665 || perm.targetPkg.equals(packageName)) { 7666 persistChanged |= perm.revokeModes(persistable 7667 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7668 7669 // Only remove when no modes remain; any persisted grants 7670 // will keep this alive. 7671 if (perm.modeFlags == 0) { 7672 it.remove(); 7673 } 7674 } 7675 } 7676 7677 if (perms.isEmpty()) { 7678 mGrantedUriPermissions.remove(targetUid); 7679 N--; 7680 i--; 7681 } 7682 } 7683 } 7684 7685 if (persistChanged) { 7686 schedulePersistUriGrants(); 7687 } 7688 } 7689 7690 @Override 7691 public IBinder newUriPermissionOwner(String name) { 7692 enforceNotIsolatedCaller("newUriPermissionOwner"); 7693 synchronized(this) { 7694 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7695 return owner.getExternalTokenLocked(); 7696 } 7697 } 7698 7699 /** 7700 * @param uri This uri must NOT contain an embedded userId. 7701 * @param sourceUserId The userId in which the uri is to be resolved. 7702 * @param targetUserId The userId of the app that receives the grant. 7703 */ 7704 @Override 7705 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7706 final int modeFlags, int sourceUserId, int targetUserId) { 7707 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7708 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7709 synchronized(this) { 7710 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7711 if (owner == null) { 7712 throw new IllegalArgumentException("Unknown owner: " + token); 7713 } 7714 if (fromUid != Binder.getCallingUid()) { 7715 if (Binder.getCallingUid() != Process.myUid()) { 7716 // Only system code can grant URI permissions on behalf 7717 // of other users. 7718 throw new SecurityException("nice try"); 7719 } 7720 } 7721 if (targetPkg == null) { 7722 throw new IllegalArgumentException("null target"); 7723 } 7724 if (uri == null) { 7725 throw new IllegalArgumentException("null uri"); 7726 } 7727 7728 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7729 modeFlags, owner, targetUserId); 7730 } 7731 } 7732 7733 /** 7734 * @param uri This uri must NOT contain an embedded userId. 7735 * @param userId The userId in which the uri is to be resolved. 7736 */ 7737 @Override 7738 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7739 synchronized(this) { 7740 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7741 if (owner == null) { 7742 throw new IllegalArgumentException("Unknown owner: " + token); 7743 } 7744 7745 if (uri == null) { 7746 owner.removeUriPermissionsLocked(mode); 7747 } else { 7748 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7749 } 7750 } 7751 } 7752 7753 private void schedulePersistUriGrants() { 7754 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7755 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7756 10 * DateUtils.SECOND_IN_MILLIS); 7757 } 7758 } 7759 7760 private void writeGrantedUriPermissions() { 7761 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7762 7763 // Snapshot permissions so we can persist without lock 7764 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7765 synchronized (this) { 7766 final int size = mGrantedUriPermissions.size(); 7767 for (int i = 0; i < size; i++) { 7768 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7769 for (UriPermission perm : perms.values()) { 7770 if (perm.persistedModeFlags != 0) { 7771 persist.add(perm.snapshot()); 7772 } 7773 } 7774 } 7775 } 7776 7777 FileOutputStream fos = null; 7778 try { 7779 fos = mGrantFile.startWrite(); 7780 7781 XmlSerializer out = new FastXmlSerializer(); 7782 out.setOutput(fos, "utf-8"); 7783 out.startDocument(null, true); 7784 out.startTag(null, TAG_URI_GRANTS); 7785 for (UriPermission.Snapshot perm : persist) { 7786 out.startTag(null, TAG_URI_GRANT); 7787 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7788 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7789 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7790 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7791 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7792 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7793 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7794 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7795 out.endTag(null, TAG_URI_GRANT); 7796 } 7797 out.endTag(null, TAG_URI_GRANTS); 7798 out.endDocument(); 7799 7800 mGrantFile.finishWrite(fos); 7801 } catch (IOException e) { 7802 if (fos != null) { 7803 mGrantFile.failWrite(fos); 7804 } 7805 } 7806 } 7807 7808 private void readGrantedUriPermissionsLocked() { 7809 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7810 7811 final long now = System.currentTimeMillis(); 7812 7813 FileInputStream fis = null; 7814 try { 7815 fis = mGrantFile.openRead(); 7816 final XmlPullParser in = Xml.newPullParser(); 7817 in.setInput(fis, null); 7818 7819 int type; 7820 while ((type = in.next()) != END_DOCUMENT) { 7821 final String tag = in.getName(); 7822 if (type == START_TAG) { 7823 if (TAG_URI_GRANT.equals(tag)) { 7824 final int sourceUserId; 7825 final int targetUserId; 7826 final int userHandle = readIntAttribute(in, 7827 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7828 if (userHandle != UserHandle.USER_NULL) { 7829 // For backwards compatibility. 7830 sourceUserId = userHandle; 7831 targetUserId = userHandle; 7832 } else { 7833 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7834 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7835 } 7836 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7837 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7838 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7839 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7840 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7841 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7842 7843 // Sanity check that provider still belongs to source package 7844 final ProviderInfo pi = getProviderInfoLocked( 7845 uri.getAuthority(), sourceUserId); 7846 if (pi != null && sourcePkg.equals(pi.packageName)) { 7847 int targetUid = -1; 7848 try { 7849 targetUid = AppGlobals.getPackageManager() 7850 .getPackageUid(targetPkg, targetUserId); 7851 } catch (RemoteException e) { 7852 } 7853 if (targetUid != -1) { 7854 final UriPermission perm = findOrCreateUriPermissionLocked( 7855 sourcePkg, targetPkg, targetUid, 7856 new GrantUri(sourceUserId, uri, prefix)); 7857 perm.initPersistedModes(modeFlags, createdTime); 7858 } 7859 } else { 7860 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7861 + " but instead found " + pi); 7862 } 7863 } 7864 } 7865 } 7866 } catch (FileNotFoundException e) { 7867 // Missing grants is okay 7868 } catch (IOException e) { 7869 Slog.wtf(TAG, "Failed reading Uri grants", e); 7870 } catch (XmlPullParserException e) { 7871 Slog.wtf(TAG, "Failed reading Uri grants", e); 7872 } finally { 7873 IoUtils.closeQuietly(fis); 7874 } 7875 } 7876 7877 /** 7878 * @param uri This uri must NOT contain an embedded userId. 7879 * @param userId The userId in which the uri is to be resolved. 7880 */ 7881 @Override 7882 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7883 enforceNotIsolatedCaller("takePersistableUriPermission"); 7884 7885 Preconditions.checkFlagsArgument(modeFlags, 7886 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7887 7888 synchronized (this) { 7889 final int callingUid = Binder.getCallingUid(); 7890 boolean persistChanged = false; 7891 GrantUri grantUri = new GrantUri(userId, uri, false); 7892 7893 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7894 new GrantUri(userId, uri, false)); 7895 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7896 new GrantUri(userId, uri, true)); 7897 7898 final boolean exactValid = (exactPerm != null) 7899 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7900 final boolean prefixValid = (prefixPerm != null) 7901 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7902 7903 if (!(exactValid || prefixValid)) { 7904 throw new SecurityException("No persistable permission grants found for UID " 7905 + callingUid + " and Uri " + grantUri.toSafeString()); 7906 } 7907 7908 if (exactValid) { 7909 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7910 } 7911 if (prefixValid) { 7912 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7913 } 7914 7915 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7916 7917 if (persistChanged) { 7918 schedulePersistUriGrants(); 7919 } 7920 } 7921 } 7922 7923 /** 7924 * @param uri This uri must NOT contain an embedded userId. 7925 * @param userId The userId in which the uri is to be resolved. 7926 */ 7927 @Override 7928 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7929 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7930 7931 Preconditions.checkFlagsArgument(modeFlags, 7932 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7933 7934 synchronized (this) { 7935 final int callingUid = Binder.getCallingUid(); 7936 boolean persistChanged = false; 7937 7938 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7939 new GrantUri(userId, uri, false)); 7940 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7941 new GrantUri(userId, uri, true)); 7942 if (exactPerm == null && prefixPerm == null) { 7943 throw new SecurityException("No permission grants found for UID " + callingUid 7944 + " and Uri " + uri.toSafeString()); 7945 } 7946 7947 if (exactPerm != null) { 7948 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7949 removeUriPermissionIfNeededLocked(exactPerm); 7950 } 7951 if (prefixPerm != null) { 7952 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7953 removeUriPermissionIfNeededLocked(prefixPerm); 7954 } 7955 7956 if (persistChanged) { 7957 schedulePersistUriGrants(); 7958 } 7959 } 7960 } 7961 7962 /** 7963 * Prune any older {@link UriPermission} for the given UID until outstanding 7964 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7965 * 7966 * @return if any mutations occured that require persisting. 7967 */ 7968 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7969 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7970 if (perms == null) return false; 7971 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7972 7973 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7974 for (UriPermission perm : perms.values()) { 7975 if (perm.persistedModeFlags != 0) { 7976 persisted.add(perm); 7977 } 7978 } 7979 7980 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7981 if (trimCount <= 0) return false; 7982 7983 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7984 for (int i = 0; i < trimCount; i++) { 7985 final UriPermission perm = persisted.get(i); 7986 7987 if (DEBUG_URI_PERMISSION) { 7988 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7989 } 7990 7991 perm.releasePersistableModes(~0); 7992 removeUriPermissionIfNeededLocked(perm); 7993 } 7994 7995 return true; 7996 } 7997 7998 @Override 7999 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8000 String packageName, boolean incoming) { 8001 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8002 Preconditions.checkNotNull(packageName, "packageName"); 8003 8004 final int callingUid = Binder.getCallingUid(); 8005 final IPackageManager pm = AppGlobals.getPackageManager(); 8006 try { 8007 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8008 if (packageUid != callingUid) { 8009 throw new SecurityException( 8010 "Package " + packageName + " does not belong to calling UID " + callingUid); 8011 } 8012 } catch (RemoteException e) { 8013 throw new SecurityException("Failed to verify package name ownership"); 8014 } 8015 8016 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8017 synchronized (this) { 8018 if (incoming) { 8019 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8020 callingUid); 8021 if (perms == null) { 8022 Slog.w(TAG, "No permission grants found for " + packageName); 8023 } else { 8024 for (UriPermission perm : perms.values()) { 8025 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8026 result.add(perm.buildPersistedPublicApiObject()); 8027 } 8028 } 8029 } 8030 } else { 8031 final int size = mGrantedUriPermissions.size(); 8032 for (int i = 0; i < size; i++) { 8033 final ArrayMap<GrantUri, UriPermission> perms = 8034 mGrantedUriPermissions.valueAt(i); 8035 for (UriPermission perm : perms.values()) { 8036 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8037 result.add(perm.buildPersistedPublicApiObject()); 8038 } 8039 } 8040 } 8041 } 8042 } 8043 return new ParceledListSlice<android.content.UriPermission>(result); 8044 } 8045 8046 @Override 8047 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8048 synchronized (this) { 8049 ProcessRecord app = 8050 who != null ? getRecordForAppLocked(who) : null; 8051 if (app == null) return; 8052 8053 Message msg = Message.obtain(); 8054 msg.what = WAIT_FOR_DEBUGGER_MSG; 8055 msg.obj = app; 8056 msg.arg1 = waiting ? 1 : 0; 8057 mHandler.sendMessage(msg); 8058 } 8059 } 8060 8061 @Override 8062 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8063 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8064 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8065 outInfo.availMem = Process.getFreeMemory(); 8066 outInfo.totalMem = Process.getTotalMemory(); 8067 outInfo.threshold = homeAppMem; 8068 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8069 outInfo.hiddenAppThreshold = cachedAppMem; 8070 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8071 ProcessList.SERVICE_ADJ); 8072 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8073 ProcessList.VISIBLE_APP_ADJ); 8074 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8075 ProcessList.FOREGROUND_APP_ADJ); 8076 } 8077 8078 // ========================================================= 8079 // TASK MANAGEMENT 8080 // ========================================================= 8081 8082 @Override 8083 public List<IAppTask> getAppTasks(String callingPackage) { 8084 int callingUid = Binder.getCallingUid(); 8085 long ident = Binder.clearCallingIdentity(); 8086 8087 synchronized(this) { 8088 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8089 try { 8090 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8091 8092 final int N = mRecentTasks.size(); 8093 for (int i = 0; i < N; i++) { 8094 TaskRecord tr = mRecentTasks.get(i); 8095 // Skip tasks that do not match the caller. We don't need to verify 8096 // callingPackage, because we are also limiting to callingUid and know 8097 // that will limit to the correct security sandbox. 8098 if (tr.effectiveUid != callingUid) { 8099 continue; 8100 } 8101 Intent intent = tr.getBaseIntent(); 8102 if (intent == null || 8103 !callingPackage.equals(intent.getComponent().getPackageName())) { 8104 continue; 8105 } 8106 ActivityManager.RecentTaskInfo taskInfo = 8107 createRecentTaskInfoFromTaskRecord(tr); 8108 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8109 list.add(taskImpl); 8110 } 8111 } finally { 8112 Binder.restoreCallingIdentity(ident); 8113 } 8114 return list; 8115 } 8116 } 8117 8118 @Override 8119 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8120 final int callingUid = Binder.getCallingUid(); 8121 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8122 8123 synchronized(this) { 8124 if (localLOGV) Slog.v( 8125 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8126 8127 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8128 callingUid); 8129 8130 // TODO: Improve with MRU list from all ActivityStacks. 8131 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8132 } 8133 8134 return list; 8135 } 8136 8137 /** 8138 * Creates a new RecentTaskInfo from a TaskRecord. 8139 */ 8140 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8141 // Update the task description to reflect any changes in the task stack 8142 tr.updateTaskDescription(); 8143 8144 // Compose the recent task info 8145 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8146 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8147 rti.persistentId = tr.taskId; 8148 rti.baseIntent = new Intent(tr.getBaseIntent()); 8149 rti.origActivity = tr.origActivity; 8150 rti.description = tr.lastDescription; 8151 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8152 rti.userId = tr.userId; 8153 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8154 rti.firstActiveTime = tr.firstActiveTime; 8155 rti.lastActiveTime = tr.lastActiveTime; 8156 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8157 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8158 return rti; 8159 } 8160 8161 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8162 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8163 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8164 if (!allowed) { 8165 if (checkPermission(android.Manifest.permission.GET_TASKS, 8166 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8167 // Temporary compatibility: some existing apps on the system image may 8168 // still be requesting the old permission and not switched to the new 8169 // one; if so, we'll still allow them full access. This means we need 8170 // to see if they are holding the old permission and are a system app. 8171 try { 8172 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8173 allowed = true; 8174 Slog.w(TAG, caller + ": caller " + callingUid 8175 + " is using old GET_TASKS but privileged; allowing"); 8176 } 8177 } catch (RemoteException e) { 8178 } 8179 } 8180 } 8181 if (!allowed) { 8182 Slog.w(TAG, caller + ": caller " + callingUid 8183 + " does not hold GET_TASKS; limiting output"); 8184 } 8185 return allowed; 8186 } 8187 8188 @Override 8189 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8190 final int callingUid = Binder.getCallingUid(); 8191 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8192 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8193 8194 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8195 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8196 synchronized (this) { 8197 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8198 callingUid); 8199 final boolean detailed = checkCallingPermission( 8200 android.Manifest.permission.GET_DETAILED_TASKS) 8201 == PackageManager.PERMISSION_GRANTED; 8202 8203 final int N = mRecentTasks.size(); 8204 ArrayList<ActivityManager.RecentTaskInfo> res 8205 = new ArrayList<ActivityManager.RecentTaskInfo>( 8206 maxNum < N ? maxNum : N); 8207 8208 final Set<Integer> includedUsers; 8209 if (includeProfiles) { 8210 includedUsers = getProfileIdsLocked(userId); 8211 } else { 8212 includedUsers = new HashSet<Integer>(); 8213 } 8214 includedUsers.add(Integer.valueOf(userId)); 8215 8216 for (int i=0; i<N && maxNum > 0; i++) { 8217 TaskRecord tr = mRecentTasks.get(i); 8218 // Only add calling user or related users recent tasks 8219 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8220 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8221 continue; 8222 } 8223 8224 // Return the entry if desired by the caller. We always return 8225 // the first entry, because callers always expect this to be the 8226 // foreground app. We may filter others if the caller has 8227 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8228 // we should exclude the entry. 8229 8230 if (i == 0 8231 || withExcluded 8232 || (tr.intent == null) 8233 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8234 == 0)) { 8235 if (!allowed) { 8236 // If the caller doesn't have the GET_TASKS permission, then only 8237 // allow them to see a small subset of tasks -- their own and home. 8238 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8239 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8240 continue; 8241 } 8242 } 8243 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8244 if (tr.stack != null && tr.stack.isHomeStack()) { 8245 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8246 continue; 8247 } 8248 } 8249 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8250 // Don't include auto remove tasks that are finished or finishing. 8251 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8252 + tr); 8253 continue; 8254 } 8255 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8256 && !tr.isAvailable) { 8257 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8258 continue; 8259 } 8260 8261 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8262 if (!detailed) { 8263 rti.baseIntent.replaceExtras((Bundle)null); 8264 } 8265 8266 res.add(rti); 8267 maxNum--; 8268 } 8269 } 8270 return res; 8271 } 8272 } 8273 8274 TaskRecord recentTaskForIdLocked(int id) { 8275 final int N = mRecentTasks.size(); 8276 for (int i=0; i<N; i++) { 8277 TaskRecord tr = mRecentTasks.get(i); 8278 if (tr.taskId == id) { 8279 return tr; 8280 } 8281 } 8282 return null; 8283 } 8284 8285 @Override 8286 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8287 synchronized (this) { 8288 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8289 "getTaskThumbnail()"); 8290 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8291 if (tr != null) { 8292 return tr.getTaskThumbnailLocked(); 8293 } 8294 } 8295 return null; 8296 } 8297 8298 @Override 8299 public int addAppTask(IBinder activityToken, Intent intent, 8300 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8301 final int callingUid = Binder.getCallingUid(); 8302 final long callingIdent = Binder.clearCallingIdentity(); 8303 8304 try { 8305 synchronized (this) { 8306 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8307 if (r == null) { 8308 throw new IllegalArgumentException("Activity does not exist; token=" 8309 + activityToken); 8310 } 8311 ComponentName comp = intent.getComponent(); 8312 if (comp == null) { 8313 throw new IllegalArgumentException("Intent " + intent 8314 + " must specify explicit component"); 8315 } 8316 if (thumbnail.getWidth() != mThumbnailWidth 8317 || thumbnail.getHeight() != mThumbnailHeight) { 8318 throw new IllegalArgumentException("Bad thumbnail size: got " 8319 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8320 + mThumbnailWidth + "x" + mThumbnailHeight); 8321 } 8322 if (intent.getSelector() != null) { 8323 intent.setSelector(null); 8324 } 8325 if (intent.getSourceBounds() != null) { 8326 intent.setSourceBounds(null); 8327 } 8328 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8329 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8330 // The caller has added this as an auto-remove task... that makes no 8331 // sense, so turn off auto-remove. 8332 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8333 } 8334 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8335 // Must be a new task. 8336 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8337 } 8338 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8339 mLastAddedTaskActivity = null; 8340 } 8341 ActivityInfo ainfo = mLastAddedTaskActivity; 8342 if (ainfo == null) { 8343 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8344 comp, 0, UserHandle.getUserId(callingUid)); 8345 if (ainfo.applicationInfo.uid != callingUid) { 8346 throw new SecurityException( 8347 "Can't add task for another application: target uid=" 8348 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8349 } 8350 } 8351 8352 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8353 intent, description); 8354 8355 int trimIdx = trimRecentsForTaskLocked(task, false); 8356 if (trimIdx >= 0) { 8357 // If this would have caused a trim, then we'll abort because that 8358 // means it would be added at the end of the list but then just removed. 8359 return INVALID_TASK_ID; 8360 } 8361 8362 final int N = mRecentTasks.size(); 8363 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8364 final TaskRecord tr = mRecentTasks.remove(N - 1); 8365 tr.removedFromRecents(); 8366 } 8367 8368 task.inRecents = true; 8369 mRecentTasks.add(task); 8370 r.task.stack.addTask(task, false, false); 8371 8372 task.setLastThumbnail(thumbnail); 8373 task.freeLastThumbnail(); 8374 8375 return task.taskId; 8376 } 8377 } finally { 8378 Binder.restoreCallingIdentity(callingIdent); 8379 } 8380 } 8381 8382 @Override 8383 public Point getAppTaskThumbnailSize() { 8384 synchronized (this) { 8385 return new Point(mThumbnailWidth, mThumbnailHeight); 8386 } 8387 } 8388 8389 @Override 8390 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8391 synchronized (this) { 8392 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8393 if (r != null) { 8394 r.setTaskDescription(td); 8395 r.task.updateTaskDescription(); 8396 } 8397 } 8398 } 8399 8400 @Override 8401 public Bitmap getTaskDescriptionIcon(String filename) { 8402 if (!FileUtils.isValidExtFilename(filename) 8403 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8404 throw new IllegalArgumentException("Bad filename: " + filename); 8405 } 8406 return mTaskPersister.getTaskDescriptionIcon(filename); 8407 } 8408 8409 @Override 8410 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8411 throws RemoteException { 8412 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8413 opts.getCustomInPlaceResId() == 0) { 8414 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8415 "with valid animation"); 8416 } 8417 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8418 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8419 opts.getCustomInPlaceResId()); 8420 mWindowManager.executeAppTransition(); 8421 } 8422 8423 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8424 mRecentTasks.remove(tr); 8425 tr.removedFromRecents(); 8426 ComponentName component = tr.getBaseIntent().getComponent(); 8427 if (component == null) { 8428 Slog.w(TAG, "No component for base intent of task: " + tr); 8429 return; 8430 } 8431 8432 if (!killProcess) { 8433 return; 8434 } 8435 8436 // Determine if the process(es) for this task should be killed. 8437 final String pkg = component.getPackageName(); 8438 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8439 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8440 for (int i = 0; i < pmap.size(); i++) { 8441 8442 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8443 for (int j = 0; j < uids.size(); j++) { 8444 ProcessRecord proc = uids.valueAt(j); 8445 if (proc.userId != tr.userId) { 8446 // Don't kill process for a different user. 8447 continue; 8448 } 8449 if (proc == mHomeProcess) { 8450 // Don't kill the home process along with tasks from the same package. 8451 continue; 8452 } 8453 if (!proc.pkgList.containsKey(pkg)) { 8454 // Don't kill process that is not associated with this task. 8455 continue; 8456 } 8457 8458 for (int k = 0; k < proc.activities.size(); k++) { 8459 TaskRecord otherTask = proc.activities.get(k).task; 8460 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8461 // Don't kill process(es) that has an activity in a different task that is 8462 // also in recents. 8463 return; 8464 } 8465 } 8466 8467 // Add process to kill list. 8468 procsToKill.add(proc); 8469 } 8470 } 8471 8472 // Find any running services associated with this app and stop if needed. 8473 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8474 8475 // Kill the running processes. 8476 for (int i = 0; i < procsToKill.size(); i++) { 8477 ProcessRecord pr = procsToKill.get(i); 8478 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8479 pr.kill("remove task", true); 8480 } else { 8481 pr.waitingToKill = "remove task"; 8482 } 8483 } 8484 } 8485 8486 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8487 // Remove all tasks with activities in the specified package from the list of recent tasks 8488 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8489 TaskRecord tr = mRecentTasks.get(i); 8490 if (tr.userId != userId) continue; 8491 8492 ComponentName cn = tr.intent.getComponent(); 8493 if (cn != null && cn.getPackageName().equals(packageName)) { 8494 // If the package name matches, remove the task. 8495 removeTaskByIdLocked(tr.taskId, true); 8496 } 8497 } 8498 } 8499 8500 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8501 final IPackageManager pm = AppGlobals.getPackageManager(); 8502 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8503 8504 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8505 TaskRecord tr = mRecentTasks.get(i); 8506 if (tr.userId != userId) continue; 8507 8508 ComponentName cn = tr.intent.getComponent(); 8509 if (cn != null && cn.getPackageName().equals(packageName)) { 8510 // Skip if component still exists in the package. 8511 if (componentsKnownToExist.contains(cn)) continue; 8512 8513 try { 8514 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8515 if (info != null) { 8516 componentsKnownToExist.add(cn); 8517 } else { 8518 removeTaskByIdLocked(tr.taskId, false); 8519 } 8520 } catch (RemoteException e) { 8521 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8522 } 8523 } 8524 } 8525 } 8526 8527 /** 8528 * Removes the task with the specified task id. 8529 * 8530 * @param taskId Identifier of the task to be removed. 8531 * @param killProcess Kill any process associated with the task if possible. 8532 * @return Returns true if the given task was found and removed. 8533 */ 8534 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8535 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8536 if (tr != null) { 8537 tr.removeTaskActivitiesLocked(); 8538 cleanUpRemovedTaskLocked(tr, killProcess); 8539 if (tr.isPersistable) { 8540 notifyTaskPersisterLocked(null, true); 8541 } 8542 return true; 8543 } 8544 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8545 return false; 8546 } 8547 8548 @Override 8549 public boolean removeTask(int taskId) { 8550 synchronized (this) { 8551 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8552 "removeTask()"); 8553 long ident = Binder.clearCallingIdentity(); 8554 try { 8555 return removeTaskByIdLocked(taskId, true); 8556 } finally { 8557 Binder.restoreCallingIdentity(ident); 8558 } 8559 } 8560 } 8561 8562 /** 8563 * TODO: Add mController hook 8564 */ 8565 @Override 8566 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8567 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8568 "moveTaskToFront()"); 8569 8570 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8571 synchronized(this) { 8572 moveTaskToFrontLocked(taskId, flags, options); 8573 } 8574 } 8575 8576 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8577 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8578 Binder.getCallingUid(), -1, -1, "Task to front")) { 8579 ActivityOptions.abort(options); 8580 return; 8581 } 8582 final long origId = Binder.clearCallingIdentity(); 8583 try { 8584 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8585 if (task == null) { 8586 Slog.d(TAG, "Could not find task for id: "+ taskId); 8587 return; 8588 } 8589 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8590 mStackSupervisor.showLockTaskToast(); 8591 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8592 return; 8593 } 8594 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8595 if (prev != null && prev.isRecentsActivity()) { 8596 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8597 } 8598 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront"); 8599 } finally { 8600 Binder.restoreCallingIdentity(origId); 8601 } 8602 ActivityOptions.abort(options); 8603 } 8604 8605 @Override 8606 public void moveTaskToBack(int taskId) { 8607 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8608 "moveTaskToBack()"); 8609 8610 synchronized(this) { 8611 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8612 if (tr != null) { 8613 if (tr == mStackSupervisor.mLockTaskModeTask) { 8614 mStackSupervisor.showLockTaskToast(); 8615 return; 8616 } 8617 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8618 ActivityStack stack = tr.stack; 8619 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8620 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8621 Binder.getCallingUid(), -1, -1, "Task to back")) { 8622 return; 8623 } 8624 } 8625 final long origId = Binder.clearCallingIdentity(); 8626 try { 8627 stack.moveTaskToBackLocked(taskId); 8628 } finally { 8629 Binder.restoreCallingIdentity(origId); 8630 } 8631 } 8632 } 8633 } 8634 8635 /** 8636 * Moves an activity, and all of the other activities within the same task, to the bottom 8637 * of the history stack. The activity's order within the task is unchanged. 8638 * 8639 * @param token A reference to the activity we wish to move 8640 * @param nonRoot If false then this only works if the activity is the root 8641 * of a task; if true it will work for any activity in a task. 8642 * @return Returns true if the move completed, false if not. 8643 */ 8644 @Override 8645 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8646 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8647 synchronized(this) { 8648 final long origId = Binder.clearCallingIdentity(); 8649 try { 8650 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8651 if (taskId >= 0) { 8652 if ((mStackSupervisor.mLockTaskModeTask != null) 8653 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8654 mStackSupervisor.showLockTaskToast(); 8655 return false; 8656 } 8657 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 8658 } 8659 } finally { 8660 Binder.restoreCallingIdentity(origId); 8661 } 8662 } 8663 return false; 8664 } 8665 8666 @Override 8667 public void moveTaskBackwards(int task) { 8668 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8669 "moveTaskBackwards()"); 8670 8671 synchronized(this) { 8672 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8673 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8674 return; 8675 } 8676 final long origId = Binder.clearCallingIdentity(); 8677 moveTaskBackwardsLocked(task); 8678 Binder.restoreCallingIdentity(origId); 8679 } 8680 } 8681 8682 private final void moveTaskBackwardsLocked(int task) { 8683 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8684 } 8685 8686 @Override 8687 public IBinder getHomeActivityToken() throws RemoteException { 8688 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8689 "getHomeActivityToken()"); 8690 synchronized (this) { 8691 return mStackSupervisor.getHomeActivityToken(); 8692 } 8693 } 8694 8695 @Override 8696 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8697 IActivityContainerCallback callback) throws RemoteException { 8698 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8699 "createActivityContainer()"); 8700 synchronized (this) { 8701 if (parentActivityToken == null) { 8702 throw new IllegalArgumentException("parent token must not be null"); 8703 } 8704 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8705 if (r == null) { 8706 return null; 8707 } 8708 if (callback == null) { 8709 throw new IllegalArgumentException("callback must not be null"); 8710 } 8711 return mStackSupervisor.createActivityContainer(r, callback); 8712 } 8713 } 8714 8715 @Override 8716 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8717 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8718 "deleteActivityContainer()"); 8719 synchronized (this) { 8720 mStackSupervisor.deleteActivityContainer(container); 8721 } 8722 } 8723 8724 @Override 8725 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 8726 synchronized (this) { 8727 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8728 if (stack != null && stack.mActivityContainer.isAttachedLocked()) { 8729 return stack.mActivityContainer.getDisplayId(); 8730 } 8731 return Display.DEFAULT_DISPLAY; 8732 } 8733 } 8734 8735 @Override 8736 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8737 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8738 "moveTaskToStack()"); 8739 if (stackId == HOME_STACK_ID) { 8740 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8741 new RuntimeException("here").fillInStackTrace()); 8742 } 8743 synchronized (this) { 8744 long ident = Binder.clearCallingIdentity(); 8745 try { 8746 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8747 + stackId + " toTop=" + toTop); 8748 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop); 8749 } finally { 8750 Binder.restoreCallingIdentity(ident); 8751 } 8752 } 8753 } 8754 8755 @Override 8756 public void resizeStack(int stackBoxId, Rect bounds) { 8757 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8758 "resizeStackBox()"); 8759 long ident = Binder.clearCallingIdentity(); 8760 try { 8761 mWindowManager.resizeStack(stackBoxId, bounds); 8762 } finally { 8763 Binder.restoreCallingIdentity(ident); 8764 } 8765 } 8766 8767 @Override 8768 public List<StackInfo> getAllStackInfos() { 8769 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8770 "getAllStackInfos()"); 8771 long ident = Binder.clearCallingIdentity(); 8772 try { 8773 synchronized (this) { 8774 return mStackSupervisor.getAllStackInfosLocked(); 8775 } 8776 } finally { 8777 Binder.restoreCallingIdentity(ident); 8778 } 8779 } 8780 8781 @Override 8782 public StackInfo getStackInfo(int stackId) { 8783 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8784 "getStackInfo()"); 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 return mStackSupervisor.getStackInfoLocked(stackId); 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 } 8794 8795 @Override 8796 public boolean isInHomeStack(int taskId) { 8797 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8798 "getStackInfo()"); 8799 long ident = Binder.clearCallingIdentity(); 8800 try { 8801 synchronized (this) { 8802 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8803 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8804 } 8805 } finally { 8806 Binder.restoreCallingIdentity(ident); 8807 } 8808 } 8809 8810 @Override 8811 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8812 synchronized(this) { 8813 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8814 } 8815 } 8816 8817 private boolean isLockTaskAuthorized(String pkg) { 8818 final DevicePolicyManager dpm = (DevicePolicyManager) 8819 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8820 try { 8821 int uid = mContext.getPackageManager().getPackageUid(pkg, 8822 Binder.getCallingUserHandle().getIdentifier()); 8823 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8824 } catch (NameNotFoundException e) { 8825 return false; 8826 } 8827 } 8828 8829 void startLockTaskMode(TaskRecord task) { 8830 final String pkg; 8831 synchronized (this) { 8832 pkg = task.intent.getComponent().getPackageName(); 8833 } 8834 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8835 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8836 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8837 StatusBarManagerInternal.class); 8838 if (statusBarManager != null) { 8839 statusBarManager.showScreenPinningRequest(); 8840 } 8841 return; 8842 } 8843 long ident = Binder.clearCallingIdentity(); 8844 try { 8845 synchronized (this) { 8846 // Since we lost lock on task, make sure it is still there. 8847 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8848 if (task != null) { 8849 if (!isSystemInitiated 8850 && ((mStackSupervisor.getFocusedStack() == null) 8851 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8852 throw new IllegalArgumentException("Invalid task, not in foreground"); 8853 } 8854 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated, 8855 "startLockTask"); 8856 } 8857 } 8858 } finally { 8859 Binder.restoreCallingIdentity(ident); 8860 } 8861 } 8862 8863 @Override 8864 public void startLockTaskMode(int taskId) { 8865 final TaskRecord task; 8866 long ident = Binder.clearCallingIdentity(); 8867 try { 8868 synchronized (this) { 8869 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8870 } 8871 } finally { 8872 Binder.restoreCallingIdentity(ident); 8873 } 8874 if (task != null) { 8875 startLockTaskMode(task); 8876 } 8877 } 8878 8879 @Override 8880 public void startLockTaskMode(IBinder token) { 8881 final TaskRecord task; 8882 long ident = Binder.clearCallingIdentity(); 8883 try { 8884 synchronized (this) { 8885 final ActivityRecord r = ActivityRecord.forToken(token); 8886 if (r == null) { 8887 return; 8888 } 8889 task = r.task; 8890 } 8891 } finally { 8892 Binder.restoreCallingIdentity(ident); 8893 } 8894 if (task != null) { 8895 startLockTaskMode(task); 8896 } 8897 } 8898 8899 @Override 8900 public void startLockTaskModeOnCurrent() throws RemoteException { 8901 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8902 "startLockTaskModeOnCurrent"); 8903 long ident = Binder.clearCallingIdentity(); 8904 try { 8905 ActivityRecord r = null; 8906 synchronized (this) { 8907 r = mStackSupervisor.topRunningActivityLocked(); 8908 } 8909 startLockTaskMode(r.task); 8910 } finally { 8911 Binder.restoreCallingIdentity(ident); 8912 } 8913 } 8914 8915 @Override 8916 public void stopLockTaskMode() { 8917 // Verify that the user matches the package of the intent for the TaskRecord 8918 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8919 // and stopLockTaskMode. 8920 final int callingUid = Binder.getCallingUid(); 8921 if (callingUid != Process.SYSTEM_UID) { 8922 try { 8923 String pkg = 8924 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8925 int uid = mContext.getPackageManager().getPackageUid(pkg, 8926 Binder.getCallingUserHandle().getIdentifier()); 8927 if (uid != callingUid) { 8928 throw new SecurityException("Invalid uid, expected " + uid); 8929 } 8930 } catch (NameNotFoundException e) { 8931 Log.d(TAG, "stopLockTaskMode " + e); 8932 return; 8933 } 8934 } 8935 long ident = Binder.clearCallingIdentity(); 8936 try { 8937 Log.d(TAG, "stopLockTaskMode"); 8938 // Stop lock task 8939 synchronized (this) { 8940 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask"); 8941 } 8942 } finally { 8943 Binder.restoreCallingIdentity(ident); 8944 } 8945 } 8946 8947 @Override 8948 public void stopLockTaskModeOnCurrent() throws RemoteException { 8949 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8950 "stopLockTaskModeOnCurrent"); 8951 long ident = Binder.clearCallingIdentity(); 8952 try { 8953 stopLockTaskMode(); 8954 } finally { 8955 Binder.restoreCallingIdentity(ident); 8956 } 8957 } 8958 8959 @Override 8960 public boolean isInLockTaskMode() { 8961 synchronized (this) { 8962 return mStackSupervisor.isInLockTaskMode(); 8963 } 8964 } 8965 8966 // ========================================================= 8967 // CONTENT PROVIDERS 8968 // ========================================================= 8969 8970 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8971 List<ProviderInfo> providers = null; 8972 try { 8973 providers = AppGlobals.getPackageManager(). 8974 queryContentProviders(app.processName, app.uid, 8975 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8976 } catch (RemoteException ex) { 8977 } 8978 if (DEBUG_MU) 8979 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8980 int userId = app.userId; 8981 if (providers != null) { 8982 int N = providers.size(); 8983 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8984 for (int i=0; i<N; i++) { 8985 ProviderInfo cpi = 8986 (ProviderInfo)providers.get(i); 8987 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8988 cpi.name, cpi.flags); 8989 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8990 // This is a singleton provider, but a user besides the 8991 // default user is asking to initialize a process it runs 8992 // in... well, no, it doesn't actually run in this process, 8993 // it runs in the process of the default user. Get rid of it. 8994 providers.remove(i); 8995 N--; 8996 i--; 8997 continue; 8998 } 8999 9000 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9001 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 9002 if (cpr == null) { 9003 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 9004 mProviderMap.putProviderByClass(comp, cpr); 9005 } 9006 if (DEBUG_MU) 9007 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 9008 app.pubProviders.put(cpi.name, cpr); 9009 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9010 // Don't add this if it is a platform component that is marked 9011 // to run in multiple processes, because this is actually 9012 // part of the framework so doesn't make sense to track as a 9013 // separate apk in the process. 9014 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9015 mProcessStats); 9016 } 9017 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9018 } 9019 } 9020 return providers; 9021 } 9022 9023 /** 9024 * Check if {@link ProcessRecord} has a possible chance at accessing the 9025 * given {@link ProviderInfo}. Final permission checking is always done 9026 * in {@link ContentProvider}. 9027 */ 9028 private final String checkContentProviderPermissionLocked( 9029 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9030 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9031 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9032 boolean checkedGrants = false; 9033 if (checkUser) { 9034 // Looking for cross-user grants before enforcing the typical cross-users permissions 9035 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9036 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9037 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9038 return null; 9039 } 9040 checkedGrants = true; 9041 } 9042 userId = handleIncomingUser(callingPid, callingUid, userId, 9043 false, ALLOW_NON_FULL, 9044 "checkContentProviderPermissionLocked " + cpi.authority, null); 9045 if (userId != tmpTargetUserId) { 9046 // When we actually went to determine the final targer user ID, this ended 9047 // up different than our initial check for the authority. This is because 9048 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9049 // SELF. So we need to re-check the grants again. 9050 checkedGrants = false; 9051 } 9052 } 9053 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9054 cpi.applicationInfo.uid, cpi.exported) 9055 == PackageManager.PERMISSION_GRANTED) { 9056 return null; 9057 } 9058 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9059 cpi.applicationInfo.uid, cpi.exported) 9060 == PackageManager.PERMISSION_GRANTED) { 9061 return null; 9062 } 9063 9064 PathPermission[] pps = cpi.pathPermissions; 9065 if (pps != null) { 9066 int i = pps.length; 9067 while (i > 0) { 9068 i--; 9069 PathPermission pp = pps[i]; 9070 String pprperm = pp.getReadPermission(); 9071 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9072 cpi.applicationInfo.uid, cpi.exported) 9073 == PackageManager.PERMISSION_GRANTED) { 9074 return null; 9075 } 9076 String ppwperm = pp.getWritePermission(); 9077 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9078 cpi.applicationInfo.uid, cpi.exported) 9079 == PackageManager.PERMISSION_GRANTED) { 9080 return null; 9081 } 9082 } 9083 } 9084 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9085 return null; 9086 } 9087 9088 String msg; 9089 if (!cpi.exported) { 9090 msg = "Permission Denial: opening provider " + cpi.name 9091 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9092 + ", uid=" + callingUid + ") that is not exported from uid " 9093 + cpi.applicationInfo.uid; 9094 } else { 9095 msg = "Permission Denial: opening provider " + cpi.name 9096 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9097 + ", uid=" + callingUid + ") requires " 9098 + cpi.readPermission + " or " + cpi.writePermission; 9099 } 9100 Slog.w(TAG, msg); 9101 return msg; 9102 } 9103 9104 /** 9105 * Returns if the ContentProvider has granted a uri to callingUid 9106 */ 9107 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9108 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9109 if (perms != null) { 9110 for (int i=perms.size()-1; i>=0; i--) { 9111 GrantUri grantUri = perms.keyAt(i); 9112 if (grantUri.sourceUserId == userId || !checkUser) { 9113 if (matchesProvider(grantUri.uri, cpi)) { 9114 return true; 9115 } 9116 } 9117 } 9118 } 9119 return false; 9120 } 9121 9122 /** 9123 * Returns true if the uri authority is one of the authorities specified in the provider. 9124 */ 9125 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9126 String uriAuth = uri.getAuthority(); 9127 String cpiAuth = cpi.authority; 9128 if (cpiAuth.indexOf(';') == -1) { 9129 return cpiAuth.equals(uriAuth); 9130 } 9131 String[] cpiAuths = cpiAuth.split(";"); 9132 int length = cpiAuths.length; 9133 for (int i = 0; i < length; i++) { 9134 if (cpiAuths[i].equals(uriAuth)) return true; 9135 } 9136 return false; 9137 } 9138 9139 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9140 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9141 if (r != null) { 9142 for (int i=0; i<r.conProviders.size(); i++) { 9143 ContentProviderConnection conn = r.conProviders.get(i); 9144 if (conn.provider == cpr) { 9145 if (DEBUG_PROVIDER) Slog.v(TAG, 9146 "Adding provider requested by " 9147 + r.processName + " from process " 9148 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9149 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9150 if (stable) { 9151 conn.stableCount++; 9152 conn.numStableIncs++; 9153 } else { 9154 conn.unstableCount++; 9155 conn.numUnstableIncs++; 9156 } 9157 return conn; 9158 } 9159 } 9160 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9161 if (stable) { 9162 conn.stableCount = 1; 9163 conn.numStableIncs = 1; 9164 } else { 9165 conn.unstableCount = 1; 9166 conn.numUnstableIncs = 1; 9167 } 9168 cpr.connections.add(conn); 9169 r.conProviders.add(conn); 9170 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9171 return conn; 9172 } 9173 cpr.addExternalProcessHandleLocked(externalProcessToken); 9174 return null; 9175 } 9176 9177 boolean decProviderCountLocked(ContentProviderConnection conn, 9178 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9179 if (conn != null) { 9180 cpr = conn.provider; 9181 if (DEBUG_PROVIDER) Slog.v(TAG, 9182 "Removing provider requested by " 9183 + conn.client.processName + " from process " 9184 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9185 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9186 if (stable) { 9187 conn.stableCount--; 9188 } else { 9189 conn.unstableCount--; 9190 } 9191 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9192 cpr.connections.remove(conn); 9193 conn.client.conProviders.remove(conn); 9194 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9195 return true; 9196 } 9197 return false; 9198 } 9199 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9200 return false; 9201 } 9202 9203 private void checkTime(long startTime, String where) { 9204 long now = SystemClock.elapsedRealtime(); 9205 if ((now-startTime) > 1000) { 9206 // If we are taking more than a second, log about it. 9207 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9208 } 9209 } 9210 9211 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9212 String name, IBinder token, boolean stable, int userId) { 9213 ContentProviderRecord cpr; 9214 ContentProviderConnection conn = null; 9215 ProviderInfo cpi = null; 9216 9217 synchronized(this) { 9218 long startTime = SystemClock.elapsedRealtime(); 9219 9220 ProcessRecord r = null; 9221 if (caller != null) { 9222 r = getRecordForAppLocked(caller); 9223 if (r == null) { 9224 throw new SecurityException( 9225 "Unable to find app for caller " + caller 9226 + " (pid=" + Binder.getCallingPid() 9227 + ") when getting content provider " + name); 9228 } 9229 } 9230 9231 boolean checkCrossUser = true; 9232 9233 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9234 9235 // First check if this content provider has been published... 9236 cpr = mProviderMap.getProviderByName(name, userId); 9237 // If that didn't work, check if it exists for user 0 and then 9238 // verify that it's a singleton provider before using it. 9239 if (cpr == null && userId != UserHandle.USER_OWNER) { 9240 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9241 if (cpr != null) { 9242 cpi = cpr.info; 9243 if (isSingleton(cpi.processName, cpi.applicationInfo, 9244 cpi.name, cpi.flags) 9245 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9246 userId = UserHandle.USER_OWNER; 9247 checkCrossUser = false; 9248 } else { 9249 cpr = null; 9250 cpi = null; 9251 } 9252 } 9253 } 9254 9255 boolean providerRunning = cpr != null; 9256 if (providerRunning) { 9257 cpi = cpr.info; 9258 String msg; 9259 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9260 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9261 != null) { 9262 throw new SecurityException(msg); 9263 } 9264 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9265 9266 if (r != null && cpr.canRunHere(r)) { 9267 // This provider has been published or is in the process 9268 // of being published... but it is also allowed to run 9269 // in the caller's process, so don't make a connection 9270 // and just let the caller instantiate its own instance. 9271 ContentProviderHolder holder = cpr.newHolder(null); 9272 // don't give caller the provider object, it needs 9273 // to make its own. 9274 holder.provider = null; 9275 return holder; 9276 } 9277 9278 final long origId = Binder.clearCallingIdentity(); 9279 9280 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9281 9282 // In this case the provider instance already exists, so we can 9283 // return it right away. 9284 conn = incProviderCountLocked(r, cpr, token, stable); 9285 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9286 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9287 // If this is a perceptible app accessing the provider, 9288 // make sure to count it as being accessed and thus 9289 // back up on the LRU list. This is good because 9290 // content providers are often expensive to start. 9291 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9292 updateLruProcessLocked(cpr.proc, false, null); 9293 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9294 } 9295 } 9296 9297 if (cpr.proc != null) { 9298 if (false) { 9299 if (cpr.name.flattenToShortString().equals( 9300 "com.android.providers.calendar/.CalendarProvider2")) { 9301 Slog.v(TAG, "****************** KILLING " 9302 + cpr.name.flattenToShortString()); 9303 Process.killProcess(cpr.proc.pid); 9304 } 9305 } 9306 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9307 boolean success = updateOomAdjLocked(cpr.proc); 9308 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9309 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9310 // NOTE: there is still a race here where a signal could be 9311 // pending on the process even though we managed to update its 9312 // adj level. Not sure what to do about this, but at least 9313 // the race is now smaller. 9314 if (!success) { 9315 // Uh oh... it looks like the provider's process 9316 // has been killed on us. We need to wait for a new 9317 // process to be started, and make sure its death 9318 // doesn't kill our process. 9319 Slog.i(TAG, 9320 "Existing provider " + cpr.name.flattenToShortString() 9321 + " is crashing; detaching " + r); 9322 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9323 checkTime(startTime, "getContentProviderImpl: before appDied"); 9324 appDiedLocked(cpr.proc); 9325 checkTime(startTime, "getContentProviderImpl: after appDied"); 9326 if (!lastRef) { 9327 // This wasn't the last ref our process had on 9328 // the provider... we have now been killed, bail. 9329 return null; 9330 } 9331 providerRunning = false; 9332 conn = null; 9333 } 9334 } 9335 9336 Binder.restoreCallingIdentity(origId); 9337 } 9338 9339 boolean singleton; 9340 if (!providerRunning) { 9341 try { 9342 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9343 cpi = AppGlobals.getPackageManager(). 9344 resolveContentProvider(name, 9345 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9346 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9347 } catch (RemoteException ex) { 9348 } 9349 if (cpi == null) { 9350 return null; 9351 } 9352 // If the provider is a singleton AND 9353 // (it's a call within the same user || the provider is a 9354 // privileged app) 9355 // Then allow connecting to the singleton provider 9356 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9357 cpi.name, cpi.flags) 9358 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9359 if (singleton) { 9360 userId = UserHandle.USER_OWNER; 9361 } 9362 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9363 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9364 9365 String msg; 9366 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9367 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9368 != null) { 9369 throw new SecurityException(msg); 9370 } 9371 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9372 9373 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9374 && !cpi.processName.equals("system")) { 9375 // If this content provider does not run in the system 9376 // process, and the system is not yet ready to run other 9377 // processes, then fail fast instead of hanging. 9378 throw new IllegalArgumentException( 9379 "Attempt to launch content provider before system ready"); 9380 } 9381 9382 // Make sure that the user who owns this provider is running. If not, 9383 // we don't want to allow it to run. 9384 if (!isUserRunningLocked(userId, false)) { 9385 Slog.w(TAG, "Unable to launch app " 9386 + cpi.applicationInfo.packageName + "/" 9387 + cpi.applicationInfo.uid + " for provider " 9388 + name + ": user " + userId + " is stopped"); 9389 return null; 9390 } 9391 9392 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9393 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9394 cpr = mProviderMap.getProviderByClass(comp, userId); 9395 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9396 final boolean firstClass = cpr == null; 9397 if (firstClass) { 9398 final long ident = Binder.clearCallingIdentity(); 9399 try { 9400 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9401 ApplicationInfo ai = 9402 AppGlobals.getPackageManager(). 9403 getApplicationInfo( 9404 cpi.applicationInfo.packageName, 9405 STOCK_PM_FLAGS, userId); 9406 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9407 if (ai == null) { 9408 Slog.w(TAG, "No package info for content provider " 9409 + cpi.name); 9410 return null; 9411 } 9412 ai = getAppInfoForUser(ai, userId); 9413 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9414 } catch (RemoteException ex) { 9415 // pm is in same process, this will never happen. 9416 } finally { 9417 Binder.restoreCallingIdentity(ident); 9418 } 9419 } 9420 9421 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9422 9423 if (r != null && cpr.canRunHere(r)) { 9424 // If this is a multiprocess provider, then just return its 9425 // info and allow the caller to instantiate it. Only do 9426 // this if the provider is the same user as the caller's 9427 // process, or can run as root (so can be in any process). 9428 return cpr.newHolder(null); 9429 } 9430 9431 if (DEBUG_PROVIDER) { 9432 RuntimeException e = new RuntimeException("here"); 9433 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9434 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9435 } 9436 9437 // This is single process, and our app is now connecting to it. 9438 // See if we are already in the process of launching this 9439 // provider. 9440 final int N = mLaunchingProviders.size(); 9441 int i; 9442 for (i=0; i<N; i++) { 9443 if (mLaunchingProviders.get(i) == cpr) { 9444 break; 9445 } 9446 } 9447 9448 // If the provider is not already being launched, then get it 9449 // started. 9450 if (i >= N) { 9451 final long origId = Binder.clearCallingIdentity(); 9452 9453 try { 9454 // Content provider is now in use, its package can't be stopped. 9455 try { 9456 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9457 AppGlobals.getPackageManager().setPackageStoppedState( 9458 cpr.appInfo.packageName, false, userId); 9459 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9460 } catch (RemoteException e) { 9461 } catch (IllegalArgumentException e) { 9462 Slog.w(TAG, "Failed trying to unstop package " 9463 + cpr.appInfo.packageName + ": " + e); 9464 } 9465 9466 // Use existing process if already started 9467 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9468 ProcessRecord proc = getProcessRecordLocked( 9469 cpi.processName, cpr.appInfo.uid, false); 9470 if (proc != null && proc.thread != null) { 9471 if (DEBUG_PROVIDER) { 9472 Slog.d(TAG, "Installing in existing process " + proc); 9473 } 9474 if (!proc.pubProviders.containsKey(cpi.name)) { 9475 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9476 proc.pubProviders.put(cpi.name, cpr); 9477 try { 9478 proc.thread.scheduleInstallProvider(cpi); 9479 } catch (RemoteException e) { 9480 } 9481 } 9482 } else { 9483 checkTime(startTime, "getContentProviderImpl: before start process"); 9484 proc = startProcessLocked(cpi.processName, 9485 cpr.appInfo, false, 0, "content provider", 9486 new ComponentName(cpi.applicationInfo.packageName, 9487 cpi.name), false, false, false); 9488 checkTime(startTime, "getContentProviderImpl: after start process"); 9489 if (proc == null) { 9490 Slog.w(TAG, "Unable to launch app " 9491 + cpi.applicationInfo.packageName + "/" 9492 + cpi.applicationInfo.uid + " for provider " 9493 + name + ": process is bad"); 9494 return null; 9495 } 9496 } 9497 cpr.launchingApp = proc; 9498 mLaunchingProviders.add(cpr); 9499 } finally { 9500 Binder.restoreCallingIdentity(origId); 9501 } 9502 } 9503 9504 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9505 9506 // Make sure the provider is published (the same provider class 9507 // may be published under multiple names). 9508 if (firstClass) { 9509 mProviderMap.putProviderByClass(comp, cpr); 9510 } 9511 9512 mProviderMap.putProviderByName(name, cpr); 9513 conn = incProviderCountLocked(r, cpr, token, stable); 9514 if (conn != null) { 9515 conn.waiting = true; 9516 } 9517 } 9518 checkTime(startTime, "getContentProviderImpl: done!"); 9519 } 9520 9521 // Wait for the provider to be published... 9522 synchronized (cpr) { 9523 while (cpr.provider == null) { 9524 if (cpr.launchingApp == null) { 9525 Slog.w(TAG, "Unable to launch app " 9526 + cpi.applicationInfo.packageName + "/" 9527 + cpi.applicationInfo.uid + " for provider " 9528 + name + ": launching app became null"); 9529 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9530 UserHandle.getUserId(cpi.applicationInfo.uid), 9531 cpi.applicationInfo.packageName, 9532 cpi.applicationInfo.uid, name); 9533 return null; 9534 } 9535 try { 9536 if (DEBUG_MU) { 9537 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9538 + cpr.launchingApp); 9539 } 9540 if (conn != null) { 9541 conn.waiting = true; 9542 } 9543 cpr.wait(); 9544 } catch (InterruptedException ex) { 9545 } finally { 9546 if (conn != null) { 9547 conn.waiting = false; 9548 } 9549 } 9550 } 9551 } 9552 return cpr != null ? cpr.newHolder(conn) : null; 9553 } 9554 9555 @Override 9556 public final ContentProviderHolder getContentProvider( 9557 IApplicationThread caller, String name, int userId, boolean stable) { 9558 enforceNotIsolatedCaller("getContentProvider"); 9559 if (caller == null) { 9560 String msg = "null IApplicationThread when getting content provider " 9561 + name; 9562 Slog.w(TAG, msg); 9563 throw new SecurityException(msg); 9564 } 9565 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9566 // with cross-user grant. 9567 return getContentProviderImpl(caller, name, null, stable, userId); 9568 } 9569 9570 public ContentProviderHolder getContentProviderExternal( 9571 String name, int userId, IBinder token) { 9572 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9573 "Do not have permission in call getContentProviderExternal()"); 9574 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9575 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9576 return getContentProviderExternalUnchecked(name, token, userId); 9577 } 9578 9579 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9580 IBinder token, int userId) { 9581 return getContentProviderImpl(null, name, token, true, userId); 9582 } 9583 9584 /** 9585 * Drop a content provider from a ProcessRecord's bookkeeping 9586 */ 9587 public void removeContentProvider(IBinder connection, boolean stable) { 9588 enforceNotIsolatedCaller("removeContentProvider"); 9589 long ident = Binder.clearCallingIdentity(); 9590 try { 9591 synchronized (this) { 9592 ContentProviderConnection conn; 9593 try { 9594 conn = (ContentProviderConnection)connection; 9595 } catch (ClassCastException e) { 9596 String msg ="removeContentProvider: " + connection 9597 + " not a ContentProviderConnection"; 9598 Slog.w(TAG, msg); 9599 throw new IllegalArgumentException(msg); 9600 } 9601 if (conn == null) { 9602 throw new NullPointerException("connection is null"); 9603 } 9604 if (decProviderCountLocked(conn, null, null, stable)) { 9605 updateOomAdjLocked(); 9606 } 9607 } 9608 } finally { 9609 Binder.restoreCallingIdentity(ident); 9610 } 9611 } 9612 9613 public void removeContentProviderExternal(String name, IBinder token) { 9614 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9615 "Do not have permission in call removeContentProviderExternal()"); 9616 int userId = UserHandle.getCallingUserId(); 9617 long ident = Binder.clearCallingIdentity(); 9618 try { 9619 removeContentProviderExternalUnchecked(name, token, userId); 9620 } finally { 9621 Binder.restoreCallingIdentity(ident); 9622 } 9623 } 9624 9625 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9626 synchronized (this) { 9627 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9628 if(cpr == null) { 9629 //remove from mProvidersByClass 9630 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9631 return; 9632 } 9633 9634 //update content provider record entry info 9635 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9636 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9637 if (localCpr.hasExternalProcessHandles()) { 9638 if (localCpr.removeExternalProcessHandleLocked(token)) { 9639 updateOomAdjLocked(); 9640 } else { 9641 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9642 + " with no external reference for token: " 9643 + token + "."); 9644 } 9645 } else { 9646 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9647 + " with no external references."); 9648 } 9649 } 9650 } 9651 9652 public final void publishContentProviders(IApplicationThread caller, 9653 List<ContentProviderHolder> providers) { 9654 if (providers == null) { 9655 return; 9656 } 9657 9658 enforceNotIsolatedCaller("publishContentProviders"); 9659 synchronized (this) { 9660 final ProcessRecord r = getRecordForAppLocked(caller); 9661 if (DEBUG_MU) 9662 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9663 if (r == null) { 9664 throw new SecurityException( 9665 "Unable to find app for caller " + caller 9666 + " (pid=" + Binder.getCallingPid() 9667 + ") when publishing content providers"); 9668 } 9669 9670 final long origId = Binder.clearCallingIdentity(); 9671 9672 final int N = providers.size(); 9673 for (int i=0; i<N; i++) { 9674 ContentProviderHolder src = providers.get(i); 9675 if (src == null || src.info == null || src.provider == null) { 9676 continue; 9677 } 9678 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9679 if (DEBUG_MU) 9680 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9681 if (dst != null) { 9682 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9683 mProviderMap.putProviderByClass(comp, dst); 9684 String names[] = dst.info.authority.split(";"); 9685 for (int j = 0; j < names.length; j++) { 9686 mProviderMap.putProviderByName(names[j], dst); 9687 } 9688 9689 int NL = mLaunchingProviders.size(); 9690 int j; 9691 for (j=0; j<NL; j++) { 9692 if (mLaunchingProviders.get(j) == dst) { 9693 mLaunchingProviders.remove(j); 9694 j--; 9695 NL--; 9696 } 9697 } 9698 synchronized (dst) { 9699 dst.provider = src.provider; 9700 dst.proc = r; 9701 dst.notifyAll(); 9702 } 9703 updateOomAdjLocked(r); 9704 } 9705 } 9706 9707 Binder.restoreCallingIdentity(origId); 9708 } 9709 } 9710 9711 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9712 ContentProviderConnection conn; 9713 try { 9714 conn = (ContentProviderConnection)connection; 9715 } catch (ClassCastException e) { 9716 String msg ="refContentProvider: " + connection 9717 + " not a ContentProviderConnection"; 9718 Slog.w(TAG, msg); 9719 throw new IllegalArgumentException(msg); 9720 } 9721 if (conn == null) { 9722 throw new NullPointerException("connection is null"); 9723 } 9724 9725 synchronized (this) { 9726 if (stable > 0) { 9727 conn.numStableIncs += stable; 9728 } 9729 stable = conn.stableCount + stable; 9730 if (stable < 0) { 9731 throw new IllegalStateException("stableCount < 0: " + stable); 9732 } 9733 9734 if (unstable > 0) { 9735 conn.numUnstableIncs += unstable; 9736 } 9737 unstable = conn.unstableCount + unstable; 9738 if (unstable < 0) { 9739 throw new IllegalStateException("unstableCount < 0: " + unstable); 9740 } 9741 9742 if ((stable+unstable) <= 0) { 9743 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9744 + stable + " unstable=" + unstable); 9745 } 9746 conn.stableCount = stable; 9747 conn.unstableCount = unstable; 9748 return !conn.dead; 9749 } 9750 } 9751 9752 public void unstableProviderDied(IBinder connection) { 9753 ContentProviderConnection conn; 9754 try { 9755 conn = (ContentProviderConnection)connection; 9756 } catch (ClassCastException e) { 9757 String msg ="refContentProvider: " + connection 9758 + " not a ContentProviderConnection"; 9759 Slog.w(TAG, msg); 9760 throw new IllegalArgumentException(msg); 9761 } 9762 if (conn == null) { 9763 throw new NullPointerException("connection is null"); 9764 } 9765 9766 // Safely retrieve the content provider associated with the connection. 9767 IContentProvider provider; 9768 synchronized (this) { 9769 provider = conn.provider.provider; 9770 } 9771 9772 if (provider == null) { 9773 // Um, yeah, we're way ahead of you. 9774 return; 9775 } 9776 9777 // Make sure the caller is being honest with us. 9778 if (provider.asBinder().pingBinder()) { 9779 // Er, no, still looks good to us. 9780 synchronized (this) { 9781 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9782 + " says " + conn + " died, but we don't agree"); 9783 return; 9784 } 9785 } 9786 9787 // Well look at that! It's dead! 9788 synchronized (this) { 9789 if (conn.provider.provider != provider) { 9790 // But something changed... good enough. 9791 return; 9792 } 9793 9794 ProcessRecord proc = conn.provider.proc; 9795 if (proc == null || proc.thread == null) { 9796 // Seems like the process is already cleaned up. 9797 return; 9798 } 9799 9800 // As far as we're concerned, this is just like receiving a 9801 // death notification... just a bit prematurely. 9802 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9803 + ") early provider death"); 9804 final long ident = Binder.clearCallingIdentity(); 9805 try { 9806 appDiedLocked(proc); 9807 } finally { 9808 Binder.restoreCallingIdentity(ident); 9809 } 9810 } 9811 } 9812 9813 @Override 9814 public void appNotRespondingViaProvider(IBinder connection) { 9815 enforceCallingPermission( 9816 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9817 9818 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9819 if (conn == null) { 9820 Slog.w(TAG, "ContentProviderConnection is null"); 9821 return; 9822 } 9823 9824 final ProcessRecord host = conn.provider.proc; 9825 if (host == null) { 9826 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9827 return; 9828 } 9829 9830 final long token = Binder.clearCallingIdentity(); 9831 try { 9832 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9833 } finally { 9834 Binder.restoreCallingIdentity(token); 9835 } 9836 } 9837 9838 public final void installSystemProviders() { 9839 List<ProviderInfo> providers; 9840 synchronized (this) { 9841 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9842 providers = generateApplicationProvidersLocked(app); 9843 if (providers != null) { 9844 for (int i=providers.size()-1; i>=0; i--) { 9845 ProviderInfo pi = (ProviderInfo)providers.get(i); 9846 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9847 Slog.w(TAG, "Not installing system proc provider " + pi.name 9848 + ": not system .apk"); 9849 providers.remove(i); 9850 } 9851 } 9852 } 9853 } 9854 if (providers != null) { 9855 mSystemThread.installSystemProviders(providers); 9856 } 9857 9858 mCoreSettingsObserver = new CoreSettingsObserver(this); 9859 9860 //mUsageStatsService.monitorPackages(); 9861 } 9862 9863 /** 9864 * Allows apps to retrieve the MIME type of a URI. 9865 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9866 * users, then it does not need permission to access the ContentProvider. 9867 * Either, it needs cross-user uri grants. 9868 * 9869 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9870 * 9871 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9872 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9873 */ 9874 public String getProviderMimeType(Uri uri, int userId) { 9875 enforceNotIsolatedCaller("getProviderMimeType"); 9876 final String name = uri.getAuthority(); 9877 int callingUid = Binder.getCallingUid(); 9878 int callingPid = Binder.getCallingPid(); 9879 long ident = 0; 9880 boolean clearedIdentity = false; 9881 userId = unsafeConvertIncomingUser(userId); 9882 if (canClearIdentity(callingPid, callingUid, userId)) { 9883 clearedIdentity = true; 9884 ident = Binder.clearCallingIdentity(); 9885 } 9886 ContentProviderHolder holder = null; 9887 try { 9888 holder = getContentProviderExternalUnchecked(name, null, userId); 9889 if (holder != null) { 9890 return holder.provider.getType(uri); 9891 } 9892 } catch (RemoteException e) { 9893 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9894 return null; 9895 } finally { 9896 // We need to clear the identity to call removeContentProviderExternalUnchecked 9897 if (!clearedIdentity) { 9898 ident = Binder.clearCallingIdentity(); 9899 } 9900 try { 9901 if (holder != null) { 9902 removeContentProviderExternalUnchecked(name, null, userId); 9903 } 9904 } finally { 9905 Binder.restoreCallingIdentity(ident); 9906 } 9907 } 9908 9909 return null; 9910 } 9911 9912 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9913 if (UserHandle.getUserId(callingUid) == userId) { 9914 return true; 9915 } 9916 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9917 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9918 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9919 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9920 return true; 9921 } 9922 return false; 9923 } 9924 9925 // ========================================================= 9926 // GLOBAL MANAGEMENT 9927 // ========================================================= 9928 9929 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9930 boolean isolated, int isolatedUid) { 9931 String proc = customProcess != null ? customProcess : info.processName; 9932 BatteryStatsImpl.Uid.Proc ps = null; 9933 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9934 int uid = info.uid; 9935 if (isolated) { 9936 if (isolatedUid == 0) { 9937 int userId = UserHandle.getUserId(uid); 9938 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9939 while (true) { 9940 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9941 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9942 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9943 } 9944 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9945 mNextIsolatedProcessUid++; 9946 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9947 // No process for this uid, use it. 9948 break; 9949 } 9950 stepsLeft--; 9951 if (stepsLeft <= 0) { 9952 return null; 9953 } 9954 } 9955 } else { 9956 // Special case for startIsolatedProcess (internal only), where 9957 // the uid of the isolated process is specified by the caller. 9958 uid = isolatedUid; 9959 } 9960 } 9961 return new ProcessRecord(stats, info, proc, uid); 9962 } 9963 9964 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9965 String abiOverride) { 9966 ProcessRecord app; 9967 if (!isolated) { 9968 app = getProcessRecordLocked(info.processName, info.uid, true); 9969 } else { 9970 app = null; 9971 } 9972 9973 if (app == null) { 9974 app = newProcessRecordLocked(info, null, isolated, 0); 9975 mProcessNames.put(info.processName, app.uid, app); 9976 if (isolated) { 9977 mIsolatedProcesses.put(app.uid, app); 9978 } 9979 updateLruProcessLocked(app, false, null); 9980 updateOomAdjLocked(); 9981 } 9982 9983 // This package really, really can not be stopped. 9984 try { 9985 AppGlobals.getPackageManager().setPackageStoppedState( 9986 info.packageName, false, UserHandle.getUserId(app.uid)); 9987 } catch (RemoteException e) { 9988 } catch (IllegalArgumentException e) { 9989 Slog.w(TAG, "Failed trying to unstop package " 9990 + info.packageName + ": " + e); 9991 } 9992 9993 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9994 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9995 app.persistent = true; 9996 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9997 } 9998 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9999 mPersistentStartingProcesses.add(app); 10000 startProcessLocked(app, "added application", app.processName, abiOverride, 10001 null /* entryPoint */, null /* entryPointArgs */); 10002 } 10003 10004 return app; 10005 } 10006 10007 public void unhandledBack() { 10008 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 10009 "unhandledBack()"); 10010 10011 synchronized(this) { 10012 final long origId = Binder.clearCallingIdentity(); 10013 try { 10014 getFocusedStack().unhandledBackLocked(); 10015 } finally { 10016 Binder.restoreCallingIdentity(origId); 10017 } 10018 } 10019 } 10020 10021 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10022 enforceNotIsolatedCaller("openContentUri"); 10023 final int userId = UserHandle.getCallingUserId(); 10024 String name = uri.getAuthority(); 10025 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10026 ParcelFileDescriptor pfd = null; 10027 if (cph != null) { 10028 // We record the binder invoker's uid in thread-local storage before 10029 // going to the content provider to open the file. Later, in the code 10030 // that handles all permissions checks, we look for this uid and use 10031 // that rather than the Activity Manager's own uid. The effect is that 10032 // we do the check against the caller's permissions even though it looks 10033 // to the content provider like the Activity Manager itself is making 10034 // the request. 10035 Binder token = new Binder(); 10036 sCallerIdentity.set(new Identity( 10037 token, Binder.getCallingPid(), Binder.getCallingUid())); 10038 try { 10039 pfd = cph.provider.openFile(null, uri, "r", null, token); 10040 } catch (FileNotFoundException e) { 10041 // do nothing; pfd will be returned null 10042 } finally { 10043 // Ensure that whatever happens, we clean up the identity state 10044 sCallerIdentity.remove(); 10045 // Ensure we're done with the provider. 10046 removeContentProviderExternalUnchecked(name, null, userId); 10047 } 10048 } else { 10049 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10050 } 10051 return pfd; 10052 } 10053 10054 // Actually is sleeping or shutting down or whatever else in the future 10055 // is an inactive state. 10056 public boolean isSleepingOrShuttingDown() { 10057 return isSleeping() || mShuttingDown; 10058 } 10059 10060 public boolean isSleeping() { 10061 return mSleeping; 10062 } 10063 10064 void onWakefulnessChanged(int wakefulness) { 10065 synchronized(this) { 10066 mWakefulness = wakefulness; 10067 updateSleepIfNeededLocked(); 10068 } 10069 } 10070 10071 void finishRunningVoiceLocked() { 10072 if (mRunningVoice) { 10073 mRunningVoice = false; 10074 updateSleepIfNeededLocked(); 10075 } 10076 } 10077 10078 void updateSleepIfNeededLocked() { 10079 if (mSleeping && !shouldSleepLocked()) { 10080 mSleeping = false; 10081 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10082 } else if (!mSleeping && shouldSleepLocked()) { 10083 mSleeping = true; 10084 mStackSupervisor.goingToSleepLocked(); 10085 10086 // Initialize the wake times of all processes. 10087 checkExcessivePowerUsageLocked(false); 10088 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10089 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10090 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10091 } 10092 } 10093 10094 private boolean shouldSleepLocked() { 10095 // Resume applications while running a voice interactor. 10096 if (mRunningVoice) { 10097 return false; 10098 } 10099 10100 switch (mWakefulness) { 10101 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10102 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10103 // If we're interactive but applications are already paused then defer 10104 // resuming them until the lock screen is hidden. 10105 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10106 case PowerManagerInternal.WAKEFULNESS_DOZING: 10107 // If we're dozing then pause applications whenever the lock screen is shown. 10108 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10109 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10110 default: 10111 // If we're asleep then pause applications unconditionally. 10112 return true; 10113 } 10114 } 10115 10116 /** Pokes the task persister. */ 10117 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10118 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10119 // Never persist the home stack. 10120 return; 10121 } 10122 mTaskPersister.wakeup(task, flush); 10123 } 10124 10125 /** Notifies all listeners when the task stack has changed. */ 10126 void notifyTaskStackChangedLocked() { 10127 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10128 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10129 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10130 } 10131 10132 @Override 10133 public void notifyCleartextNetwork(int uid, byte[] firstPacket) { 10134 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); 10135 } 10136 10137 @Override 10138 public boolean shutdown(int timeout) { 10139 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10140 != PackageManager.PERMISSION_GRANTED) { 10141 throw new SecurityException("Requires permission " 10142 + android.Manifest.permission.SHUTDOWN); 10143 } 10144 10145 boolean timedout = false; 10146 10147 synchronized(this) { 10148 mShuttingDown = true; 10149 updateEventDispatchingLocked(); 10150 timedout = mStackSupervisor.shutdownLocked(timeout); 10151 } 10152 10153 mAppOpsService.shutdown(); 10154 if (mUsageStatsService != null) { 10155 mUsageStatsService.prepareShutdown(); 10156 } 10157 mBatteryStatsService.shutdown(); 10158 synchronized (this) { 10159 mProcessStats.shutdownLocked(); 10160 notifyTaskPersisterLocked(null, true); 10161 } 10162 10163 return timedout; 10164 } 10165 10166 public final void activitySlept(IBinder token) { 10167 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10168 10169 final long origId = Binder.clearCallingIdentity(); 10170 10171 synchronized (this) { 10172 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10173 if (r != null) { 10174 mStackSupervisor.activitySleptLocked(r); 10175 } 10176 } 10177 10178 Binder.restoreCallingIdentity(origId); 10179 } 10180 10181 private String lockScreenShownToString() { 10182 switch (mLockScreenShown) { 10183 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10184 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10185 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10186 default: return "Unknown=" + mLockScreenShown; 10187 } 10188 } 10189 10190 void logLockScreen(String msg) { 10191 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10192 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10193 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10194 + " mSleeping=" + mSleeping); 10195 } 10196 10197 void startRunningVoiceLocked() { 10198 if (!mRunningVoice) { 10199 mRunningVoice = true; 10200 updateSleepIfNeededLocked(); 10201 } 10202 } 10203 10204 private void updateEventDispatchingLocked() { 10205 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10206 } 10207 10208 public void setLockScreenShown(boolean shown) { 10209 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10210 != PackageManager.PERMISSION_GRANTED) { 10211 throw new SecurityException("Requires permission " 10212 + android.Manifest.permission.DEVICE_POWER); 10213 } 10214 10215 synchronized(this) { 10216 long ident = Binder.clearCallingIdentity(); 10217 try { 10218 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10219 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10220 updateSleepIfNeededLocked(); 10221 } finally { 10222 Binder.restoreCallingIdentity(ident); 10223 } 10224 } 10225 } 10226 10227 @Override 10228 public void stopAppSwitches() { 10229 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10230 != PackageManager.PERMISSION_GRANTED) { 10231 throw new SecurityException("Requires permission " 10232 + android.Manifest.permission.STOP_APP_SWITCHES); 10233 } 10234 10235 synchronized(this) { 10236 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10237 + APP_SWITCH_DELAY_TIME; 10238 mDidAppSwitch = false; 10239 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10240 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10241 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10242 } 10243 } 10244 10245 public void resumeAppSwitches() { 10246 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10247 != PackageManager.PERMISSION_GRANTED) { 10248 throw new SecurityException("Requires permission " 10249 + android.Manifest.permission.STOP_APP_SWITCHES); 10250 } 10251 10252 synchronized(this) { 10253 // Note that we don't execute any pending app switches... we will 10254 // let those wait until either the timeout, or the next start 10255 // activity request. 10256 mAppSwitchesAllowedTime = 0; 10257 } 10258 } 10259 10260 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10261 int callingPid, int callingUid, String name) { 10262 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10263 return true; 10264 } 10265 10266 int perm = checkComponentPermission( 10267 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10268 sourceUid, -1, true); 10269 if (perm == PackageManager.PERMISSION_GRANTED) { 10270 return true; 10271 } 10272 10273 // If the actual IPC caller is different from the logical source, then 10274 // also see if they are allowed to control app switches. 10275 if (callingUid != -1 && callingUid != sourceUid) { 10276 perm = checkComponentPermission( 10277 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10278 callingUid, -1, true); 10279 if (perm == PackageManager.PERMISSION_GRANTED) { 10280 return true; 10281 } 10282 } 10283 10284 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10285 return false; 10286 } 10287 10288 public void setDebugApp(String packageName, boolean waitForDebugger, 10289 boolean persistent) { 10290 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10291 "setDebugApp()"); 10292 10293 long ident = Binder.clearCallingIdentity(); 10294 try { 10295 // Note that this is not really thread safe if there are multiple 10296 // callers into it at the same time, but that's not a situation we 10297 // care about. 10298 if (persistent) { 10299 final ContentResolver resolver = mContext.getContentResolver(); 10300 Settings.Global.putString( 10301 resolver, Settings.Global.DEBUG_APP, 10302 packageName); 10303 Settings.Global.putInt( 10304 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10305 waitForDebugger ? 1 : 0); 10306 } 10307 10308 synchronized (this) { 10309 if (!persistent) { 10310 mOrigDebugApp = mDebugApp; 10311 mOrigWaitForDebugger = mWaitForDebugger; 10312 } 10313 mDebugApp = packageName; 10314 mWaitForDebugger = waitForDebugger; 10315 mDebugTransient = !persistent; 10316 if (packageName != null) { 10317 forceStopPackageLocked(packageName, -1, false, false, true, true, 10318 false, UserHandle.USER_ALL, "set debug app"); 10319 } 10320 } 10321 } finally { 10322 Binder.restoreCallingIdentity(ident); 10323 } 10324 } 10325 10326 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10327 synchronized (this) { 10328 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10329 if (!isDebuggable) { 10330 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10331 throw new SecurityException("Process not debuggable: " + app.packageName); 10332 } 10333 } 10334 10335 mOpenGlTraceApp = processName; 10336 } 10337 } 10338 10339 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10340 synchronized (this) { 10341 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10342 if (!isDebuggable) { 10343 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10344 throw new SecurityException("Process not debuggable: " + app.packageName); 10345 } 10346 } 10347 mProfileApp = processName; 10348 mProfileFile = profilerInfo.profileFile; 10349 if (mProfileFd != null) { 10350 try { 10351 mProfileFd.close(); 10352 } catch (IOException e) { 10353 } 10354 mProfileFd = null; 10355 } 10356 mProfileFd = profilerInfo.profileFd; 10357 mSamplingInterval = profilerInfo.samplingInterval; 10358 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10359 mProfileType = 0; 10360 } 10361 } 10362 10363 @Override 10364 public void setAlwaysFinish(boolean enabled) { 10365 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10366 "setAlwaysFinish()"); 10367 10368 Settings.Global.putInt( 10369 mContext.getContentResolver(), 10370 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10371 10372 synchronized (this) { 10373 mAlwaysFinishActivities = enabled; 10374 } 10375 } 10376 10377 @Override 10378 public void setActivityController(IActivityController controller) { 10379 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10380 "setActivityController()"); 10381 synchronized (this) { 10382 mController = controller; 10383 Watchdog.getInstance().setActivityController(controller); 10384 } 10385 } 10386 10387 @Override 10388 public void setUserIsMonkey(boolean userIsMonkey) { 10389 synchronized (this) { 10390 synchronized (mPidsSelfLocked) { 10391 final int callingPid = Binder.getCallingPid(); 10392 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10393 if (precessRecord == null) { 10394 throw new SecurityException("Unknown process: " + callingPid); 10395 } 10396 if (precessRecord.instrumentationUiAutomationConnection == null) { 10397 throw new SecurityException("Only an instrumentation process " 10398 + "with a UiAutomation can call setUserIsMonkey"); 10399 } 10400 } 10401 mUserIsMonkey = userIsMonkey; 10402 } 10403 } 10404 10405 @Override 10406 public boolean isUserAMonkey() { 10407 synchronized (this) { 10408 // If there is a controller also implies the user is a monkey. 10409 return (mUserIsMonkey || mController != null); 10410 } 10411 } 10412 10413 public void requestBugReport() { 10414 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10415 SystemProperties.set("ctl.start", "bugreport"); 10416 } 10417 10418 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10419 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10420 } 10421 10422 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10423 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10424 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10425 } 10426 return KEY_DISPATCHING_TIMEOUT; 10427 } 10428 10429 @Override 10430 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10431 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10432 != PackageManager.PERMISSION_GRANTED) { 10433 throw new SecurityException("Requires permission " 10434 + android.Manifest.permission.FILTER_EVENTS); 10435 } 10436 ProcessRecord proc; 10437 long timeout; 10438 synchronized (this) { 10439 synchronized (mPidsSelfLocked) { 10440 proc = mPidsSelfLocked.get(pid); 10441 } 10442 timeout = getInputDispatchingTimeoutLocked(proc); 10443 } 10444 10445 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10446 return -1; 10447 } 10448 10449 return timeout; 10450 } 10451 10452 /** 10453 * Handle input dispatching timeouts. 10454 * Returns whether input dispatching should be aborted or not. 10455 */ 10456 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10457 final ActivityRecord activity, final ActivityRecord parent, 10458 final boolean aboveSystem, String reason) { 10459 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10460 != PackageManager.PERMISSION_GRANTED) { 10461 throw new SecurityException("Requires permission " 10462 + android.Manifest.permission.FILTER_EVENTS); 10463 } 10464 10465 final String annotation; 10466 if (reason == null) { 10467 annotation = "Input dispatching timed out"; 10468 } else { 10469 annotation = "Input dispatching timed out (" + reason + ")"; 10470 } 10471 10472 if (proc != null) { 10473 synchronized (this) { 10474 if (proc.debugging) { 10475 return false; 10476 } 10477 10478 if (mDidDexOpt) { 10479 // Give more time since we were dexopting. 10480 mDidDexOpt = false; 10481 return false; 10482 } 10483 10484 if (proc.instrumentationClass != null) { 10485 Bundle info = new Bundle(); 10486 info.putString("shortMsg", "keyDispatchingTimedOut"); 10487 info.putString("longMsg", annotation); 10488 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10489 return true; 10490 } 10491 } 10492 mHandler.post(new Runnable() { 10493 @Override 10494 public void run() { 10495 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10496 } 10497 }); 10498 } 10499 10500 return true; 10501 } 10502 10503 public Bundle getAssistContextExtras(int requestType) { 10504 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10505 UserHandle.getCallingUserId()); 10506 if (pae == null) { 10507 return null; 10508 } 10509 synchronized (pae) { 10510 while (!pae.haveResult) { 10511 try { 10512 pae.wait(); 10513 } catch (InterruptedException e) { 10514 } 10515 } 10516 if (pae.result != null) { 10517 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10518 } 10519 } 10520 synchronized (this) { 10521 mPendingAssistExtras.remove(pae); 10522 mHandler.removeCallbacks(pae); 10523 } 10524 return pae.extras; 10525 } 10526 10527 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10528 int userHandle) { 10529 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10530 "getAssistContextExtras()"); 10531 PendingAssistExtras pae; 10532 Bundle extras = new Bundle(); 10533 synchronized (this) { 10534 ActivityRecord activity = getFocusedStack().mResumedActivity; 10535 if (activity == null) { 10536 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10537 return null; 10538 } 10539 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10540 if (activity.app == null || activity.app.thread == null) { 10541 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10542 return null; 10543 } 10544 if (activity.app.pid == Binder.getCallingPid()) { 10545 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10546 return null; 10547 } 10548 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10549 try { 10550 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10551 requestType); 10552 mPendingAssistExtras.add(pae); 10553 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10554 } catch (RemoteException e) { 10555 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10556 return null; 10557 } 10558 return pae; 10559 } 10560 } 10561 10562 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10563 PendingAssistExtras pae = (PendingAssistExtras)token; 10564 synchronized (pae) { 10565 pae.result = extras; 10566 pae.haveResult = true; 10567 pae.notifyAll(); 10568 if (pae.intent == null) { 10569 // Caller is just waiting for the result. 10570 return; 10571 } 10572 } 10573 10574 // We are now ready to launch the assist activity. 10575 synchronized (this) { 10576 boolean exists = mPendingAssistExtras.remove(pae); 10577 mHandler.removeCallbacks(pae); 10578 if (!exists) { 10579 // Timed out. 10580 return; 10581 } 10582 } 10583 pae.intent.replaceExtras(extras); 10584 if (pae.hint != null) { 10585 pae.intent.putExtra(pae.hint, true); 10586 } 10587 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10588 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10589 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10590 closeSystemDialogs("assist"); 10591 try { 10592 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10593 } catch (ActivityNotFoundException e) { 10594 Slog.w(TAG, "No activity to handle assist action.", e); 10595 } 10596 } 10597 10598 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10599 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10600 } 10601 10602 public void registerProcessObserver(IProcessObserver observer) { 10603 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10604 "registerProcessObserver()"); 10605 synchronized (this) { 10606 mProcessObservers.register(observer); 10607 } 10608 } 10609 10610 @Override 10611 public void unregisterProcessObserver(IProcessObserver observer) { 10612 synchronized (this) { 10613 mProcessObservers.unregister(observer); 10614 } 10615 } 10616 10617 @Override 10618 public boolean convertFromTranslucent(IBinder token) { 10619 final long origId = Binder.clearCallingIdentity(); 10620 try { 10621 synchronized (this) { 10622 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10623 if (r == null) { 10624 return false; 10625 } 10626 final boolean translucentChanged = r.changeWindowTranslucency(true); 10627 if (translucentChanged) { 10628 r.task.stack.releaseBackgroundResources(); 10629 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10630 } 10631 mWindowManager.setAppFullscreen(token, true); 10632 return translucentChanged; 10633 } 10634 } finally { 10635 Binder.restoreCallingIdentity(origId); 10636 } 10637 } 10638 10639 @Override 10640 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10641 final long origId = Binder.clearCallingIdentity(); 10642 try { 10643 synchronized (this) { 10644 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10645 if (r == null) { 10646 return false; 10647 } 10648 int index = r.task.mActivities.lastIndexOf(r); 10649 if (index > 0) { 10650 ActivityRecord under = r.task.mActivities.get(index - 1); 10651 under.returningOptions = options; 10652 } 10653 final boolean translucentChanged = r.changeWindowTranslucency(false); 10654 if (translucentChanged) { 10655 r.task.stack.convertToTranslucent(r); 10656 } 10657 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10658 mWindowManager.setAppFullscreen(token, false); 10659 return translucentChanged; 10660 } 10661 } finally { 10662 Binder.restoreCallingIdentity(origId); 10663 } 10664 } 10665 10666 @Override 10667 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10668 final long origId = Binder.clearCallingIdentity(); 10669 try { 10670 synchronized (this) { 10671 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10672 if (r != null) { 10673 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10674 } 10675 } 10676 return false; 10677 } finally { 10678 Binder.restoreCallingIdentity(origId); 10679 } 10680 } 10681 10682 @Override 10683 public boolean isBackgroundVisibleBehind(IBinder token) { 10684 final long origId = Binder.clearCallingIdentity(); 10685 try { 10686 synchronized (this) { 10687 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10688 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10689 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10690 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10691 return visible; 10692 } 10693 } finally { 10694 Binder.restoreCallingIdentity(origId); 10695 } 10696 } 10697 10698 @Override 10699 public ActivityOptions getActivityOptions(IBinder token) { 10700 final long origId = Binder.clearCallingIdentity(); 10701 try { 10702 synchronized (this) { 10703 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10704 if (r != null) { 10705 final ActivityOptions activityOptions = r.pendingOptions; 10706 r.pendingOptions = null; 10707 return activityOptions; 10708 } 10709 return null; 10710 } 10711 } finally { 10712 Binder.restoreCallingIdentity(origId); 10713 } 10714 } 10715 10716 @Override 10717 public void setImmersive(IBinder token, boolean immersive) { 10718 synchronized(this) { 10719 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10720 if (r == null) { 10721 throw new IllegalArgumentException(); 10722 } 10723 r.immersive = immersive; 10724 10725 // update associated state if we're frontmost 10726 if (r == mFocusedActivity) { 10727 if (DEBUG_IMMERSIVE) { 10728 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10729 } 10730 applyUpdateLockStateLocked(r); 10731 } 10732 } 10733 } 10734 10735 @Override 10736 public boolean isImmersive(IBinder token) { 10737 synchronized (this) { 10738 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10739 if (r == null) { 10740 throw new IllegalArgumentException(); 10741 } 10742 return r.immersive; 10743 } 10744 } 10745 10746 public boolean isTopActivityImmersive() { 10747 enforceNotIsolatedCaller("startActivity"); 10748 synchronized (this) { 10749 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10750 return (r != null) ? r.immersive : false; 10751 } 10752 } 10753 10754 @Override 10755 public boolean isTopOfTask(IBinder token) { 10756 synchronized (this) { 10757 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10758 if (r == null) { 10759 throw new IllegalArgumentException(); 10760 } 10761 return r.task.getTopActivity() == r; 10762 } 10763 } 10764 10765 public final void enterSafeMode() { 10766 synchronized(this) { 10767 // It only makes sense to do this before the system is ready 10768 // and started launching other packages. 10769 if (!mSystemReady) { 10770 try { 10771 AppGlobals.getPackageManager().enterSafeMode(); 10772 } catch (RemoteException e) { 10773 } 10774 } 10775 10776 mSafeMode = true; 10777 } 10778 } 10779 10780 public final void showSafeModeOverlay() { 10781 View v = LayoutInflater.from(mContext).inflate( 10782 com.android.internal.R.layout.safe_mode, null); 10783 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10784 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10785 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10786 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10787 lp.gravity = Gravity.BOTTOM | Gravity.START; 10788 lp.format = v.getBackground().getOpacity(); 10789 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10790 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10791 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10792 ((WindowManager)mContext.getSystemService( 10793 Context.WINDOW_SERVICE)).addView(v, lp); 10794 } 10795 10796 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10797 if (!(sender instanceof PendingIntentRecord)) { 10798 return; 10799 } 10800 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10801 synchronized (stats) { 10802 if (mBatteryStatsService.isOnBattery()) { 10803 mBatteryStatsService.enforceCallingPermission(); 10804 PendingIntentRecord rec = (PendingIntentRecord)sender; 10805 int MY_UID = Binder.getCallingUid(); 10806 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10807 BatteryStatsImpl.Uid.Pkg pkg = 10808 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10809 sourcePkg != null ? sourcePkg : rec.key.packageName); 10810 pkg.incWakeupsLocked(); 10811 } 10812 } 10813 } 10814 10815 public boolean killPids(int[] pids, String pReason, boolean secure) { 10816 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10817 throw new SecurityException("killPids only available to the system"); 10818 } 10819 String reason = (pReason == null) ? "Unknown" : pReason; 10820 // XXX Note: don't acquire main activity lock here, because the window 10821 // manager calls in with its locks held. 10822 10823 boolean killed = false; 10824 synchronized (mPidsSelfLocked) { 10825 int[] types = new int[pids.length]; 10826 int worstType = 0; 10827 for (int i=0; i<pids.length; i++) { 10828 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10829 if (proc != null) { 10830 int type = proc.setAdj; 10831 types[i] = type; 10832 if (type > worstType) { 10833 worstType = type; 10834 } 10835 } 10836 } 10837 10838 // If the worst oom_adj is somewhere in the cached proc LRU range, 10839 // then constrain it so we will kill all cached procs. 10840 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10841 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10842 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10843 } 10844 10845 // If this is not a secure call, don't let it kill processes that 10846 // are important. 10847 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10848 worstType = ProcessList.SERVICE_ADJ; 10849 } 10850 10851 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10852 for (int i=0; i<pids.length; i++) { 10853 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10854 if (proc == null) { 10855 continue; 10856 } 10857 int adj = proc.setAdj; 10858 if (adj >= worstType && !proc.killedByAm) { 10859 proc.kill(reason, true); 10860 killed = true; 10861 } 10862 } 10863 } 10864 return killed; 10865 } 10866 10867 @Override 10868 public void killUid(int uid, String reason) { 10869 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10870 throw new SecurityException("killUid only available to the system"); 10871 } 10872 synchronized (this) { 10873 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10874 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10875 reason != null ? reason : "kill uid"); 10876 } 10877 } 10878 10879 @Override 10880 public boolean killProcessesBelowForeground(String reason) { 10881 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10882 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10883 } 10884 10885 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10886 } 10887 10888 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10889 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10890 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10891 } 10892 10893 boolean killed = false; 10894 synchronized (mPidsSelfLocked) { 10895 final int size = mPidsSelfLocked.size(); 10896 for (int i = 0; i < size; i++) { 10897 final int pid = mPidsSelfLocked.keyAt(i); 10898 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10899 if (proc == null) continue; 10900 10901 final int adj = proc.setAdj; 10902 if (adj > belowAdj && !proc.killedByAm) { 10903 proc.kill(reason, true); 10904 killed = true; 10905 } 10906 } 10907 } 10908 return killed; 10909 } 10910 10911 @Override 10912 public void hang(final IBinder who, boolean allowRestart) { 10913 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10914 != PackageManager.PERMISSION_GRANTED) { 10915 throw new SecurityException("Requires permission " 10916 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10917 } 10918 10919 final IBinder.DeathRecipient death = new DeathRecipient() { 10920 @Override 10921 public void binderDied() { 10922 synchronized (this) { 10923 notifyAll(); 10924 } 10925 } 10926 }; 10927 10928 try { 10929 who.linkToDeath(death, 0); 10930 } catch (RemoteException e) { 10931 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10932 return; 10933 } 10934 10935 synchronized (this) { 10936 Watchdog.getInstance().setAllowRestart(allowRestart); 10937 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10938 synchronized (death) { 10939 while (who.isBinderAlive()) { 10940 try { 10941 death.wait(); 10942 } catch (InterruptedException e) { 10943 } 10944 } 10945 } 10946 Watchdog.getInstance().setAllowRestart(true); 10947 } 10948 } 10949 10950 @Override 10951 public void restart() { 10952 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10953 != PackageManager.PERMISSION_GRANTED) { 10954 throw new SecurityException("Requires permission " 10955 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10956 } 10957 10958 Log.i(TAG, "Sending shutdown broadcast..."); 10959 10960 BroadcastReceiver br = new BroadcastReceiver() { 10961 @Override public void onReceive(Context context, Intent intent) { 10962 // Now the broadcast is done, finish up the low-level shutdown. 10963 Log.i(TAG, "Shutting down activity manager..."); 10964 shutdown(10000); 10965 Log.i(TAG, "Shutdown complete, restarting!"); 10966 Process.killProcess(Process.myPid()); 10967 System.exit(10); 10968 } 10969 }; 10970 10971 // First send the high-level shut down broadcast. 10972 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10973 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10974 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10975 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10976 mContext.sendOrderedBroadcastAsUser(intent, 10977 UserHandle.ALL, null, br, mHandler, 0, null, null); 10978 */ 10979 br.onReceive(mContext, intent); 10980 } 10981 10982 private long getLowRamTimeSinceIdle(long now) { 10983 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10984 } 10985 10986 @Override 10987 public void performIdleMaintenance() { 10988 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10989 != PackageManager.PERMISSION_GRANTED) { 10990 throw new SecurityException("Requires permission " 10991 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10992 } 10993 10994 synchronized (this) { 10995 final long now = SystemClock.uptimeMillis(); 10996 final long timeSinceLastIdle = now - mLastIdleTime; 10997 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10998 mLastIdleTime = now; 10999 mLowRamTimeSinceLastIdle = 0; 11000 if (mLowRamStartTime != 0) { 11001 mLowRamStartTime = now; 11002 } 11003 11004 StringBuilder sb = new StringBuilder(128); 11005 sb.append("Idle maintenance over "); 11006 TimeUtils.formatDuration(timeSinceLastIdle, sb); 11007 sb.append(" low RAM for "); 11008 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 11009 Slog.i(TAG, sb.toString()); 11010 11011 // If at least 1/3 of our time since the last idle period has been spent 11012 // with RAM low, then we want to kill processes. 11013 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 11014 11015 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11016 ProcessRecord proc = mLruProcesses.get(i); 11017 if (proc.notCachedSinceIdle) { 11018 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 11019 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 11020 if (doKilling && proc.initialIdlePss != 0 11021 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 11022 sb = new StringBuilder(128); 11023 sb.append("Kill"); 11024 sb.append(proc.processName); 11025 sb.append(" in idle maint: pss="); 11026 sb.append(proc.lastPss); 11027 sb.append(", initialPss="); 11028 sb.append(proc.initialIdlePss); 11029 sb.append(", period="); 11030 TimeUtils.formatDuration(timeSinceLastIdle, sb); 11031 sb.append(", lowRamPeriod="); 11032 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 11033 Slog.wtfQuiet(TAG, sb.toString()); 11034 proc.kill("idle maint (pss " + proc.lastPss 11035 + " from " + proc.initialIdlePss + ")", true); 11036 } 11037 } 11038 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 11039 proc.notCachedSinceIdle = true; 11040 proc.initialIdlePss = 0; 11041 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 11042 mTestPssMode, isSleeping(), now); 11043 } 11044 } 11045 11046 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 11047 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 11048 } 11049 } 11050 11051 private void retrieveSettings() { 11052 final ContentResolver resolver = mContext.getContentResolver(); 11053 String debugApp = Settings.Global.getString( 11054 resolver, Settings.Global.DEBUG_APP); 11055 boolean waitForDebugger = Settings.Global.getInt( 11056 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11057 boolean alwaysFinishActivities = Settings.Global.getInt( 11058 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11059 boolean forceRtl = Settings.Global.getInt( 11060 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11061 // Transfer any global setting for forcing RTL layout, into a System Property 11062 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11063 11064 Configuration configuration = new Configuration(); 11065 Settings.System.getConfiguration(resolver, configuration); 11066 if (forceRtl) { 11067 // This will take care of setting the correct layout direction flags 11068 configuration.setLayoutDirection(configuration.locale); 11069 } 11070 11071 synchronized (this) { 11072 mDebugApp = mOrigDebugApp = debugApp; 11073 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11074 mAlwaysFinishActivities = alwaysFinishActivities; 11075 // This happens before any activities are started, so we can 11076 // change mConfiguration in-place. 11077 updateConfigurationLocked(configuration, null, false, true); 11078 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11079 } 11080 } 11081 11082 /** Loads resources after the current configuration has been set. */ 11083 private void loadResourcesOnSystemReady() { 11084 final Resources res = mContext.getResources(); 11085 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11086 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11087 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11088 } 11089 11090 public boolean testIsSystemReady() { 11091 // no need to synchronize(this) just to read & return the value 11092 return mSystemReady; 11093 } 11094 11095 private static File getCalledPreBootReceiversFile() { 11096 File dataDir = Environment.getDataDirectory(); 11097 File systemDir = new File(dataDir, "system"); 11098 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11099 return fname; 11100 } 11101 11102 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11103 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11104 File file = getCalledPreBootReceiversFile(); 11105 FileInputStream fis = null; 11106 try { 11107 fis = new FileInputStream(file); 11108 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11109 int fvers = dis.readInt(); 11110 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11111 String vers = dis.readUTF(); 11112 String codename = dis.readUTF(); 11113 String build = dis.readUTF(); 11114 if (android.os.Build.VERSION.RELEASE.equals(vers) 11115 && android.os.Build.VERSION.CODENAME.equals(codename) 11116 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11117 int num = dis.readInt(); 11118 while (num > 0) { 11119 num--; 11120 String pkg = dis.readUTF(); 11121 String cls = dis.readUTF(); 11122 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11123 } 11124 } 11125 } 11126 } catch (FileNotFoundException e) { 11127 } catch (IOException e) { 11128 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11129 } finally { 11130 if (fis != null) { 11131 try { 11132 fis.close(); 11133 } catch (IOException e) { 11134 } 11135 } 11136 } 11137 return lastDoneReceivers; 11138 } 11139 11140 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11141 File file = getCalledPreBootReceiversFile(); 11142 FileOutputStream fos = null; 11143 DataOutputStream dos = null; 11144 try { 11145 fos = new FileOutputStream(file); 11146 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11147 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11148 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11149 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11150 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11151 dos.writeInt(list.size()); 11152 for (int i=0; i<list.size(); i++) { 11153 dos.writeUTF(list.get(i).getPackageName()); 11154 dos.writeUTF(list.get(i).getClassName()); 11155 } 11156 } catch (IOException e) { 11157 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11158 file.delete(); 11159 } finally { 11160 FileUtils.sync(fos); 11161 if (dos != null) { 11162 try { 11163 dos.close(); 11164 } catch (IOException e) { 11165 // TODO Auto-generated catch block 11166 e.printStackTrace(); 11167 } 11168 } 11169 } 11170 } 11171 11172 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11173 ArrayList<ComponentName> doneReceivers, int userId) { 11174 boolean waitingUpdate = false; 11175 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11176 List<ResolveInfo> ris = null; 11177 try { 11178 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11179 intent, null, 0, userId); 11180 } catch (RemoteException e) { 11181 } 11182 if (ris != null) { 11183 for (int i=ris.size()-1; i>=0; i--) { 11184 if ((ris.get(i).activityInfo.applicationInfo.flags 11185 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11186 ris.remove(i); 11187 } 11188 } 11189 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11190 11191 // For User 0, load the version number. When delivering to a new user, deliver 11192 // to all receivers. 11193 if (userId == UserHandle.USER_OWNER) { 11194 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11195 for (int i=0; i<ris.size(); i++) { 11196 ActivityInfo ai = ris.get(i).activityInfo; 11197 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11198 if (lastDoneReceivers.contains(comp)) { 11199 // We already did the pre boot receiver for this app with the current 11200 // platform version, so don't do it again... 11201 ris.remove(i); 11202 i--; 11203 // ...however, do keep it as one that has been done, so we don't 11204 // forget about it when rewriting the file of last done receivers. 11205 doneReceivers.add(comp); 11206 } 11207 } 11208 } 11209 11210 // If primary user, send broadcast to all available users, else just to userId 11211 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11212 : new int[] { userId }; 11213 for (int i = 0; i < ris.size(); i++) { 11214 ActivityInfo ai = ris.get(i).activityInfo; 11215 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11216 doneReceivers.add(comp); 11217 intent.setComponent(comp); 11218 for (int j=0; j<users.length; j++) { 11219 IIntentReceiver finisher = null; 11220 // On last receiver and user, set up a completion callback 11221 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11222 finisher = new IIntentReceiver.Stub() { 11223 public void performReceive(Intent intent, int resultCode, 11224 String data, Bundle extras, boolean ordered, 11225 boolean sticky, int sendingUser) { 11226 // The raw IIntentReceiver interface is called 11227 // with the AM lock held, so redispatch to 11228 // execute our code without the lock. 11229 mHandler.post(onFinishCallback); 11230 } 11231 }; 11232 } 11233 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11234 + " for user " + users[j]); 11235 broadcastIntentLocked(null, null, intent, null, finisher, 11236 0, null, null, null, AppOpsManager.OP_NONE, 11237 true, false, MY_PID, Process.SYSTEM_UID, 11238 users[j]); 11239 if (finisher != null) { 11240 waitingUpdate = true; 11241 } 11242 } 11243 } 11244 } 11245 11246 return waitingUpdate; 11247 } 11248 11249 public void systemReady(final Runnable goingCallback) { 11250 synchronized(this) { 11251 if (mSystemReady) { 11252 // If we're done calling all the receivers, run the next "boot phase" passed in 11253 // by the SystemServer 11254 if (goingCallback != null) { 11255 goingCallback.run(); 11256 } 11257 return; 11258 } 11259 11260 // Make sure we have the current profile info, since it is needed for 11261 // security checks. 11262 updateCurrentProfileIdsLocked(); 11263 11264 if (mRecentTasks == null) { 11265 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11266 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11267 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11268 mTaskPersister.startPersisting(); 11269 } 11270 11271 // Check to see if there are any update receivers to run. 11272 if (!mDidUpdate) { 11273 if (mWaitingUpdate) { 11274 return; 11275 } 11276 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11277 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11278 public void run() { 11279 synchronized (ActivityManagerService.this) { 11280 mDidUpdate = true; 11281 } 11282 writeLastDonePreBootReceivers(doneReceivers); 11283 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11284 false); 11285 systemReady(goingCallback); 11286 } 11287 }, doneReceivers, UserHandle.USER_OWNER); 11288 11289 if (mWaitingUpdate) { 11290 return; 11291 } 11292 mDidUpdate = true; 11293 } 11294 11295 mAppOpsService.systemReady(); 11296 mSystemReady = true; 11297 } 11298 11299 ArrayList<ProcessRecord> procsToKill = null; 11300 synchronized(mPidsSelfLocked) { 11301 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11302 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11303 if (!isAllowedWhileBooting(proc.info)){ 11304 if (procsToKill == null) { 11305 procsToKill = new ArrayList<ProcessRecord>(); 11306 } 11307 procsToKill.add(proc); 11308 } 11309 } 11310 } 11311 11312 synchronized(this) { 11313 if (procsToKill != null) { 11314 for (int i=procsToKill.size()-1; i>=0; i--) { 11315 ProcessRecord proc = procsToKill.get(i); 11316 Slog.i(TAG, "Removing system update proc: " + proc); 11317 removeProcessLocked(proc, true, false, "system update done"); 11318 } 11319 } 11320 11321 // Now that we have cleaned up any update processes, we 11322 // are ready to start launching real processes and know that 11323 // we won't trample on them any more. 11324 mProcessesReady = true; 11325 } 11326 11327 Slog.i(TAG, "System now ready"); 11328 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11329 SystemClock.uptimeMillis()); 11330 11331 synchronized(this) { 11332 // Make sure we have no pre-ready processes sitting around. 11333 11334 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11335 ResolveInfo ri = mContext.getPackageManager() 11336 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11337 STOCK_PM_FLAGS); 11338 CharSequence errorMsg = null; 11339 if (ri != null) { 11340 ActivityInfo ai = ri.activityInfo; 11341 ApplicationInfo app = ai.applicationInfo; 11342 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11343 mTopAction = Intent.ACTION_FACTORY_TEST; 11344 mTopData = null; 11345 mTopComponent = new ComponentName(app.packageName, 11346 ai.name); 11347 } else { 11348 errorMsg = mContext.getResources().getText( 11349 com.android.internal.R.string.factorytest_not_system); 11350 } 11351 } else { 11352 errorMsg = mContext.getResources().getText( 11353 com.android.internal.R.string.factorytest_no_action); 11354 } 11355 if (errorMsg != null) { 11356 mTopAction = null; 11357 mTopData = null; 11358 mTopComponent = null; 11359 Message msg = Message.obtain(); 11360 msg.what = SHOW_FACTORY_ERROR_MSG; 11361 msg.getData().putCharSequence("msg", errorMsg); 11362 mHandler.sendMessage(msg); 11363 } 11364 } 11365 } 11366 11367 retrieveSettings(); 11368 loadResourcesOnSystemReady(); 11369 11370 synchronized (this) { 11371 readGrantedUriPermissionsLocked(); 11372 } 11373 11374 if (goingCallback != null) goingCallback.run(); 11375 11376 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11377 Integer.toString(mCurrentUserId), mCurrentUserId); 11378 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11379 Integer.toString(mCurrentUserId), mCurrentUserId); 11380 mSystemServiceManager.startUser(mCurrentUserId); 11381 11382 synchronized (this) { 11383 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11384 try { 11385 List apps = AppGlobals.getPackageManager(). 11386 getPersistentApplications(STOCK_PM_FLAGS); 11387 if (apps != null) { 11388 int N = apps.size(); 11389 int i; 11390 for (i=0; i<N; i++) { 11391 ApplicationInfo info 11392 = (ApplicationInfo)apps.get(i); 11393 if (info != null && 11394 !info.packageName.equals("android")) { 11395 addAppLocked(info, false, null /* ABI override */); 11396 } 11397 } 11398 } 11399 } catch (RemoteException ex) { 11400 // pm is in same process, this will never happen. 11401 } 11402 } 11403 11404 // Start up initial activity. 11405 mBooting = true; 11406 startHomeActivityLocked(mCurrentUserId, "systemReady"); 11407 11408 try { 11409 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11410 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11411 + " data partition or your device will be unstable."); 11412 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11413 } 11414 } catch (RemoteException e) { 11415 } 11416 11417 if (!Build.isFingerprintConsistent()) { 11418 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11419 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11420 } 11421 11422 long ident = Binder.clearCallingIdentity(); 11423 try { 11424 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11425 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11426 | Intent.FLAG_RECEIVER_FOREGROUND); 11427 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11428 broadcastIntentLocked(null, null, intent, 11429 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11430 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11431 intent = new Intent(Intent.ACTION_USER_STARTING); 11432 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11433 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11434 broadcastIntentLocked(null, null, intent, 11435 null, new IIntentReceiver.Stub() { 11436 @Override 11437 public void performReceive(Intent intent, int resultCode, String data, 11438 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11439 throws RemoteException { 11440 } 11441 }, 0, null, null, 11442 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11443 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11444 } catch (Throwable t) { 11445 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11446 } finally { 11447 Binder.restoreCallingIdentity(ident); 11448 } 11449 mStackSupervisor.resumeTopActivitiesLocked(); 11450 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11451 } 11452 } 11453 11454 private boolean makeAppCrashingLocked(ProcessRecord app, 11455 String shortMsg, String longMsg, String stackTrace) { 11456 app.crashing = true; 11457 app.crashingReport = generateProcessError(app, 11458 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11459 startAppProblemLocked(app); 11460 app.stopFreezingAllLocked(); 11461 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11462 } 11463 11464 private void makeAppNotRespondingLocked(ProcessRecord app, 11465 String activity, String shortMsg, String longMsg) { 11466 app.notResponding = true; 11467 app.notRespondingReport = generateProcessError(app, 11468 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11469 activity, shortMsg, longMsg, null); 11470 startAppProblemLocked(app); 11471 app.stopFreezingAllLocked(); 11472 } 11473 11474 /** 11475 * Generate a process error record, suitable for attachment to a ProcessRecord. 11476 * 11477 * @param app The ProcessRecord in which the error occurred. 11478 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11479 * ActivityManager.AppErrorStateInfo 11480 * @param activity The activity associated with the crash, if known. 11481 * @param shortMsg Short message describing the crash. 11482 * @param longMsg Long message describing the crash. 11483 * @param stackTrace Full crash stack trace, may be null. 11484 * 11485 * @return Returns a fully-formed AppErrorStateInfo record. 11486 */ 11487 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11488 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11489 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11490 11491 report.condition = condition; 11492 report.processName = app.processName; 11493 report.pid = app.pid; 11494 report.uid = app.info.uid; 11495 report.tag = activity; 11496 report.shortMsg = shortMsg; 11497 report.longMsg = longMsg; 11498 report.stackTrace = stackTrace; 11499 11500 return report; 11501 } 11502 11503 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11504 synchronized (this) { 11505 app.crashing = false; 11506 app.crashingReport = null; 11507 app.notResponding = false; 11508 app.notRespondingReport = null; 11509 if (app.anrDialog == fromDialog) { 11510 app.anrDialog = null; 11511 } 11512 if (app.waitDialog == fromDialog) { 11513 app.waitDialog = null; 11514 } 11515 if (app.pid > 0 && app.pid != MY_PID) { 11516 handleAppCrashLocked(app, null, null, null); 11517 app.kill("user request after error", true); 11518 } 11519 } 11520 } 11521 11522 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11523 String stackTrace) { 11524 long now = SystemClock.uptimeMillis(); 11525 11526 Long crashTime; 11527 if (!app.isolated) { 11528 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11529 } else { 11530 crashTime = null; 11531 } 11532 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11533 // This process loses! 11534 Slog.w(TAG, "Process " + app.info.processName 11535 + " has crashed too many times: killing!"); 11536 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11537 app.userId, app.info.processName, app.uid); 11538 mStackSupervisor.handleAppCrashLocked(app); 11539 if (!app.persistent) { 11540 // We don't want to start this process again until the user 11541 // explicitly does so... but for persistent process, we really 11542 // need to keep it running. If a persistent process is actually 11543 // repeatedly crashing, then badness for everyone. 11544 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11545 app.info.processName); 11546 if (!app.isolated) { 11547 // XXX We don't have a way to mark isolated processes 11548 // as bad, since they don't have a peristent identity. 11549 mBadProcesses.put(app.info.processName, app.uid, 11550 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11551 mProcessCrashTimes.remove(app.info.processName, app.uid); 11552 } 11553 app.bad = true; 11554 app.removed = true; 11555 // Don't let services in this process be restarted and potentially 11556 // annoy the user repeatedly. Unless it is persistent, since those 11557 // processes run critical code. 11558 removeProcessLocked(app, false, false, "crash"); 11559 mStackSupervisor.resumeTopActivitiesLocked(); 11560 return false; 11561 } 11562 mStackSupervisor.resumeTopActivitiesLocked(); 11563 } else { 11564 mStackSupervisor.finishTopRunningActivityLocked(app); 11565 } 11566 11567 // Bump up the crash count of any services currently running in the proc. 11568 for (int i=app.services.size()-1; i>=0; i--) { 11569 // Any services running in the application need to be placed 11570 // back in the pending list. 11571 ServiceRecord sr = app.services.valueAt(i); 11572 sr.crashCount++; 11573 } 11574 11575 // If the crashing process is what we consider to be the "home process" and it has been 11576 // replaced by a third-party app, clear the package preferred activities from packages 11577 // with a home activity running in the process to prevent a repeatedly crashing app 11578 // from blocking the user to manually clear the list. 11579 final ArrayList<ActivityRecord> activities = app.activities; 11580 if (app == mHomeProcess && activities.size() > 0 11581 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11582 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11583 final ActivityRecord r = activities.get(activityNdx); 11584 if (r.isHomeActivity()) { 11585 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11586 try { 11587 ActivityThread.getPackageManager() 11588 .clearPackagePreferredActivities(r.packageName); 11589 } catch (RemoteException c) { 11590 // pm is in same process, this will never happen. 11591 } 11592 } 11593 } 11594 } 11595 11596 if (!app.isolated) { 11597 // XXX Can't keep track of crash times for isolated processes, 11598 // because they don't have a perisistent identity. 11599 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11600 } 11601 11602 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11603 return true; 11604 } 11605 11606 void startAppProblemLocked(ProcessRecord app) { 11607 // If this app is not running under the current user, then we 11608 // can't give it a report button because that would require 11609 // launching the report UI under a different user. 11610 app.errorReportReceiver = null; 11611 11612 for (int userId : mCurrentProfileIds) { 11613 if (app.userId == userId) { 11614 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11615 mContext, app.info.packageName, app.info.flags); 11616 } 11617 } 11618 skipCurrentReceiverLocked(app); 11619 } 11620 11621 void skipCurrentReceiverLocked(ProcessRecord app) { 11622 for (BroadcastQueue queue : mBroadcastQueues) { 11623 queue.skipCurrentReceiverLocked(app); 11624 } 11625 } 11626 11627 /** 11628 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11629 * The application process will exit immediately after this call returns. 11630 * @param app object of the crashing app, null for the system server 11631 * @param crashInfo describing the exception 11632 */ 11633 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11634 ProcessRecord r = findAppProcess(app, "Crash"); 11635 final String processName = app == null ? "system_server" 11636 : (r == null ? "unknown" : r.processName); 11637 11638 handleApplicationCrashInner("crash", r, processName, crashInfo); 11639 } 11640 11641 /* Native crash reporting uses this inner version because it needs to be somewhat 11642 * decoupled from the AM-managed cleanup lifecycle 11643 */ 11644 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11645 ApplicationErrorReport.CrashInfo crashInfo) { 11646 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11647 UserHandle.getUserId(Binder.getCallingUid()), processName, 11648 r == null ? -1 : r.info.flags, 11649 crashInfo.exceptionClassName, 11650 crashInfo.exceptionMessage, 11651 crashInfo.throwFileName, 11652 crashInfo.throwLineNumber); 11653 11654 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11655 11656 crashApplication(r, crashInfo); 11657 } 11658 11659 public void handleApplicationStrictModeViolation( 11660 IBinder app, 11661 int violationMask, 11662 StrictMode.ViolationInfo info) { 11663 ProcessRecord r = findAppProcess(app, "StrictMode"); 11664 if (r == null) { 11665 return; 11666 } 11667 11668 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11669 Integer stackFingerprint = info.hashCode(); 11670 boolean logIt = true; 11671 synchronized (mAlreadyLoggedViolatedStacks) { 11672 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11673 logIt = false; 11674 // TODO: sub-sample into EventLog for these, with 11675 // the info.durationMillis? Then we'd get 11676 // the relative pain numbers, without logging all 11677 // the stack traces repeatedly. We'd want to do 11678 // likewise in the client code, which also does 11679 // dup suppression, before the Binder call. 11680 } else { 11681 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11682 mAlreadyLoggedViolatedStacks.clear(); 11683 } 11684 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11685 } 11686 } 11687 if (logIt) { 11688 logStrictModeViolationToDropBox(r, info); 11689 } 11690 } 11691 11692 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11693 AppErrorResult result = new AppErrorResult(); 11694 synchronized (this) { 11695 final long origId = Binder.clearCallingIdentity(); 11696 11697 Message msg = Message.obtain(); 11698 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11699 HashMap<String, Object> data = new HashMap<String, Object>(); 11700 data.put("result", result); 11701 data.put("app", r); 11702 data.put("violationMask", violationMask); 11703 data.put("info", info); 11704 msg.obj = data; 11705 mHandler.sendMessage(msg); 11706 11707 Binder.restoreCallingIdentity(origId); 11708 } 11709 int res = result.get(); 11710 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11711 } 11712 } 11713 11714 // Depending on the policy in effect, there could be a bunch of 11715 // these in quick succession so we try to batch these together to 11716 // minimize disk writes, number of dropbox entries, and maximize 11717 // compression, by having more fewer, larger records. 11718 private void logStrictModeViolationToDropBox( 11719 ProcessRecord process, 11720 StrictMode.ViolationInfo info) { 11721 if (info == null) { 11722 return; 11723 } 11724 final boolean isSystemApp = process == null || 11725 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11726 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11727 final String processName = process == null ? "unknown" : process.processName; 11728 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11729 final DropBoxManager dbox = (DropBoxManager) 11730 mContext.getSystemService(Context.DROPBOX_SERVICE); 11731 11732 // Exit early if the dropbox isn't configured to accept this report type. 11733 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11734 11735 boolean bufferWasEmpty; 11736 boolean needsFlush; 11737 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11738 synchronized (sb) { 11739 bufferWasEmpty = sb.length() == 0; 11740 appendDropBoxProcessHeaders(process, processName, sb); 11741 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11742 sb.append("System-App: ").append(isSystemApp).append("\n"); 11743 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11744 if (info.violationNumThisLoop != 0) { 11745 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11746 } 11747 if (info.numAnimationsRunning != 0) { 11748 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11749 } 11750 if (info.broadcastIntentAction != null) { 11751 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11752 } 11753 if (info.durationMillis != -1) { 11754 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11755 } 11756 if (info.numInstances != -1) { 11757 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11758 } 11759 if (info.tags != null) { 11760 for (String tag : info.tags) { 11761 sb.append("Span-Tag: ").append(tag).append("\n"); 11762 } 11763 } 11764 sb.append("\n"); 11765 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11766 sb.append(info.crashInfo.stackTrace); 11767 sb.append("\n"); 11768 } 11769 if (info.message != null) { 11770 sb.append(info.message); 11771 sb.append("\n"); 11772 } 11773 11774 // Only buffer up to ~64k. Various logging bits truncate 11775 // things at 128k. 11776 needsFlush = (sb.length() > 64 * 1024); 11777 } 11778 11779 // Flush immediately if the buffer's grown too large, or this 11780 // is a non-system app. Non-system apps are isolated with a 11781 // different tag & policy and not batched. 11782 // 11783 // Batching is useful during internal testing with 11784 // StrictMode settings turned up high. Without batching, 11785 // thousands of separate files could be created on boot. 11786 if (!isSystemApp || needsFlush) { 11787 new Thread("Error dump: " + dropboxTag) { 11788 @Override 11789 public void run() { 11790 String report; 11791 synchronized (sb) { 11792 report = sb.toString(); 11793 sb.delete(0, sb.length()); 11794 sb.trimToSize(); 11795 } 11796 if (report.length() != 0) { 11797 dbox.addText(dropboxTag, report); 11798 } 11799 } 11800 }.start(); 11801 return; 11802 } 11803 11804 // System app batching: 11805 if (!bufferWasEmpty) { 11806 // An existing dropbox-writing thread is outstanding, so 11807 // we don't need to start it up. The existing thread will 11808 // catch the buffer appends we just did. 11809 return; 11810 } 11811 11812 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11813 // (After this point, we shouldn't access AMS internal data structures.) 11814 new Thread("Error dump: " + dropboxTag) { 11815 @Override 11816 public void run() { 11817 // 5 second sleep to let stacks arrive and be batched together 11818 try { 11819 Thread.sleep(5000); // 5 seconds 11820 } catch (InterruptedException e) {} 11821 11822 String errorReport; 11823 synchronized (mStrictModeBuffer) { 11824 errorReport = mStrictModeBuffer.toString(); 11825 if (errorReport.length() == 0) { 11826 return; 11827 } 11828 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11829 mStrictModeBuffer.trimToSize(); 11830 } 11831 dbox.addText(dropboxTag, errorReport); 11832 } 11833 }.start(); 11834 } 11835 11836 /** 11837 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11838 * @param app object of the crashing app, null for the system server 11839 * @param tag reported by the caller 11840 * @param system whether this wtf is coming from the system 11841 * @param crashInfo describing the context of the error 11842 * @return true if the process should exit immediately (WTF is fatal) 11843 */ 11844 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11845 final ApplicationErrorReport.CrashInfo crashInfo) { 11846 final int callingUid = Binder.getCallingUid(); 11847 final int callingPid = Binder.getCallingPid(); 11848 11849 if (system) { 11850 // If this is coming from the system, we could very well have low-level 11851 // system locks held, so we want to do this all asynchronously. And we 11852 // never want this to become fatal, so there is that too. 11853 mHandler.post(new Runnable() { 11854 @Override public void run() { 11855 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11856 } 11857 }); 11858 return false; 11859 } 11860 11861 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11862 crashInfo); 11863 11864 if (r != null && r.pid != Process.myPid() && 11865 Settings.Global.getInt(mContext.getContentResolver(), 11866 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11867 crashApplication(r, crashInfo); 11868 return true; 11869 } else { 11870 return false; 11871 } 11872 } 11873 11874 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11875 final ApplicationErrorReport.CrashInfo crashInfo) { 11876 final ProcessRecord r = findAppProcess(app, "WTF"); 11877 final String processName = app == null ? "system_server" 11878 : (r == null ? "unknown" : r.processName); 11879 11880 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11881 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11882 11883 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11884 11885 return r; 11886 } 11887 11888 /** 11889 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11890 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11891 */ 11892 private ProcessRecord findAppProcess(IBinder app, String reason) { 11893 if (app == null) { 11894 return null; 11895 } 11896 11897 synchronized (this) { 11898 final int NP = mProcessNames.getMap().size(); 11899 for (int ip=0; ip<NP; ip++) { 11900 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11901 final int NA = apps.size(); 11902 for (int ia=0; ia<NA; ia++) { 11903 ProcessRecord p = apps.valueAt(ia); 11904 if (p.thread != null && p.thread.asBinder() == app) { 11905 return p; 11906 } 11907 } 11908 } 11909 11910 Slog.w(TAG, "Can't find mystery application for " + reason 11911 + " from pid=" + Binder.getCallingPid() 11912 + " uid=" + Binder.getCallingUid() + ": " + app); 11913 return null; 11914 } 11915 } 11916 11917 /** 11918 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11919 * to append various headers to the dropbox log text. 11920 */ 11921 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11922 StringBuilder sb) { 11923 // Watchdog thread ends up invoking this function (with 11924 // a null ProcessRecord) to add the stack file to dropbox. 11925 // Do not acquire a lock on this (am) in such cases, as it 11926 // could cause a potential deadlock, if and when watchdog 11927 // is invoked due to unavailability of lock on am and it 11928 // would prevent watchdog from killing system_server. 11929 if (process == null) { 11930 sb.append("Process: ").append(processName).append("\n"); 11931 return; 11932 } 11933 // Note: ProcessRecord 'process' is guarded by the service 11934 // instance. (notably process.pkgList, which could otherwise change 11935 // concurrently during execution of this method) 11936 synchronized (this) { 11937 sb.append("Process: ").append(processName).append("\n"); 11938 int flags = process.info.flags; 11939 IPackageManager pm = AppGlobals.getPackageManager(); 11940 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11941 for (int ip=0; ip<process.pkgList.size(); ip++) { 11942 String pkg = process.pkgList.keyAt(ip); 11943 sb.append("Package: ").append(pkg); 11944 try { 11945 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11946 if (pi != null) { 11947 sb.append(" v").append(pi.versionCode); 11948 if (pi.versionName != null) { 11949 sb.append(" (").append(pi.versionName).append(")"); 11950 } 11951 } 11952 } catch (RemoteException e) { 11953 Slog.e(TAG, "Error getting package info: " + pkg, e); 11954 } 11955 sb.append("\n"); 11956 } 11957 } 11958 } 11959 11960 private static String processClass(ProcessRecord process) { 11961 if (process == null || process.pid == MY_PID) { 11962 return "system_server"; 11963 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11964 return "system_app"; 11965 } else { 11966 return "data_app"; 11967 } 11968 } 11969 11970 /** 11971 * Write a description of an error (crash, WTF, ANR) to the drop box. 11972 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11973 * @param process which caused the error, null means the system server 11974 * @param activity which triggered the error, null if unknown 11975 * @param parent activity related to the error, null if unknown 11976 * @param subject line related to the error, null if absent 11977 * @param report in long form describing the error, null if absent 11978 * @param logFile to include in the report, null if none 11979 * @param crashInfo giving an application stack trace, null if absent 11980 */ 11981 public void addErrorToDropBox(String eventType, 11982 ProcessRecord process, String processName, ActivityRecord activity, 11983 ActivityRecord parent, String subject, 11984 final String report, final File logFile, 11985 final ApplicationErrorReport.CrashInfo crashInfo) { 11986 // NOTE -- this must never acquire the ActivityManagerService lock, 11987 // otherwise the watchdog may be prevented from resetting the system. 11988 11989 final String dropboxTag = processClass(process) + "_" + eventType; 11990 final DropBoxManager dbox = (DropBoxManager) 11991 mContext.getSystemService(Context.DROPBOX_SERVICE); 11992 11993 // Exit early if the dropbox isn't configured to accept this report type. 11994 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11995 11996 final StringBuilder sb = new StringBuilder(1024); 11997 appendDropBoxProcessHeaders(process, processName, sb); 11998 if (activity != null) { 11999 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 12000 } 12001 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 12002 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 12003 } 12004 if (parent != null && parent != activity) { 12005 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 12006 } 12007 if (subject != null) { 12008 sb.append("Subject: ").append(subject).append("\n"); 12009 } 12010 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 12011 if (Debug.isDebuggerConnected()) { 12012 sb.append("Debugger: Connected\n"); 12013 } 12014 sb.append("\n"); 12015 12016 // Do the rest in a worker thread to avoid blocking the caller on I/O 12017 // (After this point, we shouldn't access AMS internal data structures.) 12018 Thread worker = new Thread("Error dump: " + dropboxTag) { 12019 @Override 12020 public void run() { 12021 if (report != null) { 12022 sb.append(report); 12023 } 12024 if (logFile != null) { 12025 try { 12026 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 12027 "\n\n[[TRUNCATED]]")); 12028 } catch (IOException e) { 12029 Slog.e(TAG, "Error reading " + logFile, e); 12030 } 12031 } 12032 if (crashInfo != null && crashInfo.stackTrace != null) { 12033 sb.append(crashInfo.stackTrace); 12034 } 12035 12036 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 12037 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 12038 if (lines > 0) { 12039 sb.append("\n"); 12040 12041 // Merge several logcat streams, and take the last N lines 12042 InputStreamReader input = null; 12043 try { 12044 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 12045 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 12046 "-b", "crash", 12047 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 12048 12049 try { logcat.getOutputStream().close(); } catch (IOException e) {} 12050 try { logcat.getErrorStream().close(); } catch (IOException e) {} 12051 input = new InputStreamReader(logcat.getInputStream()); 12052 12053 int num; 12054 char[] buf = new char[8192]; 12055 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 12056 } catch (IOException e) { 12057 Slog.e(TAG, "Error running logcat", e); 12058 } finally { 12059 if (input != null) try { input.close(); } catch (IOException e) {} 12060 } 12061 } 12062 12063 dbox.addText(dropboxTag, sb.toString()); 12064 } 12065 }; 12066 12067 if (process == null) { 12068 // If process is null, we are being called from some internal code 12069 // and may be about to die -- run this synchronously. 12070 worker.run(); 12071 } else { 12072 worker.start(); 12073 } 12074 } 12075 12076 /** 12077 * Bring up the "unexpected error" dialog box for a crashing app. 12078 * Deal with edge cases (intercepts from instrumented applications, 12079 * ActivityController, error intent receivers, that sort of thing). 12080 * @param r the application crashing 12081 * @param crashInfo describing the failure 12082 */ 12083 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12084 long timeMillis = System.currentTimeMillis(); 12085 String shortMsg = crashInfo.exceptionClassName; 12086 String longMsg = crashInfo.exceptionMessage; 12087 String stackTrace = crashInfo.stackTrace; 12088 if (shortMsg != null && longMsg != null) { 12089 longMsg = shortMsg + ": " + longMsg; 12090 } else if (shortMsg != null) { 12091 longMsg = shortMsg; 12092 } 12093 12094 AppErrorResult result = new AppErrorResult(); 12095 synchronized (this) { 12096 if (mController != null) { 12097 try { 12098 String name = r != null ? r.processName : null; 12099 int pid = r != null ? r.pid : Binder.getCallingPid(); 12100 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12101 if (!mController.appCrashed(name, pid, 12102 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12103 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12104 && "Native crash".equals(crashInfo.exceptionClassName)) { 12105 Slog.w(TAG, "Skip killing native crashed app " + name 12106 + "(" + pid + ") during testing"); 12107 } else { 12108 Slog.w(TAG, "Force-killing crashed app " + name 12109 + " at watcher's request"); 12110 if (r != null) { 12111 r.kill("crash", true); 12112 } else { 12113 // Huh. 12114 Process.killProcess(pid); 12115 Process.killProcessGroup(uid, pid); 12116 } 12117 } 12118 return; 12119 } 12120 } catch (RemoteException e) { 12121 mController = null; 12122 Watchdog.getInstance().setActivityController(null); 12123 } 12124 } 12125 12126 final long origId = Binder.clearCallingIdentity(); 12127 12128 // If this process is running instrumentation, finish it. 12129 if (r != null && r.instrumentationClass != null) { 12130 Slog.w(TAG, "Error in app " + r.processName 12131 + " running instrumentation " + r.instrumentationClass + ":"); 12132 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12133 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12134 Bundle info = new Bundle(); 12135 info.putString("shortMsg", shortMsg); 12136 info.putString("longMsg", longMsg); 12137 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12138 Binder.restoreCallingIdentity(origId); 12139 return; 12140 } 12141 12142 // Log crash in battery stats. 12143 if (r != null) { 12144 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12145 } 12146 12147 // If we can't identify the process or it's already exceeded its crash quota, 12148 // quit right away without showing a crash dialog. 12149 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12150 Binder.restoreCallingIdentity(origId); 12151 return; 12152 } 12153 12154 Message msg = Message.obtain(); 12155 msg.what = SHOW_ERROR_MSG; 12156 HashMap data = new HashMap(); 12157 data.put("result", result); 12158 data.put("app", r); 12159 msg.obj = data; 12160 mHandler.sendMessage(msg); 12161 12162 Binder.restoreCallingIdentity(origId); 12163 } 12164 12165 int res = result.get(); 12166 12167 Intent appErrorIntent = null; 12168 synchronized (this) { 12169 if (r != null && !r.isolated) { 12170 // XXX Can't keep track of crash time for isolated processes, 12171 // since they don't have a persistent identity. 12172 mProcessCrashTimes.put(r.info.processName, r.uid, 12173 SystemClock.uptimeMillis()); 12174 } 12175 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12176 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12177 } 12178 } 12179 12180 if (appErrorIntent != null) { 12181 try { 12182 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12183 } catch (ActivityNotFoundException e) { 12184 Slog.w(TAG, "bug report receiver dissappeared", e); 12185 } 12186 } 12187 } 12188 12189 Intent createAppErrorIntentLocked(ProcessRecord r, 12190 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12191 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12192 if (report == null) { 12193 return null; 12194 } 12195 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12196 result.setComponent(r.errorReportReceiver); 12197 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12198 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12199 return result; 12200 } 12201 12202 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12203 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12204 if (r.errorReportReceiver == null) { 12205 return null; 12206 } 12207 12208 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12209 return null; 12210 } 12211 12212 ApplicationErrorReport report = new ApplicationErrorReport(); 12213 report.packageName = r.info.packageName; 12214 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12215 report.processName = r.processName; 12216 report.time = timeMillis; 12217 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12218 12219 if (r.crashing || r.forceCrashReport) { 12220 report.type = ApplicationErrorReport.TYPE_CRASH; 12221 report.crashInfo = crashInfo; 12222 } else if (r.notResponding) { 12223 report.type = ApplicationErrorReport.TYPE_ANR; 12224 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12225 12226 report.anrInfo.activity = r.notRespondingReport.tag; 12227 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12228 report.anrInfo.info = r.notRespondingReport.longMsg; 12229 } 12230 12231 return report; 12232 } 12233 12234 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12235 enforceNotIsolatedCaller("getProcessesInErrorState"); 12236 // assume our apps are happy - lazy create the list 12237 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12238 12239 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12240 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12241 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12242 12243 synchronized (this) { 12244 12245 // iterate across all processes 12246 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12247 ProcessRecord app = mLruProcesses.get(i); 12248 if (!allUsers && app.userId != userId) { 12249 continue; 12250 } 12251 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12252 // This one's in trouble, so we'll generate a report for it 12253 // crashes are higher priority (in case there's a crash *and* an anr) 12254 ActivityManager.ProcessErrorStateInfo report = null; 12255 if (app.crashing) { 12256 report = app.crashingReport; 12257 } else if (app.notResponding) { 12258 report = app.notRespondingReport; 12259 } 12260 12261 if (report != null) { 12262 if (errList == null) { 12263 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12264 } 12265 errList.add(report); 12266 } else { 12267 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12268 " crashing = " + app.crashing + 12269 " notResponding = " + app.notResponding); 12270 } 12271 } 12272 } 12273 } 12274 12275 return errList; 12276 } 12277 12278 static int procStateToImportance(int procState, int memAdj, 12279 ActivityManager.RunningAppProcessInfo currApp) { 12280 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12281 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12282 currApp.lru = memAdj; 12283 } else { 12284 currApp.lru = 0; 12285 } 12286 return imp; 12287 } 12288 12289 private void fillInProcMemInfo(ProcessRecord app, 12290 ActivityManager.RunningAppProcessInfo outInfo) { 12291 outInfo.pid = app.pid; 12292 outInfo.uid = app.info.uid; 12293 if (mHeavyWeightProcess == app) { 12294 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12295 } 12296 if (app.persistent) { 12297 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12298 } 12299 if (app.activities.size() > 0) { 12300 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12301 } 12302 outInfo.lastTrimLevel = app.trimMemoryLevel; 12303 int adj = app.curAdj; 12304 int procState = app.curProcState; 12305 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12306 outInfo.importanceReasonCode = app.adjTypeCode; 12307 outInfo.processState = app.curProcState; 12308 } 12309 12310 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12311 enforceNotIsolatedCaller("getRunningAppProcesses"); 12312 // Lazy instantiation of list 12313 List<ActivityManager.RunningAppProcessInfo> runList = null; 12314 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12315 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12316 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12317 synchronized (this) { 12318 // Iterate across all processes 12319 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12320 ProcessRecord app = mLruProcesses.get(i); 12321 if (!allUsers && app.userId != userId) { 12322 continue; 12323 } 12324 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12325 // Generate process state info for running application 12326 ActivityManager.RunningAppProcessInfo currApp = 12327 new ActivityManager.RunningAppProcessInfo(app.processName, 12328 app.pid, app.getPackageList()); 12329 fillInProcMemInfo(app, currApp); 12330 if (app.adjSource instanceof ProcessRecord) { 12331 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12332 currApp.importanceReasonImportance = 12333 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12334 app.adjSourceProcState); 12335 } else if (app.adjSource instanceof ActivityRecord) { 12336 ActivityRecord r = (ActivityRecord)app.adjSource; 12337 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12338 } 12339 if (app.adjTarget instanceof ComponentName) { 12340 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12341 } 12342 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12343 // + " lru=" + currApp.lru); 12344 if (runList == null) { 12345 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12346 } 12347 runList.add(currApp); 12348 } 12349 } 12350 } 12351 return runList; 12352 } 12353 12354 public List<ApplicationInfo> getRunningExternalApplications() { 12355 enforceNotIsolatedCaller("getRunningExternalApplications"); 12356 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12357 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12358 if (runningApps != null && runningApps.size() > 0) { 12359 Set<String> extList = new HashSet<String>(); 12360 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12361 if (app.pkgList != null) { 12362 for (String pkg : app.pkgList) { 12363 extList.add(pkg); 12364 } 12365 } 12366 } 12367 IPackageManager pm = AppGlobals.getPackageManager(); 12368 for (String pkg : extList) { 12369 try { 12370 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12371 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12372 retList.add(info); 12373 } 12374 } catch (RemoteException e) { 12375 } 12376 } 12377 } 12378 return retList; 12379 } 12380 12381 @Override 12382 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12383 enforceNotIsolatedCaller("getMyMemoryState"); 12384 synchronized (this) { 12385 ProcessRecord proc; 12386 synchronized (mPidsSelfLocked) { 12387 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12388 } 12389 fillInProcMemInfo(proc, outInfo); 12390 } 12391 } 12392 12393 @Override 12394 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12395 if (checkCallingPermission(android.Manifest.permission.DUMP) 12396 != PackageManager.PERMISSION_GRANTED) { 12397 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12398 + Binder.getCallingPid() 12399 + ", uid=" + Binder.getCallingUid() 12400 + " without permission " 12401 + android.Manifest.permission.DUMP); 12402 return; 12403 } 12404 12405 boolean dumpAll = false; 12406 boolean dumpClient = false; 12407 String dumpPackage = null; 12408 12409 int opti = 0; 12410 while (opti < args.length) { 12411 String opt = args[opti]; 12412 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12413 break; 12414 } 12415 opti++; 12416 if ("-a".equals(opt)) { 12417 dumpAll = true; 12418 } else if ("-c".equals(opt)) { 12419 dumpClient = true; 12420 } else if ("-p".equals(opt)) { 12421 if (opti < args.length) { 12422 dumpPackage = args[opti]; 12423 opti++; 12424 } else { 12425 pw.println("Error: -p option requires package argument"); 12426 return; 12427 } 12428 dumpClient = true; 12429 } else if ("-h".equals(opt)) { 12430 pw.println("Activity manager dump options:"); 12431 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12432 pw.println(" cmd may be one of:"); 12433 pw.println(" a[ctivities]: activity stack state"); 12434 pw.println(" r[recents]: recent activities state"); 12435 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12436 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12437 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12438 pw.println(" o[om]: out of memory management"); 12439 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12440 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12441 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12442 pw.println(" as[sociations]: tracked app associations"); 12443 pw.println(" service [COMP_SPEC]: service client-side state"); 12444 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12445 pw.println(" all: dump all activities"); 12446 pw.println(" top: dump the top activity"); 12447 pw.println(" write: write all pending state to storage"); 12448 pw.println(" track-associations: enable association tracking"); 12449 pw.println(" untrack-associations: disable and clear association tracking"); 12450 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12451 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12452 pw.println(" a partial substring in a component name, a"); 12453 pw.println(" hex object identifier."); 12454 pw.println(" -a: include all available server state."); 12455 pw.println(" -c: include client state."); 12456 pw.println(" -p: limit output to given package."); 12457 return; 12458 } else { 12459 pw.println("Unknown argument: " + opt + "; use -h for help"); 12460 } 12461 } 12462 12463 long origId = Binder.clearCallingIdentity(); 12464 boolean more = false; 12465 // Is the caller requesting to dump a particular piece of data? 12466 if (opti < args.length) { 12467 String cmd = args[opti]; 12468 opti++; 12469 if ("activities".equals(cmd) || "a".equals(cmd)) { 12470 synchronized (this) { 12471 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12472 } 12473 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12474 synchronized (this) { 12475 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12476 } 12477 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12478 String[] newArgs; 12479 String name; 12480 if (opti >= args.length) { 12481 name = null; 12482 newArgs = EMPTY_STRING_ARRAY; 12483 } else { 12484 dumpPackage = args[opti]; 12485 opti++; 12486 newArgs = new String[args.length - opti]; 12487 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12488 args.length - opti); 12489 } 12490 synchronized (this) { 12491 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12492 } 12493 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12494 String[] newArgs; 12495 String name; 12496 if (opti >= args.length) { 12497 name = null; 12498 newArgs = EMPTY_STRING_ARRAY; 12499 } else { 12500 dumpPackage = args[opti]; 12501 opti++; 12502 newArgs = new String[args.length - opti]; 12503 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12504 args.length - opti); 12505 } 12506 synchronized (this) { 12507 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12508 } 12509 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12510 String[] newArgs; 12511 String name; 12512 if (opti >= args.length) { 12513 name = null; 12514 newArgs = EMPTY_STRING_ARRAY; 12515 } else { 12516 dumpPackage = args[opti]; 12517 opti++; 12518 newArgs = new String[args.length - opti]; 12519 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12520 args.length - opti); 12521 } 12522 synchronized (this) { 12523 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12524 } 12525 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12526 synchronized (this) { 12527 dumpOomLocked(fd, pw, args, opti, true); 12528 } 12529 } else if ("provider".equals(cmd)) { 12530 String[] newArgs; 12531 String name; 12532 if (opti >= args.length) { 12533 name = null; 12534 newArgs = EMPTY_STRING_ARRAY; 12535 } else { 12536 name = args[opti]; 12537 opti++; 12538 newArgs = new String[args.length - opti]; 12539 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12540 } 12541 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12542 pw.println("No providers match: " + name); 12543 pw.println("Use -h for help."); 12544 } 12545 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12546 synchronized (this) { 12547 dumpProvidersLocked(fd, pw, args, opti, true, null); 12548 } 12549 } else if ("service".equals(cmd)) { 12550 String[] newArgs; 12551 String name; 12552 if (opti >= args.length) { 12553 name = null; 12554 newArgs = EMPTY_STRING_ARRAY; 12555 } else { 12556 name = args[opti]; 12557 opti++; 12558 newArgs = new String[args.length - opti]; 12559 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12560 args.length - opti); 12561 } 12562 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12563 pw.println("No services match: " + name); 12564 pw.println("Use -h for help."); 12565 } 12566 } else if ("package".equals(cmd)) { 12567 String[] newArgs; 12568 if (opti >= args.length) { 12569 pw.println("package: no package name specified"); 12570 pw.println("Use -h for help."); 12571 } else { 12572 dumpPackage = args[opti]; 12573 opti++; 12574 newArgs = new String[args.length - opti]; 12575 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12576 args.length - opti); 12577 args = newArgs; 12578 opti = 0; 12579 more = true; 12580 } 12581 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12582 synchronized (this) { 12583 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12584 } 12585 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12586 synchronized (this) { 12587 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12588 } 12589 } else if ("write".equals(cmd)) { 12590 mTaskPersister.flush(); 12591 pw.println("All tasks persisted."); 12592 return; 12593 } else if ("track-associations".equals(cmd)) { 12594 synchronized (this) { 12595 if (!mTrackingAssociations) { 12596 mTrackingAssociations = true; 12597 pw.println("Association tracking started."); 12598 } else { 12599 pw.println("Association tracking already enabled."); 12600 } 12601 } 12602 return; 12603 } else if ("untrack-associations".equals(cmd)) { 12604 synchronized (this) { 12605 if (mTrackingAssociations) { 12606 mTrackingAssociations = false; 12607 mAssociations.clear(); 12608 pw.println("Association tracking stopped."); 12609 } else { 12610 pw.println("Association tracking not running."); 12611 } 12612 } 12613 return; 12614 } else { 12615 // Dumping a single activity? 12616 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12617 pw.println("Bad activity command, or no activities match: " + cmd); 12618 pw.println("Use -h for help."); 12619 } 12620 } 12621 if (!more) { 12622 Binder.restoreCallingIdentity(origId); 12623 return; 12624 } 12625 } 12626 12627 // No piece of data specified, dump everything. 12628 synchronized (this) { 12629 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12630 pw.println(); 12631 if (dumpAll) { 12632 pw.println("-------------------------------------------------------------------------------"); 12633 } 12634 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12635 pw.println(); 12636 if (dumpAll) { 12637 pw.println("-------------------------------------------------------------------------------"); 12638 } 12639 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12640 pw.println(); 12641 if (dumpAll) { 12642 pw.println("-------------------------------------------------------------------------------"); 12643 } 12644 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12645 pw.println(); 12646 if (dumpAll) { 12647 pw.println("-------------------------------------------------------------------------------"); 12648 } 12649 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12650 pw.println(); 12651 if (dumpAll) { 12652 pw.println("-------------------------------------------------------------------------------"); 12653 } 12654 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12655 if (mAssociations.size() > 0) { 12656 pw.println(); 12657 if (dumpAll) { 12658 pw.println("-------------------------------------------------------------------------------"); 12659 } 12660 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12661 } 12662 pw.println(); 12663 if (dumpAll) { 12664 pw.println("-------------------------------------------------------------------------------"); 12665 } 12666 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12667 } 12668 Binder.restoreCallingIdentity(origId); 12669 } 12670 12671 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12672 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12673 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12674 12675 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12676 dumpPackage); 12677 boolean needSep = printedAnything; 12678 12679 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12680 dumpPackage, needSep, " mFocusedActivity: "); 12681 if (printed) { 12682 printedAnything = true; 12683 needSep = false; 12684 } 12685 12686 if (dumpPackage == null) { 12687 if (needSep) { 12688 pw.println(); 12689 } 12690 needSep = true; 12691 printedAnything = true; 12692 mStackSupervisor.dump(pw, " "); 12693 } 12694 12695 if (!printedAnything) { 12696 pw.println(" (nothing)"); 12697 } 12698 } 12699 12700 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12701 int opti, boolean dumpAll, String dumpPackage) { 12702 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12703 12704 boolean printedAnything = false; 12705 12706 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12707 boolean printedHeader = false; 12708 12709 final int N = mRecentTasks.size(); 12710 for (int i=0; i<N; i++) { 12711 TaskRecord tr = mRecentTasks.get(i); 12712 if (dumpPackage != null) { 12713 if (tr.realActivity == null || 12714 !dumpPackage.equals(tr.realActivity)) { 12715 continue; 12716 } 12717 } 12718 if (!printedHeader) { 12719 pw.println(" Recent tasks:"); 12720 printedHeader = true; 12721 printedAnything = true; 12722 } 12723 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12724 pw.println(tr); 12725 if (dumpAll) { 12726 mRecentTasks.get(i).dump(pw, " "); 12727 } 12728 } 12729 } 12730 12731 if (!printedAnything) { 12732 pw.println(" (nothing)"); 12733 } 12734 } 12735 12736 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12737 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12738 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12739 12740 int dumpUid = 0; 12741 if (dumpPackage != null) { 12742 IPackageManager pm = AppGlobals.getPackageManager(); 12743 try { 12744 dumpUid = pm.getPackageUid(dumpPackage, 0); 12745 } catch (RemoteException e) { 12746 } 12747 } 12748 12749 boolean printedAnything = false; 12750 12751 final long now = SystemClock.uptimeMillis(); 12752 12753 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12754 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12755 = mAssociations.valueAt(i1); 12756 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12757 SparseArray<ArrayMap<String, Association>> sourceUids 12758 = targetComponents.valueAt(i2); 12759 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12760 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12761 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12762 Association ass = sourceProcesses.valueAt(i4); 12763 if (dumpPackage != null) { 12764 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12765 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12766 continue; 12767 } 12768 } 12769 printedAnything = true; 12770 pw.print(" "); 12771 pw.print(ass.mTargetProcess); 12772 pw.print("/"); 12773 UserHandle.formatUid(pw, ass.mTargetUid); 12774 pw.print(" <- "); 12775 pw.print(ass.mSourceProcess); 12776 pw.print("/"); 12777 UserHandle.formatUid(pw, ass.mSourceUid); 12778 pw.println(); 12779 pw.print(" via "); 12780 pw.print(ass.mTargetComponent.flattenToShortString()); 12781 pw.println(); 12782 pw.print(" "); 12783 long dur = ass.mTime; 12784 if (ass.mNesting > 0) { 12785 dur += now - ass.mStartTime; 12786 } 12787 TimeUtils.formatDuration(dur, pw); 12788 pw.print(" ("); 12789 pw.print(ass.mCount); 12790 pw.println(" times)"); 12791 if (ass.mNesting > 0) { 12792 pw.print(" "); 12793 pw.print(" Currently active: "); 12794 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12795 pw.println(); 12796 } 12797 } 12798 } 12799 } 12800 12801 } 12802 12803 if (!printedAnything) { 12804 pw.println(" (nothing)"); 12805 } 12806 } 12807 12808 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12809 int opti, boolean dumpAll, String dumpPackage) { 12810 boolean needSep = false; 12811 boolean printedAnything = false; 12812 int numPers = 0; 12813 12814 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12815 12816 if (dumpAll) { 12817 final int NP = mProcessNames.getMap().size(); 12818 for (int ip=0; ip<NP; ip++) { 12819 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12820 final int NA = procs.size(); 12821 for (int ia=0; ia<NA; ia++) { 12822 ProcessRecord r = procs.valueAt(ia); 12823 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12824 continue; 12825 } 12826 if (!needSep) { 12827 pw.println(" All known processes:"); 12828 needSep = true; 12829 printedAnything = true; 12830 } 12831 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12832 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12833 pw.print(" "); pw.println(r); 12834 r.dump(pw, " "); 12835 if (r.persistent) { 12836 numPers++; 12837 } 12838 } 12839 } 12840 } 12841 12842 if (mIsolatedProcesses.size() > 0) { 12843 boolean printed = false; 12844 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12845 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12846 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12847 continue; 12848 } 12849 if (!printed) { 12850 if (needSep) { 12851 pw.println(); 12852 } 12853 pw.println(" Isolated process list (sorted by uid):"); 12854 printedAnything = true; 12855 printed = true; 12856 needSep = true; 12857 } 12858 pw.println(String.format("%sIsolated #%2d: %s", 12859 " ", i, r.toString())); 12860 } 12861 } 12862 12863 if (mLruProcesses.size() > 0) { 12864 if (needSep) { 12865 pw.println(); 12866 } 12867 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12868 pw.print(" total, non-act at "); 12869 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12870 pw.print(", non-svc at "); 12871 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12872 pw.println("):"); 12873 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12874 needSep = true; 12875 printedAnything = true; 12876 } 12877 12878 if (dumpAll || dumpPackage != null) { 12879 synchronized (mPidsSelfLocked) { 12880 boolean printed = false; 12881 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12882 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12883 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12884 continue; 12885 } 12886 if (!printed) { 12887 if (needSep) pw.println(); 12888 needSep = true; 12889 pw.println(" PID mappings:"); 12890 printed = true; 12891 printedAnything = true; 12892 } 12893 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12894 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12895 } 12896 } 12897 } 12898 12899 if (mForegroundProcesses.size() > 0) { 12900 synchronized (mPidsSelfLocked) { 12901 boolean printed = false; 12902 for (int i=0; i<mForegroundProcesses.size(); i++) { 12903 ProcessRecord r = mPidsSelfLocked.get( 12904 mForegroundProcesses.valueAt(i).pid); 12905 if (dumpPackage != null && (r == null 12906 || !r.pkgList.containsKey(dumpPackage))) { 12907 continue; 12908 } 12909 if (!printed) { 12910 if (needSep) pw.println(); 12911 needSep = true; 12912 pw.println(" Foreground Processes:"); 12913 printed = true; 12914 printedAnything = true; 12915 } 12916 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12917 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12918 } 12919 } 12920 } 12921 12922 if (mPersistentStartingProcesses.size() > 0) { 12923 if (needSep) pw.println(); 12924 needSep = true; 12925 printedAnything = true; 12926 pw.println(" Persisent processes that are starting:"); 12927 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12928 "Starting Norm", "Restarting PERS", dumpPackage); 12929 } 12930 12931 if (mRemovedProcesses.size() > 0) { 12932 if (needSep) pw.println(); 12933 needSep = true; 12934 printedAnything = true; 12935 pw.println(" Processes that are being removed:"); 12936 dumpProcessList(pw, this, mRemovedProcesses, " ", 12937 "Removed Norm", "Removed PERS", dumpPackage); 12938 } 12939 12940 if (mProcessesOnHold.size() > 0) { 12941 if (needSep) pw.println(); 12942 needSep = true; 12943 printedAnything = true; 12944 pw.println(" Processes that are on old until the system is ready:"); 12945 dumpProcessList(pw, this, mProcessesOnHold, " ", 12946 "OnHold Norm", "OnHold PERS", dumpPackage); 12947 } 12948 12949 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12950 12951 if (mProcessCrashTimes.getMap().size() > 0) { 12952 boolean printed = false; 12953 long now = SystemClock.uptimeMillis(); 12954 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12955 final int NP = pmap.size(); 12956 for (int ip=0; ip<NP; ip++) { 12957 String pname = pmap.keyAt(ip); 12958 SparseArray<Long> uids = pmap.valueAt(ip); 12959 final int N = uids.size(); 12960 for (int i=0; i<N; i++) { 12961 int puid = uids.keyAt(i); 12962 ProcessRecord r = mProcessNames.get(pname, puid); 12963 if (dumpPackage != null && (r == null 12964 || !r.pkgList.containsKey(dumpPackage))) { 12965 continue; 12966 } 12967 if (!printed) { 12968 if (needSep) pw.println(); 12969 needSep = true; 12970 pw.println(" Time since processes crashed:"); 12971 printed = true; 12972 printedAnything = true; 12973 } 12974 pw.print(" Process "); pw.print(pname); 12975 pw.print(" uid "); pw.print(puid); 12976 pw.print(": last crashed "); 12977 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12978 pw.println(" ago"); 12979 } 12980 } 12981 } 12982 12983 if (mBadProcesses.getMap().size() > 0) { 12984 boolean printed = false; 12985 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12986 final int NP = pmap.size(); 12987 for (int ip=0; ip<NP; ip++) { 12988 String pname = pmap.keyAt(ip); 12989 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12990 final int N = uids.size(); 12991 for (int i=0; i<N; i++) { 12992 int puid = uids.keyAt(i); 12993 ProcessRecord r = mProcessNames.get(pname, puid); 12994 if (dumpPackage != null && (r == null 12995 || !r.pkgList.containsKey(dumpPackage))) { 12996 continue; 12997 } 12998 if (!printed) { 12999 if (needSep) pw.println(); 13000 needSep = true; 13001 pw.println(" Bad processes:"); 13002 printedAnything = true; 13003 } 13004 BadProcessInfo info = uids.valueAt(i); 13005 pw.print(" Bad process "); pw.print(pname); 13006 pw.print(" uid "); pw.print(puid); 13007 pw.print(": crashed at time "); pw.println(info.time); 13008 if (info.shortMsg != null) { 13009 pw.print(" Short msg: "); pw.println(info.shortMsg); 13010 } 13011 if (info.longMsg != null) { 13012 pw.print(" Long msg: "); pw.println(info.longMsg); 13013 } 13014 if (info.stack != null) { 13015 pw.println(" Stack:"); 13016 int lastPos = 0; 13017 for (int pos=0; pos<info.stack.length(); pos++) { 13018 if (info.stack.charAt(pos) == '\n') { 13019 pw.print(" "); 13020 pw.write(info.stack, lastPos, pos-lastPos); 13021 pw.println(); 13022 lastPos = pos+1; 13023 } 13024 } 13025 if (lastPos < info.stack.length()) { 13026 pw.print(" "); 13027 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 13028 pw.println(); 13029 } 13030 } 13031 } 13032 } 13033 } 13034 13035 if (dumpPackage == null) { 13036 pw.println(); 13037 needSep = false; 13038 pw.println(" mStartedUsers:"); 13039 for (int i=0; i<mStartedUsers.size(); i++) { 13040 UserStartedState uss = mStartedUsers.valueAt(i); 13041 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 13042 pw.print(": "); uss.dump("", pw); 13043 } 13044 pw.print(" mStartedUserArray: ["); 13045 for (int i=0; i<mStartedUserArray.length; i++) { 13046 if (i > 0) pw.print(", "); 13047 pw.print(mStartedUserArray[i]); 13048 } 13049 pw.println("]"); 13050 pw.print(" mUserLru: ["); 13051 for (int i=0; i<mUserLru.size(); i++) { 13052 if (i > 0) pw.print(", "); 13053 pw.print(mUserLru.get(i)); 13054 } 13055 pw.println("]"); 13056 if (dumpAll) { 13057 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 13058 } 13059 synchronized (mUserProfileGroupIdsSelfLocked) { 13060 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 13061 pw.println(" mUserProfileGroupIds:"); 13062 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 13063 pw.print(" User #"); 13064 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 13065 pw.print(" -> profile #"); 13066 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 13067 } 13068 } 13069 } 13070 } 13071 if (mHomeProcess != null && (dumpPackage == null 13072 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13073 if (needSep) { 13074 pw.println(); 13075 needSep = false; 13076 } 13077 pw.println(" mHomeProcess: " + mHomeProcess); 13078 } 13079 if (mPreviousProcess != null && (dumpPackage == null 13080 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13081 if (needSep) { 13082 pw.println(); 13083 needSep = false; 13084 } 13085 pw.println(" mPreviousProcess: " + mPreviousProcess); 13086 } 13087 if (dumpAll) { 13088 StringBuilder sb = new StringBuilder(128); 13089 sb.append(" mPreviousProcessVisibleTime: "); 13090 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13091 pw.println(sb); 13092 } 13093 if (mHeavyWeightProcess != null && (dumpPackage == null 13094 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13095 if (needSep) { 13096 pw.println(); 13097 needSep = false; 13098 } 13099 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13100 } 13101 if (dumpPackage == null) { 13102 pw.println(" mConfiguration: " + mConfiguration); 13103 } 13104 if (dumpAll) { 13105 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13106 if (mCompatModePackages.getPackages().size() > 0) { 13107 boolean printed = false; 13108 for (Map.Entry<String, Integer> entry 13109 : mCompatModePackages.getPackages().entrySet()) { 13110 String pkg = entry.getKey(); 13111 int mode = entry.getValue(); 13112 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13113 continue; 13114 } 13115 if (!printed) { 13116 pw.println(" mScreenCompatPackages:"); 13117 printed = true; 13118 } 13119 pw.print(" "); pw.print(pkg); pw.print(": "); 13120 pw.print(mode); pw.println(); 13121 } 13122 } 13123 } 13124 if (dumpPackage == null) { 13125 pw.println(" mWakefulness=" 13126 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13127 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13128 + lockScreenShownToString()); 13129 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13130 + " mTestPssMode=" + mTestPssMode); 13131 } 13132 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13133 || mOrigWaitForDebugger) { 13134 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13135 || dumpPackage.equals(mOrigDebugApp)) { 13136 if (needSep) { 13137 pw.println(); 13138 needSep = false; 13139 } 13140 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13141 + " mDebugTransient=" + mDebugTransient 13142 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13143 } 13144 } 13145 if (mOpenGlTraceApp != null) { 13146 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13147 if (needSep) { 13148 pw.println(); 13149 needSep = false; 13150 } 13151 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13152 } 13153 } 13154 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13155 || mProfileFd != null) { 13156 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13157 if (needSep) { 13158 pw.println(); 13159 needSep = false; 13160 } 13161 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13162 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13163 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13164 + mAutoStopProfiler); 13165 pw.println(" mProfileType=" + mProfileType); 13166 } 13167 } 13168 if (dumpPackage == null) { 13169 if (mAlwaysFinishActivities || mController != null) { 13170 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13171 + " mController=" + mController); 13172 } 13173 if (dumpAll) { 13174 pw.println(" Total persistent processes: " + numPers); 13175 pw.println(" mProcessesReady=" + mProcessesReady 13176 + " mSystemReady=" + mSystemReady 13177 + " mBooted=" + mBooted 13178 + " mFactoryTest=" + mFactoryTest); 13179 pw.println(" mBooting=" + mBooting 13180 + " mCallFinishBooting=" + mCallFinishBooting 13181 + " mBootAnimationComplete=" + mBootAnimationComplete); 13182 pw.print(" mLastPowerCheckRealtime="); 13183 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13184 pw.println(""); 13185 pw.print(" mLastPowerCheckUptime="); 13186 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13187 pw.println(""); 13188 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13189 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13190 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13191 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13192 + " (" + mLruProcesses.size() + " total)" 13193 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13194 + " mNumServiceProcs=" + mNumServiceProcs 13195 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13196 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13197 + " mLastMemoryLevel" + mLastMemoryLevel 13198 + " mLastNumProcesses" + mLastNumProcesses); 13199 long now = SystemClock.uptimeMillis(); 13200 pw.print(" mLastIdleTime="); 13201 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13202 pw.print(" mLowRamSinceLastIdle="); 13203 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13204 pw.println(); 13205 } 13206 } 13207 13208 if (!printedAnything) { 13209 pw.println(" (nothing)"); 13210 } 13211 } 13212 13213 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13214 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13215 if (mProcessesToGc.size() > 0) { 13216 boolean printed = false; 13217 long now = SystemClock.uptimeMillis(); 13218 for (int i=0; i<mProcessesToGc.size(); i++) { 13219 ProcessRecord proc = mProcessesToGc.get(i); 13220 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13221 continue; 13222 } 13223 if (!printed) { 13224 if (needSep) pw.println(); 13225 needSep = true; 13226 pw.println(" Processes that are waiting to GC:"); 13227 printed = true; 13228 } 13229 pw.print(" Process "); pw.println(proc); 13230 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13231 pw.print(", last gced="); 13232 pw.print(now-proc.lastRequestedGc); 13233 pw.print(" ms ago, last lowMem="); 13234 pw.print(now-proc.lastLowMemory); 13235 pw.println(" ms ago"); 13236 13237 } 13238 } 13239 return needSep; 13240 } 13241 13242 void printOomLevel(PrintWriter pw, String name, int adj) { 13243 pw.print(" "); 13244 if (adj >= 0) { 13245 pw.print(' '); 13246 if (adj < 10) pw.print(' '); 13247 } else { 13248 if (adj > -10) pw.print(' '); 13249 } 13250 pw.print(adj); 13251 pw.print(": "); 13252 pw.print(name); 13253 pw.print(" ("); 13254 pw.print(mProcessList.getMemLevel(adj)/1024); 13255 pw.println(" kB)"); 13256 } 13257 13258 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13259 int opti, boolean dumpAll) { 13260 boolean needSep = false; 13261 13262 if (mLruProcesses.size() > 0) { 13263 if (needSep) pw.println(); 13264 needSep = true; 13265 pw.println(" OOM levels:"); 13266 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13267 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13268 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13269 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13270 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13271 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13272 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13273 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13274 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13275 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13276 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13277 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13278 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13279 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13280 13281 if (needSep) pw.println(); 13282 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13283 pw.print(" total, non-act at "); 13284 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13285 pw.print(", non-svc at "); 13286 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13287 pw.println("):"); 13288 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13289 needSep = true; 13290 } 13291 13292 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13293 13294 pw.println(); 13295 pw.println(" mHomeProcess: " + mHomeProcess); 13296 pw.println(" mPreviousProcess: " + mPreviousProcess); 13297 if (mHeavyWeightProcess != null) { 13298 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13299 } 13300 13301 return true; 13302 } 13303 13304 /** 13305 * There are three ways to call this: 13306 * - no provider specified: dump all the providers 13307 * - a flattened component name that matched an existing provider was specified as the 13308 * first arg: dump that one provider 13309 * - the first arg isn't the flattened component name of an existing provider: 13310 * dump all providers whose component contains the first arg as a substring 13311 */ 13312 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13313 int opti, boolean dumpAll) { 13314 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13315 } 13316 13317 static class ItemMatcher { 13318 ArrayList<ComponentName> components; 13319 ArrayList<String> strings; 13320 ArrayList<Integer> objects; 13321 boolean all; 13322 13323 ItemMatcher() { 13324 all = true; 13325 } 13326 13327 void build(String name) { 13328 ComponentName componentName = ComponentName.unflattenFromString(name); 13329 if (componentName != null) { 13330 if (components == null) { 13331 components = new ArrayList<ComponentName>(); 13332 } 13333 components.add(componentName); 13334 all = false; 13335 } else { 13336 int objectId = 0; 13337 // Not a '/' separated full component name; maybe an object ID? 13338 try { 13339 objectId = Integer.parseInt(name, 16); 13340 if (objects == null) { 13341 objects = new ArrayList<Integer>(); 13342 } 13343 objects.add(objectId); 13344 all = false; 13345 } catch (RuntimeException e) { 13346 // Not an integer; just do string match. 13347 if (strings == null) { 13348 strings = new ArrayList<String>(); 13349 } 13350 strings.add(name); 13351 all = false; 13352 } 13353 } 13354 } 13355 13356 int build(String[] args, int opti) { 13357 for (; opti<args.length; opti++) { 13358 String name = args[opti]; 13359 if ("--".equals(name)) { 13360 return opti+1; 13361 } 13362 build(name); 13363 } 13364 return opti; 13365 } 13366 13367 boolean match(Object object, ComponentName comp) { 13368 if (all) { 13369 return true; 13370 } 13371 if (components != null) { 13372 for (int i=0; i<components.size(); i++) { 13373 if (components.get(i).equals(comp)) { 13374 return true; 13375 } 13376 } 13377 } 13378 if (objects != null) { 13379 for (int i=0; i<objects.size(); i++) { 13380 if (System.identityHashCode(object) == objects.get(i)) { 13381 return true; 13382 } 13383 } 13384 } 13385 if (strings != null) { 13386 String flat = comp.flattenToString(); 13387 for (int i=0; i<strings.size(); i++) { 13388 if (flat.contains(strings.get(i))) { 13389 return true; 13390 } 13391 } 13392 } 13393 return false; 13394 } 13395 } 13396 13397 /** 13398 * There are three things that cmd can be: 13399 * - a flattened component name that matches an existing activity 13400 * - the cmd arg isn't the flattened component name of an existing activity: 13401 * dump all activity whose component contains the cmd as a substring 13402 * - A hex number of the ActivityRecord object instance. 13403 */ 13404 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13405 int opti, boolean dumpAll) { 13406 ArrayList<ActivityRecord> activities; 13407 13408 synchronized (this) { 13409 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13410 } 13411 13412 if (activities.size() <= 0) { 13413 return false; 13414 } 13415 13416 String[] newArgs = new String[args.length - opti]; 13417 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13418 13419 TaskRecord lastTask = null; 13420 boolean needSep = false; 13421 for (int i=activities.size()-1; i>=0; i--) { 13422 ActivityRecord r = activities.get(i); 13423 if (needSep) { 13424 pw.println(); 13425 } 13426 needSep = true; 13427 synchronized (this) { 13428 if (lastTask != r.task) { 13429 lastTask = r.task; 13430 pw.print("TASK "); pw.print(lastTask.affinity); 13431 pw.print(" id="); pw.println(lastTask.taskId); 13432 if (dumpAll) { 13433 lastTask.dump(pw, " "); 13434 } 13435 } 13436 } 13437 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13438 } 13439 return true; 13440 } 13441 13442 /** 13443 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13444 * there is a thread associated with the activity. 13445 */ 13446 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13447 final ActivityRecord r, String[] args, boolean dumpAll) { 13448 String innerPrefix = prefix + " "; 13449 synchronized (this) { 13450 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13451 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13452 pw.print(" pid="); 13453 if (r.app != null) pw.println(r.app.pid); 13454 else pw.println("(not running)"); 13455 if (dumpAll) { 13456 r.dump(pw, innerPrefix); 13457 } 13458 } 13459 if (r.app != null && r.app.thread != null) { 13460 // flush anything that is already in the PrintWriter since the thread is going 13461 // to write to the file descriptor directly 13462 pw.flush(); 13463 try { 13464 TransferPipe tp = new TransferPipe(); 13465 try { 13466 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13467 r.appToken, innerPrefix, args); 13468 tp.go(fd); 13469 } finally { 13470 tp.kill(); 13471 } 13472 } catch (IOException e) { 13473 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13474 } catch (RemoteException e) { 13475 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13476 } 13477 } 13478 } 13479 13480 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13481 int opti, boolean dumpAll, String dumpPackage) { 13482 boolean needSep = false; 13483 boolean onlyHistory = false; 13484 boolean printedAnything = false; 13485 13486 if ("history".equals(dumpPackage)) { 13487 if (opti < args.length && "-s".equals(args[opti])) { 13488 dumpAll = false; 13489 } 13490 onlyHistory = true; 13491 dumpPackage = null; 13492 } 13493 13494 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13495 if (!onlyHistory && dumpAll) { 13496 if (mRegisteredReceivers.size() > 0) { 13497 boolean printed = false; 13498 Iterator it = mRegisteredReceivers.values().iterator(); 13499 while (it.hasNext()) { 13500 ReceiverList r = (ReceiverList)it.next(); 13501 if (dumpPackage != null && (r.app == null || 13502 !dumpPackage.equals(r.app.info.packageName))) { 13503 continue; 13504 } 13505 if (!printed) { 13506 pw.println(" Registered Receivers:"); 13507 needSep = true; 13508 printed = true; 13509 printedAnything = true; 13510 } 13511 pw.print(" * "); pw.println(r); 13512 r.dump(pw, " "); 13513 } 13514 } 13515 13516 if (mReceiverResolver.dump(pw, needSep ? 13517 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13518 " ", dumpPackage, false, false)) { 13519 needSep = true; 13520 printedAnything = true; 13521 } 13522 } 13523 13524 for (BroadcastQueue q : mBroadcastQueues) { 13525 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13526 printedAnything |= needSep; 13527 } 13528 13529 needSep = true; 13530 13531 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13532 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13533 if (needSep) { 13534 pw.println(); 13535 } 13536 needSep = true; 13537 printedAnything = true; 13538 pw.print(" Sticky broadcasts for user "); 13539 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13540 StringBuilder sb = new StringBuilder(128); 13541 for (Map.Entry<String, ArrayList<Intent>> ent 13542 : mStickyBroadcasts.valueAt(user).entrySet()) { 13543 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13544 if (dumpAll) { 13545 pw.println(":"); 13546 ArrayList<Intent> intents = ent.getValue(); 13547 final int N = intents.size(); 13548 for (int i=0; i<N; i++) { 13549 sb.setLength(0); 13550 sb.append(" Intent: "); 13551 intents.get(i).toShortString(sb, false, true, false, false); 13552 pw.println(sb.toString()); 13553 Bundle bundle = intents.get(i).getExtras(); 13554 if (bundle != null) { 13555 pw.print(" "); 13556 pw.println(bundle.toString()); 13557 } 13558 } 13559 } else { 13560 pw.println(""); 13561 } 13562 } 13563 } 13564 } 13565 13566 if (!onlyHistory && dumpAll) { 13567 pw.println(); 13568 for (BroadcastQueue queue : mBroadcastQueues) { 13569 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13570 + queue.mBroadcastsScheduled); 13571 } 13572 pw.println(" mHandler:"); 13573 mHandler.dump(new PrintWriterPrinter(pw), " "); 13574 needSep = true; 13575 printedAnything = true; 13576 } 13577 13578 if (!printedAnything) { 13579 pw.println(" (nothing)"); 13580 } 13581 } 13582 13583 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13584 int opti, boolean dumpAll, String dumpPackage) { 13585 boolean needSep; 13586 boolean printedAnything = false; 13587 13588 ItemMatcher matcher = new ItemMatcher(); 13589 matcher.build(args, opti); 13590 13591 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13592 13593 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13594 printedAnything |= needSep; 13595 13596 if (mLaunchingProviders.size() > 0) { 13597 boolean printed = false; 13598 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13599 ContentProviderRecord r = mLaunchingProviders.get(i); 13600 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13601 continue; 13602 } 13603 if (!printed) { 13604 if (needSep) pw.println(); 13605 needSep = true; 13606 pw.println(" Launching content providers:"); 13607 printed = true; 13608 printedAnything = true; 13609 } 13610 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13611 pw.println(r); 13612 } 13613 } 13614 13615 if (mGrantedUriPermissions.size() > 0) { 13616 boolean printed = false; 13617 int dumpUid = -2; 13618 if (dumpPackage != null) { 13619 try { 13620 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13621 } catch (NameNotFoundException e) { 13622 dumpUid = -1; 13623 } 13624 } 13625 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13626 int uid = mGrantedUriPermissions.keyAt(i); 13627 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13628 continue; 13629 } 13630 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13631 if (!printed) { 13632 if (needSep) pw.println(); 13633 needSep = true; 13634 pw.println(" Granted Uri Permissions:"); 13635 printed = true; 13636 printedAnything = true; 13637 } 13638 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13639 for (UriPermission perm : perms.values()) { 13640 pw.print(" "); pw.println(perm); 13641 if (dumpAll) { 13642 perm.dump(pw, " "); 13643 } 13644 } 13645 } 13646 } 13647 13648 if (!printedAnything) { 13649 pw.println(" (nothing)"); 13650 } 13651 } 13652 13653 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13654 int opti, boolean dumpAll, String dumpPackage) { 13655 boolean printed = false; 13656 13657 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13658 13659 if (mIntentSenderRecords.size() > 0) { 13660 Iterator<WeakReference<PendingIntentRecord>> it 13661 = mIntentSenderRecords.values().iterator(); 13662 while (it.hasNext()) { 13663 WeakReference<PendingIntentRecord> ref = it.next(); 13664 PendingIntentRecord rec = ref != null ? ref.get(): null; 13665 if (dumpPackage != null && (rec == null 13666 || !dumpPackage.equals(rec.key.packageName))) { 13667 continue; 13668 } 13669 printed = true; 13670 if (rec != null) { 13671 pw.print(" * "); pw.println(rec); 13672 if (dumpAll) { 13673 rec.dump(pw, " "); 13674 } 13675 } else { 13676 pw.print(" * "); pw.println(ref); 13677 } 13678 } 13679 } 13680 13681 if (!printed) { 13682 pw.println(" (nothing)"); 13683 } 13684 } 13685 13686 private static final int dumpProcessList(PrintWriter pw, 13687 ActivityManagerService service, List list, 13688 String prefix, String normalLabel, String persistentLabel, 13689 String dumpPackage) { 13690 int numPers = 0; 13691 final int N = list.size()-1; 13692 for (int i=N; i>=0; i--) { 13693 ProcessRecord r = (ProcessRecord)list.get(i); 13694 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13695 continue; 13696 } 13697 pw.println(String.format("%s%s #%2d: %s", 13698 prefix, (r.persistent ? persistentLabel : normalLabel), 13699 i, r.toString())); 13700 if (r.persistent) { 13701 numPers++; 13702 } 13703 } 13704 return numPers; 13705 } 13706 13707 private static final boolean dumpProcessOomList(PrintWriter pw, 13708 ActivityManagerService service, List<ProcessRecord> origList, 13709 String prefix, String normalLabel, String persistentLabel, 13710 boolean inclDetails, String dumpPackage) { 13711 13712 ArrayList<Pair<ProcessRecord, Integer>> list 13713 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13714 for (int i=0; i<origList.size(); i++) { 13715 ProcessRecord r = origList.get(i); 13716 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13717 continue; 13718 } 13719 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13720 } 13721 13722 if (list.size() <= 0) { 13723 return false; 13724 } 13725 13726 Comparator<Pair<ProcessRecord, Integer>> comparator 13727 = new Comparator<Pair<ProcessRecord, Integer>>() { 13728 @Override 13729 public int compare(Pair<ProcessRecord, Integer> object1, 13730 Pair<ProcessRecord, Integer> object2) { 13731 if (object1.first.setAdj != object2.first.setAdj) { 13732 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13733 } 13734 if (object1.second.intValue() != object2.second.intValue()) { 13735 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13736 } 13737 return 0; 13738 } 13739 }; 13740 13741 Collections.sort(list, comparator); 13742 13743 final long curRealtime = SystemClock.elapsedRealtime(); 13744 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13745 final long curUptime = SystemClock.uptimeMillis(); 13746 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13747 13748 for (int i=list.size()-1; i>=0; i--) { 13749 ProcessRecord r = list.get(i).first; 13750 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13751 char schedGroup; 13752 switch (r.setSchedGroup) { 13753 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13754 schedGroup = 'B'; 13755 break; 13756 case Process.THREAD_GROUP_DEFAULT: 13757 schedGroup = 'F'; 13758 break; 13759 default: 13760 schedGroup = '?'; 13761 break; 13762 } 13763 char foreground; 13764 if (r.foregroundActivities) { 13765 foreground = 'A'; 13766 } else if (r.foregroundServices) { 13767 foreground = 'S'; 13768 } else { 13769 foreground = ' '; 13770 } 13771 String procState = ProcessList.makeProcStateString(r.curProcState); 13772 pw.print(prefix); 13773 pw.print(r.persistent ? persistentLabel : normalLabel); 13774 pw.print(" #"); 13775 int num = (origList.size()-1)-list.get(i).second; 13776 if (num < 10) pw.print(' '); 13777 pw.print(num); 13778 pw.print(": "); 13779 pw.print(oomAdj); 13780 pw.print(' '); 13781 pw.print(schedGroup); 13782 pw.print('/'); 13783 pw.print(foreground); 13784 pw.print('/'); 13785 pw.print(procState); 13786 pw.print(" trm:"); 13787 if (r.trimMemoryLevel < 10) pw.print(' '); 13788 pw.print(r.trimMemoryLevel); 13789 pw.print(' '); 13790 pw.print(r.toShortString()); 13791 pw.print(" ("); 13792 pw.print(r.adjType); 13793 pw.println(')'); 13794 if (r.adjSource != null || r.adjTarget != null) { 13795 pw.print(prefix); 13796 pw.print(" "); 13797 if (r.adjTarget instanceof ComponentName) { 13798 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13799 } else if (r.adjTarget != null) { 13800 pw.print(r.adjTarget.toString()); 13801 } else { 13802 pw.print("{null}"); 13803 } 13804 pw.print("<="); 13805 if (r.adjSource instanceof ProcessRecord) { 13806 pw.print("Proc{"); 13807 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13808 pw.println("}"); 13809 } else if (r.adjSource != null) { 13810 pw.println(r.adjSource.toString()); 13811 } else { 13812 pw.println("{null}"); 13813 } 13814 } 13815 if (inclDetails) { 13816 pw.print(prefix); 13817 pw.print(" "); 13818 pw.print("oom: max="); pw.print(r.maxAdj); 13819 pw.print(" curRaw="); pw.print(r.curRawAdj); 13820 pw.print(" setRaw="); pw.print(r.setRawAdj); 13821 pw.print(" cur="); pw.print(r.curAdj); 13822 pw.print(" set="); pw.println(r.setAdj); 13823 pw.print(prefix); 13824 pw.print(" "); 13825 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13826 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13827 pw.print(" lastPss="); pw.print(r.lastPss); 13828 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13829 pw.print(prefix); 13830 pw.print(" "); 13831 pw.print("cached="); pw.print(r.cached); 13832 pw.print(" empty="); pw.print(r.empty); 13833 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13834 13835 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13836 if (r.lastWakeTime != 0) { 13837 long wtime; 13838 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13839 synchronized (stats) { 13840 wtime = stats.getProcessWakeTime(r.info.uid, 13841 r.pid, curRealtime); 13842 } 13843 long timeUsed = wtime - r.lastWakeTime; 13844 pw.print(prefix); 13845 pw.print(" "); 13846 pw.print("keep awake over "); 13847 TimeUtils.formatDuration(realtimeSince, pw); 13848 pw.print(" used "); 13849 TimeUtils.formatDuration(timeUsed, pw); 13850 pw.print(" ("); 13851 pw.print((timeUsed*100)/realtimeSince); 13852 pw.println("%)"); 13853 } 13854 if (r.lastCpuTime != 0) { 13855 long timeUsed = r.curCpuTime - r.lastCpuTime; 13856 pw.print(prefix); 13857 pw.print(" "); 13858 pw.print("run cpu over "); 13859 TimeUtils.formatDuration(uptimeSince, pw); 13860 pw.print(" used "); 13861 TimeUtils.formatDuration(timeUsed, pw); 13862 pw.print(" ("); 13863 pw.print((timeUsed*100)/uptimeSince); 13864 pw.println("%)"); 13865 } 13866 } 13867 } 13868 } 13869 return true; 13870 } 13871 13872 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13873 String[] args) { 13874 ArrayList<ProcessRecord> procs; 13875 synchronized (this) { 13876 if (args != null && args.length > start 13877 && args[start].charAt(0) != '-') { 13878 procs = new ArrayList<ProcessRecord>(); 13879 int pid = -1; 13880 try { 13881 pid = Integer.parseInt(args[start]); 13882 } catch (NumberFormatException e) { 13883 } 13884 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13885 ProcessRecord proc = mLruProcesses.get(i); 13886 if (proc.pid == pid) { 13887 procs.add(proc); 13888 } else if (allPkgs && proc.pkgList != null 13889 && proc.pkgList.containsKey(args[start])) { 13890 procs.add(proc); 13891 } else if (proc.processName.equals(args[start])) { 13892 procs.add(proc); 13893 } 13894 } 13895 if (procs.size() <= 0) { 13896 return null; 13897 } 13898 } else { 13899 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13900 } 13901 } 13902 return procs; 13903 } 13904 13905 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13906 PrintWriter pw, String[] args) { 13907 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13908 if (procs == null) { 13909 pw.println("No process found for: " + args[0]); 13910 return; 13911 } 13912 13913 long uptime = SystemClock.uptimeMillis(); 13914 long realtime = SystemClock.elapsedRealtime(); 13915 pw.println("Applications Graphics Acceleration Info:"); 13916 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13917 13918 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13919 ProcessRecord r = procs.get(i); 13920 if (r.thread != null) { 13921 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13922 pw.flush(); 13923 try { 13924 TransferPipe tp = new TransferPipe(); 13925 try { 13926 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13927 tp.go(fd); 13928 } finally { 13929 tp.kill(); 13930 } 13931 } catch (IOException e) { 13932 pw.println("Failure while dumping the app: " + r); 13933 pw.flush(); 13934 } catch (RemoteException e) { 13935 pw.println("Got a RemoteException while dumping the app " + r); 13936 pw.flush(); 13937 } 13938 } 13939 } 13940 } 13941 13942 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13943 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13944 if (procs == null) { 13945 pw.println("No process found for: " + args[0]); 13946 return; 13947 } 13948 13949 pw.println("Applications Database Info:"); 13950 13951 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13952 ProcessRecord r = procs.get(i); 13953 if (r.thread != null) { 13954 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13955 pw.flush(); 13956 try { 13957 TransferPipe tp = new TransferPipe(); 13958 try { 13959 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13960 tp.go(fd); 13961 } finally { 13962 tp.kill(); 13963 } 13964 } catch (IOException e) { 13965 pw.println("Failure while dumping the app: " + r); 13966 pw.flush(); 13967 } catch (RemoteException e) { 13968 pw.println("Got a RemoteException while dumping the app " + r); 13969 pw.flush(); 13970 } 13971 } 13972 } 13973 } 13974 13975 final static class MemItem { 13976 final boolean isProc; 13977 final String label; 13978 final String shortLabel; 13979 final long pss; 13980 final int id; 13981 final boolean hasActivities; 13982 ArrayList<MemItem> subitems; 13983 13984 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13985 boolean _hasActivities) { 13986 isProc = true; 13987 label = _label; 13988 shortLabel = _shortLabel; 13989 pss = _pss; 13990 id = _id; 13991 hasActivities = _hasActivities; 13992 } 13993 13994 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13995 isProc = false; 13996 label = _label; 13997 shortLabel = _shortLabel; 13998 pss = _pss; 13999 id = _id; 14000 hasActivities = false; 14001 } 14002 } 14003 14004 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 14005 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 14006 if (sort && !isCompact) { 14007 Collections.sort(items, new Comparator<MemItem>() { 14008 @Override 14009 public int compare(MemItem lhs, MemItem rhs) { 14010 if (lhs.pss < rhs.pss) { 14011 return 1; 14012 } else if (lhs.pss > rhs.pss) { 14013 return -1; 14014 } 14015 return 0; 14016 } 14017 }); 14018 } 14019 14020 for (int i=0; i<items.size(); i++) { 14021 MemItem mi = items.get(i); 14022 if (!isCompact) { 14023 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 14024 } else if (mi.isProc) { 14025 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 14026 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 14027 pw.println(mi.hasActivities ? ",a" : ",e"); 14028 } else { 14029 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 14030 pw.println(mi.pss); 14031 } 14032 if (mi.subitems != null) { 14033 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 14034 true, isCompact); 14035 } 14036 } 14037 } 14038 14039 // These are in KB. 14040 static final long[] DUMP_MEM_BUCKETS = new long[] { 14041 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 14042 120*1024, 160*1024, 200*1024, 14043 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 14044 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 14045 }; 14046 14047 static final void appendMemBucket(StringBuilder out, long memKB, String label, 14048 boolean stackLike) { 14049 int start = label.lastIndexOf('.'); 14050 if (start >= 0) start++; 14051 else start = 0; 14052 int end = label.length(); 14053 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 14054 if (DUMP_MEM_BUCKETS[i] >= memKB) { 14055 long bucket = DUMP_MEM_BUCKETS[i]/1024; 14056 out.append(bucket); 14057 out.append(stackLike ? "MB." : "MB "); 14058 out.append(label, start, end); 14059 return; 14060 } 14061 } 14062 out.append(memKB/1024); 14063 out.append(stackLike ? "MB." : "MB "); 14064 out.append(label, start, end); 14065 } 14066 14067 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 14068 ProcessList.NATIVE_ADJ, 14069 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 14070 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14071 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14072 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14073 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14074 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14075 }; 14076 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14077 "Native", 14078 "System", "Persistent", "Persistent Service", "Foreground", 14079 "Visible", "Perceptible", 14080 "Heavy Weight", "Backup", 14081 "A Services", "Home", 14082 "Previous", "B Services", "Cached" 14083 }; 14084 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14085 "native", 14086 "sys", "pers", "persvc", "fore", 14087 "vis", "percept", 14088 "heavy", "backup", 14089 "servicea", "home", 14090 "prev", "serviceb", "cached" 14091 }; 14092 14093 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14094 long realtime, boolean isCheckinRequest, boolean isCompact) { 14095 if (isCheckinRequest || isCompact) { 14096 // short checkin version 14097 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14098 } else { 14099 pw.println("Applications Memory Usage (kB):"); 14100 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14101 } 14102 } 14103 14104 private static final int KSM_SHARED = 0; 14105 private static final int KSM_SHARING = 1; 14106 private static final int KSM_UNSHARED = 2; 14107 private static final int KSM_VOLATILE = 3; 14108 14109 private final long[] getKsmInfo() { 14110 long[] longOut = new long[4]; 14111 final int[] SINGLE_LONG_FORMAT = new int[] { 14112 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14113 }; 14114 long[] longTmp = new long[1]; 14115 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14116 SINGLE_LONG_FORMAT, null, longTmp, null); 14117 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14118 longTmp[0] = 0; 14119 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14120 SINGLE_LONG_FORMAT, null, longTmp, null); 14121 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14122 longTmp[0] = 0; 14123 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14124 SINGLE_LONG_FORMAT, null, longTmp, null); 14125 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14126 longTmp[0] = 0; 14127 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14128 SINGLE_LONG_FORMAT, null, longTmp, null); 14129 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14130 return longOut; 14131 } 14132 14133 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14134 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14135 boolean dumpDetails = false; 14136 boolean dumpFullDetails = false; 14137 boolean dumpDalvik = false; 14138 boolean oomOnly = false; 14139 boolean isCompact = false; 14140 boolean localOnly = false; 14141 boolean packages = false; 14142 14143 int opti = 0; 14144 while (opti < args.length) { 14145 String opt = args[opti]; 14146 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14147 break; 14148 } 14149 opti++; 14150 if ("-a".equals(opt)) { 14151 dumpDetails = true; 14152 dumpFullDetails = true; 14153 dumpDalvik = true; 14154 } else if ("-d".equals(opt)) { 14155 dumpDalvik = true; 14156 } else if ("-c".equals(opt)) { 14157 isCompact = true; 14158 } else if ("--oom".equals(opt)) { 14159 oomOnly = true; 14160 } else if ("--local".equals(opt)) { 14161 localOnly = true; 14162 } else if ("--package".equals(opt)) { 14163 packages = true; 14164 } else if ("-h".equals(opt)) { 14165 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14166 pw.println(" -a: include all available information for each process."); 14167 pw.println(" -d: include dalvik details when dumping process details."); 14168 pw.println(" -c: dump in a compact machine-parseable representation."); 14169 pw.println(" --oom: only show processes organized by oom adj."); 14170 pw.println(" --local: only collect details locally, don't call process."); 14171 pw.println(" --package: interpret process arg as package, dumping all"); 14172 pw.println(" processes that have loaded that package."); 14173 pw.println("If [process] is specified it can be the name or "); 14174 pw.println("pid of a specific process to dump."); 14175 return; 14176 } else { 14177 pw.println("Unknown argument: " + opt + "; use -h for help"); 14178 } 14179 } 14180 14181 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14182 long uptime = SystemClock.uptimeMillis(); 14183 long realtime = SystemClock.elapsedRealtime(); 14184 final long[] tmpLong = new long[1]; 14185 14186 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14187 if (procs == null) { 14188 // No Java processes. Maybe they want to print a native process. 14189 if (args != null && args.length > opti 14190 && args[opti].charAt(0) != '-') { 14191 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14192 = new ArrayList<ProcessCpuTracker.Stats>(); 14193 updateCpuStatsNow(); 14194 int findPid = -1; 14195 try { 14196 findPid = Integer.parseInt(args[opti]); 14197 } catch (NumberFormatException e) { 14198 } 14199 synchronized (mProcessCpuTracker) { 14200 final int N = mProcessCpuTracker.countStats(); 14201 for (int i=0; i<N; i++) { 14202 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14203 if (st.pid == findPid || (st.baseName != null 14204 && st.baseName.equals(args[opti]))) { 14205 nativeProcs.add(st); 14206 } 14207 } 14208 } 14209 if (nativeProcs.size() > 0) { 14210 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14211 isCompact); 14212 Debug.MemoryInfo mi = null; 14213 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14214 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14215 final int pid = r.pid; 14216 if (!isCheckinRequest && dumpDetails) { 14217 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14218 } 14219 if (mi == null) { 14220 mi = new Debug.MemoryInfo(); 14221 } 14222 if (dumpDetails || (!brief && !oomOnly)) { 14223 Debug.getMemoryInfo(pid, mi); 14224 } else { 14225 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14226 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14227 } 14228 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14229 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14230 if (isCheckinRequest) { 14231 pw.println(); 14232 } 14233 } 14234 return; 14235 } 14236 } 14237 pw.println("No process found for: " + args[opti]); 14238 return; 14239 } 14240 14241 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14242 dumpDetails = true; 14243 } 14244 14245 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14246 14247 String[] innerArgs = new String[args.length-opti]; 14248 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14249 14250 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14251 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14252 long nativePss = 0; 14253 long dalvikPss = 0; 14254 long otherPss = 0; 14255 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14256 14257 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14258 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14259 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14260 14261 long totalPss = 0; 14262 long cachedPss = 0; 14263 14264 Debug.MemoryInfo mi = null; 14265 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14266 final ProcessRecord r = procs.get(i); 14267 final IApplicationThread thread; 14268 final int pid; 14269 final int oomAdj; 14270 final boolean hasActivities; 14271 synchronized (this) { 14272 thread = r.thread; 14273 pid = r.pid; 14274 oomAdj = r.getSetAdjWithServices(); 14275 hasActivities = r.activities.size() > 0; 14276 } 14277 if (thread != null) { 14278 if (!isCheckinRequest && dumpDetails) { 14279 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14280 } 14281 if (mi == null) { 14282 mi = new Debug.MemoryInfo(); 14283 } 14284 if (dumpDetails || (!brief && !oomOnly)) { 14285 Debug.getMemoryInfo(pid, mi); 14286 } else { 14287 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14288 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14289 } 14290 if (dumpDetails) { 14291 if (localOnly) { 14292 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14293 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14294 if (isCheckinRequest) { 14295 pw.println(); 14296 } 14297 } else { 14298 try { 14299 pw.flush(); 14300 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14301 dumpDalvik, innerArgs); 14302 } catch (RemoteException e) { 14303 if (!isCheckinRequest) { 14304 pw.println("Got RemoteException!"); 14305 pw.flush(); 14306 } 14307 } 14308 } 14309 } 14310 14311 final long myTotalPss = mi.getTotalPss(); 14312 final long myTotalUss = mi.getTotalUss(); 14313 14314 synchronized (this) { 14315 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14316 // Record this for posterity if the process has been stable. 14317 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14318 } 14319 } 14320 14321 if (!isCheckinRequest && mi != null) { 14322 totalPss += myTotalPss; 14323 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14324 (hasActivities ? " / activities)" : ")"), 14325 r.processName, myTotalPss, pid, hasActivities); 14326 procMems.add(pssItem); 14327 procMemsMap.put(pid, pssItem); 14328 14329 nativePss += mi.nativePss; 14330 dalvikPss += mi.dalvikPss; 14331 otherPss += mi.otherPss; 14332 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14333 long mem = mi.getOtherPss(j); 14334 miscPss[j] += mem; 14335 otherPss -= mem; 14336 } 14337 14338 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14339 cachedPss += myTotalPss; 14340 } 14341 14342 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14343 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14344 || oomIndex == (oomPss.length-1)) { 14345 oomPss[oomIndex] += myTotalPss; 14346 if (oomProcs[oomIndex] == null) { 14347 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14348 } 14349 oomProcs[oomIndex].add(pssItem); 14350 break; 14351 } 14352 } 14353 } 14354 } 14355 } 14356 14357 long nativeProcTotalPss = 0; 14358 14359 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14360 // If we are showing aggregations, also look for native processes to 14361 // include so that our aggregations are more accurate. 14362 updateCpuStatsNow(); 14363 mi = null; 14364 synchronized (mProcessCpuTracker) { 14365 final int N = mProcessCpuTracker.countStats(); 14366 for (int i=0; i<N; i++) { 14367 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14368 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14369 if (mi == null) { 14370 mi = new Debug.MemoryInfo(); 14371 } 14372 if (!brief && !oomOnly) { 14373 Debug.getMemoryInfo(st.pid, mi); 14374 } else { 14375 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14376 mi.nativePrivateDirty = (int)tmpLong[0]; 14377 } 14378 14379 final long myTotalPss = mi.getTotalPss(); 14380 totalPss += myTotalPss; 14381 nativeProcTotalPss += myTotalPss; 14382 14383 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14384 st.name, myTotalPss, st.pid, false); 14385 procMems.add(pssItem); 14386 14387 nativePss += mi.nativePss; 14388 dalvikPss += mi.dalvikPss; 14389 otherPss += mi.otherPss; 14390 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14391 long mem = mi.getOtherPss(j); 14392 miscPss[j] += mem; 14393 otherPss -= mem; 14394 } 14395 oomPss[0] += myTotalPss; 14396 if (oomProcs[0] == null) { 14397 oomProcs[0] = new ArrayList<MemItem>(); 14398 } 14399 oomProcs[0].add(pssItem); 14400 } 14401 } 14402 } 14403 14404 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14405 14406 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14407 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14408 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14409 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14410 String label = Debug.MemoryInfo.getOtherLabel(j); 14411 catMems.add(new MemItem(label, label, miscPss[j], j)); 14412 } 14413 14414 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14415 for (int j=0; j<oomPss.length; j++) { 14416 if (oomPss[j] != 0) { 14417 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14418 : DUMP_MEM_OOM_LABEL[j]; 14419 MemItem item = new MemItem(label, label, oomPss[j], 14420 DUMP_MEM_OOM_ADJ[j]); 14421 item.subitems = oomProcs[j]; 14422 oomMems.add(item); 14423 } 14424 } 14425 14426 if (!brief && !oomOnly && !isCompact) { 14427 pw.println(); 14428 pw.println("Total PSS by process:"); 14429 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14430 pw.println(); 14431 } 14432 if (!isCompact) { 14433 pw.println("Total PSS by OOM adjustment:"); 14434 } 14435 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14436 if (!brief && !oomOnly) { 14437 PrintWriter out = categoryPw != null ? categoryPw : pw; 14438 if (!isCompact) { 14439 out.println(); 14440 out.println("Total PSS by category:"); 14441 } 14442 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14443 } 14444 if (!isCompact) { 14445 pw.println(); 14446 } 14447 MemInfoReader memInfo = new MemInfoReader(); 14448 memInfo.readMemInfo(); 14449 if (nativeProcTotalPss > 0) { 14450 synchronized (this) { 14451 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14452 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14453 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14454 } 14455 } 14456 if (!brief) { 14457 if (!isCompact) { 14458 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14459 pw.print(" kB (status "); 14460 switch (mLastMemoryLevel) { 14461 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14462 pw.println("normal)"); 14463 break; 14464 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14465 pw.println("moderate)"); 14466 break; 14467 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14468 pw.println("low)"); 14469 break; 14470 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14471 pw.println("critical)"); 14472 break; 14473 default: 14474 pw.print(mLastMemoryLevel); 14475 pw.println(")"); 14476 break; 14477 } 14478 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14479 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14480 pw.print(cachedPss); pw.print(" cached pss + "); 14481 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14482 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14483 } else { 14484 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14485 pw.print(cachedPss + memInfo.getCachedSizeKb() 14486 + memInfo.getFreeSizeKb()); pw.print(","); 14487 pw.println(totalPss - cachedPss); 14488 } 14489 } 14490 if (!isCompact) { 14491 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14492 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14493 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14494 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14495 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14496 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14497 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14498 } 14499 if (!brief) { 14500 if (memInfo.getZramTotalSizeKb() != 0) { 14501 if (!isCompact) { 14502 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14503 pw.print(" kB physical used for "); 14504 pw.print(memInfo.getSwapTotalSizeKb() 14505 - memInfo.getSwapFreeSizeKb()); 14506 pw.print(" kB in swap ("); 14507 pw.print(memInfo.getSwapTotalSizeKb()); 14508 pw.println(" kB total swap)"); 14509 } else { 14510 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14511 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14512 pw.println(memInfo.getSwapFreeSizeKb()); 14513 } 14514 } 14515 final long[] ksm = getKsmInfo(); 14516 if (!isCompact) { 14517 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14518 || ksm[KSM_VOLATILE] != 0) { 14519 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14520 pw.print(" kB saved from shared "); 14521 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14522 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14523 pw.print(" kB unshared; "); 14524 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14525 } 14526 pw.print(" Tuning: "); 14527 pw.print(ActivityManager.staticGetMemoryClass()); 14528 pw.print(" (large "); 14529 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14530 pw.print("), oom "); 14531 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14532 pw.print(" kB"); 14533 pw.print(", restore limit "); 14534 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14535 pw.print(" kB"); 14536 if (ActivityManager.isLowRamDeviceStatic()) { 14537 pw.print(" (low-ram)"); 14538 } 14539 if (ActivityManager.isHighEndGfx()) { 14540 pw.print(" (high-end-gfx)"); 14541 } 14542 pw.println(); 14543 } else { 14544 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14545 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14546 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14547 pw.print("tuning,"); 14548 pw.print(ActivityManager.staticGetMemoryClass()); 14549 pw.print(','); 14550 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14551 pw.print(','); 14552 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14553 if (ActivityManager.isLowRamDeviceStatic()) { 14554 pw.print(",low-ram"); 14555 } 14556 if (ActivityManager.isHighEndGfx()) { 14557 pw.print(",high-end-gfx"); 14558 } 14559 pw.println(); 14560 } 14561 } 14562 } 14563 } 14564 14565 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14566 long memtrack, String name) { 14567 sb.append(" "); 14568 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14569 sb.append(' '); 14570 sb.append(ProcessList.makeProcStateString(procState)); 14571 sb.append(' '); 14572 ProcessList.appendRamKb(sb, pss); 14573 sb.append(" kB: "); 14574 sb.append(name); 14575 if (memtrack > 0) { 14576 sb.append(" ("); 14577 sb.append(memtrack); 14578 sb.append(" kB memtrack)"); 14579 } 14580 } 14581 14582 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14583 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14584 sb.append(" (pid "); 14585 sb.append(mi.pid); 14586 sb.append(") "); 14587 sb.append(mi.adjType); 14588 sb.append('\n'); 14589 if (mi.adjReason != null) { 14590 sb.append(" "); 14591 sb.append(mi.adjReason); 14592 sb.append('\n'); 14593 } 14594 } 14595 14596 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14597 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14598 for (int i=0, N=memInfos.size(); i<N; i++) { 14599 ProcessMemInfo mi = memInfos.get(i); 14600 infoMap.put(mi.pid, mi); 14601 } 14602 updateCpuStatsNow(); 14603 long[] memtrackTmp = new long[1]; 14604 synchronized (mProcessCpuTracker) { 14605 final int N = mProcessCpuTracker.countStats(); 14606 for (int i=0; i<N; i++) { 14607 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14608 if (st.vsize > 0) { 14609 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14610 if (pss > 0) { 14611 if (infoMap.indexOfKey(st.pid) < 0) { 14612 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14613 ProcessList.NATIVE_ADJ, -1, "native", null); 14614 mi.pss = pss; 14615 mi.memtrack = memtrackTmp[0]; 14616 memInfos.add(mi); 14617 } 14618 } 14619 } 14620 } 14621 } 14622 14623 long totalPss = 0; 14624 long totalMemtrack = 0; 14625 for (int i=0, N=memInfos.size(); i<N; i++) { 14626 ProcessMemInfo mi = memInfos.get(i); 14627 if (mi.pss == 0) { 14628 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14629 mi.memtrack = memtrackTmp[0]; 14630 } 14631 totalPss += mi.pss; 14632 totalMemtrack += mi.memtrack; 14633 } 14634 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14635 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14636 if (lhs.oomAdj != rhs.oomAdj) { 14637 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14638 } 14639 if (lhs.pss != rhs.pss) { 14640 return lhs.pss < rhs.pss ? 1 : -1; 14641 } 14642 return 0; 14643 } 14644 }); 14645 14646 StringBuilder tag = new StringBuilder(128); 14647 StringBuilder stack = new StringBuilder(128); 14648 tag.append("Low on memory -- "); 14649 appendMemBucket(tag, totalPss, "total", false); 14650 appendMemBucket(stack, totalPss, "total", true); 14651 14652 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14653 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14654 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14655 14656 boolean firstLine = true; 14657 int lastOomAdj = Integer.MIN_VALUE; 14658 long extraNativeRam = 0; 14659 long extraNativeMemtrack = 0; 14660 long cachedPss = 0; 14661 for (int i=0, N=memInfos.size(); i<N; i++) { 14662 ProcessMemInfo mi = memInfos.get(i); 14663 14664 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14665 cachedPss += mi.pss; 14666 } 14667 14668 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14669 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14670 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14671 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14672 if (lastOomAdj != mi.oomAdj) { 14673 lastOomAdj = mi.oomAdj; 14674 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14675 tag.append(" / "); 14676 } 14677 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14678 if (firstLine) { 14679 stack.append(":"); 14680 firstLine = false; 14681 } 14682 stack.append("\n\t at "); 14683 } else { 14684 stack.append("$"); 14685 } 14686 } else { 14687 tag.append(" "); 14688 stack.append("$"); 14689 } 14690 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14691 appendMemBucket(tag, mi.pss, mi.name, false); 14692 } 14693 appendMemBucket(stack, mi.pss, mi.name, true); 14694 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14695 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14696 stack.append("("); 14697 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14698 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14699 stack.append(DUMP_MEM_OOM_LABEL[k]); 14700 stack.append(":"); 14701 stack.append(DUMP_MEM_OOM_ADJ[k]); 14702 } 14703 } 14704 stack.append(")"); 14705 } 14706 } 14707 14708 appendMemInfo(fullNativeBuilder, mi); 14709 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14710 // The short form only has native processes that are >= 512K. 14711 if (mi.pss >= 512) { 14712 appendMemInfo(shortNativeBuilder, mi); 14713 } else { 14714 extraNativeRam += mi.pss; 14715 extraNativeMemtrack += mi.memtrack; 14716 } 14717 } else { 14718 // Short form has all other details, but if we have collected RAM 14719 // from smaller native processes let's dump a summary of that. 14720 if (extraNativeRam > 0) { 14721 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14722 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14723 shortNativeBuilder.append('\n'); 14724 extraNativeRam = 0; 14725 } 14726 appendMemInfo(fullJavaBuilder, mi); 14727 } 14728 } 14729 14730 fullJavaBuilder.append(" "); 14731 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14732 fullJavaBuilder.append(" kB: TOTAL"); 14733 if (totalMemtrack > 0) { 14734 fullJavaBuilder.append(" ("); 14735 fullJavaBuilder.append(totalMemtrack); 14736 fullJavaBuilder.append(" kB memtrack)"); 14737 } else { 14738 } 14739 fullJavaBuilder.append("\n"); 14740 14741 MemInfoReader memInfo = new MemInfoReader(); 14742 memInfo.readMemInfo(); 14743 final long[] infos = memInfo.getRawInfo(); 14744 14745 StringBuilder memInfoBuilder = new StringBuilder(1024); 14746 Debug.getMemInfo(infos); 14747 memInfoBuilder.append(" MemInfo: "); 14748 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14749 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14750 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14751 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14752 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14753 memInfoBuilder.append(" "); 14754 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14755 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14756 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14757 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14758 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14759 memInfoBuilder.append(" ZRAM: "); 14760 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14761 memInfoBuilder.append(" kB RAM, "); 14762 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14763 memInfoBuilder.append(" kB swap total, "); 14764 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14765 memInfoBuilder.append(" kB swap free\n"); 14766 } 14767 final long[] ksm = getKsmInfo(); 14768 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14769 || ksm[KSM_VOLATILE] != 0) { 14770 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14771 memInfoBuilder.append(" kB saved from shared "); 14772 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14773 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14774 memInfoBuilder.append(" kB unshared; "); 14775 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14776 } 14777 memInfoBuilder.append(" Free RAM: "); 14778 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14779 + memInfo.getFreeSizeKb()); 14780 memInfoBuilder.append(" kB\n"); 14781 memInfoBuilder.append(" Used RAM: "); 14782 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14783 memInfoBuilder.append(" kB\n"); 14784 memInfoBuilder.append(" Lost RAM: "); 14785 memInfoBuilder.append(memInfo.getTotalSizeKb() 14786 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14787 - memInfo.getKernelUsedSizeKb()); 14788 memInfoBuilder.append(" kB\n"); 14789 Slog.i(TAG, "Low on memory:"); 14790 Slog.i(TAG, shortNativeBuilder.toString()); 14791 Slog.i(TAG, fullJavaBuilder.toString()); 14792 Slog.i(TAG, memInfoBuilder.toString()); 14793 14794 StringBuilder dropBuilder = new StringBuilder(1024); 14795 /* 14796 StringWriter oomSw = new StringWriter(); 14797 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14798 StringWriter catSw = new StringWriter(); 14799 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14800 String[] emptyArgs = new String[] { }; 14801 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14802 oomPw.flush(); 14803 String oomString = oomSw.toString(); 14804 */ 14805 dropBuilder.append("Low on memory:"); 14806 dropBuilder.append(stack); 14807 dropBuilder.append('\n'); 14808 dropBuilder.append(fullNativeBuilder); 14809 dropBuilder.append(fullJavaBuilder); 14810 dropBuilder.append('\n'); 14811 dropBuilder.append(memInfoBuilder); 14812 dropBuilder.append('\n'); 14813 /* 14814 dropBuilder.append(oomString); 14815 dropBuilder.append('\n'); 14816 */ 14817 StringWriter catSw = new StringWriter(); 14818 synchronized (ActivityManagerService.this) { 14819 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14820 String[] emptyArgs = new String[] { }; 14821 catPw.println(); 14822 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14823 catPw.println(); 14824 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14825 false, false, null); 14826 catPw.println(); 14827 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14828 catPw.flush(); 14829 } 14830 dropBuilder.append(catSw.toString()); 14831 addErrorToDropBox("lowmem", null, "system_server", null, 14832 null, tag.toString(), dropBuilder.toString(), null, null); 14833 //Slog.i(TAG, "Sent to dropbox:"); 14834 //Slog.i(TAG, dropBuilder.toString()); 14835 synchronized (ActivityManagerService.this) { 14836 long now = SystemClock.uptimeMillis(); 14837 if (mLastMemUsageReportTime < now) { 14838 mLastMemUsageReportTime = now; 14839 } 14840 } 14841 } 14842 14843 /** 14844 * Searches array of arguments for the specified string 14845 * @param args array of argument strings 14846 * @param value value to search for 14847 * @return true if the value is contained in the array 14848 */ 14849 private static boolean scanArgs(String[] args, String value) { 14850 if (args != null) { 14851 for (String arg : args) { 14852 if (value.equals(arg)) { 14853 return true; 14854 } 14855 } 14856 } 14857 return false; 14858 } 14859 14860 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14861 ContentProviderRecord cpr, boolean always) { 14862 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14863 14864 if (!inLaunching || always) { 14865 synchronized (cpr) { 14866 cpr.launchingApp = null; 14867 cpr.notifyAll(); 14868 } 14869 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14870 String names[] = cpr.info.authority.split(";"); 14871 for (int j = 0; j < names.length; j++) { 14872 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14873 } 14874 } 14875 14876 for (int i=0; i<cpr.connections.size(); i++) { 14877 ContentProviderConnection conn = cpr.connections.get(i); 14878 if (conn.waiting) { 14879 // If this connection is waiting for the provider, then we don't 14880 // need to mess with its process unless we are always removing 14881 // or for some reason the provider is not currently launching. 14882 if (inLaunching && !always) { 14883 continue; 14884 } 14885 } 14886 ProcessRecord capp = conn.client; 14887 conn.dead = true; 14888 if (conn.stableCount > 0) { 14889 if (!capp.persistent && capp.thread != null 14890 && capp.pid != 0 14891 && capp.pid != MY_PID) { 14892 capp.kill("depends on provider " 14893 + cpr.name.flattenToShortString() 14894 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14895 } 14896 } else if (capp.thread != null && conn.provider.provider != null) { 14897 try { 14898 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14899 } catch (RemoteException e) { 14900 } 14901 // In the protocol here, we don't expect the client to correctly 14902 // clean up this connection, we'll just remove it. 14903 cpr.connections.remove(i); 14904 if (conn.client.conProviders.remove(conn)) { 14905 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14906 } 14907 } 14908 } 14909 14910 if (inLaunching && always) { 14911 mLaunchingProviders.remove(cpr); 14912 } 14913 return inLaunching; 14914 } 14915 14916 /** 14917 * Main code for cleaning up a process when it has gone away. This is 14918 * called both as a result of the process dying, or directly when stopping 14919 * a process when running in single process mode. 14920 * 14921 * @return Returns true if the given process has been restarted, so the 14922 * app that was passed in must remain on the process lists. 14923 */ 14924 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14925 boolean restarting, boolean allowRestart, int index) { 14926 if (index >= 0) { 14927 removeLruProcessLocked(app); 14928 ProcessList.remove(app.pid); 14929 } 14930 14931 mProcessesToGc.remove(app); 14932 mPendingPssProcesses.remove(app); 14933 14934 // Dismiss any open dialogs. 14935 if (app.crashDialog != null && !app.forceCrashReport) { 14936 app.crashDialog.dismiss(); 14937 app.crashDialog = null; 14938 } 14939 if (app.anrDialog != null) { 14940 app.anrDialog.dismiss(); 14941 app.anrDialog = null; 14942 } 14943 if (app.waitDialog != null) { 14944 app.waitDialog.dismiss(); 14945 app.waitDialog = null; 14946 } 14947 14948 app.crashing = false; 14949 app.notResponding = false; 14950 14951 app.resetPackageList(mProcessStats); 14952 app.unlinkDeathRecipient(); 14953 app.makeInactive(mProcessStats); 14954 app.waitingToKill = null; 14955 app.forcingToForeground = null; 14956 updateProcessForegroundLocked(app, false, false); 14957 app.foregroundActivities = false; 14958 app.hasShownUi = false; 14959 app.treatLikeActivity = false; 14960 app.hasAboveClient = false; 14961 app.hasClientActivities = false; 14962 14963 mServices.killServicesLocked(app, allowRestart); 14964 14965 boolean restart = false; 14966 14967 // Remove published content providers. 14968 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14969 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14970 final boolean always = app.bad || !allowRestart; 14971 if (removeDyingProviderLocked(app, cpr, always) || always) { 14972 // We left the provider in the launching list, need to 14973 // restart it. 14974 restart = true; 14975 } 14976 14977 cpr.provider = null; 14978 cpr.proc = null; 14979 } 14980 app.pubProviders.clear(); 14981 14982 // Take care of any launching providers waiting for this process. 14983 if (checkAppInLaunchingProvidersLocked(app, false)) { 14984 restart = true; 14985 } 14986 14987 // Unregister from connected content providers. 14988 if (!app.conProviders.isEmpty()) { 14989 for (int i=0; i<app.conProviders.size(); i++) { 14990 ContentProviderConnection conn = app.conProviders.get(i); 14991 conn.provider.connections.remove(conn); 14992 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14993 conn.provider.name); 14994 } 14995 app.conProviders.clear(); 14996 } 14997 14998 // At this point there may be remaining entries in mLaunchingProviders 14999 // where we were the only one waiting, so they are no longer of use. 15000 // Look for these and clean up if found. 15001 // XXX Commented out for now. Trying to figure out a way to reproduce 15002 // the actual situation to identify what is actually going on. 15003 if (false) { 15004 for (int i=0; i<mLaunchingProviders.size(); i++) { 15005 ContentProviderRecord cpr = (ContentProviderRecord) 15006 mLaunchingProviders.get(i); 15007 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 15008 synchronized (cpr) { 15009 cpr.launchingApp = null; 15010 cpr.notifyAll(); 15011 } 15012 } 15013 } 15014 } 15015 15016 skipCurrentReceiverLocked(app); 15017 15018 // Unregister any receivers. 15019 for (int i=app.receivers.size()-1; i>=0; i--) { 15020 removeReceiverLocked(app.receivers.valueAt(i)); 15021 } 15022 app.receivers.clear(); 15023 15024 // If the app is undergoing backup, tell the backup manager about it 15025 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 15026 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 15027 + mBackupTarget.appInfo + " died during backup"); 15028 try { 15029 IBackupManager bm = IBackupManager.Stub.asInterface( 15030 ServiceManager.getService(Context.BACKUP_SERVICE)); 15031 bm.agentDisconnected(app.info.packageName); 15032 } catch (RemoteException e) { 15033 // can't happen; backup manager is local 15034 } 15035 } 15036 15037 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 15038 ProcessChangeItem item = mPendingProcessChanges.get(i); 15039 if (item.pid == app.pid) { 15040 mPendingProcessChanges.remove(i); 15041 mAvailProcessChanges.add(item); 15042 } 15043 } 15044 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 15045 15046 // If the caller is restarting this app, then leave it in its 15047 // current lists and let the caller take care of it. 15048 if (restarting) { 15049 return false; 15050 } 15051 15052 if (!app.persistent || app.isolated) { 15053 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 15054 "Removing non-persistent process during cleanup: " + app); 15055 mProcessNames.remove(app.processName, app.uid); 15056 mIsolatedProcesses.remove(app.uid); 15057 if (mHeavyWeightProcess == app) { 15058 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 15059 mHeavyWeightProcess.userId, 0)); 15060 mHeavyWeightProcess = null; 15061 } 15062 } else if (!app.removed) { 15063 // This app is persistent, so we need to keep its record around. 15064 // If it is not already on the pending app list, add it there 15065 // and start a new process for it. 15066 if (mPersistentStartingProcesses.indexOf(app) < 0) { 15067 mPersistentStartingProcesses.add(app); 15068 restart = true; 15069 } 15070 } 15071 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15072 "Clean-up removing on hold: " + app); 15073 mProcessesOnHold.remove(app); 15074 15075 if (app == mHomeProcess) { 15076 mHomeProcess = null; 15077 } 15078 if (app == mPreviousProcess) { 15079 mPreviousProcess = null; 15080 } 15081 15082 if (restart && !app.isolated) { 15083 // We have components that still need to be running in the 15084 // process, so re-launch it. 15085 if (index < 0) { 15086 ProcessList.remove(app.pid); 15087 } 15088 mProcessNames.put(app.processName, app.uid, app); 15089 startProcessLocked(app, "restart", app.processName); 15090 return true; 15091 } else if (app.pid > 0 && app.pid != MY_PID) { 15092 // Goodbye! 15093 boolean removed; 15094 synchronized (mPidsSelfLocked) { 15095 mPidsSelfLocked.remove(app.pid); 15096 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15097 } 15098 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15099 if (app.isolated) { 15100 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15101 } 15102 app.setPid(0); 15103 } 15104 return false; 15105 } 15106 15107 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15108 // Look through the content providers we are waiting to have launched, 15109 // and if any run in this process then either schedule a restart of 15110 // the process or kill the client waiting for it if this process has 15111 // gone bad. 15112 int NL = mLaunchingProviders.size(); 15113 boolean restart = false; 15114 for (int i=0; i<NL; i++) { 15115 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15116 if (cpr.launchingApp == app) { 15117 if (!alwaysBad && !app.bad) { 15118 restart = true; 15119 } else { 15120 removeDyingProviderLocked(app, cpr, true); 15121 // cpr should have been removed from mLaunchingProviders 15122 NL = mLaunchingProviders.size(); 15123 i--; 15124 } 15125 } 15126 } 15127 return restart; 15128 } 15129 15130 // ========================================================= 15131 // SERVICES 15132 // ========================================================= 15133 15134 @Override 15135 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15136 int flags) { 15137 enforceNotIsolatedCaller("getServices"); 15138 synchronized (this) { 15139 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15140 } 15141 } 15142 15143 @Override 15144 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15145 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15146 synchronized (this) { 15147 return mServices.getRunningServiceControlPanelLocked(name); 15148 } 15149 } 15150 15151 @Override 15152 public ComponentName startService(IApplicationThread caller, Intent service, 15153 String resolvedType, int userId) { 15154 enforceNotIsolatedCaller("startService"); 15155 // Refuse possible leaked file descriptors 15156 if (service != null && service.hasFileDescriptors() == true) { 15157 throw new IllegalArgumentException("File descriptors passed in Intent"); 15158 } 15159 15160 if (DEBUG_SERVICE) 15161 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15162 synchronized(this) { 15163 final int callingPid = Binder.getCallingPid(); 15164 final int callingUid = Binder.getCallingUid(); 15165 final long origId = Binder.clearCallingIdentity(); 15166 ComponentName res = mServices.startServiceLocked(caller, service, 15167 resolvedType, callingPid, callingUid, userId); 15168 Binder.restoreCallingIdentity(origId); 15169 return res; 15170 } 15171 } 15172 15173 ComponentName startServiceInPackage(int uid, 15174 Intent service, String resolvedType, int userId) { 15175 synchronized(this) { 15176 if (DEBUG_SERVICE) 15177 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15178 final long origId = Binder.clearCallingIdentity(); 15179 ComponentName res = mServices.startServiceLocked(null, service, 15180 resolvedType, -1, uid, userId); 15181 Binder.restoreCallingIdentity(origId); 15182 return res; 15183 } 15184 } 15185 15186 @Override 15187 public int stopService(IApplicationThread caller, Intent service, 15188 String resolvedType, int userId) { 15189 enforceNotIsolatedCaller("stopService"); 15190 // Refuse possible leaked file descriptors 15191 if (service != null && service.hasFileDescriptors() == true) { 15192 throw new IllegalArgumentException("File descriptors passed in Intent"); 15193 } 15194 15195 synchronized(this) { 15196 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15197 } 15198 } 15199 15200 @Override 15201 public IBinder peekService(Intent service, String resolvedType) { 15202 enforceNotIsolatedCaller("peekService"); 15203 // Refuse possible leaked file descriptors 15204 if (service != null && service.hasFileDescriptors() == true) { 15205 throw new IllegalArgumentException("File descriptors passed in Intent"); 15206 } 15207 synchronized(this) { 15208 return mServices.peekServiceLocked(service, resolvedType); 15209 } 15210 } 15211 15212 @Override 15213 public boolean stopServiceToken(ComponentName className, IBinder token, 15214 int startId) { 15215 synchronized(this) { 15216 return mServices.stopServiceTokenLocked(className, token, startId); 15217 } 15218 } 15219 15220 @Override 15221 public void setServiceForeground(ComponentName className, IBinder token, 15222 int id, Notification notification, boolean removeNotification) { 15223 synchronized(this) { 15224 mServices.setServiceForegroundLocked(className, token, id, notification, 15225 removeNotification); 15226 } 15227 } 15228 15229 @Override 15230 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15231 boolean requireFull, String name, String callerPackage) { 15232 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15233 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15234 } 15235 15236 int unsafeConvertIncomingUser(int userId) { 15237 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15238 ? mCurrentUserId : userId; 15239 } 15240 15241 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15242 int allowMode, String name, String callerPackage) { 15243 final int callingUserId = UserHandle.getUserId(callingUid); 15244 if (callingUserId == userId) { 15245 return userId; 15246 } 15247 15248 // Note that we may be accessing mCurrentUserId outside of a lock... 15249 // shouldn't be a big deal, if this is being called outside 15250 // of a locked context there is intrinsically a race with 15251 // the value the caller will receive and someone else changing it. 15252 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15253 // we will switch to the calling user if access to the current user fails. 15254 int targetUserId = unsafeConvertIncomingUser(userId); 15255 15256 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15257 final boolean allow; 15258 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15259 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15260 // If the caller has this permission, they always pass go. And collect $200. 15261 allow = true; 15262 } else if (allowMode == ALLOW_FULL_ONLY) { 15263 // We require full access, sucks to be you. 15264 allow = false; 15265 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15266 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15267 // If the caller does not have either permission, they are always doomed. 15268 allow = false; 15269 } else if (allowMode == ALLOW_NON_FULL) { 15270 // We are blanket allowing non-full access, you lucky caller! 15271 allow = true; 15272 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15273 // We may or may not allow this depending on whether the two users are 15274 // in the same profile. 15275 synchronized (mUserProfileGroupIdsSelfLocked) { 15276 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15277 UserInfo.NO_PROFILE_GROUP_ID); 15278 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15279 UserInfo.NO_PROFILE_GROUP_ID); 15280 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15281 && callingProfile == targetProfile; 15282 } 15283 } else { 15284 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15285 } 15286 if (!allow) { 15287 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15288 // In this case, they would like to just execute as their 15289 // owner user instead of failing. 15290 targetUserId = callingUserId; 15291 } else { 15292 StringBuilder builder = new StringBuilder(128); 15293 builder.append("Permission Denial: "); 15294 builder.append(name); 15295 if (callerPackage != null) { 15296 builder.append(" from "); 15297 builder.append(callerPackage); 15298 } 15299 builder.append(" asks to run as user "); 15300 builder.append(userId); 15301 builder.append(" but is calling from user "); 15302 builder.append(UserHandle.getUserId(callingUid)); 15303 builder.append("; this requires "); 15304 builder.append(INTERACT_ACROSS_USERS_FULL); 15305 if (allowMode != ALLOW_FULL_ONLY) { 15306 builder.append(" or "); 15307 builder.append(INTERACT_ACROSS_USERS); 15308 } 15309 String msg = builder.toString(); 15310 Slog.w(TAG, msg); 15311 throw new SecurityException(msg); 15312 } 15313 } 15314 } 15315 if (!allowAll && targetUserId < 0) { 15316 throw new IllegalArgumentException( 15317 "Call does not support special user #" + targetUserId); 15318 } 15319 // Check shell permission 15320 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15321 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15322 targetUserId)) { 15323 throw new SecurityException("Shell does not have permission to access user " 15324 + targetUserId + "\n " + Debug.getCallers(3)); 15325 } 15326 } 15327 return targetUserId; 15328 } 15329 15330 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15331 String className, int flags) { 15332 boolean result = false; 15333 // For apps that don't have pre-defined UIDs, check for permission 15334 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15335 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15336 if (ActivityManager.checkUidPermission( 15337 INTERACT_ACROSS_USERS, 15338 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15339 ComponentName comp = new ComponentName(aInfo.packageName, className); 15340 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15341 + " requests FLAG_SINGLE_USER, but app does not hold " 15342 + INTERACT_ACROSS_USERS; 15343 Slog.w(TAG, msg); 15344 throw new SecurityException(msg); 15345 } 15346 // Permission passed 15347 result = true; 15348 } 15349 } else if ("system".equals(componentProcessName)) { 15350 result = true; 15351 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15352 // Phone app and persistent apps are allowed to export singleuser providers. 15353 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15354 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15355 } 15356 if (DEBUG_MU) { 15357 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15358 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15359 } 15360 return result; 15361 } 15362 15363 /** 15364 * Checks to see if the caller is in the same app as the singleton 15365 * component, or the component is in a special app. It allows special apps 15366 * to export singleton components but prevents exporting singleton 15367 * components for regular apps. 15368 */ 15369 boolean isValidSingletonCall(int callingUid, int componentUid) { 15370 int componentAppId = UserHandle.getAppId(componentUid); 15371 return UserHandle.isSameApp(callingUid, componentUid) 15372 || componentAppId == Process.SYSTEM_UID 15373 || componentAppId == Process.PHONE_UID 15374 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15375 == PackageManager.PERMISSION_GRANTED; 15376 } 15377 15378 public int bindService(IApplicationThread caller, IBinder token, 15379 Intent service, String resolvedType, 15380 IServiceConnection connection, int flags, int userId) { 15381 enforceNotIsolatedCaller("bindService"); 15382 15383 // Refuse possible leaked file descriptors 15384 if (service != null && service.hasFileDescriptors() == true) { 15385 throw new IllegalArgumentException("File descriptors passed in Intent"); 15386 } 15387 15388 synchronized(this) { 15389 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15390 connection, flags, userId); 15391 } 15392 } 15393 15394 public boolean unbindService(IServiceConnection connection) { 15395 synchronized (this) { 15396 return mServices.unbindServiceLocked(connection); 15397 } 15398 } 15399 15400 public void publishService(IBinder token, Intent intent, IBinder service) { 15401 // Refuse possible leaked file descriptors 15402 if (intent != null && intent.hasFileDescriptors() == true) { 15403 throw new IllegalArgumentException("File descriptors passed in Intent"); 15404 } 15405 15406 synchronized(this) { 15407 if (!(token instanceof ServiceRecord)) { 15408 throw new IllegalArgumentException("Invalid service token"); 15409 } 15410 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15411 } 15412 } 15413 15414 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15415 // Refuse possible leaked file descriptors 15416 if (intent != null && intent.hasFileDescriptors() == true) { 15417 throw new IllegalArgumentException("File descriptors passed in Intent"); 15418 } 15419 15420 synchronized(this) { 15421 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15422 } 15423 } 15424 15425 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15426 synchronized(this) { 15427 if (!(token instanceof ServiceRecord)) { 15428 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 15429 throw new IllegalArgumentException("Invalid service token"); 15430 } 15431 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15432 } 15433 } 15434 15435 // ========================================================= 15436 // BACKUP AND RESTORE 15437 // ========================================================= 15438 15439 // Cause the target app to be launched if necessary and its backup agent 15440 // instantiated. The backup agent will invoke backupAgentCreated() on the 15441 // activity manager to announce its creation. 15442 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15443 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15444 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15445 15446 synchronized(this) { 15447 // !!! TODO: currently no check here that we're already bound 15448 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15449 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15450 synchronized (stats) { 15451 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15452 } 15453 15454 // Backup agent is now in use, its package can't be stopped. 15455 try { 15456 AppGlobals.getPackageManager().setPackageStoppedState( 15457 app.packageName, false, UserHandle.getUserId(app.uid)); 15458 } catch (RemoteException e) { 15459 } catch (IllegalArgumentException e) { 15460 Slog.w(TAG, "Failed trying to unstop package " 15461 + app.packageName + ": " + e); 15462 } 15463 15464 BackupRecord r = new BackupRecord(ss, app, backupMode); 15465 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15466 ? new ComponentName(app.packageName, app.backupAgentName) 15467 : new ComponentName("android", "FullBackupAgent"); 15468 // startProcessLocked() returns existing proc's record if it's already running 15469 ProcessRecord proc = startProcessLocked(app.processName, app, 15470 false, 0, "backup", hostingName, false, false, false); 15471 if (proc == null) { 15472 Slog.e(TAG, "Unable to start backup agent process " + r); 15473 return false; 15474 } 15475 15476 r.app = proc; 15477 mBackupTarget = r; 15478 mBackupAppName = app.packageName; 15479 15480 // Try not to kill the process during backup 15481 updateOomAdjLocked(proc); 15482 15483 // If the process is already attached, schedule the creation of the backup agent now. 15484 // If it is not yet live, this will be done when it attaches to the framework. 15485 if (proc.thread != null) { 15486 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15487 try { 15488 proc.thread.scheduleCreateBackupAgent(app, 15489 compatibilityInfoForPackageLocked(app), backupMode); 15490 } catch (RemoteException e) { 15491 // Will time out on the backup manager side 15492 } 15493 } else { 15494 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15495 } 15496 // Invariants: at this point, the target app process exists and the application 15497 // is either already running or in the process of coming up. mBackupTarget and 15498 // mBackupAppName describe the app, so that when it binds back to the AM we 15499 // know that it's scheduled for a backup-agent operation. 15500 } 15501 15502 return true; 15503 } 15504 15505 @Override 15506 public void clearPendingBackup() { 15507 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15508 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15509 15510 synchronized (this) { 15511 mBackupTarget = null; 15512 mBackupAppName = null; 15513 } 15514 } 15515 15516 // A backup agent has just come up 15517 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15518 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15519 + " = " + agent); 15520 15521 synchronized(this) { 15522 if (!agentPackageName.equals(mBackupAppName)) { 15523 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15524 return; 15525 } 15526 } 15527 15528 long oldIdent = Binder.clearCallingIdentity(); 15529 try { 15530 IBackupManager bm = IBackupManager.Stub.asInterface( 15531 ServiceManager.getService(Context.BACKUP_SERVICE)); 15532 bm.agentConnected(agentPackageName, agent); 15533 } catch (RemoteException e) { 15534 // can't happen; the backup manager service is local 15535 } catch (Exception e) { 15536 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15537 e.printStackTrace(); 15538 } finally { 15539 Binder.restoreCallingIdentity(oldIdent); 15540 } 15541 } 15542 15543 // done with this agent 15544 public void unbindBackupAgent(ApplicationInfo appInfo) { 15545 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15546 if (appInfo == null) { 15547 Slog.w(TAG, "unbind backup agent for null app"); 15548 return; 15549 } 15550 15551 synchronized(this) { 15552 try { 15553 if (mBackupAppName == null) { 15554 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15555 return; 15556 } 15557 15558 if (!mBackupAppName.equals(appInfo.packageName)) { 15559 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15560 return; 15561 } 15562 15563 // Not backing this app up any more; reset its OOM adjustment 15564 final ProcessRecord proc = mBackupTarget.app; 15565 updateOomAdjLocked(proc); 15566 15567 // If the app crashed during backup, 'thread' will be null here 15568 if (proc.thread != null) { 15569 try { 15570 proc.thread.scheduleDestroyBackupAgent(appInfo, 15571 compatibilityInfoForPackageLocked(appInfo)); 15572 } catch (Exception e) { 15573 Slog.e(TAG, "Exception when unbinding backup agent:"); 15574 e.printStackTrace(); 15575 } 15576 } 15577 } finally { 15578 mBackupTarget = null; 15579 mBackupAppName = null; 15580 } 15581 } 15582 } 15583 // ========================================================= 15584 // BROADCASTS 15585 // ========================================================= 15586 15587 boolean isPendingBroadcastProcessLocked(int pid) { 15588 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15589 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15590 } 15591 15592 void skipPendingBroadcastLocked(int pid) { 15593 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15594 for (BroadcastQueue queue : mBroadcastQueues) { 15595 queue.skipPendingBroadcastLocked(pid); 15596 } 15597 } 15598 15599 // The app just attached; send any pending broadcasts that it should receive 15600 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15601 boolean didSomething = false; 15602 for (BroadcastQueue queue : mBroadcastQueues) { 15603 didSomething |= queue.sendPendingBroadcastsLocked(app); 15604 } 15605 return didSomething; 15606 } 15607 15608 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15609 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15610 enforceNotIsolatedCaller("registerReceiver"); 15611 ArrayList<Intent> stickyIntents = null; 15612 ProcessRecord callerApp = null; 15613 int callingUid; 15614 int callingPid; 15615 synchronized(this) { 15616 if (caller != null) { 15617 callerApp = getRecordForAppLocked(caller); 15618 if (callerApp == null) { 15619 throw new SecurityException( 15620 "Unable to find app for caller " + caller 15621 + " (pid=" + Binder.getCallingPid() 15622 + ") when registering receiver " + receiver); 15623 } 15624 if (callerApp.info.uid != Process.SYSTEM_UID && 15625 !callerApp.pkgList.containsKey(callerPackage) && 15626 !"android".equals(callerPackage)) { 15627 throw new SecurityException("Given caller package " + callerPackage 15628 + " is not running in process " + callerApp); 15629 } 15630 callingUid = callerApp.info.uid; 15631 callingPid = callerApp.pid; 15632 } else { 15633 callerPackage = null; 15634 callingUid = Binder.getCallingUid(); 15635 callingPid = Binder.getCallingPid(); 15636 } 15637 15638 userId = handleIncomingUser(callingPid, callingUid, userId, 15639 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15640 15641 Iterator<String> actions = filter.actionsIterator(); 15642 if (actions == null) { 15643 ArrayList<String> noAction = new ArrayList<String>(1); 15644 noAction.add(null); 15645 actions = noAction.iterator(); 15646 } 15647 15648 // Collect stickies of users 15649 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; 15650 while (actions.hasNext()) { 15651 String action = actions.next(); 15652 for (int id : userIds) { 15653 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); 15654 if (stickies != null) { 15655 ArrayList<Intent> intents = stickies.get(action); 15656 if (intents != null) { 15657 if (stickyIntents == null) { 15658 stickyIntents = new ArrayList<Intent>(); 15659 } 15660 stickyIntents.addAll(intents); 15661 } 15662 } 15663 } 15664 } 15665 } 15666 15667 ArrayList<Intent> allSticky = null; 15668 if (stickyIntents != null) { 15669 final ContentResolver resolver = mContext.getContentResolver(); 15670 // Look for any matching sticky broadcasts... 15671 for (int i = 0, N = stickyIntents.size(); i < N; i++) { 15672 Intent intent = stickyIntents.get(i); 15673 // If intent has scheme "content", it will need to acccess 15674 // provider that needs to lock mProviderMap in ActivityThread 15675 // and also it may need to wait application response, so we 15676 // cannot lock ActivityManagerService here. 15677 if (filter.match(resolver, intent, true, TAG) >= 0) { 15678 if (allSticky == null) { 15679 allSticky = new ArrayList<Intent>(); 15680 } 15681 allSticky.add(intent); 15682 } 15683 } 15684 } 15685 15686 // The first sticky in the list is returned directly back to the client. 15687 Intent sticky = allSticky != null ? allSticky.get(0) : null; 15688 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky); 15689 if (receiver == null) { 15690 return sticky; 15691 } 15692 15693 synchronized (this) { 15694 if (callerApp != null && callerApp.pid == 0) { 15695 // Caller already died 15696 return null; 15697 } 15698 ReceiverList rl 15699 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15700 if (rl == null) { 15701 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15702 userId, receiver); 15703 if (rl.app != null) { 15704 rl.app.receivers.add(rl); 15705 } else { 15706 try { 15707 receiver.asBinder().linkToDeath(rl, 0); 15708 } catch (RemoteException e) { 15709 return sticky; 15710 } 15711 rl.linkedToDeath = true; 15712 } 15713 mRegisteredReceivers.put(receiver.asBinder(), rl); 15714 } else if (rl.uid != callingUid) { 15715 throw new IllegalArgumentException( 15716 "Receiver requested to register for uid " + callingUid 15717 + " was previously registered for uid " + rl.uid); 15718 } else if (rl.pid != callingPid) { 15719 throw new IllegalArgumentException( 15720 "Receiver requested to register for pid " + callingPid 15721 + " was previously registered for pid " + rl.pid); 15722 } else if (rl.userId != userId) { 15723 throw new IllegalArgumentException( 15724 "Receiver requested to register for user " + userId 15725 + " was previously registered for user " + rl.userId); 15726 } 15727 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15728 permission, callingUid, userId); 15729 rl.add(bf); 15730 if (!bf.debugCheck()) { 15731 Slog.w(TAG, "==> For Dynamic broadast"); 15732 } 15733 mReceiverResolver.addFilter(bf); 15734 15735 // Enqueue broadcasts for all existing stickies that match 15736 // this filter. 15737 if (allSticky != null) { 15738 ArrayList receivers = new ArrayList(); 15739 receivers.add(bf); 15740 15741 int N = allSticky.size(); 15742 for (int i=0; i<N; i++) { 15743 Intent intent = (Intent)allSticky.get(i); 15744 BroadcastQueue queue = broadcastQueueForIntent(intent); 15745 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15746 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15747 null, null, false, true, true, -1); 15748 queue.enqueueParallelBroadcastLocked(r); 15749 queue.scheduleBroadcastsLocked(); 15750 } 15751 } 15752 15753 return sticky; 15754 } 15755 } 15756 15757 public void unregisterReceiver(IIntentReceiver receiver) { 15758 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15759 15760 final long origId = Binder.clearCallingIdentity(); 15761 try { 15762 boolean doTrim = false; 15763 15764 synchronized(this) { 15765 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15766 if (rl != null) { 15767 final BroadcastRecord r = rl.curBroadcast; 15768 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 15769 final boolean doNext = r.queue.finishReceiverLocked( 15770 r, r.resultCode, r.resultData, r.resultExtras, 15771 r.resultAbort, false); 15772 if (doNext) { 15773 doTrim = true; 15774 r.queue.processNextBroadcast(false); 15775 } 15776 } 15777 15778 if (rl.app != null) { 15779 rl.app.receivers.remove(rl); 15780 } 15781 removeReceiverLocked(rl); 15782 if (rl.linkedToDeath) { 15783 rl.linkedToDeath = false; 15784 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15785 } 15786 } 15787 } 15788 15789 // If we actually concluded any broadcasts, we might now be able 15790 // to trim the recipients' apps from our working set 15791 if (doTrim) { 15792 trimApplications(); 15793 return; 15794 } 15795 15796 } finally { 15797 Binder.restoreCallingIdentity(origId); 15798 } 15799 } 15800 15801 void removeReceiverLocked(ReceiverList rl) { 15802 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15803 int N = rl.size(); 15804 for (int i=0; i<N; i++) { 15805 mReceiverResolver.removeFilter(rl.get(i)); 15806 } 15807 } 15808 15809 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15810 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15811 ProcessRecord r = mLruProcesses.get(i); 15812 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15813 try { 15814 r.thread.dispatchPackageBroadcast(cmd, packages); 15815 } catch (RemoteException ex) { 15816 } 15817 } 15818 } 15819 } 15820 15821 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15822 int callingUid, int[] users) { 15823 List<ResolveInfo> receivers = null; 15824 try { 15825 HashSet<ComponentName> singleUserReceivers = null; 15826 boolean scannedFirstReceivers = false; 15827 for (int user : users) { 15828 // Skip users that have Shell restrictions 15829 if (callingUid == Process.SHELL_UID 15830 && getUserManagerLocked().hasUserRestriction( 15831 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15832 continue; 15833 } 15834 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15835 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15836 if (user != 0 && newReceivers != null) { 15837 // If this is not the primary user, we need to check for 15838 // any receivers that should be filtered out. 15839 for (int i=0; i<newReceivers.size(); i++) { 15840 ResolveInfo ri = newReceivers.get(i); 15841 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15842 newReceivers.remove(i); 15843 i--; 15844 } 15845 } 15846 } 15847 if (newReceivers != null && newReceivers.size() == 0) { 15848 newReceivers = null; 15849 } 15850 if (receivers == null) { 15851 receivers = newReceivers; 15852 } else if (newReceivers != null) { 15853 // We need to concatenate the additional receivers 15854 // found with what we have do far. This would be easy, 15855 // but we also need to de-dup any receivers that are 15856 // singleUser. 15857 if (!scannedFirstReceivers) { 15858 // Collect any single user receivers we had already retrieved. 15859 scannedFirstReceivers = true; 15860 for (int i=0; i<receivers.size(); i++) { 15861 ResolveInfo ri = receivers.get(i); 15862 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15863 ComponentName cn = new ComponentName( 15864 ri.activityInfo.packageName, ri.activityInfo.name); 15865 if (singleUserReceivers == null) { 15866 singleUserReceivers = new HashSet<ComponentName>(); 15867 } 15868 singleUserReceivers.add(cn); 15869 } 15870 } 15871 } 15872 // Add the new results to the existing results, tracking 15873 // and de-dupping single user receivers. 15874 for (int i=0; i<newReceivers.size(); i++) { 15875 ResolveInfo ri = newReceivers.get(i); 15876 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15877 ComponentName cn = new ComponentName( 15878 ri.activityInfo.packageName, ri.activityInfo.name); 15879 if (singleUserReceivers == null) { 15880 singleUserReceivers = new HashSet<ComponentName>(); 15881 } 15882 if (!singleUserReceivers.contains(cn)) { 15883 singleUserReceivers.add(cn); 15884 receivers.add(ri); 15885 } 15886 } else { 15887 receivers.add(ri); 15888 } 15889 } 15890 } 15891 } 15892 } catch (RemoteException ex) { 15893 // pm is in same process, this will never happen. 15894 } 15895 return receivers; 15896 } 15897 15898 private final int broadcastIntentLocked(ProcessRecord callerApp, 15899 String callerPackage, Intent intent, String resolvedType, 15900 IIntentReceiver resultTo, int resultCode, String resultData, 15901 Bundle map, String requiredPermission, int appOp, 15902 boolean ordered, boolean sticky, int callingPid, int callingUid, 15903 int userId) { 15904 intent = new Intent(intent); 15905 15906 // By default broadcasts do not go to stopped apps. 15907 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15908 15909 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15910 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15911 + " ordered=" + ordered + " userid=" + userId); 15912 if ((resultTo != null) && !ordered) { 15913 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15914 } 15915 15916 userId = handleIncomingUser(callingPid, callingUid, userId, 15917 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15918 15919 // Make sure that the user who is receiving this broadcast is running. 15920 // If not, we will just skip it. Make an exception for shutdown broadcasts 15921 // and upgrade steps. 15922 15923 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15924 if ((callingUid != Process.SYSTEM_UID 15925 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15926 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15927 Slog.w(TAG, "Skipping broadcast of " + intent 15928 + ": user " + userId + " is stopped"); 15929 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15930 } 15931 } 15932 15933 /* 15934 * Prevent non-system code (defined here to be non-persistent 15935 * processes) from sending protected broadcasts. 15936 */ 15937 int callingAppId = UserHandle.getAppId(callingUid); 15938 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15939 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15940 || callingAppId == Process.NFC_UID || callingUid == 0) { 15941 // Always okay. 15942 } else if (callerApp == null || !callerApp.persistent) { 15943 try { 15944 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15945 intent.getAction())) { 15946 String msg = "Permission Denial: not allowed to send broadcast " 15947 + intent.getAction() + " from pid=" 15948 + callingPid + ", uid=" + callingUid; 15949 Slog.w(TAG, msg); 15950 throw new SecurityException(msg); 15951 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15952 // Special case for compatibility: we don't want apps to send this, 15953 // but historically it has not been protected and apps may be using it 15954 // to poke their own app widget. So, instead of making it protected, 15955 // just limit it to the caller. 15956 if (callerApp == null) { 15957 String msg = "Permission Denial: not allowed to send broadcast " 15958 + intent.getAction() + " from unknown caller."; 15959 Slog.w(TAG, msg); 15960 throw new SecurityException(msg); 15961 } else if (intent.getComponent() != null) { 15962 // They are good enough to send to an explicit component... verify 15963 // it is being sent to the calling app. 15964 if (!intent.getComponent().getPackageName().equals( 15965 callerApp.info.packageName)) { 15966 String msg = "Permission Denial: not allowed to send broadcast " 15967 + intent.getAction() + " to " 15968 + intent.getComponent().getPackageName() + " from " 15969 + callerApp.info.packageName; 15970 Slog.w(TAG, msg); 15971 throw new SecurityException(msg); 15972 } 15973 } else { 15974 // Limit broadcast to their own package. 15975 intent.setPackage(callerApp.info.packageName); 15976 } 15977 } 15978 } catch (RemoteException e) { 15979 Slog.w(TAG, "Remote exception", e); 15980 return ActivityManager.BROADCAST_SUCCESS; 15981 } 15982 } 15983 15984 final String action = intent.getAction(); 15985 if (action != null) { 15986 switch (action) { 15987 case Intent.ACTION_UID_REMOVED: 15988 case Intent.ACTION_PACKAGE_REMOVED: 15989 case Intent.ACTION_PACKAGE_CHANGED: 15990 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15991 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15992 // Handle special intents: if this broadcast is from the package 15993 // manager about a package being removed, we need to remove all of 15994 // its activities from the history stack. 15995 if (checkComponentPermission( 15996 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15997 callingPid, callingUid, -1, true) 15998 != PackageManager.PERMISSION_GRANTED) { 15999 String msg = "Permission Denial: " + intent.getAction() 16000 + " broadcast from " + callerPackage + " (pid=" + callingPid 16001 + ", uid=" + callingUid + ")" 16002 + " requires " 16003 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 16004 Slog.w(TAG, msg); 16005 throw new SecurityException(msg); 16006 } 16007 switch (action) { 16008 case Intent.ACTION_UID_REMOVED: 16009 final Bundle intentExtras = intent.getExtras(); 16010 final int uid = intentExtras != null 16011 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 16012 if (uid >= 0) { 16013 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 16014 synchronized (bs) { 16015 bs.removeUidStatsLocked(uid); 16016 } 16017 mAppOpsService.uidRemoved(uid); 16018 } 16019 break; 16020 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 16021 // If resources are unavailable just force stop all those packages 16022 // and flush the attribute cache as well. 16023 String list[] = 16024 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16025 if (list != null && list.length > 0) { 16026 for (int i = 0; i < list.length; i++) { 16027 forceStopPackageLocked(list[i], -1, false, true, true, 16028 false, false, userId, "storage unmount"); 16029 } 16030 cleanupRecentTasksLocked(UserHandle.USER_ALL); 16031 sendPackageBroadcastLocked( 16032 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 16033 userId); 16034 } 16035 break; 16036 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 16037 cleanupRecentTasksLocked(UserHandle.USER_ALL); 16038 break; 16039 case Intent.ACTION_PACKAGE_REMOVED: 16040 case Intent.ACTION_PACKAGE_CHANGED: 16041 Uri data = intent.getData(); 16042 String ssp; 16043 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 16044 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 16045 boolean fullUninstall = removed && 16046 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16047 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 16048 forceStopPackageLocked(ssp, UserHandle.getAppId( 16049 intent.getIntExtra(Intent.EXTRA_UID, -1)), 16050 false, true, true, false, fullUninstall, userId, 16051 removed ? "pkg removed" : "pkg changed"); 16052 } 16053 if (removed) { 16054 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 16055 new String[] {ssp}, userId); 16056 if (fullUninstall) { 16057 mAppOpsService.packageRemoved( 16058 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 16059 16060 // Remove all permissions granted from/to this package 16061 removeUriPermissionsForPackageLocked(ssp, userId, true); 16062 16063 removeTasksByPackageNameLocked(ssp, userId); 16064 if (userId == UserHandle.USER_OWNER) { 16065 mTaskPersister.removeFromPackageCache(ssp); 16066 } 16067 } 16068 } else { 16069 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16070 if (userId == UserHandle.USER_OWNER) { 16071 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16072 } 16073 } 16074 } 16075 break; 16076 } 16077 break; 16078 case Intent.ACTION_PACKAGE_ADDED: 16079 // Special case for adding a package: by default turn on compatibility mode. 16080 Uri data = intent.getData(); 16081 String ssp; 16082 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16083 final boolean replacing = 16084 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16085 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16086 16087 if (replacing) { 16088 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16089 } 16090 if (userId == UserHandle.USER_OWNER) { 16091 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16092 } 16093 } 16094 break; 16095 case Intent.ACTION_TIMEZONE_CHANGED: 16096 // If this is the time zone changed action, queue up a message that will reset 16097 // the timezone of all currently running processes. This message will get 16098 // queued up before the broadcast happens. 16099 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16100 break; 16101 case Intent.ACTION_TIME_CHANGED: 16102 // If the user set the time, let all running processes know. 16103 final int is24Hour = 16104 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16105 : 0; 16106 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16107 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16108 synchronized (stats) { 16109 stats.noteCurrentTimeChangedLocked(); 16110 } 16111 break; 16112 case Intent.ACTION_CLEAR_DNS_CACHE: 16113 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16114 break; 16115 case Proxy.PROXY_CHANGE_ACTION: 16116 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16117 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16118 break; 16119 } 16120 } 16121 16122 // Add to the sticky list if requested. 16123 if (sticky) { 16124 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16125 callingPid, callingUid) 16126 != PackageManager.PERMISSION_GRANTED) { 16127 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16128 + callingPid + ", uid=" + callingUid 16129 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16130 Slog.w(TAG, msg); 16131 throw new SecurityException(msg); 16132 } 16133 if (requiredPermission != null) { 16134 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16135 + " and enforce permission " + requiredPermission); 16136 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16137 } 16138 if (intent.getComponent() != null) { 16139 throw new SecurityException( 16140 "Sticky broadcasts can't target a specific component"); 16141 } 16142 // We use userId directly here, since the "all" target is maintained 16143 // as a separate set of sticky broadcasts. 16144 if (userId != UserHandle.USER_ALL) { 16145 // But first, if this is not a broadcast to all users, then 16146 // make sure it doesn't conflict with an existing broadcast to 16147 // all users. 16148 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16149 UserHandle.USER_ALL); 16150 if (stickies != null) { 16151 ArrayList<Intent> list = stickies.get(intent.getAction()); 16152 if (list != null) { 16153 int N = list.size(); 16154 int i; 16155 for (i=0; i<N; i++) { 16156 if (intent.filterEquals(list.get(i))) { 16157 throw new IllegalArgumentException( 16158 "Sticky broadcast " + intent + " for user " 16159 + userId + " conflicts with existing global broadcast"); 16160 } 16161 } 16162 } 16163 } 16164 } 16165 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16166 if (stickies == null) { 16167 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16168 mStickyBroadcasts.put(userId, stickies); 16169 } 16170 ArrayList<Intent> list = stickies.get(intent.getAction()); 16171 if (list == null) { 16172 list = new ArrayList<Intent>(); 16173 stickies.put(intent.getAction(), list); 16174 } 16175 int N = list.size(); 16176 int i; 16177 for (i=0; i<N; i++) { 16178 if (intent.filterEquals(list.get(i))) { 16179 // This sticky already exists, replace it. 16180 list.set(i, new Intent(intent)); 16181 break; 16182 } 16183 } 16184 if (i >= N) { 16185 list.add(new Intent(intent)); 16186 } 16187 } 16188 16189 int[] users; 16190 if (userId == UserHandle.USER_ALL) { 16191 // Caller wants broadcast to go to all started users. 16192 users = mStartedUserArray; 16193 } else { 16194 // Caller wants broadcast to go to one specific user. 16195 users = new int[] {userId}; 16196 } 16197 16198 // Figure out who all will receive this broadcast. 16199 List receivers = null; 16200 List<BroadcastFilter> registeredReceivers = null; 16201 // Need to resolve the intent to interested receivers... 16202 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16203 == 0) { 16204 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16205 } 16206 if (intent.getComponent() == null) { 16207 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16208 // Query one target user at a time, excluding shell-restricted users 16209 UserManagerService ums = getUserManagerLocked(); 16210 for (int i = 0; i < users.length; i++) { 16211 if (ums.hasUserRestriction( 16212 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16213 continue; 16214 } 16215 List<BroadcastFilter> registeredReceiversForUser = 16216 mReceiverResolver.queryIntent(intent, 16217 resolvedType, false, users[i]); 16218 if (registeredReceivers == null) { 16219 registeredReceivers = registeredReceiversForUser; 16220 } else if (registeredReceiversForUser != null) { 16221 registeredReceivers.addAll(registeredReceiversForUser); 16222 } 16223 } 16224 } else { 16225 registeredReceivers = mReceiverResolver.queryIntent(intent, 16226 resolvedType, false, userId); 16227 } 16228 } 16229 16230 final boolean replacePending = 16231 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16232 16233 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16234 + " replacePending=" + replacePending); 16235 16236 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16237 if (!ordered && NR > 0) { 16238 // If we are not serializing this broadcast, then send the 16239 // registered receivers separately so they don't wait for the 16240 // components to be launched. 16241 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16242 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16243 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16244 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16245 ordered, sticky, false, userId); 16246 if (DEBUG_BROADCAST) Slog.v( 16247 TAG, "Enqueueing parallel broadcast " + r); 16248 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16249 if (!replaced) { 16250 queue.enqueueParallelBroadcastLocked(r); 16251 queue.scheduleBroadcastsLocked(); 16252 } 16253 registeredReceivers = null; 16254 NR = 0; 16255 } 16256 16257 // Merge into one list. 16258 int ir = 0; 16259 if (receivers != null) { 16260 // A special case for PACKAGE_ADDED: do not allow the package 16261 // being added to see this broadcast. This prevents them from 16262 // using this as a back door to get run as soon as they are 16263 // installed. Maybe in the future we want to have a special install 16264 // broadcast or such for apps, but we'd like to deliberately make 16265 // this decision. 16266 String skipPackages[] = null; 16267 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16268 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16269 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16270 Uri data = intent.getData(); 16271 if (data != null) { 16272 String pkgName = data.getSchemeSpecificPart(); 16273 if (pkgName != null) { 16274 skipPackages = new String[] { pkgName }; 16275 } 16276 } 16277 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16278 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16279 } 16280 if (skipPackages != null && (skipPackages.length > 0)) { 16281 for (String skipPackage : skipPackages) { 16282 if (skipPackage != null) { 16283 int NT = receivers.size(); 16284 for (int it=0; it<NT; it++) { 16285 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16286 if (curt.activityInfo.packageName.equals(skipPackage)) { 16287 receivers.remove(it); 16288 it--; 16289 NT--; 16290 } 16291 } 16292 } 16293 } 16294 } 16295 16296 int NT = receivers != null ? receivers.size() : 0; 16297 int it = 0; 16298 ResolveInfo curt = null; 16299 BroadcastFilter curr = null; 16300 while (it < NT && ir < NR) { 16301 if (curt == null) { 16302 curt = (ResolveInfo)receivers.get(it); 16303 } 16304 if (curr == null) { 16305 curr = registeredReceivers.get(ir); 16306 } 16307 if (curr.getPriority() >= curt.priority) { 16308 // Insert this broadcast record into the final list. 16309 receivers.add(it, curr); 16310 ir++; 16311 curr = null; 16312 it++; 16313 NT++; 16314 } else { 16315 // Skip to the next ResolveInfo in the final list. 16316 it++; 16317 curt = null; 16318 } 16319 } 16320 } 16321 while (ir < NR) { 16322 if (receivers == null) { 16323 receivers = new ArrayList(); 16324 } 16325 receivers.add(registeredReceivers.get(ir)); 16326 ir++; 16327 } 16328 16329 if ((receivers != null && receivers.size() > 0) 16330 || resultTo != null) { 16331 BroadcastQueue queue = broadcastQueueForIntent(intent); 16332 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16333 callerPackage, callingPid, callingUid, resolvedType, 16334 requiredPermission, appOp, receivers, resultTo, resultCode, 16335 resultData, map, ordered, sticky, false, userId); 16336 if (DEBUG_BROADCAST) Slog.v( 16337 TAG, "Enqueueing ordered broadcast " + r 16338 + ": prev had " + queue.mOrderedBroadcasts.size()); 16339 if (DEBUG_BROADCAST) { 16340 int seq = r.intent.getIntExtra("seq", -1); 16341 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16342 } 16343 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16344 if (!replaced) { 16345 queue.enqueueOrderedBroadcastLocked(r); 16346 queue.scheduleBroadcastsLocked(); 16347 } 16348 } 16349 16350 return ActivityManager.BROADCAST_SUCCESS; 16351 } 16352 16353 final Intent verifyBroadcastLocked(Intent intent) { 16354 // Refuse possible leaked file descriptors 16355 if (intent != null && intent.hasFileDescriptors() == true) { 16356 throw new IllegalArgumentException("File descriptors passed in Intent"); 16357 } 16358 16359 int flags = intent.getFlags(); 16360 16361 if (!mProcessesReady) { 16362 // if the caller really truly claims to know what they're doing, go 16363 // ahead and allow the broadcast without launching any receivers 16364 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16365 intent = new Intent(intent); 16366 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16367 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16368 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16369 + " before boot completion"); 16370 throw new IllegalStateException("Cannot broadcast before boot completed"); 16371 } 16372 } 16373 16374 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16375 throw new IllegalArgumentException( 16376 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16377 } 16378 16379 return intent; 16380 } 16381 16382 public final int broadcastIntent(IApplicationThread caller, 16383 Intent intent, String resolvedType, IIntentReceiver resultTo, 16384 int resultCode, String resultData, Bundle map, 16385 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16386 enforceNotIsolatedCaller("broadcastIntent"); 16387 synchronized(this) { 16388 intent = verifyBroadcastLocked(intent); 16389 16390 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16391 final int callingPid = Binder.getCallingPid(); 16392 final int callingUid = Binder.getCallingUid(); 16393 final long origId = Binder.clearCallingIdentity(); 16394 int res = broadcastIntentLocked(callerApp, 16395 callerApp != null ? callerApp.info.packageName : null, 16396 intent, resolvedType, resultTo, 16397 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16398 callingPid, callingUid, userId); 16399 Binder.restoreCallingIdentity(origId); 16400 return res; 16401 } 16402 } 16403 16404 int broadcastIntentInPackage(String packageName, int uid, 16405 Intent intent, String resolvedType, IIntentReceiver resultTo, 16406 int resultCode, String resultData, Bundle map, 16407 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16408 synchronized(this) { 16409 intent = verifyBroadcastLocked(intent); 16410 16411 final long origId = Binder.clearCallingIdentity(); 16412 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16413 resultTo, resultCode, resultData, map, requiredPermission, 16414 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16415 Binder.restoreCallingIdentity(origId); 16416 return res; 16417 } 16418 } 16419 16420 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16421 // Refuse possible leaked file descriptors 16422 if (intent != null && intent.hasFileDescriptors() == true) { 16423 throw new IllegalArgumentException("File descriptors passed in Intent"); 16424 } 16425 16426 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16427 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16428 16429 synchronized(this) { 16430 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16431 != PackageManager.PERMISSION_GRANTED) { 16432 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16433 + Binder.getCallingPid() 16434 + ", uid=" + Binder.getCallingUid() 16435 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16436 Slog.w(TAG, msg); 16437 throw new SecurityException(msg); 16438 } 16439 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16440 if (stickies != null) { 16441 ArrayList<Intent> list = stickies.get(intent.getAction()); 16442 if (list != null) { 16443 int N = list.size(); 16444 int i; 16445 for (i=0; i<N; i++) { 16446 if (intent.filterEquals(list.get(i))) { 16447 list.remove(i); 16448 break; 16449 } 16450 } 16451 if (list.size() <= 0) { 16452 stickies.remove(intent.getAction()); 16453 } 16454 } 16455 if (stickies.size() <= 0) { 16456 mStickyBroadcasts.remove(userId); 16457 } 16458 } 16459 } 16460 } 16461 16462 void backgroundServicesFinishedLocked(int userId) { 16463 for (BroadcastQueue queue : mBroadcastQueues) { 16464 queue.backgroundServicesFinishedLocked(userId); 16465 } 16466 } 16467 16468 public void finishReceiver(IBinder who, int resultCode, String resultData, 16469 Bundle resultExtras, boolean resultAbort, int flags) { 16470 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16471 16472 // Refuse possible leaked file descriptors 16473 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16474 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16475 } 16476 16477 final long origId = Binder.clearCallingIdentity(); 16478 try { 16479 boolean doNext = false; 16480 BroadcastRecord r; 16481 16482 synchronized(this) { 16483 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 16484 ? mFgBroadcastQueue : mBgBroadcastQueue; 16485 r = queue.getMatchingOrderedReceiver(who); 16486 if (r != null) { 16487 doNext = r.queue.finishReceiverLocked(r, resultCode, 16488 resultData, resultExtras, resultAbort, true); 16489 } 16490 } 16491 16492 if (doNext) { 16493 r.queue.processNextBroadcast(false); 16494 } 16495 trimApplications(); 16496 } finally { 16497 Binder.restoreCallingIdentity(origId); 16498 } 16499 } 16500 16501 // ========================================================= 16502 // INSTRUMENTATION 16503 // ========================================================= 16504 16505 public boolean startInstrumentation(ComponentName className, 16506 String profileFile, int flags, Bundle arguments, 16507 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16508 int userId, String abiOverride) { 16509 enforceNotIsolatedCaller("startInstrumentation"); 16510 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16511 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16512 // Refuse possible leaked file descriptors 16513 if (arguments != null && arguments.hasFileDescriptors()) { 16514 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16515 } 16516 16517 synchronized(this) { 16518 InstrumentationInfo ii = null; 16519 ApplicationInfo ai = null; 16520 try { 16521 ii = mContext.getPackageManager().getInstrumentationInfo( 16522 className, STOCK_PM_FLAGS); 16523 ai = AppGlobals.getPackageManager().getApplicationInfo( 16524 ii.targetPackage, STOCK_PM_FLAGS, userId); 16525 } catch (PackageManager.NameNotFoundException e) { 16526 } catch (RemoteException e) { 16527 } 16528 if (ii == null) { 16529 reportStartInstrumentationFailure(watcher, className, 16530 "Unable to find instrumentation info for: " + className); 16531 return false; 16532 } 16533 if (ai == null) { 16534 reportStartInstrumentationFailure(watcher, className, 16535 "Unable to find instrumentation target package: " + ii.targetPackage); 16536 return false; 16537 } 16538 16539 int match = mContext.getPackageManager().checkSignatures( 16540 ii.targetPackage, ii.packageName); 16541 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16542 String msg = "Permission Denial: starting instrumentation " 16543 + className + " from pid=" 16544 + Binder.getCallingPid() 16545 + ", uid=" + Binder.getCallingPid() 16546 + " not allowed because package " + ii.packageName 16547 + " does not have a signature matching the target " 16548 + ii.targetPackage; 16549 reportStartInstrumentationFailure(watcher, className, msg); 16550 throw new SecurityException(msg); 16551 } 16552 16553 final long origId = Binder.clearCallingIdentity(); 16554 // Instrumentation can kill and relaunch even persistent processes 16555 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16556 "start instr"); 16557 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16558 app.instrumentationClass = className; 16559 app.instrumentationInfo = ai; 16560 app.instrumentationProfileFile = profileFile; 16561 app.instrumentationArguments = arguments; 16562 app.instrumentationWatcher = watcher; 16563 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16564 app.instrumentationResultClass = className; 16565 Binder.restoreCallingIdentity(origId); 16566 } 16567 16568 return true; 16569 } 16570 16571 /** 16572 * Report errors that occur while attempting to start Instrumentation. Always writes the 16573 * error to the logs, but if somebody is watching, send the report there too. This enables 16574 * the "am" command to report errors with more information. 16575 * 16576 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16577 * @param cn The component name of the instrumentation. 16578 * @param report The error report. 16579 */ 16580 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16581 ComponentName cn, String report) { 16582 Slog.w(TAG, report); 16583 try { 16584 if (watcher != null) { 16585 Bundle results = new Bundle(); 16586 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16587 results.putString("Error", report); 16588 watcher.instrumentationStatus(cn, -1, results); 16589 } 16590 } catch (RemoteException e) { 16591 Slog.w(TAG, e); 16592 } 16593 } 16594 16595 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16596 if (app.instrumentationWatcher != null) { 16597 try { 16598 // NOTE: IInstrumentationWatcher *must* be oneway here 16599 app.instrumentationWatcher.instrumentationFinished( 16600 app.instrumentationClass, 16601 resultCode, 16602 results); 16603 } catch (RemoteException e) { 16604 } 16605 } 16606 if (app.instrumentationUiAutomationConnection != null) { 16607 try { 16608 app.instrumentationUiAutomationConnection.shutdown(); 16609 } catch (RemoteException re) { 16610 /* ignore */ 16611 } 16612 // Only a UiAutomation can set this flag and now that 16613 // it is finished we make sure it is reset to its default. 16614 mUserIsMonkey = false; 16615 } 16616 app.instrumentationWatcher = null; 16617 app.instrumentationUiAutomationConnection = null; 16618 app.instrumentationClass = null; 16619 app.instrumentationInfo = null; 16620 app.instrumentationProfileFile = null; 16621 app.instrumentationArguments = null; 16622 16623 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16624 "finished inst"); 16625 } 16626 16627 public void finishInstrumentation(IApplicationThread target, 16628 int resultCode, Bundle results) { 16629 int userId = UserHandle.getCallingUserId(); 16630 // Refuse possible leaked file descriptors 16631 if (results != null && results.hasFileDescriptors()) { 16632 throw new IllegalArgumentException("File descriptors passed in Intent"); 16633 } 16634 16635 synchronized(this) { 16636 ProcessRecord app = getRecordForAppLocked(target); 16637 if (app == null) { 16638 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16639 return; 16640 } 16641 final long origId = Binder.clearCallingIdentity(); 16642 finishInstrumentationLocked(app, resultCode, results); 16643 Binder.restoreCallingIdentity(origId); 16644 } 16645 } 16646 16647 // ========================================================= 16648 // CONFIGURATION 16649 // ========================================================= 16650 16651 public ConfigurationInfo getDeviceConfigurationInfo() { 16652 ConfigurationInfo config = new ConfigurationInfo(); 16653 synchronized (this) { 16654 config.reqTouchScreen = mConfiguration.touchscreen; 16655 config.reqKeyboardType = mConfiguration.keyboard; 16656 config.reqNavigation = mConfiguration.navigation; 16657 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16658 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16659 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16660 } 16661 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16662 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16663 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16664 } 16665 config.reqGlEsVersion = GL_ES_VERSION; 16666 } 16667 return config; 16668 } 16669 16670 ActivityStack getFocusedStack() { 16671 return mStackSupervisor.getFocusedStack(); 16672 } 16673 16674 public Configuration getConfiguration() { 16675 Configuration ci; 16676 synchronized(this) { 16677 ci = new Configuration(mConfiguration); 16678 ci.userSetLocale = false; 16679 } 16680 return ci; 16681 } 16682 16683 public void updatePersistentConfiguration(Configuration values) { 16684 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16685 "updateConfiguration()"); 16686 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16687 "updateConfiguration()"); 16688 if (values == null) { 16689 throw new NullPointerException("Configuration must not be null"); 16690 } 16691 16692 synchronized(this) { 16693 final long origId = Binder.clearCallingIdentity(); 16694 updateConfigurationLocked(values, null, true, false); 16695 Binder.restoreCallingIdentity(origId); 16696 } 16697 } 16698 16699 public void updateConfiguration(Configuration values) { 16700 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16701 "updateConfiguration()"); 16702 16703 synchronized(this) { 16704 if (values == null && mWindowManager != null) { 16705 // sentinel: fetch the current configuration from the window manager 16706 values = mWindowManager.computeNewConfiguration(); 16707 } 16708 16709 if (mWindowManager != null) { 16710 mProcessList.applyDisplaySize(mWindowManager); 16711 } 16712 16713 final long origId = Binder.clearCallingIdentity(); 16714 if (values != null) { 16715 Settings.System.clearConfiguration(values); 16716 } 16717 updateConfigurationLocked(values, null, false, false); 16718 Binder.restoreCallingIdentity(origId); 16719 } 16720 } 16721 16722 /** 16723 * Do either or both things: (1) change the current configuration, and (2) 16724 * make sure the given activity is running with the (now) current 16725 * configuration. Returns true if the activity has been left running, or 16726 * false if <var>starting</var> is being destroyed to match the new 16727 * configuration. 16728 * @param persistent TODO 16729 */ 16730 boolean updateConfigurationLocked(Configuration values, 16731 ActivityRecord starting, boolean persistent, boolean initLocale) { 16732 int changes = 0; 16733 16734 if (values != null) { 16735 Configuration newConfig = new Configuration(mConfiguration); 16736 changes = newConfig.updateFrom(values); 16737 if (changes != 0) { 16738 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16739 Slog.i(TAG, "Updating configuration to: " + values); 16740 } 16741 16742 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16743 16744 if (!initLocale && values.locale != null && values.userSetLocale) { 16745 final String languageTag = values.locale.toLanguageTag(); 16746 SystemProperties.set("persist.sys.locale", languageTag); 16747 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, 16748 values.locale)); 16749 } 16750 16751 mConfigurationSeq++; 16752 if (mConfigurationSeq <= 0) { 16753 mConfigurationSeq = 1; 16754 } 16755 newConfig.seq = mConfigurationSeq; 16756 mConfiguration = newConfig; 16757 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16758 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16759 //mUsageStatsService.noteStartConfig(newConfig); 16760 16761 final Configuration configCopy = new Configuration(mConfiguration); 16762 16763 // TODO: If our config changes, should we auto dismiss any currently 16764 // showing dialogs? 16765 mShowDialogs = shouldShowDialogs(newConfig); 16766 16767 AttributeCache ac = AttributeCache.instance(); 16768 if (ac != null) { 16769 ac.updateConfiguration(configCopy); 16770 } 16771 16772 // Make sure all resources in our process are updated 16773 // right now, so that anyone who is going to retrieve 16774 // resource values after we return will be sure to get 16775 // the new ones. This is especially important during 16776 // boot, where the first config change needs to guarantee 16777 // all resources have that config before following boot 16778 // code is executed. 16779 mSystemThread.applyConfigurationToResources(configCopy); 16780 16781 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16782 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16783 msg.obj = new Configuration(configCopy); 16784 mHandler.sendMessage(msg); 16785 } 16786 16787 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16788 ProcessRecord app = mLruProcesses.get(i); 16789 try { 16790 if (app.thread != null) { 16791 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16792 + app.processName + " new config " + mConfiguration); 16793 app.thread.scheduleConfigurationChanged(configCopy); 16794 } 16795 } catch (Exception e) { 16796 } 16797 } 16798 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16799 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16800 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16801 | Intent.FLAG_RECEIVER_FOREGROUND); 16802 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16803 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16804 Process.SYSTEM_UID, UserHandle.USER_ALL); 16805 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16806 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16807 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16808 broadcastIntentLocked(null, null, intent, 16809 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16810 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16811 } 16812 } 16813 } 16814 16815 boolean kept = true; 16816 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16817 // mainStack is null during startup. 16818 if (mainStack != null) { 16819 if (changes != 0 && starting == null) { 16820 // If the configuration changed, and the caller is not already 16821 // in the process of starting an activity, then find the top 16822 // activity to check if its configuration needs to change. 16823 starting = mainStack.topRunningActivityLocked(null); 16824 } 16825 16826 if (starting != null) { 16827 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16828 // And we need to make sure at this point that all other activities 16829 // are made visible with the correct configuration. 16830 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16831 } 16832 } 16833 16834 if (values != null && mWindowManager != null) { 16835 mWindowManager.setNewConfiguration(mConfiguration); 16836 } 16837 16838 return kept; 16839 } 16840 16841 /** 16842 * Decide based on the configuration whether we should shouw the ANR, 16843 * crash, etc dialogs. The idea is that if there is no affordnace to 16844 * press the on-screen buttons, we shouldn't show the dialog. 16845 * 16846 * A thought: SystemUI might also want to get told about this, the Power 16847 * dialog / global actions also might want different behaviors. 16848 */ 16849 private static final boolean shouldShowDialogs(Configuration config) { 16850 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16851 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16852 } 16853 16854 @Override 16855 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16856 synchronized (this) { 16857 ActivityRecord srec = ActivityRecord.forToken(token); 16858 if (srec.task != null && srec.task.stack != null) { 16859 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16860 } 16861 } 16862 return false; 16863 } 16864 16865 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16866 Intent resultData) { 16867 16868 synchronized (this) { 16869 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16870 if (stack != null) { 16871 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16872 } 16873 return false; 16874 } 16875 } 16876 16877 public int getLaunchedFromUid(IBinder activityToken) { 16878 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16879 if (srec == null) { 16880 return -1; 16881 } 16882 return srec.launchedFromUid; 16883 } 16884 16885 public String getLaunchedFromPackage(IBinder activityToken) { 16886 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16887 if (srec == null) { 16888 return null; 16889 } 16890 return srec.launchedFromPackage; 16891 } 16892 16893 // ========================================================= 16894 // LIFETIME MANAGEMENT 16895 // ========================================================= 16896 16897 // Returns which broadcast queue the app is the current [or imminent] receiver 16898 // on, or 'null' if the app is not an active broadcast recipient. 16899 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16900 BroadcastRecord r = app.curReceiver; 16901 if (r != null) { 16902 return r.queue; 16903 } 16904 16905 // It's not the current receiver, but it might be starting up to become one 16906 synchronized (this) { 16907 for (BroadcastQueue queue : mBroadcastQueues) { 16908 r = queue.mPendingBroadcast; 16909 if (r != null && r.curApp == app) { 16910 // found it; report which queue it's in 16911 return queue; 16912 } 16913 } 16914 } 16915 16916 return null; 16917 } 16918 16919 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16920 ComponentName targetComponent, String targetProcess) { 16921 if (!mTrackingAssociations) { 16922 return null; 16923 } 16924 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16925 = mAssociations.get(targetUid); 16926 if (components == null) { 16927 components = new ArrayMap<>(); 16928 mAssociations.put(targetUid, components); 16929 } 16930 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16931 if (sourceUids == null) { 16932 sourceUids = new SparseArray<>(); 16933 components.put(targetComponent, sourceUids); 16934 } 16935 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16936 if (sourceProcesses == null) { 16937 sourceProcesses = new ArrayMap<>(); 16938 sourceUids.put(sourceUid, sourceProcesses); 16939 } 16940 Association ass = sourceProcesses.get(sourceProcess); 16941 if (ass == null) { 16942 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16943 targetProcess); 16944 sourceProcesses.put(sourceProcess, ass); 16945 } 16946 ass.mCount++; 16947 ass.mNesting++; 16948 if (ass.mNesting == 1) { 16949 ass.mStartTime = SystemClock.uptimeMillis(); 16950 } 16951 return ass; 16952 } 16953 16954 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16955 ComponentName targetComponent) { 16956 if (!mTrackingAssociations) { 16957 return; 16958 } 16959 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16960 = mAssociations.get(targetUid); 16961 if (components == null) { 16962 return; 16963 } 16964 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16965 if (sourceUids == null) { 16966 return; 16967 } 16968 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16969 if (sourceProcesses == null) { 16970 return; 16971 } 16972 Association ass = sourceProcesses.get(sourceProcess); 16973 if (ass == null || ass.mNesting <= 0) { 16974 return; 16975 } 16976 ass.mNesting--; 16977 if (ass.mNesting == 0) { 16978 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16979 } 16980 } 16981 16982 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16983 boolean doingAll, long now) { 16984 if (mAdjSeq == app.adjSeq) { 16985 // This adjustment has already been computed. 16986 return app.curRawAdj; 16987 } 16988 16989 if (app.thread == null) { 16990 app.adjSeq = mAdjSeq; 16991 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16992 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16993 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16994 } 16995 16996 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16997 app.adjSource = null; 16998 app.adjTarget = null; 16999 app.empty = false; 17000 app.cached = false; 17001 17002 final int activitiesSize = app.activities.size(); 17003 17004 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 17005 // The max adjustment doesn't allow this app to be anything 17006 // below foreground, so it is not worth doing work for it. 17007 app.adjType = "fixed"; 17008 app.adjSeq = mAdjSeq; 17009 app.curRawAdj = app.maxAdj; 17010 app.foregroundActivities = false; 17011 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 17012 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 17013 // System processes can do UI, and when they do we want to have 17014 // them trim their memory after the user leaves the UI. To 17015 // facilitate this, here we need to determine whether or not it 17016 // is currently showing UI. 17017 app.systemNoUi = true; 17018 if (app == TOP_APP) { 17019 app.systemNoUi = false; 17020 } else if (activitiesSize > 0) { 17021 for (int j = 0; j < activitiesSize; j++) { 17022 final ActivityRecord r = app.activities.get(j); 17023 if (r.visible) { 17024 app.systemNoUi = false; 17025 } 17026 } 17027 } 17028 if (!app.systemNoUi) { 17029 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 17030 } 17031 return (app.curAdj=app.maxAdj); 17032 } 17033 17034 app.systemNoUi = false; 17035 17036 // Determine the importance of the process, starting with most 17037 // important to least, and assign an appropriate OOM adjustment. 17038 int adj; 17039 int schedGroup; 17040 int procState; 17041 boolean foregroundActivities = false; 17042 BroadcastQueue queue; 17043 if (app == TOP_APP) { 17044 // The last app on the list is the foreground app. 17045 adj = ProcessList.FOREGROUND_APP_ADJ; 17046 schedGroup = Process.THREAD_GROUP_DEFAULT; 17047 app.adjType = "top-activity"; 17048 foregroundActivities = true; 17049 procState = ActivityManager.PROCESS_STATE_TOP; 17050 } else if (app.instrumentationClass != null) { 17051 // Don't want to kill running instrumentation. 17052 adj = ProcessList.FOREGROUND_APP_ADJ; 17053 schedGroup = Process.THREAD_GROUP_DEFAULT; 17054 app.adjType = "instrumentation"; 17055 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17056 } else if ((queue = isReceivingBroadcast(app)) != null) { 17057 // An app that is currently receiving a broadcast also 17058 // counts as being in the foreground for OOM killer purposes. 17059 // It's placed in a sched group based on the nature of the 17060 // broadcast as reflected by which queue it's active in. 17061 adj = ProcessList.FOREGROUND_APP_ADJ; 17062 schedGroup = (queue == mFgBroadcastQueue) 17063 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17064 app.adjType = "broadcast"; 17065 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17066 } else if (app.executingServices.size() > 0) { 17067 // An app that is currently executing a service callback also 17068 // counts as being in the foreground. 17069 adj = ProcessList.FOREGROUND_APP_ADJ; 17070 schedGroup = app.execServicesFg ? 17071 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17072 app.adjType = "exec-service"; 17073 procState = ActivityManager.PROCESS_STATE_SERVICE; 17074 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17075 } else { 17076 // As far as we know the process is empty. We may change our mind later. 17077 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17078 // At this point we don't actually know the adjustment. Use the cached adj 17079 // value that the caller wants us to. 17080 adj = cachedAdj; 17081 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17082 app.cached = true; 17083 app.empty = true; 17084 app.adjType = "cch-empty"; 17085 } 17086 17087 // Examine all activities if not already foreground. 17088 if (!foregroundActivities && activitiesSize > 0) { 17089 for (int j = 0; j < activitiesSize; j++) { 17090 final ActivityRecord r = app.activities.get(j); 17091 if (r.app != app) { 17092 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17093 + app + "?!?"); 17094 continue; 17095 } 17096 if (r.visible) { 17097 // App has a visible activity; only upgrade adjustment. 17098 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17099 adj = ProcessList.VISIBLE_APP_ADJ; 17100 app.adjType = "visible"; 17101 } 17102 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17103 procState = ActivityManager.PROCESS_STATE_TOP; 17104 } 17105 schedGroup = Process.THREAD_GROUP_DEFAULT; 17106 app.cached = false; 17107 app.empty = false; 17108 foregroundActivities = true; 17109 break; 17110 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17111 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17112 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17113 app.adjType = "pausing"; 17114 } 17115 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17116 procState = ActivityManager.PROCESS_STATE_TOP; 17117 } 17118 schedGroup = Process.THREAD_GROUP_DEFAULT; 17119 app.cached = false; 17120 app.empty = false; 17121 foregroundActivities = true; 17122 } else if (r.state == ActivityState.STOPPING) { 17123 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17124 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17125 app.adjType = "stopping"; 17126 } 17127 // For the process state, we will at this point consider the 17128 // process to be cached. It will be cached either as an activity 17129 // or empty depending on whether the activity is finishing. We do 17130 // this so that we can treat the process as cached for purposes of 17131 // memory trimming (determing current memory level, trim command to 17132 // send to process) since there can be an arbitrary number of stopping 17133 // processes and they should soon all go into the cached state. 17134 if (!r.finishing) { 17135 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17136 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17137 } 17138 } 17139 app.cached = false; 17140 app.empty = false; 17141 foregroundActivities = true; 17142 } else { 17143 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17144 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17145 app.adjType = "cch-act"; 17146 } 17147 } 17148 } 17149 } 17150 17151 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17152 if (app.foregroundServices) { 17153 // The user is aware of this app, so make it visible. 17154 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17155 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17156 app.cached = false; 17157 app.adjType = "fg-service"; 17158 schedGroup = Process.THREAD_GROUP_DEFAULT; 17159 } else if (app.forcingToForeground != null) { 17160 // The user is aware of this app, so make it visible. 17161 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17162 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17163 app.cached = false; 17164 app.adjType = "force-fg"; 17165 app.adjSource = app.forcingToForeground; 17166 schedGroup = Process.THREAD_GROUP_DEFAULT; 17167 } 17168 } 17169 17170 if (app == mHeavyWeightProcess) { 17171 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17172 // We don't want to kill the current heavy-weight process. 17173 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17174 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17175 app.cached = false; 17176 app.adjType = "heavy"; 17177 } 17178 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17179 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17180 } 17181 } 17182 17183 if (app == mHomeProcess) { 17184 if (adj > ProcessList.HOME_APP_ADJ) { 17185 // This process is hosting what we currently consider to be the 17186 // home app, so we don't want to let it go into the background. 17187 adj = ProcessList.HOME_APP_ADJ; 17188 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17189 app.cached = false; 17190 app.adjType = "home"; 17191 } 17192 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17193 procState = ActivityManager.PROCESS_STATE_HOME; 17194 } 17195 } 17196 17197 if (app == mPreviousProcess && app.activities.size() > 0) { 17198 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17199 // This was the previous process that showed UI to the user. 17200 // We want to try to keep it around more aggressively, to give 17201 // a good experience around switching between two apps. 17202 adj = ProcessList.PREVIOUS_APP_ADJ; 17203 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17204 app.cached = false; 17205 app.adjType = "previous"; 17206 } 17207 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17208 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17209 } 17210 } 17211 17212 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17213 + " reason=" + app.adjType); 17214 17215 // By default, we use the computed adjustment. It may be changed if 17216 // there are applications dependent on our services or providers, but 17217 // this gives us a baseline and makes sure we don't get into an 17218 // infinite recursion. 17219 app.adjSeq = mAdjSeq; 17220 app.curRawAdj = adj; 17221 app.hasStartedServices = false; 17222 17223 if (mBackupTarget != null && app == mBackupTarget.app) { 17224 // If possible we want to avoid killing apps while they're being backed up 17225 if (adj > ProcessList.BACKUP_APP_ADJ) { 17226 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17227 adj = ProcessList.BACKUP_APP_ADJ; 17228 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17229 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17230 } 17231 app.adjType = "backup"; 17232 app.cached = false; 17233 } 17234 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17235 procState = ActivityManager.PROCESS_STATE_BACKUP; 17236 } 17237 } 17238 17239 boolean mayBeTop = false; 17240 17241 for (int is = app.services.size()-1; 17242 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17243 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17244 || procState > ActivityManager.PROCESS_STATE_TOP); 17245 is--) { 17246 ServiceRecord s = app.services.valueAt(is); 17247 if (s.startRequested) { 17248 app.hasStartedServices = true; 17249 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17250 procState = ActivityManager.PROCESS_STATE_SERVICE; 17251 } 17252 if (app.hasShownUi && app != mHomeProcess) { 17253 // If this process has shown some UI, let it immediately 17254 // go to the LRU list because it may be pretty heavy with 17255 // UI stuff. We'll tag it with a label just to help 17256 // debug and understand what is going on. 17257 if (adj > ProcessList.SERVICE_ADJ) { 17258 app.adjType = "cch-started-ui-services"; 17259 } 17260 } else { 17261 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17262 // This service has seen some activity within 17263 // recent memory, so we will keep its process ahead 17264 // of the background processes. 17265 if (adj > ProcessList.SERVICE_ADJ) { 17266 adj = ProcessList.SERVICE_ADJ; 17267 app.adjType = "started-services"; 17268 app.cached = false; 17269 } 17270 } 17271 // If we have let the service slide into the background 17272 // state, still have some text describing what it is doing 17273 // even though the service no longer has an impact. 17274 if (adj > ProcessList.SERVICE_ADJ) { 17275 app.adjType = "cch-started-services"; 17276 } 17277 } 17278 } 17279 for (int conni = s.connections.size()-1; 17280 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17281 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17282 || procState > ActivityManager.PROCESS_STATE_TOP); 17283 conni--) { 17284 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17285 for (int i = 0; 17286 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17287 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17288 || procState > ActivityManager.PROCESS_STATE_TOP); 17289 i++) { 17290 // XXX should compute this based on the max of 17291 // all connected clients. 17292 ConnectionRecord cr = clist.get(i); 17293 if (cr.binding.client == app) { 17294 // Binding to ourself is not interesting. 17295 continue; 17296 } 17297 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17298 ProcessRecord client = cr.binding.client; 17299 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17300 TOP_APP, doingAll, now); 17301 int clientProcState = client.curProcState; 17302 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17303 // If the other app is cached for any reason, for purposes here 17304 // we are going to consider it empty. The specific cached state 17305 // doesn't propagate except under certain conditions. 17306 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17307 } 17308 String adjType = null; 17309 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17310 // Not doing bind OOM management, so treat 17311 // this guy more like a started service. 17312 if (app.hasShownUi && app != mHomeProcess) { 17313 // If this process has shown some UI, let it immediately 17314 // go to the LRU list because it may be pretty heavy with 17315 // UI stuff. We'll tag it with a label just to help 17316 // debug and understand what is going on. 17317 if (adj > clientAdj) { 17318 adjType = "cch-bound-ui-services"; 17319 } 17320 app.cached = false; 17321 clientAdj = adj; 17322 clientProcState = procState; 17323 } else { 17324 if (now >= (s.lastActivity 17325 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17326 // This service has not seen activity within 17327 // recent memory, so allow it to drop to the 17328 // LRU list if there is no other reason to keep 17329 // it around. We'll also tag it with a label just 17330 // to help debug and undertand what is going on. 17331 if (adj > clientAdj) { 17332 adjType = "cch-bound-services"; 17333 } 17334 clientAdj = adj; 17335 } 17336 } 17337 } 17338 if (adj > clientAdj) { 17339 // If this process has recently shown UI, and 17340 // the process that is binding to it is less 17341 // important than being visible, then we don't 17342 // care about the binding as much as we care 17343 // about letting this process get into the LRU 17344 // list to be killed and restarted if needed for 17345 // memory. 17346 if (app.hasShownUi && app != mHomeProcess 17347 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17348 adjType = "cch-bound-ui-services"; 17349 } else { 17350 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17351 |Context.BIND_IMPORTANT)) != 0) { 17352 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17353 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17354 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17355 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17356 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17357 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17358 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17359 adj = clientAdj; 17360 } else { 17361 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17362 adj = ProcessList.VISIBLE_APP_ADJ; 17363 } 17364 } 17365 if (!client.cached) { 17366 app.cached = false; 17367 } 17368 adjType = "service"; 17369 } 17370 } 17371 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17372 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17373 schedGroup = Process.THREAD_GROUP_DEFAULT; 17374 } 17375 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17376 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17377 // Special handling of clients who are in the top state. 17378 // We *may* want to consider this process to be in the 17379 // top state as well, but only if there is not another 17380 // reason for it to be running. Being on the top is a 17381 // special state, meaning you are specifically running 17382 // for the current top app. If the process is already 17383 // running in the background for some other reason, it 17384 // is more important to continue considering it to be 17385 // in the background state. 17386 mayBeTop = true; 17387 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17388 } else { 17389 // Special handling for above-top states (persistent 17390 // processes). These should not bring the current process 17391 // into the top state, since they are not on top. Instead 17392 // give them the best state after that. 17393 clientProcState = 17394 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17395 } 17396 } 17397 } else { 17398 if (clientProcState < 17399 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17400 clientProcState = 17401 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17402 } 17403 } 17404 if (procState > clientProcState) { 17405 procState = clientProcState; 17406 } 17407 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17408 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17409 app.pendingUiClean = true; 17410 } 17411 if (adjType != null) { 17412 app.adjType = adjType; 17413 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17414 .REASON_SERVICE_IN_USE; 17415 app.adjSource = cr.binding.client; 17416 app.adjSourceProcState = clientProcState; 17417 app.adjTarget = s.name; 17418 } 17419 } 17420 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17421 app.treatLikeActivity = true; 17422 } 17423 final ActivityRecord a = cr.activity; 17424 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17425 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17426 (a.visible || a.state == ActivityState.RESUMED 17427 || a.state == ActivityState.PAUSING)) { 17428 adj = ProcessList.FOREGROUND_APP_ADJ; 17429 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17430 schedGroup = Process.THREAD_GROUP_DEFAULT; 17431 } 17432 app.cached = false; 17433 app.adjType = "service"; 17434 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17435 .REASON_SERVICE_IN_USE; 17436 app.adjSource = a; 17437 app.adjSourceProcState = procState; 17438 app.adjTarget = s.name; 17439 } 17440 } 17441 } 17442 } 17443 } 17444 17445 for (int provi = app.pubProviders.size()-1; 17446 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17447 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17448 || procState > ActivityManager.PROCESS_STATE_TOP); 17449 provi--) { 17450 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17451 for (int i = cpr.connections.size()-1; 17452 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17453 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17454 || procState > ActivityManager.PROCESS_STATE_TOP); 17455 i--) { 17456 ContentProviderConnection conn = cpr.connections.get(i); 17457 ProcessRecord client = conn.client; 17458 if (client == app) { 17459 // Being our own client is not interesting. 17460 continue; 17461 } 17462 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17463 int clientProcState = client.curProcState; 17464 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17465 // If the other app is cached for any reason, for purposes here 17466 // we are going to consider it empty. 17467 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17468 } 17469 if (adj > clientAdj) { 17470 if (app.hasShownUi && app != mHomeProcess 17471 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17472 app.adjType = "cch-ui-provider"; 17473 } else { 17474 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17475 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17476 app.adjType = "provider"; 17477 } 17478 app.cached &= client.cached; 17479 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17480 .REASON_PROVIDER_IN_USE; 17481 app.adjSource = client; 17482 app.adjSourceProcState = clientProcState; 17483 app.adjTarget = cpr.name; 17484 } 17485 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17486 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17487 // Special handling of clients who are in the top state. 17488 // We *may* want to consider this process to be in the 17489 // top state as well, but only if there is not another 17490 // reason for it to be running. Being on the top is a 17491 // special state, meaning you are specifically running 17492 // for the current top app. If the process is already 17493 // running in the background for some other reason, it 17494 // is more important to continue considering it to be 17495 // in the background state. 17496 mayBeTop = true; 17497 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17498 } else { 17499 // Special handling for above-top states (persistent 17500 // processes). These should not bring the current process 17501 // into the top state, since they are not on top. Instead 17502 // give them the best state after that. 17503 clientProcState = 17504 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17505 } 17506 } 17507 if (procState > clientProcState) { 17508 procState = clientProcState; 17509 } 17510 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17511 schedGroup = Process.THREAD_GROUP_DEFAULT; 17512 } 17513 } 17514 // If the provider has external (non-framework) process 17515 // dependencies, ensure that its adjustment is at least 17516 // FOREGROUND_APP_ADJ. 17517 if (cpr.hasExternalProcessHandles()) { 17518 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17519 adj = ProcessList.FOREGROUND_APP_ADJ; 17520 schedGroup = Process.THREAD_GROUP_DEFAULT; 17521 app.cached = false; 17522 app.adjType = "provider"; 17523 app.adjTarget = cpr.name; 17524 } 17525 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17526 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17527 } 17528 } 17529 } 17530 17531 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17532 // A client of one of our services or providers is in the top state. We 17533 // *may* want to be in the top state, but not if we are already running in 17534 // the background for some other reason. For the decision here, we are going 17535 // to pick out a few specific states that we want to remain in when a client 17536 // is top (states that tend to be longer-term) and otherwise allow it to go 17537 // to the top state. 17538 switch (procState) { 17539 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17540 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17541 case ActivityManager.PROCESS_STATE_SERVICE: 17542 // These all are longer-term states, so pull them up to the top 17543 // of the background states, but not all the way to the top state. 17544 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17545 break; 17546 default: 17547 // Otherwise, top is a better choice, so take it. 17548 procState = ActivityManager.PROCESS_STATE_TOP; 17549 break; 17550 } 17551 } 17552 17553 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17554 if (app.hasClientActivities) { 17555 // This is a cached process, but with client activities. Mark it so. 17556 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17557 app.adjType = "cch-client-act"; 17558 } else if (app.treatLikeActivity) { 17559 // This is a cached process, but somebody wants us to treat it like it has 17560 // an activity, okay! 17561 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17562 app.adjType = "cch-as-act"; 17563 } 17564 } 17565 17566 if (adj == ProcessList.SERVICE_ADJ) { 17567 if (doingAll) { 17568 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17569 mNewNumServiceProcs++; 17570 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17571 if (!app.serviceb) { 17572 // This service isn't far enough down on the LRU list to 17573 // normally be a B service, but if we are low on RAM and it 17574 // is large we want to force it down since we would prefer to 17575 // keep launcher over it. 17576 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17577 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17578 app.serviceHighRam = true; 17579 app.serviceb = true; 17580 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17581 } else { 17582 mNewNumAServiceProcs++; 17583 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17584 } 17585 } else { 17586 app.serviceHighRam = false; 17587 } 17588 } 17589 if (app.serviceb) { 17590 adj = ProcessList.SERVICE_B_ADJ; 17591 } 17592 } 17593 17594 app.curRawAdj = adj; 17595 17596 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17597 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17598 if (adj > app.maxAdj) { 17599 adj = app.maxAdj; 17600 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17601 schedGroup = Process.THREAD_GROUP_DEFAULT; 17602 } 17603 } 17604 17605 // Do final modification to adj. Everything we do between here and applying 17606 // the final setAdj must be done in this function, because we will also use 17607 // it when computing the final cached adj later. Note that we don't need to 17608 // worry about this for max adj above, since max adj will always be used to 17609 // keep it out of the cached vaues. 17610 app.curAdj = app.modifyRawOomAdj(adj); 17611 app.curSchedGroup = schedGroup; 17612 app.curProcState = procState; 17613 app.foregroundActivities = foregroundActivities; 17614 17615 return app.curRawAdj; 17616 } 17617 17618 /** 17619 * Record new PSS sample for a process. 17620 */ 17621 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17622 proc.lastPssTime = now; 17623 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17624 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17625 + ": " + pss + " lastPss=" + proc.lastPss 17626 + " state=" + ProcessList.makeProcStateString(procState)); 17627 if (proc.initialIdlePss == 0) { 17628 proc.initialIdlePss = pss; 17629 } 17630 proc.lastPss = pss; 17631 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17632 proc.lastCachedPss = pss; 17633 } 17634 } 17635 17636 /** 17637 * Schedule PSS collection of a process. 17638 */ 17639 void requestPssLocked(ProcessRecord proc, int procState) { 17640 if (mPendingPssProcesses.contains(proc)) { 17641 return; 17642 } 17643 if (mPendingPssProcesses.size() == 0) { 17644 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17645 } 17646 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17647 proc.pssProcState = procState; 17648 mPendingPssProcesses.add(proc); 17649 } 17650 17651 /** 17652 * Schedule PSS collection of all processes. 17653 */ 17654 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17655 if (!always) { 17656 if (now < (mLastFullPssTime + 17657 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17658 return; 17659 } 17660 } 17661 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17662 mLastFullPssTime = now; 17663 mFullPssPending = true; 17664 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17665 mPendingPssProcesses.clear(); 17666 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17667 ProcessRecord app = mLruProcesses.get(i); 17668 if (app.thread == null 17669 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 17670 continue; 17671 } 17672 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17673 app.pssProcState = app.setProcState; 17674 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17675 mTestPssMode, isSleeping(), now); 17676 mPendingPssProcesses.add(app); 17677 } 17678 } 17679 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17680 } 17681 17682 public void setTestPssMode(boolean enabled) { 17683 synchronized (this) { 17684 mTestPssMode = enabled; 17685 if (enabled) { 17686 // Whenever we enable the mode, we want to take a snapshot all of current 17687 // process mem use. 17688 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17689 } 17690 } 17691 } 17692 17693 /** 17694 * Ask a given process to GC right now. 17695 */ 17696 final void performAppGcLocked(ProcessRecord app) { 17697 try { 17698 app.lastRequestedGc = SystemClock.uptimeMillis(); 17699 if (app.thread != null) { 17700 if (app.reportLowMemory) { 17701 app.reportLowMemory = false; 17702 app.thread.scheduleLowMemory(); 17703 } else { 17704 app.thread.processInBackground(); 17705 } 17706 } 17707 } catch (Exception e) { 17708 // whatever. 17709 } 17710 } 17711 17712 /** 17713 * Returns true if things are idle enough to perform GCs. 17714 */ 17715 private final boolean canGcNowLocked() { 17716 boolean processingBroadcasts = false; 17717 for (BroadcastQueue q : mBroadcastQueues) { 17718 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17719 processingBroadcasts = true; 17720 } 17721 } 17722 return !processingBroadcasts 17723 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17724 } 17725 17726 /** 17727 * Perform GCs on all processes that are waiting for it, but only 17728 * if things are idle. 17729 */ 17730 final void performAppGcsLocked() { 17731 final int N = mProcessesToGc.size(); 17732 if (N <= 0) { 17733 return; 17734 } 17735 if (canGcNowLocked()) { 17736 while (mProcessesToGc.size() > 0) { 17737 ProcessRecord proc = mProcessesToGc.remove(0); 17738 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17739 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17740 <= SystemClock.uptimeMillis()) { 17741 // To avoid spamming the system, we will GC processes one 17742 // at a time, waiting a few seconds between each. 17743 performAppGcLocked(proc); 17744 scheduleAppGcsLocked(); 17745 return; 17746 } else { 17747 // It hasn't been long enough since we last GCed this 17748 // process... put it in the list to wait for its time. 17749 addProcessToGcListLocked(proc); 17750 break; 17751 } 17752 } 17753 } 17754 17755 scheduleAppGcsLocked(); 17756 } 17757 } 17758 17759 /** 17760 * If all looks good, perform GCs on all processes waiting for them. 17761 */ 17762 final void performAppGcsIfAppropriateLocked() { 17763 if (canGcNowLocked()) { 17764 performAppGcsLocked(); 17765 return; 17766 } 17767 // Still not idle, wait some more. 17768 scheduleAppGcsLocked(); 17769 } 17770 17771 /** 17772 * Schedule the execution of all pending app GCs. 17773 */ 17774 final void scheduleAppGcsLocked() { 17775 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17776 17777 if (mProcessesToGc.size() > 0) { 17778 // Schedule a GC for the time to the next process. 17779 ProcessRecord proc = mProcessesToGc.get(0); 17780 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17781 17782 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17783 long now = SystemClock.uptimeMillis(); 17784 if (when < (now+GC_TIMEOUT)) { 17785 when = now + GC_TIMEOUT; 17786 } 17787 mHandler.sendMessageAtTime(msg, when); 17788 } 17789 } 17790 17791 /** 17792 * Add a process to the array of processes waiting to be GCed. Keeps the 17793 * list in sorted order by the last GC time. The process can't already be 17794 * on the list. 17795 */ 17796 final void addProcessToGcListLocked(ProcessRecord proc) { 17797 boolean added = false; 17798 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17799 if (mProcessesToGc.get(i).lastRequestedGc < 17800 proc.lastRequestedGc) { 17801 added = true; 17802 mProcessesToGc.add(i+1, proc); 17803 break; 17804 } 17805 } 17806 if (!added) { 17807 mProcessesToGc.add(0, proc); 17808 } 17809 } 17810 17811 /** 17812 * Set up to ask a process to GC itself. This will either do it 17813 * immediately, or put it on the list of processes to gc the next 17814 * time things are idle. 17815 */ 17816 final void scheduleAppGcLocked(ProcessRecord app) { 17817 long now = SystemClock.uptimeMillis(); 17818 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17819 return; 17820 } 17821 if (!mProcessesToGc.contains(app)) { 17822 addProcessToGcListLocked(app); 17823 scheduleAppGcsLocked(); 17824 } 17825 } 17826 17827 final void checkExcessivePowerUsageLocked(boolean doKills) { 17828 updateCpuStatsNow(); 17829 17830 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17831 boolean doWakeKills = doKills; 17832 boolean doCpuKills = doKills; 17833 if (mLastPowerCheckRealtime == 0) { 17834 doWakeKills = false; 17835 } 17836 if (mLastPowerCheckUptime == 0) { 17837 doCpuKills = false; 17838 } 17839 if (stats.isScreenOn()) { 17840 doWakeKills = false; 17841 } 17842 final long curRealtime = SystemClock.elapsedRealtime(); 17843 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17844 final long curUptime = SystemClock.uptimeMillis(); 17845 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17846 mLastPowerCheckRealtime = curRealtime; 17847 mLastPowerCheckUptime = curUptime; 17848 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17849 doWakeKills = false; 17850 } 17851 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17852 doCpuKills = false; 17853 } 17854 int i = mLruProcesses.size(); 17855 while (i > 0) { 17856 i--; 17857 ProcessRecord app = mLruProcesses.get(i); 17858 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17859 long wtime; 17860 synchronized (stats) { 17861 wtime = stats.getProcessWakeTime(app.info.uid, 17862 app.pid, curRealtime); 17863 } 17864 long wtimeUsed = wtime - app.lastWakeTime; 17865 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17866 if (DEBUG_POWER) { 17867 StringBuilder sb = new StringBuilder(128); 17868 sb.append("Wake for "); 17869 app.toShortString(sb); 17870 sb.append(": over "); 17871 TimeUtils.formatDuration(realtimeSince, sb); 17872 sb.append(" used "); 17873 TimeUtils.formatDuration(wtimeUsed, sb); 17874 sb.append(" ("); 17875 sb.append((wtimeUsed*100)/realtimeSince); 17876 sb.append("%)"); 17877 Slog.i(TAG, sb.toString()); 17878 sb.setLength(0); 17879 sb.append("CPU for "); 17880 app.toShortString(sb); 17881 sb.append(": over "); 17882 TimeUtils.formatDuration(uptimeSince, sb); 17883 sb.append(" used "); 17884 TimeUtils.formatDuration(cputimeUsed, sb); 17885 sb.append(" ("); 17886 sb.append((cputimeUsed*100)/uptimeSince); 17887 sb.append("%)"); 17888 Slog.i(TAG, sb.toString()); 17889 } 17890 // If a process has held a wake lock for more 17891 // than 50% of the time during this period, 17892 // that sounds bad. Kill! 17893 if (doWakeKills && realtimeSince > 0 17894 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17895 synchronized (stats) { 17896 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17897 realtimeSince, wtimeUsed); 17898 } 17899 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17900 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17901 } else if (doCpuKills && uptimeSince > 0 17902 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17903 synchronized (stats) { 17904 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17905 uptimeSince, cputimeUsed); 17906 } 17907 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17908 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17909 } else { 17910 app.lastWakeTime = wtime; 17911 app.lastCpuTime = app.curCpuTime; 17912 } 17913 } 17914 } 17915 } 17916 17917 private final boolean applyOomAdjLocked(ProcessRecord app, 17918 ProcessRecord TOP_APP, boolean doingAll, long now) { 17919 boolean success = true; 17920 17921 if (app.curRawAdj != app.setRawAdj) { 17922 app.setRawAdj = app.curRawAdj; 17923 } 17924 17925 int changes = 0; 17926 17927 if (app.curAdj != app.setAdj) { 17928 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17929 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17930 TAG, "Set " + app.pid + " " + app.processName + 17931 " adj " + app.curAdj + ": " + app.adjType); 17932 app.setAdj = app.curAdj; 17933 } 17934 17935 if (app.setSchedGroup != app.curSchedGroup) { 17936 app.setSchedGroup = app.curSchedGroup; 17937 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17938 "Setting process group of " + app.processName 17939 + " to " + app.curSchedGroup); 17940 if (app.waitingToKill != null && 17941 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17942 app.kill(app.waitingToKill, true); 17943 success = false; 17944 } else { 17945 if (true) { 17946 long oldId = Binder.clearCallingIdentity(); 17947 try { 17948 Process.setProcessGroup(app.pid, app.curSchedGroup); 17949 } catch (Exception e) { 17950 Slog.w(TAG, "Failed setting process group of " + app.pid 17951 + " to " + app.curSchedGroup); 17952 e.printStackTrace(); 17953 } finally { 17954 Binder.restoreCallingIdentity(oldId); 17955 } 17956 } else { 17957 if (app.thread != null) { 17958 try { 17959 app.thread.setSchedulingGroup(app.curSchedGroup); 17960 } catch (RemoteException e) { 17961 } 17962 } 17963 } 17964 Process.setSwappiness(app.pid, 17965 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17966 } 17967 } 17968 if (app.repForegroundActivities != app.foregroundActivities) { 17969 app.repForegroundActivities = app.foregroundActivities; 17970 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17971 } 17972 if (app.repProcState != app.curProcState) { 17973 app.repProcState = app.curProcState; 17974 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17975 if (app.thread != null) { 17976 try { 17977 if (false) { 17978 //RuntimeException h = new RuntimeException("here"); 17979 Slog.i(TAG, "Sending new process state " + app.repProcState 17980 + " to " + app /*, h*/); 17981 } 17982 app.thread.setProcessState(app.repProcState); 17983 } catch (RemoteException e) { 17984 } 17985 } 17986 } 17987 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT 17988 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { 17989 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17990 // Experimental code to more aggressively collect pss while 17991 // running test... the problem is that this tends to collect 17992 // the data right when a process is transitioning between process 17993 // states, which well tend to give noisy data. 17994 long start = SystemClock.uptimeMillis(); 17995 long pss = Debug.getPss(app.pid, mTmpLong, null); 17996 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17997 mPendingPssProcesses.remove(app); 17998 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17999 + " to " + app.curProcState + ": " 18000 + (SystemClock.uptimeMillis()-start) + "ms"); 18001 } 18002 app.lastStateTime = now; 18003 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 18004 mTestPssMode, isSleeping(), now); 18005 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 18006 + ProcessList.makeProcStateString(app.setProcState) + " to " 18007 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 18008 + (app.nextPssTime-now) + ": " + app); 18009 } else { 18010 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 18011 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 18012 mTestPssMode)))) { 18013 requestPssLocked(app, app.setProcState); 18014 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 18015 mTestPssMode, isSleeping(), now); 18016 } else if (false && DEBUG_PSS) { 18017 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 18018 } 18019 } 18020 if (app.setProcState != app.curProcState) { 18021 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18022 "Proc state change of " + app.processName 18023 + " to " + app.curProcState); 18024 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 18025 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 18026 if (setImportant && !curImportant) { 18027 // This app is no longer something we consider important enough to allow to 18028 // use arbitrary amounts of battery power. Note 18029 // its current wake lock time to later know to kill it if 18030 // it is not behaving well. 18031 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 18032 synchronized (stats) { 18033 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 18034 app.pid, SystemClock.elapsedRealtime()); 18035 } 18036 app.lastCpuTime = app.curCpuTime; 18037 18038 } 18039 app.setProcState = app.curProcState; 18040 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 18041 app.notCachedSinceIdle = false; 18042 } 18043 if (!doingAll) { 18044 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 18045 } else { 18046 app.procStateChanged = true; 18047 } 18048 } 18049 18050 if (changes != 0) { 18051 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 18052 int i = mPendingProcessChanges.size()-1; 18053 ProcessChangeItem item = null; 18054 while (i >= 0) { 18055 item = mPendingProcessChanges.get(i); 18056 if (item.pid == app.pid) { 18057 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18058 break; 18059 } 18060 i--; 18061 } 18062 if (i < 0) { 18063 // No existing item in pending changes; need a new one. 18064 final int NA = mAvailProcessChanges.size(); 18065 if (NA > 0) { 18066 item = mAvailProcessChanges.remove(NA-1); 18067 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18068 } else { 18069 item = new ProcessChangeItem(); 18070 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18071 } 18072 item.changes = 0; 18073 item.pid = app.pid; 18074 item.uid = app.info.uid; 18075 if (mPendingProcessChanges.size() == 0) { 18076 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18077 "*** Enqueueing dispatch processes changed!"); 18078 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18079 } 18080 mPendingProcessChanges.add(item); 18081 } 18082 item.changes |= changes; 18083 item.processState = app.repProcState; 18084 item.foregroundActivities = app.repForegroundActivities; 18085 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18086 + Integer.toHexString(System.identityHashCode(item)) 18087 + " " + app.toShortString() + ": changes=" + item.changes 18088 + " procState=" + item.processState 18089 + " foreground=" + item.foregroundActivities 18090 + " type=" + app.adjType + " source=" + app.adjSource 18091 + " target=" + app.adjTarget); 18092 } 18093 18094 return success; 18095 } 18096 18097 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18098 if (proc.thread != null) { 18099 if (proc.baseProcessTracker != null) { 18100 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18101 } 18102 if (proc.repProcState >= 0) { 18103 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18104 proc.repProcState); 18105 } 18106 } 18107 } 18108 18109 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18110 ProcessRecord TOP_APP, boolean doingAll, long now) { 18111 if (app.thread == null) { 18112 return false; 18113 } 18114 18115 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18116 18117 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18118 } 18119 18120 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18121 boolean oomAdj) { 18122 if (isForeground != proc.foregroundServices) { 18123 proc.foregroundServices = isForeground; 18124 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18125 proc.info.uid); 18126 if (isForeground) { 18127 if (curProcs == null) { 18128 curProcs = new ArrayList<ProcessRecord>(); 18129 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18130 } 18131 if (!curProcs.contains(proc)) { 18132 curProcs.add(proc); 18133 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18134 proc.info.packageName, proc.info.uid); 18135 } 18136 } else { 18137 if (curProcs != null) { 18138 if (curProcs.remove(proc)) { 18139 mBatteryStatsService.noteEvent( 18140 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18141 proc.info.packageName, proc.info.uid); 18142 if (curProcs.size() <= 0) { 18143 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18144 } 18145 } 18146 } 18147 } 18148 if (oomAdj) { 18149 updateOomAdjLocked(); 18150 } 18151 } 18152 } 18153 18154 private final ActivityRecord resumedAppLocked() { 18155 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18156 String pkg; 18157 int uid; 18158 if (act != null) { 18159 pkg = act.packageName; 18160 uid = act.info.applicationInfo.uid; 18161 } else { 18162 pkg = null; 18163 uid = -1; 18164 } 18165 // Has the UID or resumed package name changed? 18166 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18167 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18168 if (mCurResumedPackage != null) { 18169 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18170 mCurResumedPackage, mCurResumedUid); 18171 } 18172 mCurResumedPackage = pkg; 18173 mCurResumedUid = uid; 18174 if (mCurResumedPackage != null) { 18175 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18176 mCurResumedPackage, mCurResumedUid); 18177 } 18178 } 18179 return act; 18180 } 18181 18182 final boolean updateOomAdjLocked(ProcessRecord app) { 18183 final ActivityRecord TOP_ACT = resumedAppLocked(); 18184 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18185 final boolean wasCached = app.cached; 18186 18187 mAdjSeq++; 18188 18189 // This is the desired cached adjusment we want to tell it to use. 18190 // If our app is currently cached, we know it, and that is it. Otherwise, 18191 // we don't know it yet, and it needs to now be cached we will then 18192 // need to do a complete oom adj. 18193 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18194 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18195 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18196 SystemClock.uptimeMillis()); 18197 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18198 // Changed to/from cached state, so apps after it in the LRU 18199 // list may also be changed. 18200 updateOomAdjLocked(); 18201 } 18202 return success; 18203 } 18204 18205 final void updateOomAdjLocked() { 18206 final ActivityRecord TOP_ACT = resumedAppLocked(); 18207 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18208 final long now = SystemClock.uptimeMillis(); 18209 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18210 final int N = mLruProcesses.size(); 18211 18212 if (false) { 18213 RuntimeException e = new RuntimeException(); 18214 e.fillInStackTrace(); 18215 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18216 } 18217 18218 mAdjSeq++; 18219 mNewNumServiceProcs = 0; 18220 mNewNumAServiceProcs = 0; 18221 18222 final int emptyProcessLimit; 18223 final int cachedProcessLimit; 18224 if (mProcessLimit <= 0) { 18225 emptyProcessLimit = cachedProcessLimit = 0; 18226 } else if (mProcessLimit == 1) { 18227 emptyProcessLimit = 1; 18228 cachedProcessLimit = 0; 18229 } else { 18230 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18231 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18232 } 18233 18234 // Let's determine how many processes we have running vs. 18235 // how many slots we have for background processes; we may want 18236 // to put multiple processes in a slot of there are enough of 18237 // them. 18238 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18239 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18240 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18241 if (numEmptyProcs > cachedProcessLimit) { 18242 // If there are more empty processes than our limit on cached 18243 // processes, then use the cached process limit for the factor. 18244 // This ensures that the really old empty processes get pushed 18245 // down to the bottom, so if we are running low on memory we will 18246 // have a better chance at keeping around more cached processes 18247 // instead of a gazillion empty processes. 18248 numEmptyProcs = cachedProcessLimit; 18249 } 18250 int emptyFactor = numEmptyProcs/numSlots; 18251 if (emptyFactor < 1) emptyFactor = 1; 18252 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18253 if (cachedFactor < 1) cachedFactor = 1; 18254 int stepCached = 0; 18255 int stepEmpty = 0; 18256 int numCached = 0; 18257 int numEmpty = 0; 18258 int numTrimming = 0; 18259 18260 mNumNonCachedProcs = 0; 18261 mNumCachedHiddenProcs = 0; 18262 18263 // First update the OOM adjustment for each of the 18264 // application processes based on their current state. 18265 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18266 int nextCachedAdj = curCachedAdj+1; 18267 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18268 int nextEmptyAdj = curEmptyAdj+2; 18269 for (int i=N-1; i>=0; i--) { 18270 ProcessRecord app = mLruProcesses.get(i); 18271 if (!app.killedByAm && app.thread != null) { 18272 app.procStateChanged = false; 18273 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18274 18275 // If we haven't yet assigned the final cached adj 18276 // to the process, do that now. 18277 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18278 switch (app.curProcState) { 18279 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18280 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18281 // This process is a cached process holding activities... 18282 // assign it the next cached value for that type, and then 18283 // step that cached level. 18284 app.curRawAdj = curCachedAdj; 18285 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18286 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18287 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18288 + ")"); 18289 if (curCachedAdj != nextCachedAdj) { 18290 stepCached++; 18291 if (stepCached >= cachedFactor) { 18292 stepCached = 0; 18293 curCachedAdj = nextCachedAdj; 18294 nextCachedAdj += 2; 18295 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18296 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18297 } 18298 } 18299 } 18300 break; 18301 default: 18302 // For everything else, assign next empty cached process 18303 // level and bump that up. Note that this means that 18304 // long-running services that have dropped down to the 18305 // cached level will be treated as empty (since their process 18306 // state is still as a service), which is what we want. 18307 app.curRawAdj = curEmptyAdj; 18308 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18309 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18310 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18311 + ")"); 18312 if (curEmptyAdj != nextEmptyAdj) { 18313 stepEmpty++; 18314 if (stepEmpty >= emptyFactor) { 18315 stepEmpty = 0; 18316 curEmptyAdj = nextEmptyAdj; 18317 nextEmptyAdj += 2; 18318 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18319 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18320 } 18321 } 18322 } 18323 break; 18324 } 18325 } 18326 18327 applyOomAdjLocked(app, TOP_APP, true, now); 18328 18329 // Count the number of process types. 18330 switch (app.curProcState) { 18331 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18332 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18333 mNumCachedHiddenProcs++; 18334 numCached++; 18335 if (numCached > cachedProcessLimit) { 18336 app.kill("cached #" + numCached, true); 18337 } 18338 break; 18339 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18340 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18341 && app.lastActivityTime < oldTime) { 18342 app.kill("empty for " 18343 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18344 / 1000) + "s", true); 18345 } else { 18346 numEmpty++; 18347 if (numEmpty > emptyProcessLimit) { 18348 app.kill("empty #" + numEmpty, true); 18349 } 18350 } 18351 break; 18352 default: 18353 mNumNonCachedProcs++; 18354 break; 18355 } 18356 18357 if (app.isolated && app.services.size() <= 0) { 18358 // If this is an isolated process, and there are no 18359 // services running in it, then the process is no longer 18360 // needed. We agressively kill these because we can by 18361 // definition not re-use the same process again, and it is 18362 // good to avoid having whatever code was running in them 18363 // left sitting around after no longer needed. 18364 app.kill("isolated not needed", true); 18365 } 18366 18367 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18368 && !app.killedByAm) { 18369 numTrimming++; 18370 } 18371 } 18372 } 18373 18374 mNumServiceProcs = mNewNumServiceProcs; 18375 18376 // Now determine the memory trimming level of background processes. 18377 // Unfortunately we need to start at the back of the list to do this 18378 // properly. We only do this if the number of background apps we 18379 // are managing to keep around is less than half the maximum we desire; 18380 // if we are keeping a good number around, we'll let them use whatever 18381 // memory they want. 18382 final int numCachedAndEmpty = numCached + numEmpty; 18383 int memFactor; 18384 if (numCached <= ProcessList.TRIM_CACHED_APPS 18385 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18386 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18387 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18388 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18389 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18390 } else { 18391 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18392 } 18393 } else { 18394 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18395 } 18396 // We always allow the memory level to go up (better). We only allow it to go 18397 // down if we are in a state where that is allowed, *and* the total number of processes 18398 // has gone down since last time. 18399 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18400 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18401 + " last=" + mLastNumProcesses); 18402 if (memFactor > mLastMemoryLevel) { 18403 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18404 memFactor = mLastMemoryLevel; 18405 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18406 } 18407 } 18408 mLastMemoryLevel = memFactor; 18409 mLastNumProcesses = mLruProcesses.size(); 18410 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18411 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18412 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18413 if (mLowRamStartTime == 0) { 18414 mLowRamStartTime = now; 18415 } 18416 int step = 0; 18417 int fgTrimLevel; 18418 switch (memFactor) { 18419 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18420 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18421 break; 18422 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18423 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18424 break; 18425 default: 18426 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18427 break; 18428 } 18429 int factor = numTrimming/3; 18430 int minFactor = 2; 18431 if (mHomeProcess != null) minFactor++; 18432 if (mPreviousProcess != null) minFactor++; 18433 if (factor < minFactor) factor = minFactor; 18434 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18435 for (int i=N-1; i>=0; i--) { 18436 ProcessRecord app = mLruProcesses.get(i); 18437 if (allChanged || app.procStateChanged) { 18438 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18439 app.procStateChanged = false; 18440 } 18441 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18442 && !app.killedByAm) { 18443 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18444 try { 18445 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18446 "Trimming memory of " + app.processName 18447 + " to " + curLevel); 18448 app.thread.scheduleTrimMemory(curLevel); 18449 } catch (RemoteException e) { 18450 } 18451 if (false) { 18452 // For now we won't do this; our memory trimming seems 18453 // to be good enough at this point that destroying 18454 // activities causes more harm than good. 18455 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18456 && app != mHomeProcess && app != mPreviousProcess) { 18457 // Need to do this on its own message because the stack may not 18458 // be in a consistent state at this point. 18459 // For these apps we will also finish their activities 18460 // to help them free memory. 18461 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18462 } 18463 } 18464 } 18465 app.trimMemoryLevel = curLevel; 18466 step++; 18467 if (step >= factor) { 18468 step = 0; 18469 switch (curLevel) { 18470 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18471 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18472 break; 18473 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18474 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18475 break; 18476 } 18477 } 18478 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18479 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18480 && app.thread != null) { 18481 try { 18482 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18483 "Trimming memory of heavy-weight " + app.processName 18484 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18485 app.thread.scheduleTrimMemory( 18486 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18487 } catch (RemoteException e) { 18488 } 18489 } 18490 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18491 } else { 18492 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18493 || app.systemNoUi) && app.pendingUiClean) { 18494 // If this application is now in the background and it 18495 // had done UI, then give it the special trim level to 18496 // have it free UI resources. 18497 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18498 if (app.trimMemoryLevel < level && app.thread != null) { 18499 try { 18500 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18501 "Trimming memory of bg-ui " + app.processName 18502 + " to " + level); 18503 app.thread.scheduleTrimMemory(level); 18504 } catch (RemoteException e) { 18505 } 18506 } 18507 app.pendingUiClean = false; 18508 } 18509 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18510 try { 18511 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18512 "Trimming memory of fg " + app.processName 18513 + " to " + fgTrimLevel); 18514 app.thread.scheduleTrimMemory(fgTrimLevel); 18515 } catch (RemoteException e) { 18516 } 18517 } 18518 app.trimMemoryLevel = fgTrimLevel; 18519 } 18520 } 18521 } else { 18522 if (mLowRamStartTime != 0) { 18523 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18524 mLowRamStartTime = 0; 18525 } 18526 for (int i=N-1; i>=0; i--) { 18527 ProcessRecord app = mLruProcesses.get(i); 18528 if (allChanged || app.procStateChanged) { 18529 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18530 app.procStateChanged = false; 18531 } 18532 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18533 || app.systemNoUi) && app.pendingUiClean) { 18534 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18535 && app.thread != null) { 18536 try { 18537 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18538 "Trimming memory of ui hidden " + app.processName 18539 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18540 app.thread.scheduleTrimMemory( 18541 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18542 } catch (RemoteException e) { 18543 } 18544 } 18545 app.pendingUiClean = false; 18546 } 18547 app.trimMemoryLevel = 0; 18548 } 18549 } 18550 18551 if (mAlwaysFinishActivities) { 18552 // Need to do this on its own message because the stack may not 18553 // be in a consistent state at this point. 18554 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18555 } 18556 18557 if (allChanged) { 18558 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18559 } 18560 18561 if (mProcessStats.shouldWriteNowLocked(now)) { 18562 mHandler.post(new Runnable() { 18563 @Override public void run() { 18564 synchronized (ActivityManagerService.this) { 18565 mProcessStats.writeStateAsyncLocked(); 18566 } 18567 } 18568 }); 18569 } 18570 18571 if (DEBUG_OOM_ADJ) { 18572 if (false) { 18573 RuntimeException here = new RuntimeException("here"); 18574 here.fillInStackTrace(); 18575 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18576 } else { 18577 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18578 } 18579 } 18580 } 18581 18582 final void trimApplications() { 18583 synchronized (this) { 18584 int i; 18585 18586 // First remove any unused application processes whose package 18587 // has been removed. 18588 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18589 final ProcessRecord app = mRemovedProcesses.get(i); 18590 if (app.activities.size() == 0 18591 && app.curReceiver == null && app.services.size() == 0) { 18592 Slog.i( 18593 TAG, "Exiting empty application process " 18594 + app.processName + " (" 18595 + (app.thread != null ? app.thread.asBinder() : null) 18596 + ")\n"); 18597 if (app.pid > 0 && app.pid != MY_PID) { 18598 app.kill("empty", false); 18599 } else { 18600 try { 18601 app.thread.scheduleExit(); 18602 } catch (Exception e) { 18603 // Ignore exceptions. 18604 } 18605 } 18606 cleanUpApplicationRecordLocked(app, false, true, -1); 18607 mRemovedProcesses.remove(i); 18608 18609 if (app.persistent) { 18610 addAppLocked(app.info, false, null /* ABI override */); 18611 } 18612 } 18613 } 18614 18615 // Now update the oom adj for all processes. 18616 updateOomAdjLocked(); 18617 } 18618 } 18619 18620 /** This method sends the specified signal to each of the persistent apps */ 18621 public void signalPersistentProcesses(int sig) throws RemoteException { 18622 if (sig != Process.SIGNAL_USR1) { 18623 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18624 } 18625 18626 synchronized (this) { 18627 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18628 != PackageManager.PERMISSION_GRANTED) { 18629 throw new SecurityException("Requires permission " 18630 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18631 } 18632 18633 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18634 ProcessRecord r = mLruProcesses.get(i); 18635 if (r.thread != null && r.persistent) { 18636 Process.sendSignal(r.pid, sig); 18637 } 18638 } 18639 } 18640 } 18641 18642 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18643 if (proc == null || proc == mProfileProc) { 18644 proc = mProfileProc; 18645 profileType = mProfileType; 18646 clearProfilerLocked(); 18647 } 18648 if (proc == null) { 18649 return; 18650 } 18651 try { 18652 proc.thread.profilerControl(false, null, profileType); 18653 } catch (RemoteException e) { 18654 throw new IllegalStateException("Process disappeared"); 18655 } 18656 } 18657 18658 private void clearProfilerLocked() { 18659 if (mProfileFd != null) { 18660 try { 18661 mProfileFd.close(); 18662 } catch (IOException e) { 18663 } 18664 } 18665 mProfileApp = null; 18666 mProfileProc = null; 18667 mProfileFile = null; 18668 mProfileType = 0; 18669 mAutoStopProfiler = false; 18670 mSamplingInterval = 0; 18671 } 18672 18673 public boolean profileControl(String process, int userId, boolean start, 18674 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18675 18676 try { 18677 synchronized (this) { 18678 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18679 // its own permission. 18680 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18681 != PackageManager.PERMISSION_GRANTED) { 18682 throw new SecurityException("Requires permission " 18683 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18684 } 18685 18686 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18687 throw new IllegalArgumentException("null profile info or fd"); 18688 } 18689 18690 ProcessRecord proc = null; 18691 if (process != null) { 18692 proc = findProcessLocked(process, userId, "profileControl"); 18693 } 18694 18695 if (start && (proc == null || proc.thread == null)) { 18696 throw new IllegalArgumentException("Unknown process: " + process); 18697 } 18698 18699 if (start) { 18700 stopProfilerLocked(null, 0); 18701 setProfileApp(proc.info, proc.processName, profilerInfo); 18702 mProfileProc = proc; 18703 mProfileType = profileType; 18704 ParcelFileDescriptor fd = profilerInfo.profileFd; 18705 try { 18706 fd = fd.dup(); 18707 } catch (IOException e) { 18708 fd = null; 18709 } 18710 profilerInfo.profileFd = fd; 18711 proc.thread.profilerControl(start, profilerInfo, profileType); 18712 fd = null; 18713 mProfileFd = null; 18714 } else { 18715 stopProfilerLocked(proc, profileType); 18716 if (profilerInfo != null && profilerInfo.profileFd != null) { 18717 try { 18718 profilerInfo.profileFd.close(); 18719 } catch (IOException e) { 18720 } 18721 } 18722 } 18723 18724 return true; 18725 } 18726 } catch (RemoteException e) { 18727 throw new IllegalStateException("Process disappeared"); 18728 } finally { 18729 if (profilerInfo != null && profilerInfo.profileFd != null) { 18730 try { 18731 profilerInfo.profileFd.close(); 18732 } catch (IOException e) { 18733 } 18734 } 18735 } 18736 } 18737 18738 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18739 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18740 userId, true, ALLOW_FULL_ONLY, callName, null); 18741 ProcessRecord proc = null; 18742 try { 18743 int pid = Integer.parseInt(process); 18744 synchronized (mPidsSelfLocked) { 18745 proc = mPidsSelfLocked.get(pid); 18746 } 18747 } catch (NumberFormatException e) { 18748 } 18749 18750 if (proc == null) { 18751 ArrayMap<String, SparseArray<ProcessRecord>> all 18752 = mProcessNames.getMap(); 18753 SparseArray<ProcessRecord> procs = all.get(process); 18754 if (procs != null && procs.size() > 0) { 18755 proc = procs.valueAt(0); 18756 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18757 for (int i=1; i<procs.size(); i++) { 18758 ProcessRecord thisProc = procs.valueAt(i); 18759 if (thisProc.userId == userId) { 18760 proc = thisProc; 18761 break; 18762 } 18763 } 18764 } 18765 } 18766 } 18767 18768 return proc; 18769 } 18770 18771 public boolean dumpHeap(String process, int userId, boolean managed, 18772 String path, ParcelFileDescriptor fd) throws RemoteException { 18773 18774 try { 18775 synchronized (this) { 18776 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18777 // its own permission (same as profileControl). 18778 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18779 != PackageManager.PERMISSION_GRANTED) { 18780 throw new SecurityException("Requires permission " 18781 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18782 } 18783 18784 if (fd == null) { 18785 throw new IllegalArgumentException("null fd"); 18786 } 18787 18788 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18789 if (proc == null || proc.thread == null) { 18790 throw new IllegalArgumentException("Unknown process: " + process); 18791 } 18792 18793 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18794 if (!isDebuggable) { 18795 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18796 throw new SecurityException("Process not debuggable: " + proc); 18797 } 18798 } 18799 18800 proc.thread.dumpHeap(managed, path, fd); 18801 fd = null; 18802 return true; 18803 } 18804 } catch (RemoteException e) { 18805 throw new IllegalStateException("Process disappeared"); 18806 } finally { 18807 if (fd != null) { 18808 try { 18809 fd.close(); 18810 } catch (IOException e) { 18811 } 18812 } 18813 } 18814 } 18815 18816 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18817 public void monitor() { 18818 synchronized (this) { } 18819 } 18820 18821 void onCoreSettingsChange(Bundle settings) { 18822 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18823 ProcessRecord processRecord = mLruProcesses.get(i); 18824 try { 18825 if (processRecord.thread != null) { 18826 processRecord.thread.setCoreSettings(settings); 18827 } 18828 } catch (RemoteException re) { 18829 /* ignore */ 18830 } 18831 } 18832 } 18833 18834 // Multi-user methods 18835 18836 /** 18837 * Start user, if its not already running, but don't bring it to foreground. 18838 */ 18839 @Override 18840 public boolean startUserInBackground(final int userId) { 18841 return startUser(userId, /* foreground */ false); 18842 } 18843 18844 /** 18845 * Start user, if its not already running, and bring it to foreground. 18846 */ 18847 boolean startUserInForeground(final int userId, Dialog dlg) { 18848 boolean result = startUser(userId, /* foreground */ true); 18849 dlg.dismiss(); 18850 return result; 18851 } 18852 18853 /** 18854 * Refreshes the list of users related to the current user when either a 18855 * user switch happens or when a new related user is started in the 18856 * background. 18857 */ 18858 private void updateCurrentProfileIdsLocked() { 18859 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18860 mCurrentUserId, false /* enabledOnly */); 18861 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18862 for (int i = 0; i < currentProfileIds.length; i++) { 18863 currentProfileIds[i] = profiles.get(i).id; 18864 } 18865 mCurrentProfileIds = currentProfileIds; 18866 18867 synchronized (mUserProfileGroupIdsSelfLocked) { 18868 mUserProfileGroupIdsSelfLocked.clear(); 18869 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18870 for (int i = 0; i < users.size(); i++) { 18871 UserInfo user = users.get(i); 18872 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18873 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18874 } 18875 } 18876 } 18877 } 18878 18879 private Set getProfileIdsLocked(int userId) { 18880 Set userIds = new HashSet<Integer>(); 18881 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18882 userId, false /* enabledOnly */); 18883 for (UserInfo user : profiles) { 18884 userIds.add(Integer.valueOf(user.id)); 18885 } 18886 return userIds; 18887 } 18888 18889 @Override 18890 public boolean switchUser(final int userId) { 18891 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18892 String userName; 18893 synchronized (this) { 18894 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18895 if (userInfo == null) { 18896 Slog.w(TAG, "No user info for user #" + userId); 18897 return false; 18898 } 18899 if (userInfo.isManagedProfile()) { 18900 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18901 return false; 18902 } 18903 userName = userInfo.name; 18904 mTargetUserId = userId; 18905 } 18906 mHandler.removeMessages(START_USER_SWITCH_MSG); 18907 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18908 return true; 18909 } 18910 18911 private void showUserSwitchDialog(int userId, String userName) { 18912 // The dialog will show and then initiate the user switch by calling startUserInForeground 18913 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18914 true /* above system */); 18915 d.show(); 18916 } 18917 18918 private boolean startUser(final int userId, final boolean foreground) { 18919 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18920 != PackageManager.PERMISSION_GRANTED) { 18921 String msg = "Permission Denial: switchUser() from pid=" 18922 + Binder.getCallingPid() 18923 + ", uid=" + Binder.getCallingUid() 18924 + " requires " + INTERACT_ACROSS_USERS_FULL; 18925 Slog.w(TAG, msg); 18926 throw new SecurityException(msg); 18927 } 18928 18929 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18930 18931 final long ident = Binder.clearCallingIdentity(); 18932 try { 18933 synchronized (this) { 18934 final int oldUserId = mCurrentUserId; 18935 if (oldUserId == userId) { 18936 return true; 18937 } 18938 18939 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser"); 18940 18941 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18942 if (userInfo == null) { 18943 Slog.w(TAG, "No user info for user #" + userId); 18944 return false; 18945 } 18946 if (foreground && userInfo.isManagedProfile()) { 18947 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18948 return false; 18949 } 18950 18951 if (foreground) { 18952 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18953 R.anim.screen_user_enter); 18954 } 18955 18956 boolean needStart = false; 18957 18958 // If the user we are switching to is not currently started, then 18959 // we need to start it now. 18960 if (mStartedUsers.get(userId) == null) { 18961 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18962 updateStartedUserArrayLocked(); 18963 needStart = true; 18964 } 18965 18966 final Integer userIdInt = Integer.valueOf(userId); 18967 mUserLru.remove(userIdInt); 18968 mUserLru.add(userIdInt); 18969 18970 if (foreground) { 18971 mCurrentUserId = userId; 18972 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18973 updateCurrentProfileIdsLocked(); 18974 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18975 // Once the internal notion of the active user has switched, we lock the device 18976 // with the option to show the user switcher on the keyguard. 18977 mWindowManager.lockNow(null); 18978 } else { 18979 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18980 updateCurrentProfileIdsLocked(); 18981 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18982 mUserLru.remove(currentUserIdInt); 18983 mUserLru.add(currentUserIdInt); 18984 } 18985 18986 final UserStartedState uss = mStartedUsers.get(userId); 18987 18988 // Make sure user is in the started state. If it is currently 18989 // stopping, we need to knock that off. 18990 if (uss.mState == UserStartedState.STATE_STOPPING) { 18991 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18992 // so we can just fairly silently bring the user back from 18993 // the almost-dead. 18994 uss.mState = UserStartedState.STATE_RUNNING; 18995 updateStartedUserArrayLocked(); 18996 needStart = true; 18997 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18998 // This means ACTION_SHUTDOWN has been sent, so we will 18999 // need to treat this as a new boot of the user. 19000 uss.mState = UserStartedState.STATE_BOOTING; 19001 updateStartedUserArrayLocked(); 19002 needStart = true; 19003 } 19004 19005 if (uss.mState == UserStartedState.STATE_BOOTING) { 19006 // Booting up a new user, need to tell system services about it. 19007 // Note that this is on the same handler as scheduling of broadcasts, 19008 // which is important because it needs to go first. 19009 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 19010 } 19011 19012 if (foreground) { 19013 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 19014 oldUserId)); 19015 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 19016 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19017 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 19018 oldUserId, userId, uss)); 19019 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 19020 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 19021 } 19022 19023 if (needStart) { 19024 // Send USER_STARTED broadcast 19025 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 19026 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19027 | Intent.FLAG_RECEIVER_FOREGROUND); 19028 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19029 broadcastIntentLocked(null, null, intent, 19030 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19031 false, false, MY_PID, Process.SYSTEM_UID, userId); 19032 } 19033 19034 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 19035 if (userId != UserHandle.USER_OWNER) { 19036 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 19037 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 19038 broadcastIntentLocked(null, null, intent, null, 19039 new IIntentReceiver.Stub() { 19040 public void performReceive(Intent intent, int resultCode, 19041 String data, Bundle extras, boolean ordered, 19042 boolean sticky, int sendingUser) { 19043 onUserInitialized(uss, foreground, oldUserId, userId); 19044 } 19045 }, 0, null, null, null, AppOpsManager.OP_NONE, 19046 true, false, MY_PID, Process.SYSTEM_UID, 19047 userId); 19048 uss.initializing = true; 19049 } else { 19050 getUserManagerLocked().makeInitialized(userInfo.id); 19051 } 19052 } 19053 19054 if (foreground) { 19055 if (!uss.initializing) { 19056 moveUserToForeground(uss, oldUserId, userId); 19057 } 19058 } else { 19059 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19060 } 19061 19062 if (needStart) { 19063 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19064 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19065 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19066 broadcastIntentLocked(null, null, intent, 19067 null, new IIntentReceiver.Stub() { 19068 @Override 19069 public void performReceive(Intent intent, int resultCode, String data, 19070 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19071 throws RemoteException { 19072 } 19073 }, 0, null, null, 19074 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19075 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19076 } 19077 } 19078 } finally { 19079 Binder.restoreCallingIdentity(ident); 19080 } 19081 19082 return true; 19083 } 19084 19085 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19086 long ident = Binder.clearCallingIdentity(); 19087 try { 19088 Intent intent; 19089 if (oldUserId >= 0) { 19090 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19091 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19092 int count = profiles.size(); 19093 for (int i = 0; i < count; i++) { 19094 int profileUserId = profiles.get(i).id; 19095 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19096 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19097 | Intent.FLAG_RECEIVER_FOREGROUND); 19098 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19099 broadcastIntentLocked(null, null, intent, 19100 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19101 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19102 } 19103 } 19104 if (newUserId >= 0) { 19105 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19106 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19107 int count = profiles.size(); 19108 for (int i = 0; i < count; i++) { 19109 int profileUserId = profiles.get(i).id; 19110 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19111 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19112 | Intent.FLAG_RECEIVER_FOREGROUND); 19113 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19114 broadcastIntentLocked(null, null, intent, 19115 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19116 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19117 } 19118 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19119 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19120 | Intent.FLAG_RECEIVER_FOREGROUND); 19121 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19122 broadcastIntentLocked(null, null, intent, 19123 null, null, 0, null, null, 19124 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19125 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19126 } 19127 } finally { 19128 Binder.restoreCallingIdentity(ident); 19129 } 19130 } 19131 19132 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19133 final int newUserId) { 19134 final int N = mUserSwitchObservers.beginBroadcast(); 19135 if (N > 0) { 19136 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19137 int mCount = 0; 19138 @Override 19139 public void sendResult(Bundle data) throws RemoteException { 19140 synchronized (ActivityManagerService.this) { 19141 if (mCurUserSwitchCallback == this) { 19142 mCount++; 19143 if (mCount == N) { 19144 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19145 } 19146 } 19147 } 19148 } 19149 }; 19150 synchronized (this) { 19151 uss.switching = true; 19152 mCurUserSwitchCallback = callback; 19153 } 19154 for (int i=0; i<N; i++) { 19155 try { 19156 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19157 newUserId, callback); 19158 } catch (RemoteException e) { 19159 } 19160 } 19161 } else { 19162 synchronized (this) { 19163 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19164 } 19165 } 19166 mUserSwitchObservers.finishBroadcast(); 19167 } 19168 19169 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19170 synchronized (this) { 19171 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19172 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19173 } 19174 } 19175 19176 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19177 mCurUserSwitchCallback = null; 19178 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19179 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19180 oldUserId, newUserId, uss)); 19181 } 19182 19183 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19184 synchronized (this) { 19185 if (foreground) { 19186 moveUserToForeground(uss, oldUserId, newUserId); 19187 } 19188 } 19189 19190 completeSwitchAndInitalize(uss, newUserId, true, false); 19191 } 19192 19193 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19194 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19195 if (homeInFront) { 19196 startHomeActivityLocked(newUserId, "moveUserToFroreground"); 19197 } else { 19198 mStackSupervisor.resumeTopActivitiesLocked(); 19199 } 19200 EventLogTags.writeAmSwitchUser(newUserId); 19201 getUserManagerLocked().userForeground(newUserId); 19202 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19203 } 19204 19205 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19206 completeSwitchAndInitalize(uss, newUserId, false, true); 19207 } 19208 19209 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19210 boolean clearInitializing, boolean clearSwitching) { 19211 boolean unfrozen = false; 19212 synchronized (this) { 19213 if (clearInitializing) { 19214 uss.initializing = false; 19215 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19216 } 19217 if (clearSwitching) { 19218 uss.switching = false; 19219 } 19220 if (!uss.switching && !uss.initializing) { 19221 mWindowManager.stopFreezingScreen(); 19222 unfrozen = true; 19223 } 19224 } 19225 if (unfrozen) { 19226 final int N = mUserSwitchObservers.beginBroadcast(); 19227 for (int i=0; i<N; i++) { 19228 try { 19229 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19230 } catch (RemoteException e) { 19231 } 19232 } 19233 mUserSwitchObservers.finishBroadcast(); 19234 } 19235 stopGuestUserIfBackground(); 19236 } 19237 19238 /** 19239 * Stops the guest user if it has gone to the background. 19240 */ 19241 private void stopGuestUserIfBackground() { 19242 synchronized (this) { 19243 final int num = mUserLru.size(); 19244 for (int i = 0; i < num; i++) { 19245 Integer oldUserId = mUserLru.get(i); 19246 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19247 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19248 || oldUss.mState == UserStartedState.STATE_STOPPING 19249 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19250 continue; 19251 } 19252 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19253 if (userInfo.isGuest()) { 19254 // This is a user to be stopped. 19255 stopUserLocked(oldUserId, null); 19256 break; 19257 } 19258 } 19259 } 19260 } 19261 19262 void scheduleStartProfilesLocked() { 19263 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19264 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19265 DateUtils.SECOND_IN_MILLIS); 19266 } 19267 } 19268 19269 void startProfilesLocked() { 19270 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19271 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19272 mCurrentUserId, false /* enabledOnly */); 19273 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19274 for (UserInfo user : profiles) { 19275 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19276 && user.id != mCurrentUserId) { 19277 toStart.add(user); 19278 } 19279 } 19280 final int n = toStart.size(); 19281 int i = 0; 19282 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19283 startUserInBackground(toStart.get(i).id); 19284 } 19285 if (i < n) { 19286 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19287 } 19288 } 19289 19290 void finishUserBoot(UserStartedState uss) { 19291 synchronized (this) { 19292 if (uss.mState == UserStartedState.STATE_BOOTING 19293 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19294 uss.mState = UserStartedState.STATE_RUNNING; 19295 final int userId = uss.mHandle.getIdentifier(); 19296 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19297 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19298 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19299 broadcastIntentLocked(null, null, intent, 19300 null, null, 0, null, null, 19301 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19302 true, false, MY_PID, Process.SYSTEM_UID, userId); 19303 } 19304 } 19305 } 19306 19307 void finishUserSwitch(UserStartedState uss) { 19308 synchronized (this) { 19309 finishUserBoot(uss); 19310 19311 startProfilesLocked(); 19312 19313 int num = mUserLru.size(); 19314 int i = 0; 19315 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19316 Integer oldUserId = mUserLru.get(i); 19317 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19318 if (oldUss == null) { 19319 // Shouldn't happen, but be sane if it does. 19320 mUserLru.remove(i); 19321 num--; 19322 continue; 19323 } 19324 if (oldUss.mState == UserStartedState.STATE_STOPPING 19325 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19326 // This user is already stopping, doesn't count. 19327 num--; 19328 i++; 19329 continue; 19330 } 19331 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19332 // Owner and current can't be stopped, but count as running. 19333 i++; 19334 continue; 19335 } 19336 // This is a user to be stopped. 19337 stopUserLocked(oldUserId, null); 19338 num--; 19339 i++; 19340 } 19341 } 19342 } 19343 19344 @Override 19345 public int stopUser(final int userId, final IStopUserCallback callback) { 19346 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19347 != PackageManager.PERMISSION_GRANTED) { 19348 String msg = "Permission Denial: switchUser() from pid=" 19349 + Binder.getCallingPid() 19350 + ", uid=" + Binder.getCallingUid() 19351 + " requires " + INTERACT_ACROSS_USERS_FULL; 19352 Slog.w(TAG, msg); 19353 throw new SecurityException(msg); 19354 } 19355 if (userId <= 0) { 19356 throw new IllegalArgumentException("Can't stop primary user " + userId); 19357 } 19358 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19359 synchronized (this) { 19360 return stopUserLocked(userId, callback); 19361 } 19362 } 19363 19364 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19365 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19366 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19367 return ActivityManager.USER_OP_IS_CURRENT; 19368 } 19369 19370 final UserStartedState uss = mStartedUsers.get(userId); 19371 if (uss == null) { 19372 // User is not started, nothing to do... but we do need to 19373 // callback if requested. 19374 if (callback != null) { 19375 mHandler.post(new Runnable() { 19376 @Override 19377 public void run() { 19378 try { 19379 callback.userStopped(userId); 19380 } catch (RemoteException e) { 19381 } 19382 } 19383 }); 19384 } 19385 return ActivityManager.USER_OP_SUCCESS; 19386 } 19387 19388 if (callback != null) { 19389 uss.mStopCallbacks.add(callback); 19390 } 19391 19392 if (uss.mState != UserStartedState.STATE_STOPPING 19393 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19394 uss.mState = UserStartedState.STATE_STOPPING; 19395 updateStartedUserArrayLocked(); 19396 19397 long ident = Binder.clearCallingIdentity(); 19398 try { 19399 // We are going to broadcast ACTION_USER_STOPPING and then 19400 // once that is done send a final ACTION_SHUTDOWN and then 19401 // stop the user. 19402 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19403 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19404 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19405 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19406 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19407 // This is the result receiver for the final shutdown broadcast. 19408 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19409 @Override 19410 public void performReceive(Intent intent, int resultCode, String data, 19411 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19412 finishUserStop(uss); 19413 } 19414 }; 19415 // This is the result receiver for the initial stopping broadcast. 19416 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19417 @Override 19418 public void performReceive(Intent intent, int resultCode, String data, 19419 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19420 // On to the next. 19421 synchronized (ActivityManagerService.this) { 19422 if (uss.mState != UserStartedState.STATE_STOPPING) { 19423 // Whoops, we are being started back up. Abort, abort! 19424 return; 19425 } 19426 uss.mState = UserStartedState.STATE_SHUTDOWN; 19427 } 19428 mBatteryStatsService.noteEvent( 19429 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19430 Integer.toString(userId), userId); 19431 mSystemServiceManager.stopUser(userId); 19432 broadcastIntentLocked(null, null, shutdownIntent, 19433 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19434 true, false, MY_PID, Process.SYSTEM_UID, userId); 19435 } 19436 }; 19437 // Kick things off. 19438 broadcastIntentLocked(null, null, stoppingIntent, 19439 null, stoppingReceiver, 0, null, null, 19440 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19441 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19442 } finally { 19443 Binder.restoreCallingIdentity(ident); 19444 } 19445 } 19446 19447 return ActivityManager.USER_OP_SUCCESS; 19448 } 19449 19450 void finishUserStop(UserStartedState uss) { 19451 final int userId = uss.mHandle.getIdentifier(); 19452 boolean stopped; 19453 ArrayList<IStopUserCallback> callbacks; 19454 synchronized (this) { 19455 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19456 if (mStartedUsers.get(userId) != uss) { 19457 stopped = false; 19458 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19459 stopped = false; 19460 } else { 19461 stopped = true; 19462 // User can no longer run. 19463 mStartedUsers.remove(userId); 19464 mUserLru.remove(Integer.valueOf(userId)); 19465 updateStartedUserArrayLocked(); 19466 19467 // Clean up all state and processes associated with the user. 19468 // Kill all the processes for the user. 19469 forceStopUserLocked(userId, "finish user"); 19470 } 19471 19472 // Explicitly remove the old information in mRecentTasks. 19473 removeRecentTasksForUserLocked(userId); 19474 } 19475 19476 for (int i=0; i<callbacks.size(); i++) { 19477 try { 19478 if (stopped) callbacks.get(i).userStopped(userId); 19479 else callbacks.get(i).userStopAborted(userId); 19480 } catch (RemoteException e) { 19481 } 19482 } 19483 19484 if (stopped) { 19485 mSystemServiceManager.cleanupUser(userId); 19486 synchronized (this) { 19487 mStackSupervisor.removeUserLocked(userId); 19488 } 19489 } 19490 } 19491 19492 @Override 19493 public UserInfo getCurrentUser() { 19494 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19495 != PackageManager.PERMISSION_GRANTED) && ( 19496 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19497 != PackageManager.PERMISSION_GRANTED)) { 19498 String msg = "Permission Denial: getCurrentUser() from pid=" 19499 + Binder.getCallingPid() 19500 + ", uid=" + Binder.getCallingUid() 19501 + " requires " + INTERACT_ACROSS_USERS; 19502 Slog.w(TAG, msg); 19503 throw new SecurityException(msg); 19504 } 19505 synchronized (this) { 19506 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19507 return getUserManagerLocked().getUserInfo(userId); 19508 } 19509 } 19510 19511 int getCurrentUserIdLocked() { 19512 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19513 } 19514 19515 @Override 19516 public boolean isUserRunning(int userId, boolean orStopped) { 19517 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19518 != PackageManager.PERMISSION_GRANTED) { 19519 String msg = "Permission Denial: isUserRunning() from pid=" 19520 + Binder.getCallingPid() 19521 + ", uid=" + Binder.getCallingUid() 19522 + " requires " + INTERACT_ACROSS_USERS; 19523 Slog.w(TAG, msg); 19524 throw new SecurityException(msg); 19525 } 19526 synchronized (this) { 19527 return isUserRunningLocked(userId, orStopped); 19528 } 19529 } 19530 19531 boolean isUserRunningLocked(int userId, boolean orStopped) { 19532 UserStartedState state = mStartedUsers.get(userId); 19533 if (state == null) { 19534 return false; 19535 } 19536 if (orStopped) { 19537 return true; 19538 } 19539 return state.mState != UserStartedState.STATE_STOPPING 19540 && state.mState != UserStartedState.STATE_SHUTDOWN; 19541 } 19542 19543 @Override 19544 public int[] getRunningUserIds() { 19545 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19546 != PackageManager.PERMISSION_GRANTED) { 19547 String msg = "Permission Denial: isUserRunning() from pid=" 19548 + Binder.getCallingPid() 19549 + ", uid=" + Binder.getCallingUid() 19550 + " requires " + INTERACT_ACROSS_USERS; 19551 Slog.w(TAG, msg); 19552 throw new SecurityException(msg); 19553 } 19554 synchronized (this) { 19555 return mStartedUserArray; 19556 } 19557 } 19558 19559 private void updateStartedUserArrayLocked() { 19560 int num = 0; 19561 for (int i=0; i<mStartedUsers.size(); i++) { 19562 UserStartedState uss = mStartedUsers.valueAt(i); 19563 // This list does not include stopping users. 19564 if (uss.mState != UserStartedState.STATE_STOPPING 19565 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19566 num++; 19567 } 19568 } 19569 mStartedUserArray = new int[num]; 19570 num = 0; 19571 for (int i=0; i<mStartedUsers.size(); i++) { 19572 UserStartedState uss = mStartedUsers.valueAt(i); 19573 if (uss.mState != UserStartedState.STATE_STOPPING 19574 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19575 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19576 num++; 19577 } 19578 } 19579 } 19580 19581 @Override 19582 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19583 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19584 != PackageManager.PERMISSION_GRANTED) { 19585 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19586 + Binder.getCallingPid() 19587 + ", uid=" + Binder.getCallingUid() 19588 + " requires " + INTERACT_ACROSS_USERS_FULL; 19589 Slog.w(TAG, msg); 19590 throw new SecurityException(msg); 19591 } 19592 19593 mUserSwitchObservers.register(observer); 19594 } 19595 19596 @Override 19597 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19598 mUserSwitchObservers.unregister(observer); 19599 } 19600 19601 private boolean userExists(int userId) { 19602 if (userId == 0) { 19603 return true; 19604 } 19605 UserManagerService ums = getUserManagerLocked(); 19606 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19607 } 19608 19609 int[] getUsersLocked() { 19610 UserManagerService ums = getUserManagerLocked(); 19611 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19612 } 19613 19614 UserManagerService getUserManagerLocked() { 19615 if (mUserManager == null) { 19616 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19617 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19618 } 19619 return mUserManager; 19620 } 19621 19622 private int applyUserId(int uid, int userId) { 19623 return UserHandle.getUid(userId, uid); 19624 } 19625 19626 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19627 if (info == null) return null; 19628 ApplicationInfo newInfo = new ApplicationInfo(info); 19629 newInfo.uid = applyUserId(info.uid, userId); 19630 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19631 + info.packageName; 19632 return newInfo; 19633 } 19634 19635 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19636 if (aInfo == null 19637 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19638 return aInfo; 19639 } 19640 19641 ActivityInfo info = new ActivityInfo(aInfo); 19642 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19643 return info; 19644 } 19645 19646 private final class LocalService extends ActivityManagerInternal { 19647 @Override 19648 public void onWakefulnessChanged(int wakefulness) { 19649 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19650 } 19651 19652 @Override 19653 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19654 String processName, String abiOverride, int uid, Runnable crashHandler) { 19655 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19656 processName, abiOverride, uid, crashHandler); 19657 } 19658 } 19659 19660 /** 19661 * An implementation of IAppTask, that allows an app to manage its own tasks via 19662 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19663 * only the process that calls getAppTasks() can call the AppTask methods. 19664 */ 19665 class AppTaskImpl extends IAppTask.Stub { 19666 private int mTaskId; 19667 private int mCallingUid; 19668 19669 public AppTaskImpl(int taskId, int callingUid) { 19670 mTaskId = taskId; 19671 mCallingUid = callingUid; 19672 } 19673 19674 private void checkCaller() { 19675 if (mCallingUid != Binder.getCallingUid()) { 19676 throw new SecurityException("Caller " + mCallingUid 19677 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19678 } 19679 } 19680 19681 @Override 19682 public void finishAndRemoveTask() { 19683 checkCaller(); 19684 19685 synchronized (ActivityManagerService.this) { 19686 long origId = Binder.clearCallingIdentity(); 19687 try { 19688 if (!removeTaskByIdLocked(mTaskId, false)) { 19689 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19690 } 19691 } finally { 19692 Binder.restoreCallingIdentity(origId); 19693 } 19694 } 19695 } 19696 19697 @Override 19698 public ActivityManager.RecentTaskInfo getTaskInfo() { 19699 checkCaller(); 19700 19701 synchronized (ActivityManagerService.this) { 19702 long origId = Binder.clearCallingIdentity(); 19703 try { 19704 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19705 if (tr == null) { 19706 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19707 } 19708 return createRecentTaskInfoFromTaskRecord(tr); 19709 } finally { 19710 Binder.restoreCallingIdentity(origId); 19711 } 19712 } 19713 } 19714 19715 @Override 19716 public void moveToFront() { 19717 checkCaller(); 19718 // Will bring task to front if it already has a root activity. 19719 startActivityFromRecentsInner(mTaskId, null); 19720 } 19721 19722 @Override 19723 public int startActivity(IBinder whoThread, String callingPackage, 19724 Intent intent, String resolvedType, Bundle options) { 19725 checkCaller(); 19726 19727 int callingUser = UserHandle.getCallingUserId(); 19728 TaskRecord tr; 19729 IApplicationThread appThread; 19730 synchronized (ActivityManagerService.this) { 19731 tr = recentTaskForIdLocked(mTaskId); 19732 if (tr == null) { 19733 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19734 } 19735 appThread = ApplicationThreadNative.asInterface(whoThread); 19736 if (appThread == null) { 19737 throw new IllegalArgumentException("Bad app thread " + appThread); 19738 } 19739 } 19740 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19741 resolvedType, null, null, null, null, 0, 0, null, null, 19742 null, options, callingUser, null, tr); 19743 } 19744 19745 @Override 19746 public void setExcludeFromRecents(boolean exclude) { 19747 checkCaller(); 19748 19749 synchronized (ActivityManagerService.this) { 19750 long origId = Binder.clearCallingIdentity(); 19751 try { 19752 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19753 if (tr == null) { 19754 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19755 } 19756 Intent intent = tr.getBaseIntent(); 19757 if (exclude) { 19758 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19759 } else { 19760 intent.setFlags(intent.getFlags() 19761 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19762 } 19763 } finally { 19764 Binder.restoreCallingIdentity(origId); 19765 } 19766 } 19767 } 19768 } 19769} 19770