ActivityManagerService.java revision 2cffc7dafd390f6fe24a9fbb3ef3bc8226f5b385
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; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.Installer; 85import com.android.server.pm.UserManagerService; 86import com.android.server.statusbar.StatusBarManagerInternal; 87import com.android.server.wm.AppTransition; 88import com.android.server.wm.WindowManagerService; 89import com.google.android.collect.Lists; 90import com.google.android.collect.Maps; 91 92import libcore.io.IoUtils; 93 94import org.xmlpull.v1.XmlPullParser; 95import org.xmlpull.v1.XmlPullParserException; 96import org.xmlpull.v1.XmlSerializer; 97 98import android.app.Activity; 99import android.app.ActivityManager; 100import android.app.ActivityManager.RunningTaskInfo; 101import android.app.ActivityManager.StackInfo; 102import android.app.ActivityManagerInternal; 103import android.app.ActivityManagerNative; 104import android.app.ActivityOptions; 105import android.app.ActivityThread; 106import android.app.AlertDialog; 107import android.app.AppGlobals; 108import android.app.ApplicationErrorReport; 109import android.app.Dialog; 110import android.app.IActivityController; 111import android.app.IApplicationThread; 112import android.app.IInstrumentationWatcher; 113import android.app.INotificationManager; 114import android.app.IProcessObserver; 115import android.app.IServiceConnection; 116import android.app.IStopUserCallback; 117import android.app.IUiAutomationConnection; 118import android.app.IUserSwitchObserver; 119import android.app.Instrumentation; 120import android.app.Notification; 121import android.app.NotificationManager; 122import android.app.PendingIntent; 123import android.app.backup.IBackupManager; 124import android.content.ActivityNotFoundException; 125import android.content.BroadcastReceiver; 126import android.content.ClipData; 127import android.content.ComponentCallbacks2; 128import android.content.ComponentName; 129import android.content.ContentProvider; 130import android.content.ContentResolver; 131import android.content.Context; 132import android.content.DialogInterface; 133import android.content.IContentProvider; 134import android.content.IIntentReceiver; 135import android.content.IIntentSender; 136import android.content.Intent; 137import android.content.IntentFilter; 138import android.content.IntentSender; 139import android.content.pm.ActivityInfo; 140import android.content.pm.ApplicationInfo; 141import android.content.pm.ConfigurationInfo; 142import android.content.pm.IPackageDataObserver; 143import android.content.pm.IPackageManager; 144import android.content.pm.InstrumentationInfo; 145import android.content.pm.PackageInfo; 146import android.content.pm.PackageManager; 147import android.content.pm.ParceledListSlice; 148import android.content.pm.UserInfo; 149import android.content.pm.PackageManager.NameNotFoundException; 150import android.content.pm.PathPermission; 151import android.content.pm.ProviderInfo; 152import android.content.pm.ResolveInfo; 153import android.content.pm.ServiceInfo; 154import android.content.res.CompatibilityInfo; 155import android.content.res.Configuration; 156import android.net.Proxy; 157import android.net.ProxyInfo; 158import android.net.Uri; 159import android.os.Binder; 160import android.os.Build; 161import android.os.Bundle; 162import android.os.Debug; 163import android.os.DropBoxManager; 164import android.os.Environment; 165import android.os.FactoryTest; 166import android.os.FileObserver; 167import android.os.FileUtils; 168import android.os.Handler; 169import android.os.IBinder; 170import android.os.IPermissionController; 171import android.os.IRemoteCallback; 172import android.os.IUserManager; 173import android.os.Looper; 174import android.os.Message; 175import android.os.Parcel; 176import android.os.ParcelFileDescriptor; 177import android.os.Process; 178import android.os.RemoteCallbackList; 179import android.os.RemoteException; 180import android.os.SELinux; 181import android.os.ServiceManager; 182import android.os.StrictMode; 183import android.os.SystemClock; 184import android.os.SystemProperties; 185import android.os.UpdateLock; 186import android.os.UserHandle; 187import android.os.UserManager; 188import android.provider.Settings; 189import android.text.format.DateUtils; 190import android.text.format.Time; 191import android.util.AtomicFile; 192import android.util.EventLog; 193import android.util.Log; 194import android.util.Pair; 195import android.util.PrintWriterPrinter; 196import android.util.Slog; 197import android.util.SparseArray; 198import android.util.TimeUtils; 199import android.util.Xml; 200import android.view.Gravity; 201import android.view.LayoutInflater; 202import android.view.View; 203import android.view.WindowManager; 204 205import dalvik.system.VMRuntime; 206 207import java.io.BufferedInputStream; 208import java.io.BufferedOutputStream; 209import java.io.DataInputStream; 210import java.io.DataOutputStream; 211import java.io.File; 212import java.io.FileDescriptor; 213import java.io.FileInputStream; 214import java.io.FileNotFoundException; 215import java.io.FileOutputStream; 216import java.io.IOException; 217import java.io.InputStreamReader; 218import java.io.PrintWriter; 219import java.io.StringWriter; 220import java.lang.ref.WeakReference; 221import java.util.ArrayList; 222import java.util.Arrays; 223import java.util.Collections; 224import java.util.Comparator; 225import java.util.HashMap; 226import java.util.HashSet; 227import java.util.Iterator; 228import java.util.List; 229import java.util.Locale; 230import java.util.Map; 231import java.util.Set; 232import java.util.concurrent.atomic.AtomicBoolean; 233import java.util.concurrent.atomic.AtomicLong; 234 235public final class ActivityManagerService extends ActivityManagerNative 236 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 237 238 private static final String USER_DATA_DIR = "/data/user/"; 239 // File that stores last updated system version and called preboot receivers 240 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 241 242 static final String TAG = "ActivityManager"; 243 static final String TAG_MU = "ActivityManagerServiceMU"; 244 static final boolean DEBUG = false; 245 static final boolean localLOGV = DEBUG; 246 static final boolean DEBUG_BACKUP = localLOGV || false; 247 static final boolean DEBUG_BROADCAST = localLOGV || false; 248 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 249 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 250 static final boolean DEBUG_CLEANUP = localLOGV || false; 251 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 252 static final boolean DEBUG_FOCUS = false; 253 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 254 static final boolean DEBUG_MU = localLOGV || false; 255 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 256 static final boolean DEBUG_LRU = localLOGV || false; 257 static final boolean DEBUG_PAUSE = localLOGV || false; 258 static final boolean DEBUG_POWER = localLOGV || false; 259 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 260 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 261 static final boolean DEBUG_PROCESSES = localLOGV || false; 262 static final boolean DEBUG_PROVIDER = localLOGV || false; 263 static final boolean DEBUG_RESULTS = localLOGV || false; 264 static final boolean DEBUG_SERVICE = localLOGV || false; 265 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 266 static final boolean DEBUG_STACK = localLOGV || false; 267 static final boolean DEBUG_SWITCH = localLOGV || false; 268 static final boolean DEBUG_TASKS = localLOGV || false; 269 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 270 static final boolean DEBUG_TRANSITION = localLOGV || false; 271 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 272 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 273 static final boolean DEBUG_VISBILITY = localLOGV || false; 274 static final boolean DEBUG_PSS = localLOGV || false; 275 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 276 static final boolean DEBUG_RECENTS = localLOGV || false; 277 static final boolean VALIDATE_TOKENS = false; 278 static final boolean SHOW_ACTIVITY_START_TIME = true; 279 280 // Control over CPU and battery monitoring. 281 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 282 static final boolean MONITOR_CPU_USAGE = true; 283 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 284 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 285 static final boolean MONITOR_THREAD_CPU_USAGE = false; 286 287 // The flags that are set for all calls we make to the package manager. 288 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 289 290 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 291 292 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 293 294 // Maximum number recent bitmaps to keep in memory. 295 static final int MAX_RECENT_BITMAPS = 5; 296 297 // Amount of time after a call to stopAppSwitches() during which we will 298 // prevent further untrusted switches from happening. 299 static final long APP_SWITCH_DELAY_TIME = 5*1000; 300 301 // How long we wait for a launched process to attach to the activity manager 302 // before we decide it's never going to come up for real. 303 static final int PROC_START_TIMEOUT = 10*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, when the process was 307 // started with a wrapper for instrumentation (such as Valgrind) because it 308 // could take much longer than usual. 309 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 310 311 // How long to wait after going idle before forcing apps to GC. 312 static final int GC_TIMEOUT = 5*1000; 313 314 // The minimum amount of time between successive GC requests for a process. 315 static final int GC_MIN_INTERVAL = 60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process. 318 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 319 320 // The minimum amount of time between successive PSS requests for a process 321 // when the request is due to the memory state being lowered. 322 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 323 324 // The rate at which we check for apps using excessive power -- 15 mins. 325 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 326 327 // The minimum sample duration we will allow before deciding we have 328 // enough data on wake locks to start killing things. 329 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 330 331 // The minimum sample duration we will allow before deciding we have 332 // enough data on CPU usage to start killing things. 333 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 334 335 // How long we allow a receiver to run before giving up on it. 336 static final int BROADCAST_FG_TIMEOUT = 10*1000; 337 static final int BROADCAST_BG_TIMEOUT = 60*1000; 338 339 // How long we wait until we timeout on key dispatching. 340 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 341 342 // How long we wait until we timeout on key dispatching during instrumentation. 343 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 344 345 // Amount of time we wait for observers to handle a user switch before 346 // giving up on them and unfreezing the screen. 347 static final int USER_SWITCH_TIMEOUT = 2*1000; 348 349 // Maximum number of users we allow to be running at a time. 350 static final int MAX_RUNNING_USERS = 3; 351 352 // How long to wait in getAssistContextExtras for the activity and foreground services 353 // to respond with the result. 354 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 355 356 // Maximum number of persisted Uri grants a package is allowed 357 static final int MAX_PERSISTED_URI_GRANTS = 128; 358 359 static final int MY_PID = Process.myPid(); 360 361 static final String[] EMPTY_STRING_ARRAY = new String[0]; 362 363 // How many bytes to write into the dropbox log before truncating 364 static final int DROPBOX_MAX_SIZE = 256 * 1024; 365 366 // Access modes for handleIncomingUser. 367 static final int ALLOW_NON_FULL = 0; 368 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 369 static final int ALLOW_FULL_ONLY = 2; 370 371 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 372 373 /** All system services */ 374 SystemServiceManager mSystemServiceManager; 375 376 private Installer mInstaller; 377 378 /** Run all ActivityStacks through this */ 379 ActivityStackSupervisor mStackSupervisor; 380 381 public IntentFirewall mIntentFirewall; 382 383 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 384 // default actuion automatically. Important for devices without direct input 385 // devices. 386 private boolean mShowDialogs = true; 387 388 BroadcastQueue mFgBroadcastQueue; 389 BroadcastQueue mBgBroadcastQueue; 390 // Convenient for easy iteration over the queues. Foreground is first 391 // so that dispatch of foreground broadcasts gets precedence. 392 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 393 394 BroadcastQueue broadcastQueueForIntent(Intent intent) { 395 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 396 if (DEBUG_BACKGROUND_BROADCAST) { 397 Slog.i(TAG, "Broadcast intent " + intent + " on " 398 + (isFg ? "foreground" : "background") 399 + " queue"); 400 } 401 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 402 } 403 404 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 405 for (BroadcastQueue queue : mBroadcastQueues) { 406 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 407 if (r != null) { 408 return r; 409 } 410 } 411 return null; 412 } 413 414 /** 415 * Activity we have told the window manager to have key focus. 416 */ 417 ActivityRecord mFocusedActivity = null; 418 419 /** 420 * List of intents that were used to start the most recent tasks. 421 */ 422 ArrayList<TaskRecord> mRecentTasks; 423 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 424 425 /** 426 * For addAppTask: cached of the last activity component that was added. 427 */ 428 ComponentName mLastAddedTaskComponent; 429 430 /** 431 * For addAppTask: cached of the last activity uid that was added. 432 */ 433 int mLastAddedTaskUid; 434 435 /** 436 * For addAppTask: cached of the last ActivityInfo that was added. 437 */ 438 ActivityInfo mLastAddedTaskActivity; 439 440 public class PendingAssistExtras extends Binder implements Runnable { 441 public final ActivityRecord activity; 442 public final Bundle extras; 443 public final Intent intent; 444 public final String hint; 445 public final int userHandle; 446 public boolean haveResult = false; 447 public Bundle result = null; 448 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 449 String _hint, int _userHandle) { 450 activity = _activity; 451 extras = _extras; 452 intent = _intent; 453 hint = _hint; 454 userHandle = _userHandle; 455 } 456 @Override 457 public void run() { 458 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 459 synchronized (this) { 460 haveResult = true; 461 notifyAll(); 462 } 463 } 464 } 465 466 final ArrayList<PendingAssistExtras> mPendingAssistExtras 467 = new ArrayList<PendingAssistExtras>(); 468 469 /** 470 * Process management. 471 */ 472 final ProcessList mProcessList = new ProcessList(); 473 474 /** 475 * All of the applications we currently have running organized by name. 476 * The keys are strings of the application package name (as 477 * returned by the package manager), and the keys are ApplicationRecord 478 * objects. 479 */ 480 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 481 482 /** 483 * Tracking long-term execution of processes to look for abuse and other 484 * bad app behavior. 485 */ 486 final ProcessStatsService mProcessStats; 487 488 /** 489 * The currently running isolated processes. 490 */ 491 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 492 493 /** 494 * Counter for assigning isolated process uids, to avoid frequently reusing the 495 * same ones. 496 */ 497 int mNextIsolatedProcessUid = 0; 498 499 /** 500 * The currently running heavy-weight process, if any. 501 */ 502 ProcessRecord mHeavyWeightProcess = null; 503 504 /** 505 * The last time that various processes have crashed. 506 */ 507 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 508 509 /** 510 * Information about a process that is currently marked as bad. 511 */ 512 static final class BadProcessInfo { 513 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 514 this.time = time; 515 this.shortMsg = shortMsg; 516 this.longMsg = longMsg; 517 this.stack = stack; 518 } 519 520 final long time; 521 final String shortMsg; 522 final String longMsg; 523 final String stack; 524 } 525 526 /** 527 * Set of applications that we consider to be bad, and will reject 528 * incoming broadcasts from (which the user has no control over). 529 * Processes are added to this set when they have crashed twice within 530 * a minimum amount of time; they are removed from it when they are 531 * later restarted (hopefully due to some user action). The value is the 532 * time it was added to the list. 533 */ 534 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 535 536 /** 537 * All of the processes we currently have running organized by pid. 538 * The keys are the pid running the application. 539 * 540 * <p>NOTE: This object is protected by its own lock, NOT the global 541 * activity manager lock! 542 */ 543 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 544 545 /** 546 * All of the processes that have been forced to be foreground. The key 547 * is the pid of the caller who requested it (we hold a death 548 * link on it). 549 */ 550 abstract class ForegroundToken implements IBinder.DeathRecipient { 551 int pid; 552 IBinder token; 553 } 554 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 555 556 /** 557 * List of records for processes that someone had tried to start before the 558 * system was ready. We don't start them at that point, but ensure they 559 * are started by the time booting is complete. 560 */ 561 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 562 563 /** 564 * List of persistent applications that are in the process 565 * of being started. 566 */ 567 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * Processes that are being forcibly torn down. 571 */ 572 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 573 574 /** 575 * List of running applications, sorted by recent usage. 576 * The first entry in the list is the least recently used. 577 */ 578 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Where in mLruProcesses that the processes hosting activities start. 582 */ 583 int mLruProcessActivityStart = 0; 584 585 /** 586 * Where in mLruProcesses that the processes hosting services start. 587 * This is after (lower index) than mLruProcessesActivityStart. 588 */ 589 int mLruProcessServiceStart = 0; 590 591 /** 592 * List of processes that should gc as soon as things are idle. 593 */ 594 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Processes we want to collect PSS data from. 598 */ 599 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 600 601 /** 602 * Last time we requested PSS data of all processes. 603 */ 604 long mLastFullPssTime = SystemClock.uptimeMillis(); 605 606 /** 607 * If set, the next time we collect PSS data we should do a full collection 608 * with data from native processes and the kernel. 609 */ 610 boolean mFullPssPending = false; 611 612 /** 613 * This is the process holding what we currently consider to be 614 * the "home" activity. 615 */ 616 ProcessRecord mHomeProcess; 617 618 /** 619 * This is the process holding the activity the user last visited that 620 * is in a different process from the one they are currently in. 621 */ 622 ProcessRecord mPreviousProcess; 623 624 /** 625 * The time at which the previous process was last visible. 626 */ 627 long mPreviousProcessVisibleTime; 628 629 /** 630 * Which uses have been started, so are allowed to run code. 631 */ 632 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 633 634 /** 635 * LRU list of history of current users. Most recently current is at the end. 636 */ 637 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 638 639 /** 640 * Constant array of the users that are currently started. 641 */ 642 int[] mStartedUserArray = new int[] { 0 }; 643 644 /** 645 * Registered observers of the user switching mechanics. 646 */ 647 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 648 = new RemoteCallbackList<IUserSwitchObserver>(); 649 650 /** 651 * Currently active user switch. 652 */ 653 Object mCurUserSwitchCallback; 654 655 /** 656 * Packages that the user has asked to have run in screen size 657 * compatibility mode instead of filling the screen. 658 */ 659 final CompatModePackages mCompatModePackages; 660 661 /** 662 * Set of IntentSenderRecord objects that are currently active. 663 */ 664 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 665 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 666 667 /** 668 * Fingerprints (hashCode()) of stack traces that we've 669 * already logged DropBox entries for. Guarded by itself. If 670 * something (rogue user app) forces this over 671 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 672 */ 673 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 674 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 675 676 /** 677 * Strict Mode background batched logging state. 678 * 679 * The string buffer is guarded by itself, and its lock is also 680 * used to determine if another batched write is already 681 * in-flight. 682 */ 683 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 684 685 /** 686 * Keeps track of all IIntentReceivers that have been registered for 687 * broadcasts. Hash keys are the receiver IBinder, hash value is 688 * a ReceiverList. 689 */ 690 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 691 new HashMap<IBinder, ReceiverList>(); 692 693 /** 694 * Resolver for broadcast intents to registered receivers. 695 * Holds BroadcastFilter (subclass of IntentFilter). 696 */ 697 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 698 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 699 @Override 700 protected boolean allowFilterResult( 701 BroadcastFilter filter, List<BroadcastFilter> dest) { 702 IBinder target = filter.receiverList.receiver.asBinder(); 703 for (int i=dest.size()-1; i>=0; i--) { 704 if (dest.get(i).receiverList.receiver.asBinder() == target) { 705 return false; 706 } 707 } 708 return true; 709 } 710 711 @Override 712 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 713 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 714 || userId == filter.owningUserId) { 715 return super.newResult(filter, match, userId); 716 } 717 return null; 718 } 719 720 @Override 721 protected BroadcastFilter[] newArray(int size) { 722 return new BroadcastFilter[size]; 723 } 724 725 @Override 726 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 727 return packageName.equals(filter.packageName); 728 } 729 }; 730 731 /** 732 * State of all active sticky broadcasts per user. Keys are the action of the 733 * sticky Intent, values are an ArrayList of all broadcasted intents with 734 * that action (which should usually be one). The SparseArray is keyed 735 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 736 * for stickies that are sent to all users. 737 */ 738 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 739 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 740 741 final ActiveServices mServices; 742 743 /** 744 * Backup/restore process management 745 */ 746 String mBackupAppName = null; 747 BackupRecord mBackupTarget = null; 748 749 final ProviderMap mProviderMap; 750 751 /** 752 * List of content providers who have clients waiting for them. The 753 * application is currently being launched and the provider will be 754 * removed from this list once it is published. 755 */ 756 final ArrayList<ContentProviderRecord> mLaunchingProviders 757 = new ArrayList<ContentProviderRecord>(); 758 759 /** 760 * File storing persisted {@link #mGrantedUriPermissions}. 761 */ 762 private final AtomicFile mGrantFile; 763 764 /** XML constants used in {@link #mGrantFile} */ 765 private static final String TAG_URI_GRANTS = "uri-grants"; 766 private static final String TAG_URI_GRANT = "uri-grant"; 767 private static final String ATTR_USER_HANDLE = "userHandle"; 768 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 769 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 770 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 771 private static final String ATTR_TARGET_PKG = "targetPkg"; 772 private static final String ATTR_URI = "uri"; 773 private static final String ATTR_MODE_FLAGS = "modeFlags"; 774 private static final String ATTR_CREATED_TIME = "createdTime"; 775 private static final String ATTR_PREFIX = "prefix"; 776 777 /** 778 * Global set of specific {@link Uri} permissions that have been granted. 779 * This optimized lookup structure maps from {@link UriPermission#targetUid} 780 * to {@link UriPermission#uri} to {@link UriPermission}. 781 */ 782 @GuardedBy("this") 783 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 784 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 785 786 public static class GrantUri { 787 public final int sourceUserId; 788 public final Uri uri; 789 public boolean prefix; 790 791 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 792 this.sourceUserId = sourceUserId; 793 this.uri = uri; 794 this.prefix = prefix; 795 } 796 797 @Override 798 public int hashCode() { 799 return toString().hashCode(); 800 } 801 802 @Override 803 public boolean equals(Object o) { 804 if (o instanceof GrantUri) { 805 GrantUri other = (GrantUri) o; 806 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 807 && prefix == other.prefix; 808 } 809 return false; 810 } 811 812 @Override 813 public String toString() { 814 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 815 if (prefix) result += " [prefix]"; 816 return result; 817 } 818 819 public String toSafeString() { 820 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 821 if (prefix) result += " [prefix]"; 822 return result; 823 } 824 825 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 826 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 827 ContentProvider.getUriWithoutUserId(uri), false); 828 } 829 } 830 831 CoreSettingsObserver mCoreSettingsObserver; 832 833 /** 834 * Thread-local storage used to carry caller permissions over through 835 * indirect content-provider access. 836 */ 837 private class Identity { 838 public int pid; 839 public int uid; 840 841 Identity(int _pid, int _uid) { 842 pid = _pid; 843 uid = _uid; 844 } 845 } 846 847 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 848 849 /** 850 * All information we have collected about the runtime performance of 851 * any user id that can impact battery performance. 852 */ 853 final BatteryStatsService mBatteryStatsService; 854 855 /** 856 * Information about component usage 857 */ 858 UsageStatsManagerInternal mUsageStatsService; 859 860 /** 861 * Information about and control over application operations 862 */ 863 final AppOpsService mAppOpsService; 864 865 /** 866 * Save recent tasks information across reboots. 867 */ 868 final TaskPersister mTaskPersister; 869 870 /** 871 * Current configuration information. HistoryRecord objects are given 872 * a reference to this object to indicate which configuration they are 873 * currently running in, so this object must be kept immutable. 874 */ 875 Configuration mConfiguration = new Configuration(); 876 877 /** 878 * Current sequencing integer of the configuration, for skipping old 879 * configurations. 880 */ 881 int mConfigurationSeq = 0; 882 883 /** 884 * Hardware-reported OpenGLES version. 885 */ 886 final int GL_ES_VERSION; 887 888 /** 889 * List of initialization arguments to pass to all processes when binding applications to them. 890 * For example, references to the commonly used services. 891 */ 892 HashMap<String, IBinder> mAppBindArgs; 893 894 /** 895 * Temporary to avoid allocations. Protected by main lock. 896 */ 897 final StringBuilder mStringBuilder = new StringBuilder(256); 898 899 /** 900 * Used to control how we initialize the service. 901 */ 902 ComponentName mTopComponent; 903 String mTopAction = Intent.ACTION_MAIN; 904 String mTopData; 905 boolean mProcessesReady = false; 906 boolean mSystemReady = false; 907 boolean mBooting = false; 908 boolean mCallFinishBooting = false; 909 boolean mBootAnimationComplete = false; 910 boolean mWaitingUpdate = false; 911 boolean mDidUpdate = false; 912 boolean mOnBattery = false; 913 boolean mLaunchWarningShown = false; 914 915 Context mContext; 916 917 int mFactoryTest; 918 919 boolean mCheckedForSetup; 920 921 /** 922 * The time at which we will allow normal application switches again, 923 * after a call to {@link #stopAppSwitches()}. 924 */ 925 long mAppSwitchesAllowedTime; 926 927 /** 928 * This is set to true after the first switch after mAppSwitchesAllowedTime 929 * is set; any switches after that will clear the time. 930 */ 931 boolean mDidAppSwitch; 932 933 /** 934 * Last time (in realtime) at which we checked for power usage. 935 */ 936 long mLastPowerCheckRealtime; 937 938 /** 939 * Last time (in uptime) at which we checked for power usage. 940 */ 941 long mLastPowerCheckUptime; 942 943 /** 944 * Set while we are wanting to sleep, to prevent any 945 * activities from being started/resumed. 946 */ 947 private boolean mSleeping = false; 948 949 /** 950 * Set while we are running a voice interaction. This overrides 951 * sleeping while it is active. 952 */ 953 private boolean mRunningVoice = false; 954 955 /** 956 * State of external calls telling us if the device is asleep. 957 */ 958 private boolean mWentToSleep = false; 959 960 static final int LOCK_SCREEN_HIDDEN = 0; 961 static final int LOCK_SCREEN_LEAVING = 1; 962 static final int LOCK_SCREEN_SHOWN = 2; 963 /** 964 * State of external call telling us if the lock screen is shown. 965 */ 966 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 967 968 /** 969 * Set if we are shutting down the system, similar to sleeping. 970 */ 971 boolean mShuttingDown = false; 972 973 /** 974 * Current sequence id for oom_adj computation traversal. 975 */ 976 int mAdjSeq = 0; 977 978 /** 979 * Current sequence id for process LRU updating. 980 */ 981 int mLruSeq = 0; 982 983 /** 984 * Keep track of the non-cached/empty process we last found, to help 985 * determine how to distribute cached/empty processes next time. 986 */ 987 int mNumNonCachedProcs = 0; 988 989 /** 990 * Keep track of the number of cached hidden procs, to balance oom adj 991 * distribution between those and empty procs. 992 */ 993 int mNumCachedHiddenProcs = 0; 994 995 /** 996 * Keep track of the number of service processes we last found, to 997 * determine on the next iteration which should be B services. 998 */ 999 int mNumServiceProcs = 0; 1000 int mNewNumAServiceProcs = 0; 1001 int mNewNumServiceProcs = 0; 1002 1003 /** 1004 * Allow the current computed overall memory level of the system to go down? 1005 * This is set to false when we are killing processes for reasons other than 1006 * memory management, so that the now smaller process list will not be taken as 1007 * an indication that memory is tighter. 1008 */ 1009 boolean mAllowLowerMemLevel = false; 1010 1011 /** 1012 * The last computed memory level, for holding when we are in a state that 1013 * processes are going away for other reasons. 1014 */ 1015 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1016 1017 /** 1018 * The last total number of process we have, to determine if changes actually look 1019 * like a shrinking number of process due to lower RAM. 1020 */ 1021 int mLastNumProcesses; 1022 1023 /** 1024 * The uptime of the last time we performed idle maintenance. 1025 */ 1026 long mLastIdleTime = SystemClock.uptimeMillis(); 1027 1028 /** 1029 * Total time spent with RAM that has been added in the past since the last idle time. 1030 */ 1031 long mLowRamTimeSinceLastIdle = 0; 1032 1033 /** 1034 * If RAM is currently low, when that horrible situation started. 1035 */ 1036 long mLowRamStartTime = 0; 1037 1038 /** 1039 * For reporting to battery stats the current top application. 1040 */ 1041 private String mCurResumedPackage = null; 1042 private int mCurResumedUid = -1; 1043 1044 /** 1045 * For reporting to battery stats the apps currently running foreground 1046 * service. The ProcessMap is package/uid tuples; each of these contain 1047 * an array of the currently foreground processes. 1048 */ 1049 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1050 = new ProcessMap<ArrayList<ProcessRecord>>(); 1051 1052 /** 1053 * This is set if we had to do a delayed dexopt of an app before launching 1054 * it, to increase the ANR timeouts in that case. 1055 */ 1056 boolean mDidDexOpt; 1057 1058 /** 1059 * Set if the systemServer made a call to enterSafeMode. 1060 */ 1061 boolean mSafeMode; 1062 1063 String mDebugApp = null; 1064 boolean mWaitForDebugger = false; 1065 boolean mDebugTransient = false; 1066 String mOrigDebugApp = null; 1067 boolean mOrigWaitForDebugger = false; 1068 boolean mAlwaysFinishActivities = false; 1069 IActivityController mController = null; 1070 String mProfileApp = null; 1071 ProcessRecord mProfileProc = null; 1072 String mProfileFile; 1073 ParcelFileDescriptor mProfileFd; 1074 int mSamplingInterval = 0; 1075 boolean mAutoStopProfiler = false; 1076 int mProfileType = 0; 1077 String mOpenGlTraceApp = null; 1078 1079 static class ProcessChangeItem { 1080 static final int CHANGE_ACTIVITIES = 1<<0; 1081 static final int CHANGE_PROCESS_STATE = 1<<1; 1082 int changes; 1083 int uid; 1084 int pid; 1085 int processState; 1086 boolean foregroundActivities; 1087 } 1088 1089 final RemoteCallbackList<IProcessObserver> mProcessObservers 1090 = new RemoteCallbackList<IProcessObserver>(); 1091 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1092 1093 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1094 = new ArrayList<ProcessChangeItem>(); 1095 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1096 = new ArrayList<ProcessChangeItem>(); 1097 1098 /** 1099 * Runtime CPU use collection thread. This object's lock is used to 1100 * perform synchronization with the thread (notifying it to run). 1101 */ 1102 final Thread mProcessCpuThread; 1103 1104 /** 1105 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1106 * Must acquire this object's lock when accessing it. 1107 * NOTE: this lock will be held while doing long operations (trawling 1108 * through all processes in /proc), so it should never be acquired by 1109 * any critical paths such as when holding the main activity manager lock. 1110 */ 1111 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1112 MONITOR_THREAD_CPU_USAGE); 1113 final AtomicLong mLastCpuTime = new AtomicLong(0); 1114 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1115 1116 long mLastWriteTime = 0; 1117 1118 /** 1119 * Used to retain an update lock when the foreground activity is in 1120 * immersive mode. 1121 */ 1122 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1123 1124 /** 1125 * Set to true after the system has finished booting. 1126 */ 1127 boolean mBooted = false; 1128 1129 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1130 int mProcessLimitOverride = -1; 1131 1132 WindowManagerService mWindowManager; 1133 1134 final ActivityThread mSystemThread; 1135 1136 // Holds the current foreground user's id 1137 int mCurrentUserId = 0; 1138 // Holds the target user's id during a user switch 1139 int mTargetUserId = UserHandle.USER_NULL; 1140 // If there are multiple profiles for the current user, their ids are here 1141 // Currently only the primary user can have managed profiles 1142 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1143 1144 /** 1145 * Mapping from each known user ID to the profile group ID it is associated with. 1146 */ 1147 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1148 1149 private UserManagerService mUserManager; 1150 1151 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1152 final ProcessRecord mApp; 1153 final int mPid; 1154 final IApplicationThread mAppThread; 1155 1156 AppDeathRecipient(ProcessRecord app, int pid, 1157 IApplicationThread thread) { 1158 if (localLOGV) Slog.v( 1159 TAG, "New death recipient " + this 1160 + " for thread " + thread.asBinder()); 1161 mApp = app; 1162 mPid = pid; 1163 mAppThread = thread; 1164 } 1165 1166 @Override 1167 public void binderDied() { 1168 if (localLOGV) Slog.v( 1169 TAG, "Death received in " + this 1170 + " for thread " + mAppThread.asBinder()); 1171 synchronized(ActivityManagerService.this) { 1172 appDiedLocked(mApp, mPid, mAppThread); 1173 } 1174 } 1175 } 1176 1177 static final int SHOW_ERROR_MSG = 1; 1178 static final int SHOW_NOT_RESPONDING_MSG = 2; 1179 static final int SHOW_FACTORY_ERROR_MSG = 3; 1180 static final int UPDATE_CONFIGURATION_MSG = 4; 1181 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1182 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1183 static final int SERVICE_TIMEOUT_MSG = 12; 1184 static final int UPDATE_TIME_ZONE = 13; 1185 static final int SHOW_UID_ERROR_MSG = 14; 1186 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1187 static final int PROC_START_TIMEOUT_MSG = 20; 1188 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1189 static final int KILL_APPLICATION_MSG = 22; 1190 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1191 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1192 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1193 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1194 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1195 static final int CLEAR_DNS_CACHE_MSG = 28; 1196 static final int UPDATE_HTTP_PROXY_MSG = 29; 1197 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1198 static final int DISPATCH_PROCESSES_CHANGED = 31; 1199 static final int DISPATCH_PROCESS_DIED = 32; 1200 static final int REPORT_MEM_USAGE_MSG = 33; 1201 static final int REPORT_USER_SWITCH_MSG = 34; 1202 static final int CONTINUE_USER_SWITCH_MSG = 35; 1203 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1204 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1205 static final int PERSIST_URI_GRANTS_MSG = 38; 1206 static final int REQUEST_ALL_PSS_MSG = 39; 1207 static final int START_PROFILES_MSG = 40; 1208 static final int UPDATE_TIME = 41; 1209 static final int SYSTEM_USER_START_MSG = 42; 1210 static final int SYSTEM_USER_CURRENT_MSG = 43; 1211 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1212 static final int FINISH_BOOTING_MSG = 45; 1213 static final int START_USER_SWITCH_MSG = 46; 1214 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1215 static final int DISMISS_DIALOG_MSG = 48; 1216 1217 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1218 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1219 static final int FIRST_COMPAT_MODE_MSG = 300; 1220 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1221 1222 CompatModeDialog mCompatModeDialog; 1223 long mLastMemUsageReportTime = 0; 1224 1225 /** 1226 * Flag whether the current user is a "monkey", i.e. whether 1227 * the UI is driven by a UI automation tool. 1228 */ 1229 private boolean mUserIsMonkey; 1230 1231 /** Flag whether the device has a Recents UI */ 1232 boolean mHasRecents; 1233 1234 /** The dimensions of the thumbnails in the Recents UI. */ 1235 int mThumbnailWidth; 1236 int mThumbnailHeight; 1237 1238 final ServiceThread mHandlerThread; 1239 final MainHandler mHandler; 1240 1241 final class MainHandler extends Handler { 1242 public MainHandler(Looper looper) { 1243 super(looper, null, true); 1244 } 1245 1246 @Override 1247 public void handleMessage(Message msg) { 1248 switch (msg.what) { 1249 case SHOW_ERROR_MSG: { 1250 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1251 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1252 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1253 synchronized (ActivityManagerService.this) { 1254 ProcessRecord proc = (ProcessRecord)data.get("app"); 1255 AppErrorResult res = (AppErrorResult) data.get("result"); 1256 if (proc != null && proc.crashDialog != null) { 1257 Slog.e(TAG, "App already has crash dialog: " + proc); 1258 if (res != null) { 1259 res.set(0); 1260 } 1261 return; 1262 } 1263 boolean isBackground = (UserHandle.getAppId(proc.uid) 1264 >= Process.FIRST_APPLICATION_UID 1265 && proc.pid != MY_PID); 1266 for (int userId : mCurrentProfileIds) { 1267 isBackground &= (proc.userId != userId); 1268 } 1269 if (isBackground && !showBackground) { 1270 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1271 if (res != null) { 1272 res.set(0); 1273 } 1274 return; 1275 } 1276 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1277 Dialog d = new AppErrorDialog(mContext, 1278 ActivityManagerService.this, res, proc); 1279 d.show(); 1280 proc.crashDialog = d; 1281 } else { 1282 // The device is asleep, so just pretend that the user 1283 // saw a crash dialog and hit "force quit". 1284 if (res != null) { 1285 res.set(0); 1286 } 1287 } 1288 } 1289 1290 ensureBootCompleted(); 1291 } break; 1292 case SHOW_NOT_RESPONDING_MSG: { 1293 synchronized (ActivityManagerService.this) { 1294 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1295 ProcessRecord proc = (ProcessRecord)data.get("app"); 1296 if (proc != null && proc.anrDialog != null) { 1297 Slog.e(TAG, "App already has anr dialog: " + proc); 1298 return; 1299 } 1300 1301 Intent intent = new Intent("android.intent.action.ANR"); 1302 if (!mProcessesReady) { 1303 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1304 | Intent.FLAG_RECEIVER_FOREGROUND); 1305 } 1306 broadcastIntentLocked(null, null, intent, 1307 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1308 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1309 1310 if (mShowDialogs) { 1311 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1312 mContext, proc, (ActivityRecord)data.get("activity"), 1313 msg.arg1 != 0); 1314 d.show(); 1315 proc.anrDialog = d; 1316 } else { 1317 // Just kill the app if there is no dialog to be shown. 1318 killAppAtUsersRequest(proc, null); 1319 } 1320 } 1321 1322 ensureBootCompleted(); 1323 } break; 1324 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1325 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1326 synchronized (ActivityManagerService.this) { 1327 ProcessRecord proc = (ProcessRecord) data.get("app"); 1328 if (proc == null) { 1329 Slog.e(TAG, "App not found when showing strict mode dialog."); 1330 break; 1331 } 1332 if (proc.crashDialog != null) { 1333 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1334 return; 1335 } 1336 AppErrorResult res = (AppErrorResult) data.get("result"); 1337 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1338 Dialog d = new StrictModeViolationDialog(mContext, 1339 ActivityManagerService.this, res, proc); 1340 d.show(); 1341 proc.crashDialog = d; 1342 } else { 1343 // The device is asleep, so just pretend that the user 1344 // saw a crash dialog and hit "force quit". 1345 res.set(0); 1346 } 1347 } 1348 ensureBootCompleted(); 1349 } break; 1350 case SHOW_FACTORY_ERROR_MSG: { 1351 Dialog d = new FactoryErrorDialog( 1352 mContext, msg.getData().getCharSequence("msg")); 1353 d.show(); 1354 ensureBootCompleted(); 1355 } break; 1356 case UPDATE_CONFIGURATION_MSG: { 1357 final ContentResolver resolver = mContext.getContentResolver(); 1358 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1359 } break; 1360 case GC_BACKGROUND_PROCESSES_MSG: { 1361 synchronized (ActivityManagerService.this) { 1362 performAppGcsIfAppropriateLocked(); 1363 } 1364 } break; 1365 case WAIT_FOR_DEBUGGER_MSG: { 1366 synchronized (ActivityManagerService.this) { 1367 ProcessRecord app = (ProcessRecord)msg.obj; 1368 if (msg.arg1 != 0) { 1369 if (!app.waitedForDebugger) { 1370 Dialog d = new AppWaitingForDebuggerDialog( 1371 ActivityManagerService.this, 1372 mContext, app); 1373 app.waitDialog = d; 1374 app.waitedForDebugger = true; 1375 d.show(); 1376 } 1377 } else { 1378 if (app.waitDialog != null) { 1379 app.waitDialog.dismiss(); 1380 app.waitDialog = null; 1381 } 1382 } 1383 } 1384 } break; 1385 case SERVICE_TIMEOUT_MSG: { 1386 if (mDidDexOpt) { 1387 mDidDexOpt = false; 1388 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1389 nmsg.obj = msg.obj; 1390 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1391 return; 1392 } 1393 mServices.serviceTimeout((ProcessRecord)msg.obj); 1394 } break; 1395 case UPDATE_TIME_ZONE: { 1396 synchronized (ActivityManagerService.this) { 1397 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1398 ProcessRecord r = mLruProcesses.get(i); 1399 if (r.thread != null) { 1400 try { 1401 r.thread.updateTimeZone(); 1402 } catch (RemoteException ex) { 1403 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1404 } 1405 } 1406 } 1407 } 1408 } break; 1409 case CLEAR_DNS_CACHE_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1412 ProcessRecord r = mLruProcesses.get(i); 1413 if (r.thread != null) { 1414 try { 1415 r.thread.clearDnsCache(); 1416 } catch (RemoteException ex) { 1417 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1418 } 1419 } 1420 } 1421 } 1422 } break; 1423 case UPDATE_HTTP_PROXY_MSG: { 1424 ProxyInfo proxy = (ProxyInfo)msg.obj; 1425 String host = ""; 1426 String port = ""; 1427 String exclList = ""; 1428 Uri pacFileUrl = Uri.EMPTY; 1429 if (proxy != null) { 1430 host = proxy.getHost(); 1431 port = Integer.toString(proxy.getPort()); 1432 exclList = proxy.getExclusionListAsString(); 1433 pacFileUrl = proxy.getPacFileUrl(); 1434 } 1435 synchronized (ActivityManagerService.this) { 1436 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1437 ProcessRecord r = mLruProcesses.get(i); 1438 if (r.thread != null) { 1439 try { 1440 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1441 } catch (RemoteException ex) { 1442 Slog.w(TAG, "Failed to update http proxy for: " + 1443 r.info.processName); 1444 } 1445 } 1446 } 1447 } 1448 } break; 1449 case SHOW_UID_ERROR_MSG: { 1450 if (mShowDialogs) { 1451 AlertDialog d = new BaseErrorDialog(mContext); 1452 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1453 d.setCancelable(false); 1454 d.setTitle(mContext.getText(R.string.android_system_label)); 1455 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1456 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1457 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1458 d.show(); 1459 } 1460 } break; 1461 case SHOW_FINGERPRINT_ERROR_MSG: { 1462 if (mShowDialogs) { 1463 AlertDialog d = new BaseErrorDialog(mContext); 1464 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1465 d.setCancelable(false); 1466 d.setTitle(mContext.getText(R.string.android_system_label)); 1467 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1468 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1469 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1470 d.show(); 1471 } 1472 } break; 1473 case PROC_START_TIMEOUT_MSG: { 1474 if (mDidDexOpt) { 1475 mDidDexOpt = false; 1476 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1477 nmsg.obj = msg.obj; 1478 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1479 return; 1480 } 1481 ProcessRecord app = (ProcessRecord)msg.obj; 1482 synchronized (ActivityManagerService.this) { 1483 processStartTimedOutLocked(app); 1484 } 1485 } break; 1486 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1487 synchronized (ActivityManagerService.this) { 1488 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1489 } 1490 } break; 1491 case KILL_APPLICATION_MSG: { 1492 synchronized (ActivityManagerService.this) { 1493 int appid = msg.arg1; 1494 boolean restart = (msg.arg2 == 1); 1495 Bundle bundle = (Bundle)msg.obj; 1496 String pkg = bundle.getString("pkg"); 1497 String reason = bundle.getString("reason"); 1498 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1499 false, UserHandle.USER_ALL, reason); 1500 } 1501 } break; 1502 case FINALIZE_PENDING_INTENT_MSG: { 1503 ((PendingIntentRecord)msg.obj).completeFinalize(); 1504 } break; 1505 case POST_HEAVY_NOTIFICATION_MSG: { 1506 INotificationManager inm = NotificationManager.getService(); 1507 if (inm == null) { 1508 return; 1509 } 1510 1511 ActivityRecord root = (ActivityRecord)msg.obj; 1512 ProcessRecord process = root.app; 1513 if (process == null) { 1514 return; 1515 } 1516 1517 try { 1518 Context context = mContext.createPackageContext(process.info.packageName, 0); 1519 String text = mContext.getString(R.string.heavy_weight_notification, 1520 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1521 Notification notification = new Notification(); 1522 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1523 notification.when = 0; 1524 notification.flags = Notification.FLAG_ONGOING_EVENT; 1525 notification.tickerText = text; 1526 notification.defaults = 0; // please be quiet 1527 notification.sound = null; 1528 notification.vibrate = null; 1529 notification.color = mContext.getResources().getColor( 1530 com.android.internal.R.color.system_notification_accent_color); 1531 notification.setLatestEventInfo(context, text, 1532 mContext.getText(R.string.heavy_weight_notification_detail), 1533 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1534 PendingIntent.FLAG_CANCEL_CURRENT, null, 1535 new UserHandle(root.userId))); 1536 1537 try { 1538 int[] outId = new int[1]; 1539 inm.enqueueNotificationWithTag("android", "android", null, 1540 R.string.heavy_weight_notification, 1541 notification, outId, root.userId); 1542 } catch (RuntimeException e) { 1543 Slog.w(ActivityManagerService.TAG, 1544 "Error showing notification for heavy-weight app", e); 1545 } catch (RemoteException e) { 1546 } 1547 } catch (NameNotFoundException e) { 1548 Slog.w(TAG, "Unable to create context for heavy notification", e); 1549 } 1550 } break; 1551 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1552 INotificationManager inm = NotificationManager.getService(); 1553 if (inm == null) { 1554 return; 1555 } 1556 try { 1557 inm.cancelNotificationWithTag("android", null, 1558 R.string.heavy_weight_notification, msg.arg1); 1559 } catch (RuntimeException e) { 1560 Slog.w(ActivityManagerService.TAG, 1561 "Error canceling notification for service", e); 1562 } catch (RemoteException e) { 1563 } 1564 } break; 1565 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1566 synchronized (ActivityManagerService.this) { 1567 checkExcessivePowerUsageLocked(true); 1568 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1569 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1570 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1571 } 1572 } break; 1573 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1574 synchronized (ActivityManagerService.this) { 1575 ActivityRecord ar = (ActivityRecord)msg.obj; 1576 if (mCompatModeDialog != null) { 1577 if (mCompatModeDialog.mAppInfo.packageName.equals( 1578 ar.info.applicationInfo.packageName)) { 1579 return; 1580 } 1581 mCompatModeDialog.dismiss(); 1582 mCompatModeDialog = null; 1583 } 1584 if (ar != null && false) { 1585 if (mCompatModePackages.getPackageAskCompatModeLocked( 1586 ar.packageName)) { 1587 int mode = mCompatModePackages.computeCompatModeLocked( 1588 ar.info.applicationInfo); 1589 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1590 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1591 mCompatModeDialog = new CompatModeDialog( 1592 ActivityManagerService.this, mContext, 1593 ar.info.applicationInfo); 1594 mCompatModeDialog.show(); 1595 } 1596 } 1597 } 1598 } 1599 break; 1600 } 1601 case DISPATCH_PROCESSES_CHANGED: { 1602 dispatchProcessesChanged(); 1603 break; 1604 } 1605 case DISPATCH_PROCESS_DIED: { 1606 final int pid = msg.arg1; 1607 final int uid = msg.arg2; 1608 dispatchProcessDied(pid, uid); 1609 break; 1610 } 1611 case REPORT_MEM_USAGE_MSG: { 1612 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1613 Thread thread = new Thread() { 1614 @Override public void run() { 1615 reportMemUsage(memInfos); 1616 } 1617 }; 1618 thread.start(); 1619 break; 1620 } 1621 case START_USER_SWITCH_MSG: { 1622 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1623 break; 1624 } 1625 case REPORT_USER_SWITCH_MSG: { 1626 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1627 break; 1628 } 1629 case CONTINUE_USER_SWITCH_MSG: { 1630 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1631 break; 1632 } 1633 case USER_SWITCH_TIMEOUT_MSG: { 1634 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1635 break; 1636 } 1637 case IMMERSIVE_MODE_LOCK_MSG: { 1638 final boolean nextState = (msg.arg1 != 0); 1639 if (mUpdateLock.isHeld() != nextState) { 1640 if (DEBUG_IMMERSIVE) { 1641 final ActivityRecord r = (ActivityRecord) msg.obj; 1642 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1643 } 1644 if (nextState) { 1645 mUpdateLock.acquire(); 1646 } else { 1647 mUpdateLock.release(); 1648 } 1649 } 1650 break; 1651 } 1652 case PERSIST_URI_GRANTS_MSG: { 1653 writeGrantedUriPermissions(); 1654 break; 1655 } 1656 case REQUEST_ALL_PSS_MSG: { 1657 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1658 break; 1659 } 1660 case START_PROFILES_MSG: { 1661 synchronized (ActivityManagerService.this) { 1662 startProfilesLocked(); 1663 } 1664 break; 1665 } 1666 case UPDATE_TIME: { 1667 synchronized (ActivityManagerService.this) { 1668 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1669 ProcessRecord r = mLruProcesses.get(i); 1670 if (r.thread != null) { 1671 try { 1672 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1673 } catch (RemoteException ex) { 1674 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1675 } 1676 } 1677 } 1678 } 1679 break; 1680 } 1681 case SYSTEM_USER_START_MSG: { 1682 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1683 Integer.toString(msg.arg1), msg.arg1); 1684 mSystemServiceManager.startUser(msg.arg1); 1685 break; 1686 } 1687 case SYSTEM_USER_CURRENT_MSG: { 1688 mBatteryStatsService.noteEvent( 1689 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1690 Integer.toString(msg.arg2), msg.arg2); 1691 mBatteryStatsService.noteEvent( 1692 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1693 Integer.toString(msg.arg1), msg.arg1); 1694 mSystemServiceManager.switchUser(msg.arg1); 1695 break; 1696 } 1697 case ENTER_ANIMATION_COMPLETE_MSG: { 1698 synchronized (ActivityManagerService.this) { 1699 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1700 if (r != null && r.app != null && r.app.thread != null) { 1701 try { 1702 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1703 } catch (RemoteException e) { 1704 } 1705 } 1706 } 1707 break; 1708 } 1709 case FINISH_BOOTING_MSG: { 1710 if (msg.arg1 != 0) { 1711 finishBooting(); 1712 } 1713 if (msg.arg2 != 0) { 1714 enableScreenAfterBoot(); 1715 } 1716 break; 1717 } 1718 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1719 try { 1720 Locale l = (Locale) msg.obj; 1721 IBinder service = ServiceManager.getService("mount"); 1722 IMountService mountService = IMountService.Stub.asInterface(service); 1723 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1724 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1725 } catch (RemoteException e) { 1726 Log.e(TAG, "Error storing locale for decryption UI", e); 1727 } 1728 break; 1729 } 1730 case DISMISS_DIALOG_MSG: { 1731 final Dialog d = (Dialog) msg.obj; 1732 d.dismiss(); 1733 break; 1734 } 1735 } 1736 } 1737 }; 1738 1739 static final int COLLECT_PSS_BG_MSG = 1; 1740 1741 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1742 @Override 1743 public void handleMessage(Message msg) { 1744 switch (msg.what) { 1745 case COLLECT_PSS_BG_MSG: { 1746 long start = SystemClock.uptimeMillis(); 1747 MemInfoReader memInfo = null; 1748 synchronized (ActivityManagerService.this) { 1749 if (mFullPssPending) { 1750 mFullPssPending = false; 1751 memInfo = new MemInfoReader(); 1752 } 1753 } 1754 if (memInfo != null) { 1755 updateCpuStatsNow(); 1756 long nativeTotalPss = 0; 1757 synchronized (mProcessCpuTracker) { 1758 final int N = mProcessCpuTracker.countStats(); 1759 for (int j=0; j<N; j++) { 1760 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1761 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1762 // This is definitely an application process; skip it. 1763 continue; 1764 } 1765 synchronized (mPidsSelfLocked) { 1766 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1767 // This is one of our own processes; skip it. 1768 continue; 1769 } 1770 } 1771 nativeTotalPss += Debug.getPss(st.pid, null); 1772 } 1773 } 1774 memInfo.readMemInfo(); 1775 synchronized (ActivityManagerService.this) { 1776 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1777 + (SystemClock.uptimeMillis()-start) + "ms"); 1778 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1779 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1780 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1781 } 1782 } 1783 1784 int i = 0; 1785 int num = 0; 1786 long[] tmp = new long[1]; 1787 do { 1788 ProcessRecord proc; 1789 int procState; 1790 int pid; 1791 synchronized (ActivityManagerService.this) { 1792 if (i >= mPendingPssProcesses.size()) { 1793 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1794 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1795 mPendingPssProcesses.clear(); 1796 return; 1797 } 1798 proc = mPendingPssProcesses.get(i); 1799 procState = proc.pssProcState; 1800 if (proc.thread != null && procState == proc.setProcState) { 1801 pid = proc.pid; 1802 } else { 1803 proc = null; 1804 pid = 0; 1805 } 1806 i++; 1807 } 1808 if (proc != null) { 1809 long pss = Debug.getPss(pid, tmp); 1810 synchronized (ActivityManagerService.this) { 1811 if (proc.thread != null && proc.setProcState == procState 1812 && proc.pid == pid) { 1813 num++; 1814 proc.lastPssTime = SystemClock.uptimeMillis(); 1815 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1816 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1817 + ": " + pss + " lastPss=" + proc.lastPss 1818 + " state=" + ProcessList.makeProcStateString(procState)); 1819 if (proc.initialIdlePss == 0) { 1820 proc.initialIdlePss = pss; 1821 } 1822 proc.lastPss = pss; 1823 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1824 proc.lastCachedPss = pss; 1825 } 1826 } 1827 } 1828 } 1829 } while (true); 1830 } 1831 } 1832 } 1833 }; 1834 1835 /** 1836 * Monitor for package changes and update our internal state. 1837 */ 1838 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1839 @Override 1840 public void onPackageRemoved(String packageName, int uid) { 1841 // Remove all tasks with activities in the specified package from the list of recent tasks 1842 final int eventUserId = getChangingUserId(); 1843 synchronized (ActivityManagerService.this) { 1844 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1845 TaskRecord tr = mRecentTasks.get(i); 1846 if (tr.userId != eventUserId) continue; 1847 1848 ComponentName cn = tr.intent.getComponent(); 1849 if (cn != null && cn.getPackageName().equals(packageName)) { 1850 // If the package name matches, remove the task 1851 removeTaskByIdLocked(tr.taskId, true); 1852 } 1853 } 1854 } 1855 } 1856 1857 @Override 1858 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1859 onPackageModified(packageName); 1860 return true; 1861 } 1862 1863 @Override 1864 public void onPackageModified(String packageName) { 1865 final int eventUserId = getChangingUserId(); 1866 final IPackageManager pm = AppGlobals.getPackageManager(); 1867 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1868 new ArrayList<Pair<Intent, Integer>>(); 1869 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1870 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1871 // Copy the list of recent tasks so that we don't hold onto the lock on 1872 // ActivityManagerService for long periods while checking if components exist. 1873 synchronized (ActivityManagerService.this) { 1874 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1875 TaskRecord tr = mRecentTasks.get(i); 1876 if (tr.userId != eventUserId) continue; 1877 1878 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1879 } 1880 } 1881 // Check the recent tasks and filter out all tasks with components that no longer exist. 1882 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1883 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1884 ComponentName cn = p.first.getComponent(); 1885 if (cn != null && cn.getPackageName().equals(packageName)) { 1886 if (componentsKnownToExist.contains(cn)) { 1887 // If we know that the component still exists in the package, then skip 1888 continue; 1889 } 1890 try { 1891 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1892 if (info != null) { 1893 componentsKnownToExist.add(cn); 1894 } else { 1895 tasksToRemove.add(p.second); 1896 } 1897 } catch (RemoteException e) { 1898 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1899 } 1900 } 1901 } 1902 // Prune all the tasks with removed components from the list of recent tasks 1903 synchronized (ActivityManagerService.this) { 1904 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1905 removeTaskByIdLocked(tasksToRemove.get(i), false); 1906 } 1907 } 1908 } 1909 1910 @Override 1911 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1912 // Force stop the specified packages 1913 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1914 if (packages != null) { 1915 for (String pkg : packages) { 1916 synchronized (ActivityManagerService.this) { 1917 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1918 userId, "finished booting")) { 1919 return true; 1920 } 1921 } 1922 } 1923 } 1924 return false; 1925 } 1926 }; 1927 1928 public void setSystemProcess() { 1929 try { 1930 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1931 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1932 ServiceManager.addService("meminfo", new MemBinder(this)); 1933 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1934 ServiceManager.addService("dbinfo", new DbBinder(this)); 1935 if (MONITOR_CPU_USAGE) { 1936 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1937 } 1938 ServiceManager.addService("permission", new PermissionController(this)); 1939 1940 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1941 "android", STOCK_PM_FLAGS); 1942 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1943 1944 synchronized (this) { 1945 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1946 app.persistent = true; 1947 app.pid = MY_PID; 1948 app.maxAdj = ProcessList.SYSTEM_ADJ; 1949 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1950 mProcessNames.put(app.processName, app.uid, app); 1951 synchronized (mPidsSelfLocked) { 1952 mPidsSelfLocked.put(app.pid, app); 1953 } 1954 updateLruProcessLocked(app, false, null); 1955 updateOomAdjLocked(); 1956 } 1957 } catch (PackageManager.NameNotFoundException e) { 1958 throw new RuntimeException( 1959 "Unable to find android system package", e); 1960 } 1961 } 1962 1963 public void setWindowManager(WindowManagerService wm) { 1964 mWindowManager = wm; 1965 mStackSupervisor.setWindowManager(wm); 1966 } 1967 1968 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1969 mUsageStatsService = usageStatsManager; 1970 } 1971 1972 public void startObservingNativeCrashes() { 1973 final NativeCrashListener ncl = new NativeCrashListener(this); 1974 ncl.start(); 1975 } 1976 1977 public IAppOpsService getAppOpsService() { 1978 return mAppOpsService; 1979 } 1980 1981 static class MemBinder extends Binder { 1982 ActivityManagerService mActivityManagerService; 1983 MemBinder(ActivityManagerService activityManagerService) { 1984 mActivityManagerService = activityManagerService; 1985 } 1986 1987 @Override 1988 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1989 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1990 != PackageManager.PERMISSION_GRANTED) { 1991 pw.println("Permission Denial: can't dump meminfo from from pid=" 1992 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1993 + " without permission " + android.Manifest.permission.DUMP); 1994 return; 1995 } 1996 1997 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1998 } 1999 } 2000 2001 static class GraphicsBinder extends Binder { 2002 ActivityManagerService mActivityManagerService; 2003 GraphicsBinder(ActivityManagerService activityManagerService) { 2004 mActivityManagerService = activityManagerService; 2005 } 2006 2007 @Override 2008 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2009 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2010 != PackageManager.PERMISSION_GRANTED) { 2011 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2012 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2013 + " without permission " + android.Manifest.permission.DUMP); 2014 return; 2015 } 2016 2017 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2018 } 2019 } 2020 2021 static class DbBinder extends Binder { 2022 ActivityManagerService mActivityManagerService; 2023 DbBinder(ActivityManagerService activityManagerService) { 2024 mActivityManagerService = activityManagerService; 2025 } 2026 2027 @Override 2028 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2029 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2030 != PackageManager.PERMISSION_GRANTED) { 2031 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2032 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2033 + " without permission " + android.Manifest.permission.DUMP); 2034 return; 2035 } 2036 2037 mActivityManagerService.dumpDbInfo(fd, pw, args); 2038 } 2039 } 2040 2041 static class CpuBinder extends Binder { 2042 ActivityManagerService mActivityManagerService; 2043 CpuBinder(ActivityManagerService activityManagerService) { 2044 mActivityManagerService = activityManagerService; 2045 } 2046 2047 @Override 2048 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2049 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2050 != PackageManager.PERMISSION_GRANTED) { 2051 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2052 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2053 + " without permission " + android.Manifest.permission.DUMP); 2054 return; 2055 } 2056 2057 synchronized (mActivityManagerService.mProcessCpuTracker) { 2058 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2059 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2060 SystemClock.uptimeMillis())); 2061 } 2062 } 2063 } 2064 2065 public static final class Lifecycle extends SystemService { 2066 private final ActivityManagerService mService; 2067 2068 public Lifecycle(Context context) { 2069 super(context); 2070 mService = new ActivityManagerService(context); 2071 } 2072 2073 @Override 2074 public void onStart() { 2075 mService.start(); 2076 } 2077 2078 public ActivityManagerService getService() { 2079 return mService; 2080 } 2081 } 2082 2083 // Note: This method is invoked on the main thread but may need to attach various 2084 // handlers to other threads. So take care to be explicit about the looper. 2085 public ActivityManagerService(Context systemContext) { 2086 mContext = systemContext; 2087 mFactoryTest = FactoryTest.getMode(); 2088 mSystemThread = ActivityThread.currentActivityThread(); 2089 2090 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2091 2092 mHandlerThread = new ServiceThread(TAG, 2093 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2094 mHandlerThread.start(); 2095 mHandler = new MainHandler(mHandlerThread.getLooper()); 2096 2097 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2098 "foreground", BROADCAST_FG_TIMEOUT, false); 2099 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2100 "background", BROADCAST_BG_TIMEOUT, true); 2101 mBroadcastQueues[0] = mFgBroadcastQueue; 2102 mBroadcastQueues[1] = mBgBroadcastQueue; 2103 2104 mServices = new ActiveServices(this); 2105 mProviderMap = new ProviderMap(this); 2106 2107 // TODO: Move creation of battery stats service outside of activity manager service. 2108 File dataDir = Environment.getDataDirectory(); 2109 File systemDir = new File(dataDir, "system"); 2110 systemDir.mkdirs(); 2111 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2112 mBatteryStatsService.getActiveStatistics().readLocked(); 2113 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2114 mOnBattery = DEBUG_POWER ? true 2115 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2116 mBatteryStatsService.getActiveStatistics().setCallback(this); 2117 2118 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2119 2120 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2121 2122 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2123 2124 // User 0 is the first and only user that runs at boot. 2125 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2126 mUserLru.add(Integer.valueOf(0)); 2127 updateStartedUserArrayLocked(); 2128 2129 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2130 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2131 2132 mConfiguration.setToDefaults(); 2133 mConfiguration.setLocale(Locale.getDefault()); 2134 2135 mConfigurationSeq = mConfiguration.seq = 1; 2136 mProcessCpuTracker.init(); 2137 2138 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2139 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2140 mStackSupervisor = new ActivityStackSupervisor(this); 2141 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2142 2143 mProcessCpuThread = new Thread("CpuTracker") { 2144 @Override 2145 public void run() { 2146 while (true) { 2147 try { 2148 try { 2149 synchronized(this) { 2150 final long now = SystemClock.uptimeMillis(); 2151 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2152 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2153 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2154 // + ", write delay=" + nextWriteDelay); 2155 if (nextWriteDelay < nextCpuDelay) { 2156 nextCpuDelay = nextWriteDelay; 2157 } 2158 if (nextCpuDelay > 0) { 2159 mProcessCpuMutexFree.set(true); 2160 this.wait(nextCpuDelay); 2161 } 2162 } 2163 } catch (InterruptedException e) { 2164 } 2165 updateCpuStatsNow(); 2166 } catch (Exception e) { 2167 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2168 } 2169 } 2170 } 2171 }; 2172 2173 Watchdog.getInstance().addMonitor(this); 2174 Watchdog.getInstance().addThread(mHandler); 2175 } 2176 2177 public void setSystemServiceManager(SystemServiceManager mgr) { 2178 mSystemServiceManager = mgr; 2179 } 2180 2181 public void setInstaller(Installer installer) { 2182 mInstaller = installer; 2183 } 2184 2185 private void start() { 2186 Process.removeAllProcessGroups(); 2187 mProcessCpuThread.start(); 2188 2189 mBatteryStatsService.publish(mContext); 2190 mAppOpsService.publish(mContext); 2191 Slog.d("AppOps", "AppOpsService published"); 2192 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2193 } 2194 2195 public void initPowerManagement() { 2196 mStackSupervisor.initPowerManagement(); 2197 mBatteryStatsService.initPowerManagement(); 2198 } 2199 2200 @Override 2201 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2202 throws RemoteException { 2203 if (code == SYSPROPS_TRANSACTION) { 2204 // We need to tell all apps about the system property change. 2205 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2206 synchronized(this) { 2207 final int NP = mProcessNames.getMap().size(); 2208 for (int ip=0; ip<NP; ip++) { 2209 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2210 final int NA = apps.size(); 2211 for (int ia=0; ia<NA; ia++) { 2212 ProcessRecord app = apps.valueAt(ia); 2213 if (app.thread != null) { 2214 procs.add(app.thread.asBinder()); 2215 } 2216 } 2217 } 2218 } 2219 2220 int N = procs.size(); 2221 for (int i=0; i<N; i++) { 2222 Parcel data2 = Parcel.obtain(); 2223 try { 2224 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2225 } catch (RemoteException e) { 2226 } 2227 data2.recycle(); 2228 } 2229 } 2230 try { 2231 return super.onTransact(code, data, reply, flags); 2232 } catch (RuntimeException e) { 2233 // The activity manager only throws security exceptions, so let's 2234 // log all others. 2235 if (!(e instanceof SecurityException)) { 2236 Slog.wtf(TAG, "Activity Manager Crash", e); 2237 } 2238 throw e; 2239 } 2240 } 2241 2242 void updateCpuStats() { 2243 final long now = SystemClock.uptimeMillis(); 2244 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2245 return; 2246 } 2247 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2248 synchronized (mProcessCpuThread) { 2249 mProcessCpuThread.notify(); 2250 } 2251 } 2252 } 2253 2254 void updateCpuStatsNow() { 2255 synchronized (mProcessCpuTracker) { 2256 mProcessCpuMutexFree.set(false); 2257 final long now = SystemClock.uptimeMillis(); 2258 boolean haveNewCpuStats = false; 2259 2260 if (MONITOR_CPU_USAGE && 2261 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2262 mLastCpuTime.set(now); 2263 haveNewCpuStats = true; 2264 mProcessCpuTracker.update(); 2265 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2266 //Slog.i(TAG, "Total CPU usage: " 2267 // + mProcessCpu.getTotalCpuPercent() + "%"); 2268 2269 // Slog the cpu usage if the property is set. 2270 if ("true".equals(SystemProperties.get("events.cpu"))) { 2271 int user = mProcessCpuTracker.getLastUserTime(); 2272 int system = mProcessCpuTracker.getLastSystemTime(); 2273 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2274 int irq = mProcessCpuTracker.getLastIrqTime(); 2275 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2276 int idle = mProcessCpuTracker.getLastIdleTime(); 2277 2278 int total = user + system + iowait + irq + softIrq + idle; 2279 if (total == 0) total = 1; 2280 2281 EventLog.writeEvent(EventLogTags.CPU, 2282 ((user+system+iowait+irq+softIrq) * 100) / total, 2283 (user * 100) / total, 2284 (system * 100) / total, 2285 (iowait * 100) / total, 2286 (irq * 100) / total, 2287 (softIrq * 100) / total); 2288 } 2289 } 2290 2291 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2292 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2293 synchronized(bstats) { 2294 synchronized(mPidsSelfLocked) { 2295 if (haveNewCpuStats) { 2296 if (mOnBattery) { 2297 int perc = bstats.startAddingCpuLocked(); 2298 int totalUTime = 0; 2299 int totalSTime = 0; 2300 final int N = mProcessCpuTracker.countStats(); 2301 for (int i=0; i<N; i++) { 2302 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2303 if (!st.working) { 2304 continue; 2305 } 2306 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2307 int otherUTime = (st.rel_utime*perc)/100; 2308 int otherSTime = (st.rel_stime*perc)/100; 2309 totalUTime += otherUTime; 2310 totalSTime += otherSTime; 2311 if (pr != null) { 2312 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2313 if (ps == null || !ps.isActive()) { 2314 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2315 pr.info.uid, pr.processName); 2316 } 2317 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2318 st.rel_stime-otherSTime); 2319 ps.addSpeedStepTimes(cpuSpeedTimes); 2320 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2321 } else { 2322 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2323 if (ps == null || !ps.isActive()) { 2324 st.batteryStats = ps = bstats.getProcessStatsLocked( 2325 bstats.mapUid(st.uid), st.name); 2326 } 2327 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2328 st.rel_stime-otherSTime); 2329 ps.addSpeedStepTimes(cpuSpeedTimes); 2330 } 2331 } 2332 bstats.finishAddingCpuLocked(perc, totalUTime, 2333 totalSTime, cpuSpeedTimes); 2334 } 2335 } 2336 } 2337 2338 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2339 mLastWriteTime = now; 2340 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2341 } 2342 } 2343 } 2344 } 2345 2346 @Override 2347 public void batteryNeedsCpuUpdate() { 2348 updateCpuStatsNow(); 2349 } 2350 2351 @Override 2352 public void batteryPowerChanged(boolean onBattery) { 2353 // When plugging in, update the CPU stats first before changing 2354 // the plug state. 2355 updateCpuStatsNow(); 2356 synchronized (this) { 2357 synchronized(mPidsSelfLocked) { 2358 mOnBattery = DEBUG_POWER ? true : onBattery; 2359 } 2360 } 2361 } 2362 2363 /** 2364 * Initialize the application bind args. These are passed to each 2365 * process when the bindApplication() IPC is sent to the process. They're 2366 * lazily setup to make sure the services are running when they're asked for. 2367 */ 2368 private HashMap<String, IBinder> getCommonServicesLocked() { 2369 if (mAppBindArgs == null) { 2370 mAppBindArgs = new HashMap<String, IBinder>(); 2371 2372 // Setup the application init args 2373 mAppBindArgs.put("package", ServiceManager.getService("package")); 2374 mAppBindArgs.put("window", ServiceManager.getService("window")); 2375 mAppBindArgs.put(Context.ALARM_SERVICE, 2376 ServiceManager.getService(Context.ALARM_SERVICE)); 2377 } 2378 return mAppBindArgs; 2379 } 2380 2381 final void setFocusedActivityLocked(ActivityRecord r) { 2382 if (mFocusedActivity != r) { 2383 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2384 mFocusedActivity = r; 2385 if (r.task != null && r.task.voiceInteractor != null) { 2386 startRunningVoiceLocked(); 2387 } else { 2388 finishRunningVoiceLocked(); 2389 } 2390 mStackSupervisor.setFocusedStack(r); 2391 if (r != null) { 2392 mWindowManager.setFocusedApp(r.appToken, true); 2393 } 2394 applyUpdateLockStateLocked(r); 2395 } 2396 } 2397 2398 final void clearFocusedActivity(ActivityRecord r) { 2399 if (mFocusedActivity == r) { 2400 mFocusedActivity = null; 2401 } 2402 } 2403 2404 @Override 2405 public void setFocusedStack(int stackId) { 2406 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2407 synchronized (ActivityManagerService.this) { 2408 ActivityStack stack = mStackSupervisor.getStack(stackId); 2409 if (stack != null) { 2410 ActivityRecord r = stack.topRunningActivityLocked(null); 2411 if (r != null) { 2412 setFocusedActivityLocked(r); 2413 } 2414 } 2415 } 2416 } 2417 2418 @Override 2419 public void notifyActivityDrawn(IBinder token) { 2420 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2421 synchronized (this) { 2422 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2423 if (r != null) { 2424 r.task.stack.notifyActivityDrawnLocked(r); 2425 } 2426 } 2427 } 2428 2429 final void applyUpdateLockStateLocked(ActivityRecord r) { 2430 // Modifications to the UpdateLock state are done on our handler, outside 2431 // the activity manager's locks. The new state is determined based on the 2432 // state *now* of the relevant activity record. The object is passed to 2433 // the handler solely for logging detail, not to be consulted/modified. 2434 final boolean nextState = r != null && r.immersive; 2435 mHandler.sendMessage( 2436 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2437 } 2438 2439 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2440 Message msg = Message.obtain(); 2441 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2442 msg.obj = r.task.askedCompatMode ? null : r; 2443 mHandler.sendMessage(msg); 2444 } 2445 2446 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2447 String what, Object obj, ProcessRecord srcApp) { 2448 app.lastActivityTime = now; 2449 2450 if (app.activities.size() > 0) { 2451 // Don't want to touch dependent processes that are hosting activities. 2452 return index; 2453 } 2454 2455 int lrui = mLruProcesses.lastIndexOf(app); 2456 if (lrui < 0) { 2457 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2458 + what + " " + obj + " from " + srcApp); 2459 return index; 2460 } 2461 2462 if (lrui >= index) { 2463 // Don't want to cause this to move dependent processes *back* in the 2464 // list as if they were less frequently used. 2465 return index; 2466 } 2467 2468 if (lrui >= mLruProcessActivityStart) { 2469 // Don't want to touch dependent processes that are hosting activities. 2470 return index; 2471 } 2472 2473 mLruProcesses.remove(lrui); 2474 if (index > 0) { 2475 index--; 2476 } 2477 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2478 + " in LRU list: " + app); 2479 mLruProcesses.add(index, app); 2480 return index; 2481 } 2482 2483 final void removeLruProcessLocked(ProcessRecord app) { 2484 int lrui = mLruProcesses.lastIndexOf(app); 2485 if (lrui >= 0) { 2486 if (!app.killed) { 2487 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2488 Process.killProcessQuiet(app.pid); 2489 Process.killProcessGroup(app.info.uid, app.pid); 2490 } 2491 if (lrui <= mLruProcessActivityStart) { 2492 mLruProcessActivityStart--; 2493 } 2494 if (lrui <= mLruProcessServiceStart) { 2495 mLruProcessServiceStart--; 2496 } 2497 mLruProcesses.remove(lrui); 2498 } 2499 } 2500 2501 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2502 ProcessRecord client) { 2503 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2504 || app.treatLikeActivity; 2505 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2506 if (!activityChange && hasActivity) { 2507 // The process has activities, so we are only allowing activity-based adjustments 2508 // to move it. It should be kept in the front of the list with other 2509 // processes that have activities, and we don't want those to change their 2510 // order except due to activity operations. 2511 return; 2512 } 2513 2514 mLruSeq++; 2515 final long now = SystemClock.uptimeMillis(); 2516 app.lastActivityTime = now; 2517 2518 // First a quick reject: if the app is already at the position we will 2519 // put it, then there is nothing to do. 2520 if (hasActivity) { 2521 final int N = mLruProcesses.size(); 2522 if (N > 0 && mLruProcesses.get(N-1) == app) { 2523 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2524 return; 2525 } 2526 } else { 2527 if (mLruProcessServiceStart > 0 2528 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2529 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2530 return; 2531 } 2532 } 2533 2534 int lrui = mLruProcesses.lastIndexOf(app); 2535 2536 if (app.persistent && lrui >= 0) { 2537 // We don't care about the position of persistent processes, as long as 2538 // they are in the list. 2539 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2540 return; 2541 } 2542 2543 /* In progress: compute new position first, so we can avoid doing work 2544 if the process is not actually going to move. Not yet working. 2545 int addIndex; 2546 int nextIndex; 2547 boolean inActivity = false, inService = false; 2548 if (hasActivity) { 2549 // Process has activities, put it at the very tipsy-top. 2550 addIndex = mLruProcesses.size(); 2551 nextIndex = mLruProcessServiceStart; 2552 inActivity = true; 2553 } else if (hasService) { 2554 // Process has services, put it at the top of the service list. 2555 addIndex = mLruProcessActivityStart; 2556 nextIndex = mLruProcessServiceStart; 2557 inActivity = true; 2558 inService = true; 2559 } else { 2560 // Process not otherwise of interest, it goes to the top of the non-service area. 2561 addIndex = mLruProcessServiceStart; 2562 if (client != null) { 2563 int clientIndex = mLruProcesses.lastIndexOf(client); 2564 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2565 + app); 2566 if (clientIndex >= 0 && addIndex > clientIndex) { 2567 addIndex = clientIndex; 2568 } 2569 } 2570 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2571 } 2572 2573 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2574 + mLruProcessActivityStart + "): " + app); 2575 */ 2576 2577 if (lrui >= 0) { 2578 if (lrui < mLruProcessActivityStart) { 2579 mLruProcessActivityStart--; 2580 } 2581 if (lrui < mLruProcessServiceStart) { 2582 mLruProcessServiceStart--; 2583 } 2584 /* 2585 if (addIndex > lrui) { 2586 addIndex--; 2587 } 2588 if (nextIndex > lrui) { 2589 nextIndex--; 2590 } 2591 */ 2592 mLruProcesses.remove(lrui); 2593 } 2594 2595 /* 2596 mLruProcesses.add(addIndex, app); 2597 if (inActivity) { 2598 mLruProcessActivityStart++; 2599 } 2600 if (inService) { 2601 mLruProcessActivityStart++; 2602 } 2603 */ 2604 2605 int nextIndex; 2606 if (hasActivity) { 2607 final int N = mLruProcesses.size(); 2608 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2609 // Process doesn't have activities, but has clients with 2610 // activities... move it up, but one below the top (the top 2611 // should always have a real activity). 2612 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2613 mLruProcesses.add(N-1, app); 2614 // To keep it from spamming the LRU list (by making a bunch of clients), 2615 // we will push down any other entries owned by the app. 2616 final int uid = app.info.uid; 2617 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2618 ProcessRecord subProc = mLruProcesses.get(i); 2619 if (subProc.info.uid == uid) { 2620 // We want to push this one down the list. If the process after 2621 // it is for the same uid, however, don't do so, because we don't 2622 // want them internally to be re-ordered. 2623 if (mLruProcesses.get(i-1).info.uid != uid) { 2624 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2625 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2626 ProcessRecord tmp = mLruProcesses.get(i); 2627 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2628 mLruProcesses.set(i-1, tmp); 2629 i--; 2630 } 2631 } else { 2632 // A gap, we can stop here. 2633 break; 2634 } 2635 } 2636 } else { 2637 // Process has activities, put it at the very tipsy-top. 2638 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2639 mLruProcesses.add(app); 2640 } 2641 nextIndex = mLruProcessServiceStart; 2642 } else if (hasService) { 2643 // Process has services, put it at the top of the service list. 2644 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2645 mLruProcesses.add(mLruProcessActivityStart, app); 2646 nextIndex = mLruProcessServiceStart; 2647 mLruProcessActivityStart++; 2648 } else { 2649 // Process not otherwise of interest, it goes to the top of the non-service area. 2650 int index = mLruProcessServiceStart; 2651 if (client != null) { 2652 // If there is a client, don't allow the process to be moved up higher 2653 // in the list than that client. 2654 int clientIndex = mLruProcesses.lastIndexOf(client); 2655 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2656 + " when updating " + app); 2657 if (clientIndex <= lrui) { 2658 // Don't allow the client index restriction to push it down farther in the 2659 // list than it already is. 2660 clientIndex = lrui; 2661 } 2662 if (clientIndex >= 0 && index > clientIndex) { 2663 index = clientIndex; 2664 } 2665 } 2666 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2667 mLruProcesses.add(index, app); 2668 nextIndex = index-1; 2669 mLruProcessActivityStart++; 2670 mLruProcessServiceStart++; 2671 } 2672 2673 // If the app is currently using a content provider or service, 2674 // bump those processes as well. 2675 for (int j=app.connections.size()-1; j>=0; j--) { 2676 ConnectionRecord cr = app.connections.valueAt(j); 2677 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2678 && cr.binding.service.app != null 2679 && cr.binding.service.app.lruSeq != mLruSeq 2680 && !cr.binding.service.app.persistent) { 2681 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2682 "service connection", cr, app); 2683 } 2684 } 2685 for (int j=app.conProviders.size()-1; j>=0; j--) { 2686 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2687 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2688 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2689 "provider reference", cpr, app); 2690 } 2691 } 2692 } 2693 2694 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2695 if (uid == Process.SYSTEM_UID) { 2696 // The system gets to run in any process. If there are multiple 2697 // processes with the same uid, just pick the first (this 2698 // should never happen). 2699 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2700 if (procs == null) return null; 2701 final int N = procs.size(); 2702 for (int i = 0; i < N; i++) { 2703 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2704 } 2705 } 2706 ProcessRecord proc = mProcessNames.get(processName, uid); 2707 if (false && proc != null && !keepIfLarge 2708 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2709 && proc.lastCachedPss >= 4000) { 2710 // Turn this condition on to cause killing to happen regularly, for testing. 2711 if (proc.baseProcessTracker != null) { 2712 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2713 } 2714 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2715 } else if (proc != null && !keepIfLarge 2716 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2717 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2718 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2719 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2720 if (proc.baseProcessTracker != null) { 2721 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2722 } 2723 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2724 } 2725 } 2726 return proc; 2727 } 2728 2729 void ensurePackageDexOpt(String packageName) { 2730 IPackageManager pm = AppGlobals.getPackageManager(); 2731 try { 2732 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2733 mDidDexOpt = true; 2734 } 2735 } catch (RemoteException e) { 2736 } 2737 } 2738 2739 boolean isNextTransitionForward() { 2740 int transit = mWindowManager.getPendingAppTransition(); 2741 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2742 || transit == AppTransition.TRANSIT_TASK_OPEN 2743 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2744 } 2745 2746 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2747 String processName, String abiOverride, int uid, Runnable crashHandler) { 2748 synchronized(this) { 2749 ApplicationInfo info = new ApplicationInfo(); 2750 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2751 // For isolated processes, the former contains the parent's uid and the latter the 2752 // actual uid of the isolated process. 2753 // In the special case introduced by this method (which is, starting an isolated 2754 // process directly from the SystemServer without an actual parent app process) the 2755 // closest thing to a parent's uid is SYSTEM_UID. 2756 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2757 // the |isolated| logic in the ProcessRecord constructor. 2758 info.uid = Process.SYSTEM_UID; 2759 info.processName = processName; 2760 info.className = entryPoint; 2761 info.packageName = "android"; 2762 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2763 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2764 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2765 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2766 crashHandler); 2767 return proc != null ? proc.pid : 0; 2768 } 2769 } 2770 2771 final ProcessRecord startProcessLocked(String processName, 2772 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2773 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2774 boolean isolated, boolean keepIfLarge) { 2775 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2776 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2777 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2778 null /* crashHandler */); 2779 } 2780 2781 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2782 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2783 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2784 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2785 long startTime = SystemClock.elapsedRealtime(); 2786 ProcessRecord app; 2787 if (!isolated) { 2788 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2789 checkTime(startTime, "startProcess: after getProcessRecord"); 2790 } else { 2791 // If this is an isolated process, it can't re-use an existing process. 2792 app = null; 2793 } 2794 // We don't have to do anything more if: 2795 // (1) There is an existing application record; and 2796 // (2) The caller doesn't think it is dead, OR there is no thread 2797 // object attached to it so we know it couldn't have crashed; and 2798 // (3) There is a pid assigned to it, so it is either starting or 2799 // already running. 2800 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2801 + " app=" + app + " knownToBeDead=" + knownToBeDead 2802 + " thread=" + (app != null ? app.thread : null) 2803 + " pid=" + (app != null ? app.pid : -1)); 2804 if (app != null && app.pid > 0) { 2805 if (!knownToBeDead || app.thread == null) { 2806 // We already have the app running, or are waiting for it to 2807 // come up (we have a pid but not yet its thread), so keep it. 2808 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2809 // If this is a new package in the process, add the package to the list 2810 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2811 checkTime(startTime, "startProcess: done, added package to proc"); 2812 return app; 2813 } 2814 2815 // An application record is attached to a previous process, 2816 // clean it up now. 2817 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2818 checkTime(startTime, "startProcess: bad proc running, killing"); 2819 Process.killProcessGroup(app.info.uid, app.pid); 2820 handleAppDiedLocked(app, true, true); 2821 checkTime(startTime, "startProcess: done killing old proc"); 2822 } 2823 2824 String hostingNameStr = hostingName != null 2825 ? hostingName.flattenToShortString() : null; 2826 2827 if (!isolated) { 2828 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2829 // If we are in the background, then check to see if this process 2830 // is bad. If so, we will just silently fail. 2831 if (mBadProcesses.get(info.processName, info.uid) != null) { 2832 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2833 + "/" + info.processName); 2834 return null; 2835 } 2836 } else { 2837 // When the user is explicitly starting a process, then clear its 2838 // crash count so that we won't make it bad until they see at 2839 // least one crash dialog again, and make the process good again 2840 // if it had been bad. 2841 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2842 + "/" + info.processName); 2843 mProcessCrashTimes.remove(info.processName, info.uid); 2844 if (mBadProcesses.get(info.processName, info.uid) != null) { 2845 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2846 UserHandle.getUserId(info.uid), info.uid, 2847 info.processName); 2848 mBadProcesses.remove(info.processName, info.uid); 2849 if (app != null) { 2850 app.bad = false; 2851 } 2852 } 2853 } 2854 } 2855 2856 if (app == null) { 2857 checkTime(startTime, "startProcess: creating new process record"); 2858 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2859 app.crashHandler = crashHandler; 2860 if (app == null) { 2861 Slog.w(TAG, "Failed making new process record for " 2862 + processName + "/" + info.uid + " isolated=" + isolated); 2863 return null; 2864 } 2865 mProcessNames.put(processName, app.uid, app); 2866 if (isolated) { 2867 mIsolatedProcesses.put(app.uid, app); 2868 } 2869 checkTime(startTime, "startProcess: done creating new process record"); 2870 } else { 2871 // If this is a new package in the process, add the package to the list 2872 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2873 checkTime(startTime, "startProcess: added package to existing proc"); 2874 } 2875 2876 // If the system is not ready yet, then hold off on starting this 2877 // process until it is. 2878 if (!mProcessesReady 2879 && !isAllowedWhileBooting(info) 2880 && !allowWhileBooting) { 2881 if (!mProcessesOnHold.contains(app)) { 2882 mProcessesOnHold.add(app); 2883 } 2884 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2885 checkTime(startTime, "startProcess: returning with proc on hold"); 2886 return app; 2887 } 2888 2889 checkTime(startTime, "startProcess: stepping in to startProcess"); 2890 startProcessLocked( 2891 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2892 checkTime(startTime, "startProcess: done starting proc!"); 2893 return (app.pid != 0) ? app : null; 2894 } 2895 2896 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2897 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2898 } 2899 2900 private final void startProcessLocked(ProcessRecord app, 2901 String hostingType, String hostingNameStr) { 2902 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2903 null /* entryPoint */, null /* entryPointArgs */); 2904 } 2905 2906 private final void startProcessLocked(ProcessRecord app, String hostingType, 2907 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2908 long startTime = SystemClock.elapsedRealtime(); 2909 if (app.pid > 0 && app.pid != MY_PID) { 2910 checkTime(startTime, "startProcess: removing from pids map"); 2911 synchronized (mPidsSelfLocked) { 2912 mPidsSelfLocked.remove(app.pid); 2913 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2914 } 2915 checkTime(startTime, "startProcess: done removing from pids map"); 2916 app.setPid(0); 2917 } 2918 2919 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2920 "startProcessLocked removing on hold: " + app); 2921 mProcessesOnHold.remove(app); 2922 2923 checkTime(startTime, "startProcess: starting to update cpu stats"); 2924 updateCpuStats(); 2925 checkTime(startTime, "startProcess: done updating cpu stats"); 2926 2927 try { 2928 int uid = app.uid; 2929 2930 int[] gids = null; 2931 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2932 if (!app.isolated) { 2933 int[] permGids = null; 2934 try { 2935 checkTime(startTime, "startProcess: getting gids from package manager"); 2936 final PackageManager pm = mContext.getPackageManager(); 2937 permGids = pm.getPackageGids(app.info.packageName); 2938 2939 if (Environment.isExternalStorageEmulated()) { 2940 checkTime(startTime, "startProcess: checking external storage perm"); 2941 if (pm.checkPermission( 2942 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2943 app.info.packageName) == PERMISSION_GRANTED) { 2944 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2945 } else { 2946 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2947 } 2948 } 2949 } catch (PackageManager.NameNotFoundException e) { 2950 Slog.w(TAG, "Unable to retrieve gids", e); 2951 } 2952 2953 /* 2954 * Add shared application and profile GIDs so applications can share some 2955 * resources like shared libraries and access user-wide resources 2956 */ 2957 if (permGids == null) { 2958 gids = new int[2]; 2959 } else { 2960 gids = new int[permGids.length + 2]; 2961 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2962 } 2963 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2964 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2965 } 2966 checkTime(startTime, "startProcess: building args"); 2967 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2968 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2969 && mTopComponent != null 2970 && app.processName.equals(mTopComponent.getPackageName())) { 2971 uid = 0; 2972 } 2973 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2974 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2975 uid = 0; 2976 } 2977 } 2978 int debugFlags = 0; 2979 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2980 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2981 // Also turn on CheckJNI for debuggable apps. It's quite 2982 // awkward to turn on otherwise. 2983 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2984 } 2985 // Run the app in safe mode if its manifest requests so or the 2986 // system is booted in safe mode. 2987 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2988 mSafeMode == true) { 2989 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2990 } 2991 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2992 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2993 } 2994 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2995 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2996 } 2997 if ("1".equals(SystemProperties.get("debug.assert"))) { 2998 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2999 } 3000 3001 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3002 if (requiredAbi == null) { 3003 requiredAbi = Build.SUPPORTED_ABIS[0]; 3004 } 3005 3006 String instructionSet = null; 3007 if (app.info.primaryCpuAbi != null) { 3008 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3009 } 3010 3011 // Start the process. It will either succeed and return a result containing 3012 // the PID of the new process, or else throw a RuntimeException. 3013 boolean isActivityProcess = (entryPoint == null); 3014 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3015 checkTime(startTime, "startProcess: asking zygote to start proc"); 3016 Process.ProcessStartResult startResult = Process.start(entryPoint, 3017 app.processName, uid, uid, gids, debugFlags, mountExternal, 3018 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3019 app.info.dataDir, entryPointArgs); 3020 checkTime(startTime, "startProcess: returned from zygote!"); 3021 3022 if (app.isolated) { 3023 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3024 } 3025 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3026 checkTime(startTime, "startProcess: done updating battery stats"); 3027 3028 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3029 UserHandle.getUserId(uid), startResult.pid, uid, 3030 app.processName, hostingType, 3031 hostingNameStr != null ? hostingNameStr : ""); 3032 3033 if (app.persistent) { 3034 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3035 } 3036 3037 checkTime(startTime, "startProcess: building log message"); 3038 StringBuilder buf = mStringBuilder; 3039 buf.setLength(0); 3040 buf.append("Start proc "); 3041 buf.append(app.processName); 3042 if (!isActivityProcess) { 3043 buf.append(" ["); 3044 buf.append(entryPoint); 3045 buf.append("]"); 3046 } 3047 buf.append(" for "); 3048 buf.append(hostingType); 3049 if (hostingNameStr != null) { 3050 buf.append(" "); 3051 buf.append(hostingNameStr); 3052 } 3053 buf.append(": pid="); 3054 buf.append(startResult.pid); 3055 buf.append(" uid="); 3056 buf.append(uid); 3057 buf.append(" gids={"); 3058 if (gids != null) { 3059 for (int gi=0; gi<gids.length; gi++) { 3060 if (gi != 0) buf.append(", "); 3061 buf.append(gids[gi]); 3062 3063 } 3064 } 3065 buf.append("}"); 3066 if (requiredAbi != null) { 3067 buf.append(" abi="); 3068 buf.append(requiredAbi); 3069 } 3070 Slog.i(TAG, buf.toString()); 3071 app.setPid(startResult.pid); 3072 app.usingWrapper = startResult.usingWrapper; 3073 app.removed = false; 3074 app.killed = false; 3075 app.killedByAm = false; 3076 checkTime(startTime, "startProcess: starting to update pids map"); 3077 synchronized (mPidsSelfLocked) { 3078 this.mPidsSelfLocked.put(startResult.pid, app); 3079 if (isActivityProcess) { 3080 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3081 msg.obj = app; 3082 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3083 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3084 } 3085 } 3086 checkTime(startTime, "startProcess: done updating pids map"); 3087 } catch (RuntimeException e) { 3088 // XXX do better error recovery. 3089 app.setPid(0); 3090 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3091 if (app.isolated) { 3092 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3093 } 3094 Slog.e(TAG, "Failure starting process " + app.processName, e); 3095 } 3096 } 3097 3098 void updateUsageStats(ActivityRecord component, boolean resumed) { 3099 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3100 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3101 if (resumed) { 3102 if (mUsageStatsService != null) { 3103 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3104 UsageEvents.Event.MOVE_TO_FOREGROUND); 3105 } 3106 synchronized (stats) { 3107 stats.noteActivityResumedLocked(component.app.uid); 3108 } 3109 } else { 3110 if (mUsageStatsService != null) { 3111 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3112 UsageEvents.Event.MOVE_TO_BACKGROUND); 3113 } 3114 synchronized (stats) { 3115 stats.noteActivityPausedLocked(component.app.uid); 3116 } 3117 } 3118 } 3119 3120 Intent getHomeIntent() { 3121 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3122 intent.setComponent(mTopComponent); 3123 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3124 intent.addCategory(Intent.CATEGORY_HOME); 3125 } 3126 return intent; 3127 } 3128 3129 boolean startHomeActivityLocked(int userId) { 3130 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3131 && mTopAction == null) { 3132 // We are running in factory test mode, but unable to find 3133 // the factory test app, so just sit around displaying the 3134 // error message and don't try to start anything. 3135 return false; 3136 } 3137 Intent intent = getHomeIntent(); 3138 ActivityInfo aInfo = 3139 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3140 if (aInfo != null) { 3141 intent.setComponent(new ComponentName( 3142 aInfo.applicationInfo.packageName, aInfo.name)); 3143 // Don't do this if the home app is currently being 3144 // instrumented. 3145 aInfo = new ActivityInfo(aInfo); 3146 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3147 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3148 aInfo.applicationInfo.uid, true); 3149 if (app == null || app.instrumentationClass == null) { 3150 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3151 mStackSupervisor.startHomeActivity(intent, aInfo); 3152 } 3153 } 3154 3155 return true; 3156 } 3157 3158 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3159 ActivityInfo ai = null; 3160 ComponentName comp = intent.getComponent(); 3161 try { 3162 if (comp != null) { 3163 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3164 } else { 3165 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3166 intent, 3167 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3168 flags, userId); 3169 3170 if (info != null) { 3171 ai = info.activityInfo; 3172 } 3173 } 3174 } catch (RemoteException e) { 3175 // ignore 3176 } 3177 3178 return ai; 3179 } 3180 3181 /** 3182 * Starts the "new version setup screen" if appropriate. 3183 */ 3184 void startSetupActivityLocked() { 3185 // Only do this once per boot. 3186 if (mCheckedForSetup) { 3187 return; 3188 } 3189 3190 // We will show this screen if the current one is a different 3191 // version than the last one shown, and we are not running in 3192 // low-level factory test mode. 3193 final ContentResolver resolver = mContext.getContentResolver(); 3194 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3195 Settings.Global.getInt(resolver, 3196 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3197 mCheckedForSetup = true; 3198 3199 // See if we should be showing the platform update setup UI. 3200 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3201 List<ResolveInfo> ris = mContext.getPackageManager() 3202 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3203 3204 // We don't allow third party apps to replace this. 3205 ResolveInfo ri = null; 3206 for (int i=0; ris != null && i<ris.size(); i++) { 3207 if ((ris.get(i).activityInfo.applicationInfo.flags 3208 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3209 ri = ris.get(i); 3210 break; 3211 } 3212 } 3213 3214 if (ri != null) { 3215 String vers = ri.activityInfo.metaData != null 3216 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3217 : null; 3218 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3219 vers = ri.activityInfo.applicationInfo.metaData.getString( 3220 Intent.METADATA_SETUP_VERSION); 3221 } 3222 String lastVers = Settings.Secure.getString( 3223 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3224 if (vers != null && !vers.equals(lastVers)) { 3225 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3226 intent.setComponent(new ComponentName( 3227 ri.activityInfo.packageName, ri.activityInfo.name)); 3228 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3229 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3230 null); 3231 } 3232 } 3233 } 3234 } 3235 3236 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3237 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3238 } 3239 3240 void enforceNotIsolatedCaller(String caller) { 3241 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3242 throw new SecurityException("Isolated process not allowed to call " + caller); 3243 } 3244 } 3245 3246 void enforceShellRestriction(String restriction, int userHandle) { 3247 if (Binder.getCallingUid() == Process.SHELL_UID) { 3248 if (userHandle < 0 3249 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3250 throw new SecurityException("Shell does not have permission to access user " 3251 + userHandle); 3252 } 3253 } 3254 } 3255 3256 @Override 3257 public int getFrontActivityScreenCompatMode() { 3258 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3259 synchronized (this) { 3260 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3261 } 3262 } 3263 3264 @Override 3265 public void setFrontActivityScreenCompatMode(int mode) { 3266 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3267 "setFrontActivityScreenCompatMode"); 3268 synchronized (this) { 3269 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3270 } 3271 } 3272 3273 @Override 3274 public int getPackageScreenCompatMode(String packageName) { 3275 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3276 synchronized (this) { 3277 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3278 } 3279 } 3280 3281 @Override 3282 public void setPackageScreenCompatMode(String packageName, int mode) { 3283 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3284 "setPackageScreenCompatMode"); 3285 synchronized (this) { 3286 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3287 } 3288 } 3289 3290 @Override 3291 public boolean getPackageAskScreenCompat(String packageName) { 3292 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3293 synchronized (this) { 3294 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3295 } 3296 } 3297 3298 @Override 3299 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3300 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3301 "setPackageAskScreenCompat"); 3302 synchronized (this) { 3303 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3304 } 3305 } 3306 3307 private void dispatchProcessesChanged() { 3308 int N; 3309 synchronized (this) { 3310 N = mPendingProcessChanges.size(); 3311 if (mActiveProcessChanges.length < N) { 3312 mActiveProcessChanges = new ProcessChangeItem[N]; 3313 } 3314 mPendingProcessChanges.toArray(mActiveProcessChanges); 3315 mAvailProcessChanges.addAll(mPendingProcessChanges); 3316 mPendingProcessChanges.clear(); 3317 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3318 } 3319 3320 int i = mProcessObservers.beginBroadcast(); 3321 while (i > 0) { 3322 i--; 3323 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3324 if (observer != null) { 3325 try { 3326 for (int j=0; j<N; j++) { 3327 ProcessChangeItem item = mActiveProcessChanges[j]; 3328 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3329 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3330 + item.pid + " uid=" + item.uid + ": " 3331 + item.foregroundActivities); 3332 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3333 item.foregroundActivities); 3334 } 3335 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3336 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3337 + item.pid + " uid=" + item.uid + ": " + item.processState); 3338 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3339 } 3340 } 3341 } catch (RemoteException e) { 3342 } 3343 } 3344 } 3345 mProcessObservers.finishBroadcast(); 3346 } 3347 3348 private void dispatchProcessDied(int pid, int uid) { 3349 int i = mProcessObservers.beginBroadcast(); 3350 while (i > 0) { 3351 i--; 3352 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3353 if (observer != null) { 3354 try { 3355 observer.onProcessDied(pid, uid); 3356 } catch (RemoteException e) { 3357 } 3358 } 3359 } 3360 mProcessObservers.finishBroadcast(); 3361 } 3362 3363 @Override 3364 public final int startActivity(IApplicationThread caller, String callingPackage, 3365 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3366 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3367 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3368 resultWho, requestCode, startFlags, profilerInfo, options, 3369 UserHandle.getCallingUserId()); 3370 } 3371 3372 @Override 3373 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3374 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3375 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3376 enforceNotIsolatedCaller("startActivity"); 3377 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3378 false, ALLOW_FULL_ONLY, "startActivity", null); 3379 // TODO: Switch to user app stacks here. 3380 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3381 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3382 profilerInfo, null, null, options, userId, null, null); 3383 } 3384 3385 @Override 3386 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3387 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3388 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3389 3390 // This is very dangerous -- it allows you to perform a start activity (including 3391 // permission grants) as any app that may launch one of your own activities. So 3392 // we will only allow this to be done from activities that are part of the core framework, 3393 // and then only when they are running as the system. 3394 final ActivityRecord sourceRecord; 3395 final int targetUid; 3396 final String targetPackage; 3397 synchronized (this) { 3398 if (resultTo == null) { 3399 throw new SecurityException("Must be called from an activity"); 3400 } 3401 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3402 if (sourceRecord == null) { 3403 throw new SecurityException("Called with bad activity token: " + resultTo); 3404 } 3405 if (!sourceRecord.info.packageName.equals("android")) { 3406 throw new SecurityException( 3407 "Must be called from an activity that is declared in the android package"); 3408 } 3409 if (sourceRecord.app == null) { 3410 throw new SecurityException("Called without a process attached to activity"); 3411 } 3412 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3413 // This is still okay, as long as this activity is running under the 3414 // uid of the original calling activity. 3415 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3416 throw new SecurityException( 3417 "Calling activity in uid " + sourceRecord.app.uid 3418 + " must be system uid or original calling uid " 3419 + sourceRecord.launchedFromUid); 3420 } 3421 } 3422 targetUid = sourceRecord.launchedFromUid; 3423 targetPackage = sourceRecord.launchedFromPackage; 3424 } 3425 3426 if (userId == UserHandle.USER_NULL) { 3427 userId = UserHandle.getUserId(sourceRecord.app.uid); 3428 } 3429 3430 // TODO: Switch to user app stacks here. 3431 try { 3432 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3433 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3434 null, null, options, userId, null, null); 3435 return ret; 3436 } catch (SecurityException e) { 3437 // XXX need to figure out how to propagate to original app. 3438 // A SecurityException here is generally actually a fault of the original 3439 // calling activity (such as a fairly granting permissions), so propagate it 3440 // back to them. 3441 /* 3442 StringBuilder msg = new StringBuilder(); 3443 msg.append("While launching"); 3444 msg.append(intent.toString()); 3445 msg.append(": "); 3446 msg.append(e.getMessage()); 3447 */ 3448 throw e; 3449 } 3450 } 3451 3452 @Override 3453 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3454 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3455 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3456 enforceNotIsolatedCaller("startActivityAndWait"); 3457 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3458 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3459 WaitResult res = new WaitResult(); 3460 // TODO: Switch to user app stacks here. 3461 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3462 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3463 options, userId, null, null); 3464 return res; 3465 } 3466 3467 @Override 3468 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3469 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3470 int startFlags, Configuration config, Bundle options, int userId) { 3471 enforceNotIsolatedCaller("startActivityWithConfig"); 3472 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3473 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3474 // TODO: Switch to user app stacks here. 3475 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3476 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3477 null, null, config, options, userId, null, null); 3478 return ret; 3479 } 3480 3481 @Override 3482 public int startActivityIntentSender(IApplicationThread caller, 3483 IntentSender intent, Intent fillInIntent, String resolvedType, 3484 IBinder resultTo, String resultWho, int requestCode, 3485 int flagsMask, int flagsValues, Bundle options) { 3486 enforceNotIsolatedCaller("startActivityIntentSender"); 3487 // Refuse possible leaked file descriptors 3488 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3489 throw new IllegalArgumentException("File descriptors passed in Intent"); 3490 } 3491 3492 IIntentSender sender = intent.getTarget(); 3493 if (!(sender instanceof PendingIntentRecord)) { 3494 throw new IllegalArgumentException("Bad PendingIntent object"); 3495 } 3496 3497 PendingIntentRecord pir = (PendingIntentRecord)sender; 3498 3499 synchronized (this) { 3500 // If this is coming from the currently resumed activity, it is 3501 // effectively saying that app switches are allowed at this point. 3502 final ActivityStack stack = getFocusedStack(); 3503 if (stack.mResumedActivity != null && 3504 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3505 mAppSwitchesAllowedTime = 0; 3506 } 3507 } 3508 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3509 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3510 return ret; 3511 } 3512 3513 @Override 3514 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3515 Intent intent, String resolvedType, IVoiceInteractionSession session, 3516 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3517 Bundle options, int userId) { 3518 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3519 != PackageManager.PERMISSION_GRANTED) { 3520 String msg = "Permission Denial: startVoiceActivity() from pid=" 3521 + Binder.getCallingPid() 3522 + ", uid=" + Binder.getCallingUid() 3523 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3524 Slog.w(TAG, msg); 3525 throw new SecurityException(msg); 3526 } 3527 if (session == null || interactor == null) { 3528 throw new NullPointerException("null session or interactor"); 3529 } 3530 userId = handleIncomingUser(callingPid, callingUid, userId, 3531 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3532 // TODO: Switch to user app stacks here. 3533 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3534 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3535 null, options, userId, null, null); 3536 } 3537 3538 @Override 3539 public boolean startNextMatchingActivity(IBinder callingActivity, 3540 Intent intent, Bundle options) { 3541 // Refuse possible leaked file descriptors 3542 if (intent != null && intent.hasFileDescriptors() == true) { 3543 throw new IllegalArgumentException("File descriptors passed in Intent"); 3544 } 3545 3546 synchronized (this) { 3547 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3548 if (r == null) { 3549 ActivityOptions.abort(options); 3550 return false; 3551 } 3552 if (r.app == null || r.app.thread == null) { 3553 // The caller is not running... d'oh! 3554 ActivityOptions.abort(options); 3555 return false; 3556 } 3557 intent = new Intent(intent); 3558 // The caller is not allowed to change the data. 3559 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3560 // And we are resetting to find the next component... 3561 intent.setComponent(null); 3562 3563 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3564 3565 ActivityInfo aInfo = null; 3566 try { 3567 List<ResolveInfo> resolves = 3568 AppGlobals.getPackageManager().queryIntentActivities( 3569 intent, r.resolvedType, 3570 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3571 UserHandle.getCallingUserId()); 3572 3573 // Look for the original activity in the list... 3574 final int N = resolves != null ? resolves.size() : 0; 3575 for (int i=0; i<N; i++) { 3576 ResolveInfo rInfo = resolves.get(i); 3577 if (rInfo.activityInfo.packageName.equals(r.packageName) 3578 && rInfo.activityInfo.name.equals(r.info.name)) { 3579 // We found the current one... the next matching is 3580 // after it. 3581 i++; 3582 if (i<N) { 3583 aInfo = resolves.get(i).activityInfo; 3584 } 3585 if (debug) { 3586 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3587 + "/" + r.info.name); 3588 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3589 + "/" + aInfo.name); 3590 } 3591 break; 3592 } 3593 } 3594 } catch (RemoteException e) { 3595 } 3596 3597 if (aInfo == null) { 3598 // Nobody who is next! 3599 ActivityOptions.abort(options); 3600 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3601 return false; 3602 } 3603 3604 intent.setComponent(new ComponentName( 3605 aInfo.applicationInfo.packageName, aInfo.name)); 3606 intent.setFlags(intent.getFlags()&~( 3607 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3608 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3609 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3610 Intent.FLAG_ACTIVITY_NEW_TASK)); 3611 3612 // Okay now we need to start the new activity, replacing the 3613 // currently running activity. This is a little tricky because 3614 // we want to start the new one as if the current one is finished, 3615 // but not finish the current one first so that there is no flicker. 3616 // And thus... 3617 final boolean wasFinishing = r.finishing; 3618 r.finishing = true; 3619 3620 // Propagate reply information over to the new activity. 3621 final ActivityRecord resultTo = r.resultTo; 3622 final String resultWho = r.resultWho; 3623 final int requestCode = r.requestCode; 3624 r.resultTo = null; 3625 if (resultTo != null) { 3626 resultTo.removeResultsLocked(r, resultWho, requestCode); 3627 } 3628 3629 final long origId = Binder.clearCallingIdentity(); 3630 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3631 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3632 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3633 -1, r.launchedFromUid, 0, options, false, null, null, null); 3634 Binder.restoreCallingIdentity(origId); 3635 3636 r.finishing = wasFinishing; 3637 if (res != ActivityManager.START_SUCCESS) { 3638 return false; 3639 } 3640 return true; 3641 } 3642 } 3643 3644 @Override 3645 public final int startActivityFromRecents(int taskId, Bundle options) { 3646 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3647 String msg = "Permission Denial: startActivityFromRecents called without " + 3648 START_TASKS_FROM_RECENTS; 3649 Slog.w(TAG, msg); 3650 throw new SecurityException(msg); 3651 } 3652 return startActivityFromRecentsInner(taskId, options); 3653 } 3654 3655 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3656 final TaskRecord task; 3657 final int callingUid; 3658 final String callingPackage; 3659 final Intent intent; 3660 final int userId; 3661 synchronized (this) { 3662 task = recentTaskForIdLocked(taskId); 3663 if (task == null) { 3664 throw new IllegalArgumentException("Task " + taskId + " not found."); 3665 } 3666 callingUid = task.mCallingUid; 3667 callingPackage = task.mCallingPackage; 3668 intent = task.intent; 3669 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3670 userId = task.userId; 3671 } 3672 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3673 options, userId, null, task); 3674 } 3675 3676 final int startActivityInPackage(int uid, String callingPackage, 3677 Intent intent, String resolvedType, IBinder resultTo, 3678 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3679 IActivityContainer container, TaskRecord inTask) { 3680 3681 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3682 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3683 3684 // TODO: Switch to user app stacks here. 3685 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3686 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3687 null, null, null, options, userId, container, inTask); 3688 return ret; 3689 } 3690 3691 @Override 3692 public final int startActivities(IApplicationThread caller, String callingPackage, 3693 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3694 int userId) { 3695 enforceNotIsolatedCaller("startActivities"); 3696 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3697 false, ALLOW_FULL_ONLY, "startActivity", null); 3698 // TODO: Switch to user app stacks here. 3699 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3700 resolvedTypes, resultTo, options, userId); 3701 return ret; 3702 } 3703 3704 final int startActivitiesInPackage(int uid, String callingPackage, 3705 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3706 Bundle options, int userId) { 3707 3708 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3709 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3710 // TODO: Switch to user app stacks here. 3711 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3712 resultTo, options, userId); 3713 return ret; 3714 } 3715 3716 //explicitly remove thd old information in mRecentTasks when removing existing user. 3717 private void removeRecentTasksForUserLocked(int userId) { 3718 if(userId <= 0) { 3719 Slog.i(TAG, "Can't remove recent task on user " + userId); 3720 return; 3721 } 3722 3723 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3724 TaskRecord tr = mRecentTasks.get(i); 3725 if (tr.userId == userId) { 3726 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3727 + " when finishing user" + userId); 3728 mRecentTasks.remove(i); 3729 tr.removedFromRecents(mTaskPersister); 3730 } 3731 } 3732 3733 // Remove tasks from persistent storage. 3734 mTaskPersister.wakeup(null, true); 3735 } 3736 3737 // Sort by taskId 3738 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3739 @Override 3740 public int compare(TaskRecord lhs, TaskRecord rhs) { 3741 return rhs.taskId - lhs.taskId; 3742 } 3743 }; 3744 3745 // Extract the affiliates of the chain containing mRecentTasks[start]. 3746 private int processNextAffiliateChain(int start) { 3747 final TaskRecord startTask = mRecentTasks.get(start); 3748 final int affiliateId = startTask.mAffiliatedTaskId; 3749 3750 // Quick identification of isolated tasks. I.e. those not launched behind. 3751 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3752 startTask.mNextAffiliate == null) { 3753 // There is still a slim chance that there are other tasks that point to this task 3754 // and that the chain is so messed up that this task no longer points to them but 3755 // the gain of this optimization outweighs the risk. 3756 startTask.inRecents = true; 3757 return start + 1; 3758 } 3759 3760 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3761 mTmpRecents.clear(); 3762 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3763 final TaskRecord task = mRecentTasks.get(i); 3764 if (task.mAffiliatedTaskId == affiliateId) { 3765 mRecentTasks.remove(i); 3766 mTmpRecents.add(task); 3767 } 3768 } 3769 3770 // Sort them all by taskId. That is the order they were create in and that order will 3771 // always be correct. 3772 Collections.sort(mTmpRecents, mTaskRecordComparator); 3773 3774 // Go through and fix up the linked list. 3775 // The first one is the end of the chain and has no next. 3776 final TaskRecord first = mTmpRecents.get(0); 3777 first.inRecents = true; 3778 if (first.mNextAffiliate != null) { 3779 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3780 first.setNextAffiliate(null); 3781 mTaskPersister.wakeup(first, false); 3782 } 3783 // Everything in the middle is doubly linked from next to prev. 3784 final int tmpSize = mTmpRecents.size(); 3785 for (int i = 0; i < tmpSize - 1; ++i) { 3786 final TaskRecord next = mTmpRecents.get(i); 3787 final TaskRecord prev = mTmpRecents.get(i + 1); 3788 if (next.mPrevAffiliate != prev) { 3789 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3790 " setting prev=" + prev); 3791 next.setPrevAffiliate(prev); 3792 mTaskPersister.wakeup(next, false); 3793 } 3794 if (prev.mNextAffiliate != next) { 3795 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3796 " setting next=" + next); 3797 prev.setNextAffiliate(next); 3798 mTaskPersister.wakeup(prev, false); 3799 } 3800 prev.inRecents = true; 3801 } 3802 // The last one is the beginning of the list and has no prev. 3803 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3804 if (last.mPrevAffiliate != null) { 3805 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3806 last.setPrevAffiliate(null); 3807 mTaskPersister.wakeup(last, false); 3808 } 3809 3810 // Insert the group back into mRecentTasks at start. 3811 mRecentTasks.addAll(start, mTmpRecents); 3812 3813 // Let the caller know where we left off. 3814 return start + tmpSize; 3815 } 3816 3817 /** 3818 * Update the recent tasks lists: make sure tasks should still be here (their 3819 * applications / activities still exist), update their availability, fixup ordering 3820 * of affiliations. 3821 */ 3822 void cleanupRecentTasksLocked(int userId) { 3823 if (mRecentTasks == null) { 3824 // Happens when called from the packagemanager broadcast before boot. 3825 return; 3826 } 3827 3828 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3829 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3830 final IPackageManager pm = AppGlobals.getPackageManager(); 3831 final ActivityInfo dummyAct = new ActivityInfo(); 3832 final ApplicationInfo dummyApp = new ApplicationInfo(); 3833 3834 int N = mRecentTasks.size(); 3835 3836 int[] users = userId == UserHandle.USER_ALL 3837 ? getUsersLocked() : new int[] { userId }; 3838 for (int user : users) { 3839 for (int i = 0; i < N; i++) { 3840 TaskRecord task = mRecentTasks.get(i); 3841 if (task.userId != user) { 3842 // Only look at tasks for the user ID of interest. 3843 continue; 3844 } 3845 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3846 // This situation is broken, and we should just get rid of it now. 3847 mRecentTasks.remove(i); 3848 task.removedFromRecents(mTaskPersister); 3849 i--; 3850 N--; 3851 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3852 continue; 3853 } 3854 // Check whether this activity is currently available. 3855 if (task.realActivity != null) { 3856 ActivityInfo ai = availActCache.get(task.realActivity); 3857 if (ai == null) { 3858 try { 3859 ai = pm.getActivityInfo(task.realActivity, 3860 PackageManager.GET_UNINSTALLED_PACKAGES 3861 | PackageManager.GET_DISABLED_COMPONENTS, user); 3862 } catch (RemoteException e) { 3863 // Will never happen. 3864 continue; 3865 } 3866 if (ai == null) { 3867 ai = dummyAct; 3868 } 3869 availActCache.put(task.realActivity, ai); 3870 } 3871 if (ai == dummyAct) { 3872 // This could be either because the activity no longer exists, or the 3873 // app is temporarily gone. For the former we want to remove the recents 3874 // entry; for the latter we want to mark it as unavailable. 3875 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3876 if (app == null) { 3877 try { 3878 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3879 PackageManager.GET_UNINSTALLED_PACKAGES 3880 | PackageManager.GET_DISABLED_COMPONENTS, user); 3881 } catch (RemoteException e) { 3882 // Will never happen. 3883 continue; 3884 } 3885 if (app == null) { 3886 app = dummyApp; 3887 } 3888 availAppCache.put(task.realActivity.getPackageName(), app); 3889 } 3890 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3891 // Doesn't exist any more! Good-bye. 3892 mRecentTasks.remove(i); 3893 task.removedFromRecents(mTaskPersister); 3894 i--; 3895 N--; 3896 Slog.w(TAG, "Removing no longer valid recent: " + task); 3897 continue; 3898 } else { 3899 // Otherwise just not available for now. 3900 if (task.isAvailable) { 3901 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3902 + task); 3903 } 3904 task.isAvailable = false; 3905 } 3906 } else { 3907 if (!ai.enabled || !ai.applicationInfo.enabled 3908 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3909 if (task.isAvailable) { 3910 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3911 + task + " (enabled=" + ai.enabled + "/" 3912 + ai.applicationInfo.enabled + " flags=" 3913 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3914 } 3915 task.isAvailable = false; 3916 } else { 3917 if (!task.isAvailable) { 3918 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3919 + task); 3920 } 3921 task.isAvailable = true; 3922 } 3923 } 3924 } 3925 } 3926 } 3927 3928 // Verify the affiliate chain for each task. 3929 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3930 } 3931 3932 mTmpRecents.clear(); 3933 // mRecentTasks is now in sorted, affiliated order. 3934 } 3935 3936 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3937 int N = mRecentTasks.size(); 3938 TaskRecord top = task; 3939 int topIndex = taskIndex; 3940 while (top.mNextAffiliate != null && topIndex > 0) { 3941 top = top.mNextAffiliate; 3942 topIndex--; 3943 } 3944 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3945 + topIndex + " from intial " + taskIndex); 3946 // Find the end of the chain, doing a sanity check along the way. 3947 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3948 int endIndex = topIndex; 3949 TaskRecord prev = top; 3950 while (endIndex < N) { 3951 TaskRecord cur = mRecentTasks.get(endIndex); 3952 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3953 + endIndex + " " + cur); 3954 if (cur == top) { 3955 // Verify start of the chain. 3956 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3957 Slog.wtf(TAG, "Bad chain @" + endIndex 3958 + ": first task has next affiliate: " + prev); 3959 sane = false; 3960 break; 3961 } 3962 } else { 3963 // Verify middle of the chain's next points back to the one before. 3964 if (cur.mNextAffiliate != prev 3965 || cur.mNextAffiliateTaskId != prev.taskId) { 3966 Slog.wtf(TAG, "Bad chain @" + endIndex 3967 + ": middle task " + cur + " @" + endIndex 3968 + " has bad next affiliate " 3969 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3970 + ", expected " + prev); 3971 sane = false; 3972 break; 3973 } 3974 } 3975 if (cur.mPrevAffiliateTaskId == -1) { 3976 // Chain ends here. 3977 if (cur.mPrevAffiliate != null) { 3978 Slog.wtf(TAG, "Bad chain @" + endIndex 3979 + ": last task " + cur + " has previous affiliate " 3980 + cur.mPrevAffiliate); 3981 sane = false; 3982 } 3983 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3984 break; 3985 } else { 3986 // Verify middle of the chain's prev points to a valid item. 3987 if (cur.mPrevAffiliate == null) { 3988 Slog.wtf(TAG, "Bad chain @" + endIndex 3989 + ": task " + cur + " has previous affiliate " 3990 + cur.mPrevAffiliate + " but should be id " 3991 + cur.mPrevAffiliate); 3992 sane = false; 3993 break; 3994 } 3995 } 3996 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3997 Slog.wtf(TAG, "Bad chain @" + endIndex 3998 + ": task " + cur + " has affiliated id " 3999 + cur.mAffiliatedTaskId + " but should be " 4000 + task.mAffiliatedTaskId); 4001 sane = false; 4002 break; 4003 } 4004 prev = cur; 4005 endIndex++; 4006 if (endIndex >= N) { 4007 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4008 + ": last task " + prev); 4009 sane = false; 4010 break; 4011 } 4012 } 4013 if (sane) { 4014 if (endIndex < taskIndex) { 4015 Slog.wtf(TAG, "Bad chain @" + endIndex 4016 + ": did not extend to task " + task + " @" + taskIndex); 4017 sane = false; 4018 } 4019 } 4020 if (sane) { 4021 // All looks good, we can just move all of the affiliated tasks 4022 // to the top. 4023 for (int i=topIndex; i<=endIndex; i++) { 4024 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4025 + " from " + i + " to " + (i-topIndex)); 4026 TaskRecord cur = mRecentTasks.remove(i); 4027 mRecentTasks.add(i-topIndex, cur); 4028 } 4029 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4030 + " to " + endIndex); 4031 return true; 4032 } 4033 4034 // Whoops, couldn't do it. 4035 return false; 4036 } 4037 4038 final void addRecentTaskLocked(TaskRecord task) { 4039 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4040 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4041 4042 int N = mRecentTasks.size(); 4043 // Quick case: check if the top-most recent task is the same. 4044 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4045 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4046 return; 4047 } 4048 // Another quick case: check if this is part of a set of affiliated 4049 // tasks that are at the top. 4050 if (isAffiliated && N > 0 && task.inRecents 4051 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4052 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4053 + " at top when adding " + task); 4054 return; 4055 } 4056 // Another quick case: never add voice sessions. 4057 if (task.voiceSession != null) { 4058 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4059 return; 4060 } 4061 4062 boolean needAffiliationFix = false; 4063 4064 // Slightly less quick case: the task is already in recents, so all we need 4065 // to do is move it. 4066 if (task.inRecents) { 4067 int taskIndex = mRecentTasks.indexOf(task); 4068 if (taskIndex >= 0) { 4069 if (!isAffiliated) { 4070 // Simple case: this is not an affiliated task, so we just move it to the front. 4071 mRecentTasks.remove(taskIndex); 4072 mRecentTasks.add(0, task); 4073 notifyTaskPersisterLocked(task, false); 4074 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4075 + " from " + taskIndex); 4076 return; 4077 } else { 4078 // More complicated: need to keep all affiliated tasks together. 4079 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4080 // All went well. 4081 return; 4082 } 4083 4084 // Uh oh... something bad in the affiliation chain, try to rebuild 4085 // everything and then go through our general path of adding a new task. 4086 needAffiliationFix = true; 4087 } 4088 } else { 4089 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4090 needAffiliationFix = true; 4091 } 4092 } 4093 4094 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4095 trimRecentsForTask(task, true); 4096 4097 N = mRecentTasks.size(); 4098 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4099 final TaskRecord tr = mRecentTasks.remove(N - 1); 4100 tr.removedFromRecents(mTaskPersister); 4101 N--; 4102 } 4103 task.inRecents = true; 4104 if (!isAffiliated || needAffiliationFix) { 4105 // If this is a simple non-affiliated task, or we had some failure trying to 4106 // handle it as part of an affilated task, then just place it at the top. 4107 mRecentTasks.add(0, task); 4108 } else if (isAffiliated) { 4109 // If this is a new affiliated task, then move all of the affiliated tasks 4110 // to the front and insert this new one. 4111 TaskRecord other = task.mNextAffiliate; 4112 if (other == null) { 4113 other = task.mPrevAffiliate; 4114 } 4115 if (other != null) { 4116 int otherIndex = mRecentTasks.indexOf(other); 4117 if (otherIndex >= 0) { 4118 // Insert new task at appropriate location. 4119 int taskIndex; 4120 if (other == task.mNextAffiliate) { 4121 // We found the index of our next affiliation, which is who is 4122 // before us in the list, so add after that point. 4123 taskIndex = otherIndex+1; 4124 } else { 4125 // We found the index of our previous affiliation, which is who is 4126 // after us in the list, so add at their position. 4127 taskIndex = otherIndex; 4128 } 4129 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4130 + taskIndex + ": " + task); 4131 mRecentTasks.add(taskIndex, task); 4132 4133 // Now move everything to the front. 4134 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4135 // All went well. 4136 return; 4137 } 4138 4139 // Uh oh... something bad in the affiliation chain, try to rebuild 4140 // everything and then go through our general path of adding a new task. 4141 needAffiliationFix = true; 4142 } else { 4143 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4144 + other); 4145 needAffiliationFix = true; 4146 } 4147 } else { 4148 if (DEBUG_RECENTS) Slog.d(TAG, 4149 "addRecent: adding affiliated task without next/prev:" + task); 4150 needAffiliationFix = true; 4151 } 4152 } 4153 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4154 4155 if (needAffiliationFix) { 4156 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4157 cleanupRecentTasksLocked(task.userId); 4158 } 4159 } 4160 4161 /** 4162 * If needed, remove oldest existing entries in recents that are for the same kind 4163 * of task as the given one. 4164 */ 4165 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4166 int N = mRecentTasks.size(); 4167 final Intent intent = task.intent; 4168 final boolean document = intent != null && intent.isDocument(); 4169 4170 int maxRecents = task.maxRecents - 1; 4171 for (int i=0; i<N; i++) { 4172 final TaskRecord tr = mRecentTasks.get(i); 4173 if (task != tr) { 4174 if (task.userId != tr.userId) { 4175 continue; 4176 } 4177 if (i > MAX_RECENT_BITMAPS) { 4178 tr.freeLastThumbnail(); 4179 } 4180 final Intent trIntent = tr.intent; 4181 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4182 (intent == null || !intent.filterEquals(trIntent))) { 4183 continue; 4184 } 4185 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4186 if (document && trIsDocument) { 4187 // These are the same document activity (not necessarily the same doc). 4188 if (maxRecents > 0) { 4189 --maxRecents; 4190 continue; 4191 } 4192 // Hit the maximum number of documents for this task. Fall through 4193 // and remove this document from recents. 4194 } else if (document || trIsDocument) { 4195 // Only one of these is a document. Not the droid we're looking for. 4196 continue; 4197 } 4198 } 4199 4200 if (!doTrim) { 4201 // If the caller is not actually asking for a trim, just tell them we reached 4202 // a point where the trim would happen. 4203 return i; 4204 } 4205 4206 // Either task and tr are the same or, their affinities match or their intents match 4207 // and neither of them is a document, or they are documents using the same activity 4208 // and their maxRecents has been reached. 4209 tr.disposeThumbnail(); 4210 mRecentTasks.remove(i); 4211 if (task != tr) { 4212 tr.removedFromRecents(mTaskPersister); 4213 } 4214 i--; 4215 N--; 4216 if (task.intent == null) { 4217 // If the new recent task we are adding is not fully 4218 // specified, then replace it with the existing recent task. 4219 task = tr; 4220 } 4221 notifyTaskPersisterLocked(tr, false); 4222 } 4223 4224 return -1; 4225 } 4226 4227 @Override 4228 public void reportActivityFullyDrawn(IBinder token) { 4229 synchronized (this) { 4230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4231 if (r == null) { 4232 return; 4233 } 4234 r.reportFullyDrawnLocked(); 4235 } 4236 } 4237 4238 @Override 4239 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4240 synchronized (this) { 4241 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4242 if (r == null) { 4243 return; 4244 } 4245 final long origId = Binder.clearCallingIdentity(); 4246 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4247 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4248 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4249 if (config != null) { 4250 r.frozenBeforeDestroy = true; 4251 if (!updateConfigurationLocked(config, r, false, false)) { 4252 mStackSupervisor.resumeTopActivitiesLocked(); 4253 } 4254 } 4255 Binder.restoreCallingIdentity(origId); 4256 } 4257 } 4258 4259 @Override 4260 public int getRequestedOrientation(IBinder token) { 4261 synchronized (this) { 4262 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4263 if (r == null) { 4264 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4265 } 4266 return mWindowManager.getAppOrientation(r.appToken); 4267 } 4268 } 4269 4270 /** 4271 * This is the internal entry point for handling Activity.finish(). 4272 * 4273 * @param token The Binder token referencing the Activity we want to finish. 4274 * @param resultCode Result code, if any, from this Activity. 4275 * @param resultData Result data (Intent), if any, from this Activity. 4276 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4277 * the root Activity in the task. 4278 * 4279 * @return Returns true if the activity successfully finished, or false if it is still running. 4280 */ 4281 @Override 4282 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4283 boolean finishTask) { 4284 // Refuse possible leaked file descriptors 4285 if (resultData != null && resultData.hasFileDescriptors() == true) { 4286 throw new IllegalArgumentException("File descriptors passed in Intent"); 4287 } 4288 4289 synchronized(this) { 4290 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4291 if (r == null) { 4292 return true; 4293 } 4294 // Keep track of the root activity of the task before we finish it 4295 TaskRecord tr = r.task; 4296 ActivityRecord rootR = tr.getRootActivity(); 4297 if (rootR == null) { 4298 Slog.w(TAG, "Finishing task with all activities already finished"); 4299 } 4300 // Do not allow task to finish in Lock Task mode. 4301 if (tr == mStackSupervisor.mLockTaskModeTask) { 4302 if (rootR == r) { 4303 Slog.i(TAG, "Not finishing task in lock task mode"); 4304 mStackSupervisor.showLockTaskToast(); 4305 return false; 4306 } 4307 } 4308 if (mController != null) { 4309 // Find the first activity that is not finishing. 4310 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4311 if (next != null) { 4312 // ask watcher if this is allowed 4313 boolean resumeOK = true; 4314 try { 4315 resumeOK = mController.activityResuming(next.packageName); 4316 } catch (RemoteException e) { 4317 mController = null; 4318 Watchdog.getInstance().setActivityController(null); 4319 } 4320 4321 if (!resumeOK) { 4322 Slog.i(TAG, "Not finishing activity because controller resumed"); 4323 return false; 4324 } 4325 } 4326 } 4327 final long origId = Binder.clearCallingIdentity(); 4328 try { 4329 boolean res; 4330 if (finishTask && r == rootR) { 4331 // If requested, remove the task that is associated to this activity only if it 4332 // was the root activity in the task. The result code and data is ignored 4333 // because we don't support returning them across task boundaries. 4334 res = removeTaskByIdLocked(tr.taskId, false); 4335 if (!res) { 4336 Slog.i(TAG, "Removing task failed to finish activity"); 4337 } 4338 } else { 4339 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4340 resultData, "app-request", true); 4341 if (!res) { 4342 Slog.i(TAG, "Failed to finish by app-request"); 4343 } 4344 } 4345 return res; 4346 } finally { 4347 Binder.restoreCallingIdentity(origId); 4348 } 4349 } 4350 } 4351 4352 @Override 4353 public final void finishHeavyWeightApp() { 4354 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4355 != PackageManager.PERMISSION_GRANTED) { 4356 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4357 + Binder.getCallingPid() 4358 + ", uid=" + Binder.getCallingUid() 4359 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4360 Slog.w(TAG, msg); 4361 throw new SecurityException(msg); 4362 } 4363 4364 synchronized(this) { 4365 if (mHeavyWeightProcess == null) { 4366 return; 4367 } 4368 4369 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4370 mHeavyWeightProcess.activities); 4371 for (int i=0; i<activities.size(); i++) { 4372 ActivityRecord r = activities.get(i); 4373 if (!r.finishing) { 4374 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4375 null, "finish-heavy", true); 4376 } 4377 } 4378 4379 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4380 mHeavyWeightProcess.userId, 0)); 4381 mHeavyWeightProcess = null; 4382 } 4383 } 4384 4385 @Override 4386 public void crashApplication(int uid, int initialPid, String packageName, 4387 String message) { 4388 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4389 != PackageManager.PERMISSION_GRANTED) { 4390 String msg = "Permission Denial: crashApplication() from pid=" 4391 + Binder.getCallingPid() 4392 + ", uid=" + Binder.getCallingUid() 4393 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4394 Slog.w(TAG, msg); 4395 throw new SecurityException(msg); 4396 } 4397 4398 synchronized(this) { 4399 ProcessRecord proc = null; 4400 4401 // Figure out which process to kill. We don't trust that initialPid 4402 // still has any relation to current pids, so must scan through the 4403 // list. 4404 synchronized (mPidsSelfLocked) { 4405 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4406 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4407 if (p.uid != uid) { 4408 continue; 4409 } 4410 if (p.pid == initialPid) { 4411 proc = p; 4412 break; 4413 } 4414 if (p.pkgList.containsKey(packageName)) { 4415 proc = p; 4416 } 4417 } 4418 } 4419 4420 if (proc == null) { 4421 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4422 + " initialPid=" + initialPid 4423 + " packageName=" + packageName); 4424 return; 4425 } 4426 4427 if (proc.thread != null) { 4428 if (proc.pid == Process.myPid()) { 4429 Log.w(TAG, "crashApplication: trying to crash self!"); 4430 return; 4431 } 4432 long ident = Binder.clearCallingIdentity(); 4433 try { 4434 proc.thread.scheduleCrash(message); 4435 } catch (RemoteException e) { 4436 } 4437 Binder.restoreCallingIdentity(ident); 4438 } 4439 } 4440 } 4441 4442 @Override 4443 public final void finishSubActivity(IBinder token, String resultWho, 4444 int requestCode) { 4445 synchronized(this) { 4446 final long origId = Binder.clearCallingIdentity(); 4447 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4448 if (r != null) { 4449 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4450 } 4451 Binder.restoreCallingIdentity(origId); 4452 } 4453 } 4454 4455 @Override 4456 public boolean finishActivityAffinity(IBinder token) { 4457 synchronized(this) { 4458 final long origId = Binder.clearCallingIdentity(); 4459 try { 4460 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4461 4462 ActivityRecord rootR = r.task.getRootActivity(); 4463 // Do not allow task to finish in Lock Task mode. 4464 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4465 if (rootR == r) { 4466 mStackSupervisor.showLockTaskToast(); 4467 return false; 4468 } 4469 } 4470 boolean res = false; 4471 if (r != null) { 4472 res = r.task.stack.finishActivityAffinityLocked(r); 4473 } 4474 return res; 4475 } finally { 4476 Binder.restoreCallingIdentity(origId); 4477 } 4478 } 4479 } 4480 4481 @Override 4482 public void finishVoiceTask(IVoiceInteractionSession session) { 4483 synchronized(this) { 4484 final long origId = Binder.clearCallingIdentity(); 4485 try { 4486 mStackSupervisor.finishVoiceTask(session); 4487 } finally { 4488 Binder.restoreCallingIdentity(origId); 4489 } 4490 } 4491 4492 } 4493 4494 @Override 4495 public boolean releaseActivityInstance(IBinder token) { 4496 synchronized(this) { 4497 final long origId = Binder.clearCallingIdentity(); 4498 try { 4499 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4500 if (r.task == null || r.task.stack == null) { 4501 return false; 4502 } 4503 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4504 } finally { 4505 Binder.restoreCallingIdentity(origId); 4506 } 4507 } 4508 } 4509 4510 @Override 4511 public void releaseSomeActivities(IApplicationThread appInt) { 4512 synchronized(this) { 4513 final long origId = Binder.clearCallingIdentity(); 4514 try { 4515 ProcessRecord app = getRecordForAppLocked(appInt); 4516 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4517 } finally { 4518 Binder.restoreCallingIdentity(origId); 4519 } 4520 } 4521 } 4522 4523 @Override 4524 public boolean willActivityBeVisible(IBinder token) { 4525 synchronized(this) { 4526 ActivityStack stack = ActivityRecord.getStackLocked(token); 4527 if (stack != null) { 4528 return stack.willActivityBeVisibleLocked(token); 4529 } 4530 return false; 4531 } 4532 } 4533 4534 @Override 4535 public void overridePendingTransition(IBinder token, String packageName, 4536 int enterAnim, int exitAnim) { 4537 synchronized(this) { 4538 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4539 if (self == null) { 4540 return; 4541 } 4542 4543 final long origId = Binder.clearCallingIdentity(); 4544 4545 if (self.state == ActivityState.RESUMED 4546 || self.state == ActivityState.PAUSING) { 4547 mWindowManager.overridePendingAppTransition(packageName, 4548 enterAnim, exitAnim, null); 4549 } 4550 4551 Binder.restoreCallingIdentity(origId); 4552 } 4553 } 4554 4555 /** 4556 * Main function for removing an existing process from the activity manager 4557 * as a result of that process going away. Clears out all connections 4558 * to the process. 4559 */ 4560 private final void handleAppDiedLocked(ProcessRecord app, 4561 boolean restarting, boolean allowRestart) { 4562 int pid = app.pid; 4563 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4564 if (!kept && !restarting) { 4565 removeLruProcessLocked(app); 4566 if (pid > 0) { 4567 ProcessList.remove(pid); 4568 } 4569 } 4570 4571 if (mProfileProc == app) { 4572 clearProfilerLocked(); 4573 } 4574 4575 // Remove this application's activities from active lists. 4576 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4577 4578 app.activities.clear(); 4579 4580 if (app.instrumentationClass != null) { 4581 Slog.w(TAG, "Crash of app " + app.processName 4582 + " running instrumentation " + app.instrumentationClass); 4583 Bundle info = new Bundle(); 4584 info.putString("shortMsg", "Process crashed."); 4585 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4586 } 4587 4588 if (!restarting) { 4589 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4590 // If there was nothing to resume, and we are not already 4591 // restarting this process, but there is a visible activity that 4592 // is hosted by the process... then make sure all visible 4593 // activities are running, taking care of restarting this 4594 // process. 4595 if (hasVisibleActivities) { 4596 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4597 } 4598 } 4599 } 4600 } 4601 4602 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4603 IBinder threadBinder = thread.asBinder(); 4604 // Find the application record. 4605 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4606 ProcessRecord rec = mLruProcesses.get(i); 4607 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4608 return i; 4609 } 4610 } 4611 return -1; 4612 } 4613 4614 final ProcessRecord getRecordForAppLocked( 4615 IApplicationThread thread) { 4616 if (thread == null) { 4617 return null; 4618 } 4619 4620 int appIndex = getLRURecordIndexForAppLocked(thread); 4621 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4622 } 4623 4624 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4625 // If there are no longer any background processes running, 4626 // and the app that died was not running instrumentation, 4627 // then tell everyone we are now low on memory. 4628 boolean haveBg = false; 4629 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4630 ProcessRecord rec = mLruProcesses.get(i); 4631 if (rec.thread != null 4632 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4633 haveBg = true; 4634 break; 4635 } 4636 } 4637 4638 if (!haveBg) { 4639 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4640 if (doReport) { 4641 long now = SystemClock.uptimeMillis(); 4642 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4643 doReport = false; 4644 } else { 4645 mLastMemUsageReportTime = now; 4646 } 4647 } 4648 final ArrayList<ProcessMemInfo> memInfos 4649 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4650 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4651 long now = SystemClock.uptimeMillis(); 4652 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4653 ProcessRecord rec = mLruProcesses.get(i); 4654 if (rec == dyingProc || rec.thread == null) { 4655 continue; 4656 } 4657 if (doReport) { 4658 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4659 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4660 } 4661 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4662 // The low memory report is overriding any current 4663 // state for a GC request. Make sure to do 4664 // heavy/important/visible/foreground processes first. 4665 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4666 rec.lastRequestedGc = 0; 4667 } else { 4668 rec.lastRequestedGc = rec.lastLowMemory; 4669 } 4670 rec.reportLowMemory = true; 4671 rec.lastLowMemory = now; 4672 mProcessesToGc.remove(rec); 4673 addProcessToGcListLocked(rec); 4674 } 4675 } 4676 if (doReport) { 4677 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4678 mHandler.sendMessage(msg); 4679 } 4680 scheduleAppGcsLocked(); 4681 } 4682 } 4683 4684 final void appDiedLocked(ProcessRecord app) { 4685 appDiedLocked(app, app.pid, app.thread); 4686 } 4687 4688 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4689 // First check if this ProcessRecord is actually active for the pid. 4690 synchronized (mPidsSelfLocked) { 4691 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4692 if (curProc != app) { 4693 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4694 return; 4695 } 4696 } 4697 4698 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4699 synchronized (stats) { 4700 stats.noteProcessDiedLocked(app.info.uid, pid); 4701 } 4702 4703 Process.killProcessQuiet(pid); 4704 Process.killProcessGroup(app.info.uid, pid); 4705 app.killed = true; 4706 4707 // Clean up already done if the process has been re-started. 4708 if (app.pid == pid && app.thread != null && 4709 app.thread.asBinder() == thread.asBinder()) { 4710 boolean doLowMem = app.instrumentationClass == null; 4711 boolean doOomAdj = doLowMem; 4712 if (!app.killedByAm) { 4713 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4714 + ") has died"); 4715 mAllowLowerMemLevel = true; 4716 } else { 4717 // Note that we always want to do oom adj to update our state with the 4718 // new number of procs. 4719 mAllowLowerMemLevel = false; 4720 doLowMem = false; 4721 } 4722 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4723 if (DEBUG_CLEANUP) Slog.v( 4724 TAG, "Dying app: " + app + ", pid: " + pid 4725 + ", thread: " + thread.asBinder()); 4726 handleAppDiedLocked(app, false, true); 4727 4728 if (doOomAdj) { 4729 updateOomAdjLocked(); 4730 } 4731 if (doLowMem) { 4732 doLowMemReportIfNeededLocked(app); 4733 } 4734 } else if (app.pid != pid) { 4735 // A new process has already been started. 4736 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4737 + ") has died and restarted (pid " + app.pid + ")."); 4738 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4739 } else if (DEBUG_PROCESSES) { 4740 Slog.d(TAG, "Received spurious death notification for thread " 4741 + thread.asBinder()); 4742 } 4743 } 4744 4745 /** 4746 * If a stack trace dump file is configured, dump process stack traces. 4747 * @param clearTraces causes the dump file to be erased prior to the new 4748 * traces being written, if true; when false, the new traces will be 4749 * appended to any existing file content. 4750 * @param firstPids of dalvik VM processes to dump stack traces for first 4751 * @param lastPids of dalvik VM processes to dump stack traces for last 4752 * @param nativeProcs optional list of native process names to dump stack crawls 4753 * @return file containing stack traces, or null if no dump file is configured 4754 */ 4755 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4756 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4757 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4758 if (tracesPath == null || tracesPath.length() == 0) { 4759 return null; 4760 } 4761 4762 File tracesFile = new File(tracesPath); 4763 try { 4764 File tracesDir = tracesFile.getParentFile(); 4765 if (!tracesDir.exists()) { 4766 tracesDir.mkdirs(); 4767 if (!SELinux.restorecon(tracesDir)) { 4768 return null; 4769 } 4770 } 4771 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4772 4773 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4774 tracesFile.createNewFile(); 4775 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4776 } catch (IOException e) { 4777 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4778 return null; 4779 } 4780 4781 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4782 return tracesFile; 4783 } 4784 4785 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4786 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4787 // Use a FileObserver to detect when traces finish writing. 4788 // The order of traces is considered important to maintain for legibility. 4789 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4790 @Override 4791 public synchronized void onEvent(int event, String path) { notify(); } 4792 }; 4793 4794 try { 4795 observer.startWatching(); 4796 4797 // First collect all of the stacks of the most important pids. 4798 if (firstPids != null) { 4799 try { 4800 int num = firstPids.size(); 4801 for (int i = 0; i < num; i++) { 4802 synchronized (observer) { 4803 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4804 observer.wait(200); // Wait for write-close, give up after 200msec 4805 } 4806 } 4807 } catch (InterruptedException e) { 4808 Slog.wtf(TAG, e); 4809 } 4810 } 4811 4812 // Next collect the stacks of the native pids 4813 if (nativeProcs != null) { 4814 int[] pids = Process.getPidsForCommands(nativeProcs); 4815 if (pids != null) { 4816 for (int pid : pids) { 4817 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4818 } 4819 } 4820 } 4821 4822 // Lastly, measure CPU usage. 4823 if (processCpuTracker != null) { 4824 processCpuTracker.init(); 4825 System.gc(); 4826 processCpuTracker.update(); 4827 try { 4828 synchronized (processCpuTracker) { 4829 processCpuTracker.wait(500); // measure over 1/2 second. 4830 } 4831 } catch (InterruptedException e) { 4832 } 4833 processCpuTracker.update(); 4834 4835 // We'll take the stack crawls of just the top apps using CPU. 4836 final int N = processCpuTracker.countWorkingStats(); 4837 int numProcs = 0; 4838 for (int i=0; i<N && numProcs<5; i++) { 4839 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4840 if (lastPids.indexOfKey(stats.pid) >= 0) { 4841 numProcs++; 4842 try { 4843 synchronized (observer) { 4844 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4845 observer.wait(200); // Wait for write-close, give up after 200msec 4846 } 4847 } catch (InterruptedException e) { 4848 Slog.wtf(TAG, e); 4849 } 4850 4851 } 4852 } 4853 } 4854 } finally { 4855 observer.stopWatching(); 4856 } 4857 } 4858 4859 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4860 if (true || IS_USER_BUILD) { 4861 return; 4862 } 4863 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4864 if (tracesPath == null || tracesPath.length() == 0) { 4865 return; 4866 } 4867 4868 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4869 StrictMode.allowThreadDiskWrites(); 4870 try { 4871 final File tracesFile = new File(tracesPath); 4872 final File tracesDir = tracesFile.getParentFile(); 4873 final File tracesTmp = new File(tracesDir, "__tmp__"); 4874 try { 4875 if (!tracesDir.exists()) { 4876 tracesDir.mkdirs(); 4877 if (!SELinux.restorecon(tracesDir.getPath())) { 4878 return; 4879 } 4880 } 4881 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4882 4883 if (tracesFile.exists()) { 4884 tracesTmp.delete(); 4885 tracesFile.renameTo(tracesTmp); 4886 } 4887 StringBuilder sb = new StringBuilder(); 4888 Time tobj = new Time(); 4889 tobj.set(System.currentTimeMillis()); 4890 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4891 sb.append(": "); 4892 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4893 sb.append(" since "); 4894 sb.append(msg); 4895 FileOutputStream fos = new FileOutputStream(tracesFile); 4896 fos.write(sb.toString().getBytes()); 4897 if (app == null) { 4898 fos.write("\n*** No application process!".getBytes()); 4899 } 4900 fos.close(); 4901 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4902 } catch (IOException e) { 4903 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4904 return; 4905 } 4906 4907 if (app != null) { 4908 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4909 firstPids.add(app.pid); 4910 dumpStackTraces(tracesPath, firstPids, null, null, null); 4911 } 4912 4913 File lastTracesFile = null; 4914 File curTracesFile = null; 4915 for (int i=9; i>=0; i--) { 4916 String name = String.format(Locale.US, "slow%02d.txt", i); 4917 curTracesFile = new File(tracesDir, name); 4918 if (curTracesFile.exists()) { 4919 if (lastTracesFile != null) { 4920 curTracesFile.renameTo(lastTracesFile); 4921 } else { 4922 curTracesFile.delete(); 4923 } 4924 } 4925 lastTracesFile = curTracesFile; 4926 } 4927 tracesFile.renameTo(curTracesFile); 4928 if (tracesTmp.exists()) { 4929 tracesTmp.renameTo(tracesFile); 4930 } 4931 } finally { 4932 StrictMode.setThreadPolicy(oldPolicy); 4933 } 4934 } 4935 4936 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4937 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4938 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4939 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4940 4941 if (mController != null) { 4942 try { 4943 // 0 == continue, -1 = kill process immediately 4944 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4945 if (res < 0 && app.pid != MY_PID) { 4946 app.kill("anr", true); 4947 } 4948 } catch (RemoteException e) { 4949 mController = null; 4950 Watchdog.getInstance().setActivityController(null); 4951 } 4952 } 4953 4954 long anrTime = SystemClock.uptimeMillis(); 4955 if (MONITOR_CPU_USAGE) { 4956 updateCpuStatsNow(); 4957 } 4958 4959 synchronized (this) { 4960 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4961 if (mShuttingDown) { 4962 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4963 return; 4964 } else if (app.notResponding) { 4965 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4966 return; 4967 } else if (app.crashing) { 4968 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4969 return; 4970 } 4971 4972 // In case we come through here for the same app before completing 4973 // this one, mark as anring now so we will bail out. 4974 app.notResponding = true; 4975 4976 // Log the ANR to the event log. 4977 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4978 app.processName, app.info.flags, annotation); 4979 4980 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4981 firstPids.add(app.pid); 4982 4983 int parentPid = app.pid; 4984 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4985 if (parentPid != app.pid) firstPids.add(parentPid); 4986 4987 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4988 4989 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4990 ProcessRecord r = mLruProcesses.get(i); 4991 if (r != null && r.thread != null) { 4992 int pid = r.pid; 4993 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4994 if (r.persistent) { 4995 firstPids.add(pid); 4996 } else { 4997 lastPids.put(pid, Boolean.TRUE); 4998 } 4999 } 5000 } 5001 } 5002 } 5003 5004 // Log the ANR to the main log. 5005 StringBuilder info = new StringBuilder(); 5006 info.setLength(0); 5007 info.append("ANR in ").append(app.processName); 5008 if (activity != null && activity.shortComponentName != null) { 5009 info.append(" (").append(activity.shortComponentName).append(")"); 5010 } 5011 info.append("\n"); 5012 info.append("PID: ").append(app.pid).append("\n"); 5013 if (annotation != null) { 5014 info.append("Reason: ").append(annotation).append("\n"); 5015 } 5016 if (parent != null && parent != activity) { 5017 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5018 } 5019 5020 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5021 5022 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5023 NATIVE_STACKS_OF_INTEREST); 5024 5025 String cpuInfo = null; 5026 if (MONITOR_CPU_USAGE) { 5027 updateCpuStatsNow(); 5028 synchronized (mProcessCpuTracker) { 5029 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5030 } 5031 info.append(processCpuTracker.printCurrentLoad()); 5032 info.append(cpuInfo); 5033 } 5034 5035 info.append(processCpuTracker.printCurrentState(anrTime)); 5036 5037 Slog.e(TAG, info.toString()); 5038 if (tracesFile == null) { 5039 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5040 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5041 } 5042 5043 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5044 cpuInfo, tracesFile, null); 5045 5046 if (mController != null) { 5047 try { 5048 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5049 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5050 if (res != 0) { 5051 if (res < 0 && app.pid != MY_PID) { 5052 app.kill("anr", true); 5053 } else { 5054 synchronized (this) { 5055 mServices.scheduleServiceTimeoutLocked(app); 5056 } 5057 } 5058 return; 5059 } 5060 } catch (RemoteException e) { 5061 mController = null; 5062 Watchdog.getInstance().setActivityController(null); 5063 } 5064 } 5065 5066 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5067 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5068 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5069 5070 synchronized (this) { 5071 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5072 app.kill("bg anr", true); 5073 return; 5074 } 5075 5076 // Set the app's notResponding state, and look up the errorReportReceiver 5077 makeAppNotRespondingLocked(app, 5078 activity != null ? activity.shortComponentName : null, 5079 annotation != null ? "ANR " + annotation : "ANR", 5080 info.toString()); 5081 5082 // Bring up the infamous App Not Responding dialog 5083 Message msg = Message.obtain(); 5084 HashMap<String, Object> map = new HashMap<String, Object>(); 5085 msg.what = SHOW_NOT_RESPONDING_MSG; 5086 msg.obj = map; 5087 msg.arg1 = aboveSystem ? 1 : 0; 5088 map.put("app", app); 5089 if (activity != null) { 5090 map.put("activity", activity); 5091 } 5092 5093 mHandler.sendMessage(msg); 5094 } 5095 } 5096 5097 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5098 if (!mLaunchWarningShown) { 5099 mLaunchWarningShown = true; 5100 mHandler.post(new Runnable() { 5101 @Override 5102 public void run() { 5103 synchronized (ActivityManagerService.this) { 5104 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5105 d.show(); 5106 mHandler.postDelayed(new Runnable() { 5107 @Override 5108 public void run() { 5109 synchronized (ActivityManagerService.this) { 5110 d.dismiss(); 5111 mLaunchWarningShown = false; 5112 } 5113 } 5114 }, 4000); 5115 } 5116 } 5117 }); 5118 } 5119 } 5120 5121 @Override 5122 public boolean clearApplicationUserData(final String packageName, 5123 final IPackageDataObserver observer, int userId) { 5124 enforceNotIsolatedCaller("clearApplicationUserData"); 5125 int uid = Binder.getCallingUid(); 5126 int pid = Binder.getCallingPid(); 5127 userId = handleIncomingUser(pid, uid, 5128 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5129 long callingId = Binder.clearCallingIdentity(); 5130 try { 5131 IPackageManager pm = AppGlobals.getPackageManager(); 5132 int pkgUid = -1; 5133 synchronized(this) { 5134 try { 5135 pkgUid = pm.getPackageUid(packageName, userId); 5136 } catch (RemoteException e) { 5137 } 5138 if (pkgUid == -1) { 5139 Slog.w(TAG, "Invalid packageName: " + packageName); 5140 if (observer != null) { 5141 try { 5142 observer.onRemoveCompleted(packageName, false); 5143 } catch (RemoteException e) { 5144 Slog.i(TAG, "Observer no longer exists."); 5145 } 5146 } 5147 return false; 5148 } 5149 if (uid == pkgUid || checkComponentPermission( 5150 android.Manifest.permission.CLEAR_APP_USER_DATA, 5151 pid, uid, -1, true) 5152 == PackageManager.PERMISSION_GRANTED) { 5153 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5154 } else { 5155 throw new SecurityException("PID " + pid + " does not have permission " 5156 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5157 + " of package " + packageName); 5158 } 5159 5160 // Remove all tasks match the cleared application package and user 5161 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5162 final TaskRecord tr = mRecentTasks.get(i); 5163 final String taskPackageName = 5164 tr.getBaseIntent().getComponent().getPackageName(); 5165 if (tr.userId != userId) continue; 5166 if (!taskPackageName.equals(packageName)) continue; 5167 removeTaskByIdLocked(tr.taskId, false); 5168 } 5169 } 5170 5171 try { 5172 // Clear application user data 5173 pm.clearApplicationUserData(packageName, observer, userId); 5174 5175 synchronized(this) { 5176 // Remove all permissions granted from/to this package 5177 removeUriPermissionsForPackageLocked(packageName, userId, true); 5178 } 5179 5180 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5181 Uri.fromParts("package", packageName, null)); 5182 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5183 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5184 null, null, 0, null, null, null, false, false, userId); 5185 } catch (RemoteException e) { 5186 } 5187 } finally { 5188 Binder.restoreCallingIdentity(callingId); 5189 } 5190 return true; 5191 } 5192 5193 @Override 5194 public void killBackgroundProcesses(final String packageName, int userId) { 5195 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5196 != PackageManager.PERMISSION_GRANTED && 5197 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5198 != PackageManager.PERMISSION_GRANTED) { 5199 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5200 + Binder.getCallingPid() 5201 + ", uid=" + Binder.getCallingUid() 5202 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5203 Slog.w(TAG, msg); 5204 throw new SecurityException(msg); 5205 } 5206 5207 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5208 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5209 long callingId = Binder.clearCallingIdentity(); 5210 try { 5211 IPackageManager pm = AppGlobals.getPackageManager(); 5212 synchronized(this) { 5213 int appId = -1; 5214 try { 5215 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5216 } catch (RemoteException e) { 5217 } 5218 if (appId == -1) { 5219 Slog.w(TAG, "Invalid packageName: " + packageName); 5220 return; 5221 } 5222 killPackageProcessesLocked(packageName, appId, userId, 5223 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5224 } 5225 } finally { 5226 Binder.restoreCallingIdentity(callingId); 5227 } 5228 } 5229 5230 @Override 5231 public void killAllBackgroundProcesses() { 5232 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5233 != PackageManager.PERMISSION_GRANTED) { 5234 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5235 + Binder.getCallingPid() 5236 + ", uid=" + Binder.getCallingUid() 5237 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5238 Slog.w(TAG, msg); 5239 throw new SecurityException(msg); 5240 } 5241 5242 long callingId = Binder.clearCallingIdentity(); 5243 try { 5244 synchronized(this) { 5245 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5246 final int NP = mProcessNames.getMap().size(); 5247 for (int ip=0; ip<NP; ip++) { 5248 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5249 final int NA = apps.size(); 5250 for (int ia=0; ia<NA; ia++) { 5251 ProcessRecord app = apps.valueAt(ia); 5252 if (app.persistent) { 5253 // we don't kill persistent processes 5254 continue; 5255 } 5256 if (app.removed) { 5257 procs.add(app); 5258 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5259 app.removed = true; 5260 procs.add(app); 5261 } 5262 } 5263 } 5264 5265 int N = procs.size(); 5266 for (int i=0; i<N; i++) { 5267 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5268 } 5269 mAllowLowerMemLevel = true; 5270 updateOomAdjLocked(); 5271 doLowMemReportIfNeededLocked(null); 5272 } 5273 } finally { 5274 Binder.restoreCallingIdentity(callingId); 5275 } 5276 } 5277 5278 @Override 5279 public void forceStopPackage(final String packageName, int userId) { 5280 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5281 != PackageManager.PERMISSION_GRANTED) { 5282 String msg = "Permission Denial: forceStopPackage() from pid=" 5283 + Binder.getCallingPid() 5284 + ", uid=" + Binder.getCallingUid() 5285 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5286 Slog.w(TAG, msg); 5287 throw new SecurityException(msg); 5288 } 5289 final int callingPid = Binder.getCallingPid(); 5290 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5291 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5292 long callingId = Binder.clearCallingIdentity(); 5293 try { 5294 IPackageManager pm = AppGlobals.getPackageManager(); 5295 synchronized(this) { 5296 int[] users = userId == UserHandle.USER_ALL 5297 ? getUsersLocked() : new int[] { userId }; 5298 for (int user : users) { 5299 int pkgUid = -1; 5300 try { 5301 pkgUid = pm.getPackageUid(packageName, user); 5302 } catch (RemoteException e) { 5303 } 5304 if (pkgUid == -1) { 5305 Slog.w(TAG, "Invalid packageName: " + packageName); 5306 continue; 5307 } 5308 try { 5309 pm.setPackageStoppedState(packageName, true, user); 5310 } catch (RemoteException e) { 5311 } catch (IllegalArgumentException e) { 5312 Slog.w(TAG, "Failed trying to unstop package " 5313 + packageName + ": " + e); 5314 } 5315 if (isUserRunningLocked(user, false)) { 5316 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5317 } 5318 } 5319 } 5320 } finally { 5321 Binder.restoreCallingIdentity(callingId); 5322 } 5323 } 5324 5325 @Override 5326 public void addPackageDependency(String packageName) { 5327 synchronized (this) { 5328 int callingPid = Binder.getCallingPid(); 5329 if (callingPid == Process.myPid()) { 5330 // Yeah, um, no. 5331 Slog.w(TAG, "Can't addPackageDependency on system process"); 5332 return; 5333 } 5334 ProcessRecord proc; 5335 synchronized (mPidsSelfLocked) { 5336 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5337 } 5338 if (proc != null) { 5339 if (proc.pkgDeps == null) { 5340 proc.pkgDeps = new ArraySet<String>(1); 5341 } 5342 proc.pkgDeps.add(packageName); 5343 } 5344 } 5345 } 5346 5347 /* 5348 * The pkg name and app id have to be specified. 5349 */ 5350 @Override 5351 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5352 if (pkg == null) { 5353 return; 5354 } 5355 // Make sure the uid is valid. 5356 if (appid < 0) { 5357 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5358 return; 5359 } 5360 int callerUid = Binder.getCallingUid(); 5361 // Only the system server can kill an application 5362 if (callerUid == Process.SYSTEM_UID) { 5363 // Post an aysnc message to kill the application 5364 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5365 msg.arg1 = appid; 5366 msg.arg2 = 0; 5367 Bundle bundle = new Bundle(); 5368 bundle.putString("pkg", pkg); 5369 bundle.putString("reason", reason); 5370 msg.obj = bundle; 5371 mHandler.sendMessage(msg); 5372 } else { 5373 throw new SecurityException(callerUid + " cannot kill pkg: " + 5374 pkg); 5375 } 5376 } 5377 5378 @Override 5379 public void closeSystemDialogs(String reason) { 5380 enforceNotIsolatedCaller("closeSystemDialogs"); 5381 5382 final int pid = Binder.getCallingPid(); 5383 final int uid = Binder.getCallingUid(); 5384 final long origId = Binder.clearCallingIdentity(); 5385 try { 5386 synchronized (this) { 5387 // Only allow this from foreground processes, so that background 5388 // applications can't abuse it to prevent system UI from being shown. 5389 if (uid >= Process.FIRST_APPLICATION_UID) { 5390 ProcessRecord proc; 5391 synchronized (mPidsSelfLocked) { 5392 proc = mPidsSelfLocked.get(pid); 5393 } 5394 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5395 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5396 + " from background process " + proc); 5397 return; 5398 } 5399 } 5400 closeSystemDialogsLocked(reason); 5401 } 5402 } finally { 5403 Binder.restoreCallingIdentity(origId); 5404 } 5405 } 5406 5407 void closeSystemDialogsLocked(String reason) { 5408 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5409 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5410 | Intent.FLAG_RECEIVER_FOREGROUND); 5411 if (reason != null) { 5412 intent.putExtra("reason", reason); 5413 } 5414 mWindowManager.closeSystemDialogs(reason); 5415 5416 mStackSupervisor.closeSystemDialogsLocked(); 5417 5418 broadcastIntentLocked(null, null, intent, null, 5419 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5420 Process.SYSTEM_UID, UserHandle.USER_ALL); 5421 } 5422 5423 @Override 5424 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5425 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5426 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5427 for (int i=pids.length-1; i>=0; i--) { 5428 ProcessRecord proc; 5429 int oomAdj; 5430 synchronized (this) { 5431 synchronized (mPidsSelfLocked) { 5432 proc = mPidsSelfLocked.get(pids[i]); 5433 oomAdj = proc != null ? proc.setAdj : 0; 5434 } 5435 } 5436 infos[i] = new Debug.MemoryInfo(); 5437 Debug.getMemoryInfo(pids[i], infos[i]); 5438 if (proc != null) { 5439 synchronized (this) { 5440 if (proc.thread != null && proc.setAdj == oomAdj) { 5441 // Record this for posterity if the process has been stable. 5442 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5443 infos[i].getTotalUss(), false, proc.pkgList); 5444 } 5445 } 5446 } 5447 } 5448 return infos; 5449 } 5450 5451 @Override 5452 public long[] getProcessPss(int[] pids) { 5453 enforceNotIsolatedCaller("getProcessPss"); 5454 long[] pss = new long[pids.length]; 5455 for (int i=pids.length-1; i>=0; i--) { 5456 ProcessRecord proc; 5457 int oomAdj; 5458 synchronized (this) { 5459 synchronized (mPidsSelfLocked) { 5460 proc = mPidsSelfLocked.get(pids[i]); 5461 oomAdj = proc != null ? proc.setAdj : 0; 5462 } 5463 } 5464 long[] tmpUss = new long[1]; 5465 pss[i] = Debug.getPss(pids[i], tmpUss); 5466 if (proc != null) { 5467 synchronized (this) { 5468 if (proc.thread != null && proc.setAdj == oomAdj) { 5469 // Record this for posterity if the process has been stable. 5470 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5471 } 5472 } 5473 } 5474 } 5475 return pss; 5476 } 5477 5478 @Override 5479 public void killApplicationProcess(String processName, int uid) { 5480 if (processName == null) { 5481 return; 5482 } 5483 5484 int callerUid = Binder.getCallingUid(); 5485 // Only the system server can kill an application 5486 if (callerUid == Process.SYSTEM_UID) { 5487 synchronized (this) { 5488 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5489 if (app != null && app.thread != null) { 5490 try { 5491 app.thread.scheduleSuicide(); 5492 } catch (RemoteException e) { 5493 // If the other end already died, then our work here is done. 5494 } 5495 } else { 5496 Slog.w(TAG, "Process/uid not found attempting kill of " 5497 + processName + " / " + uid); 5498 } 5499 } 5500 } else { 5501 throw new SecurityException(callerUid + " cannot kill app process: " + 5502 processName); 5503 } 5504 } 5505 5506 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5507 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5508 false, true, false, false, UserHandle.getUserId(uid), reason); 5509 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5510 Uri.fromParts("package", packageName, null)); 5511 if (!mProcessesReady) { 5512 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5513 | Intent.FLAG_RECEIVER_FOREGROUND); 5514 } 5515 intent.putExtra(Intent.EXTRA_UID, uid); 5516 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5517 broadcastIntentLocked(null, null, intent, 5518 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5519 false, false, 5520 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5521 } 5522 5523 private void forceStopUserLocked(int userId, String reason) { 5524 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5525 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5527 | Intent.FLAG_RECEIVER_FOREGROUND); 5528 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5529 broadcastIntentLocked(null, null, intent, 5530 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5531 false, false, 5532 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5533 } 5534 5535 private final boolean killPackageProcessesLocked(String packageName, int appId, 5536 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5537 boolean doit, boolean evenPersistent, String reason) { 5538 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5539 5540 // Remove all processes this package may have touched: all with the 5541 // same UID (except for the system or root user), and all whose name 5542 // matches the package name. 5543 final int NP = mProcessNames.getMap().size(); 5544 for (int ip=0; ip<NP; ip++) { 5545 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5546 final int NA = apps.size(); 5547 for (int ia=0; ia<NA; ia++) { 5548 ProcessRecord app = apps.valueAt(ia); 5549 if (app.persistent && !evenPersistent) { 5550 // we don't kill persistent processes 5551 continue; 5552 } 5553 if (app.removed) { 5554 if (doit) { 5555 procs.add(app); 5556 } 5557 continue; 5558 } 5559 5560 // Skip process if it doesn't meet our oom adj requirement. 5561 if (app.setAdj < minOomAdj) { 5562 continue; 5563 } 5564 5565 // If no package is specified, we call all processes under the 5566 // give user id. 5567 if (packageName == null) { 5568 if (app.userId != userId) { 5569 continue; 5570 } 5571 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5572 continue; 5573 } 5574 // Package has been specified, we want to hit all processes 5575 // that match it. We need to qualify this by the processes 5576 // that are running under the specified app and user ID. 5577 } else { 5578 final boolean isDep = app.pkgDeps != null 5579 && app.pkgDeps.contains(packageName); 5580 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5581 continue; 5582 } 5583 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5584 continue; 5585 } 5586 if (!app.pkgList.containsKey(packageName) && !isDep) { 5587 continue; 5588 } 5589 } 5590 5591 // Process has passed all conditions, kill it! 5592 if (!doit) { 5593 return true; 5594 } 5595 app.removed = true; 5596 procs.add(app); 5597 } 5598 } 5599 5600 int N = procs.size(); 5601 for (int i=0; i<N; i++) { 5602 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5603 } 5604 updateOomAdjLocked(); 5605 return N > 0; 5606 } 5607 5608 private final boolean forceStopPackageLocked(String name, int appId, 5609 boolean callerWillRestart, boolean purgeCache, boolean doit, 5610 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5611 int i; 5612 int N; 5613 5614 if (userId == UserHandle.USER_ALL && name == null) { 5615 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5616 } 5617 5618 if (appId < 0 && name != null) { 5619 try { 5620 appId = UserHandle.getAppId( 5621 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5622 } catch (RemoteException e) { 5623 } 5624 } 5625 5626 if (doit) { 5627 if (name != null) { 5628 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5629 + " user=" + userId + ": " + reason); 5630 } else { 5631 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5632 } 5633 5634 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5635 for (int ip=pmap.size()-1; ip>=0; ip--) { 5636 SparseArray<Long> ba = pmap.valueAt(ip); 5637 for (i=ba.size()-1; i>=0; i--) { 5638 boolean remove = false; 5639 final int entUid = ba.keyAt(i); 5640 if (name != null) { 5641 if (userId == UserHandle.USER_ALL) { 5642 if (UserHandle.getAppId(entUid) == appId) { 5643 remove = true; 5644 } 5645 } else { 5646 if (entUid == UserHandle.getUid(userId, appId)) { 5647 remove = true; 5648 } 5649 } 5650 } else if (UserHandle.getUserId(entUid) == userId) { 5651 remove = true; 5652 } 5653 if (remove) { 5654 ba.removeAt(i); 5655 } 5656 } 5657 if (ba.size() == 0) { 5658 pmap.removeAt(ip); 5659 } 5660 } 5661 } 5662 5663 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5664 -100, callerWillRestart, true, doit, evenPersistent, 5665 name == null ? ("stop user " + userId) : ("stop " + name)); 5666 5667 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5668 if (!doit) { 5669 return true; 5670 } 5671 didSomething = true; 5672 } 5673 5674 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5675 if (!doit) { 5676 return true; 5677 } 5678 didSomething = true; 5679 } 5680 5681 if (name == null) { 5682 // Remove all sticky broadcasts from this user. 5683 mStickyBroadcasts.remove(userId); 5684 } 5685 5686 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5687 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5688 userId, providers)) { 5689 if (!doit) { 5690 return true; 5691 } 5692 didSomething = true; 5693 } 5694 N = providers.size(); 5695 for (i=0; i<N; i++) { 5696 removeDyingProviderLocked(null, providers.get(i), true); 5697 } 5698 5699 // Remove transient permissions granted from/to this package/user 5700 removeUriPermissionsForPackageLocked(name, userId, false); 5701 5702 if (name == null || uninstalling) { 5703 // Remove pending intents. For now we only do this when force 5704 // stopping users, because we have some problems when doing this 5705 // for packages -- app widgets are not currently cleaned up for 5706 // such packages, so they can be left with bad pending intents. 5707 if (mIntentSenderRecords.size() > 0) { 5708 Iterator<WeakReference<PendingIntentRecord>> it 5709 = mIntentSenderRecords.values().iterator(); 5710 while (it.hasNext()) { 5711 WeakReference<PendingIntentRecord> wpir = it.next(); 5712 if (wpir == null) { 5713 it.remove(); 5714 continue; 5715 } 5716 PendingIntentRecord pir = wpir.get(); 5717 if (pir == null) { 5718 it.remove(); 5719 continue; 5720 } 5721 if (name == null) { 5722 // Stopping user, remove all objects for the user. 5723 if (pir.key.userId != userId) { 5724 // Not the same user, skip it. 5725 continue; 5726 } 5727 } else { 5728 if (UserHandle.getAppId(pir.uid) != appId) { 5729 // Different app id, skip it. 5730 continue; 5731 } 5732 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5733 // Different user, skip it. 5734 continue; 5735 } 5736 if (!pir.key.packageName.equals(name)) { 5737 // Different package, skip it. 5738 continue; 5739 } 5740 } 5741 if (!doit) { 5742 return true; 5743 } 5744 didSomething = true; 5745 it.remove(); 5746 pir.canceled = true; 5747 if (pir.key.activity != null) { 5748 pir.key.activity.pendingResults.remove(pir.ref); 5749 } 5750 } 5751 } 5752 } 5753 5754 if (doit) { 5755 if (purgeCache && name != null) { 5756 AttributeCache ac = AttributeCache.instance(); 5757 if (ac != null) { 5758 ac.removePackage(name); 5759 } 5760 } 5761 if (mBooted) { 5762 mStackSupervisor.resumeTopActivitiesLocked(); 5763 mStackSupervisor.scheduleIdleLocked(); 5764 } 5765 } 5766 5767 return didSomething; 5768 } 5769 5770 private final boolean removeProcessLocked(ProcessRecord app, 5771 boolean callerWillRestart, boolean allowRestart, String reason) { 5772 final String name = app.processName; 5773 final int uid = app.uid; 5774 if (DEBUG_PROCESSES) Slog.d( 5775 TAG, "Force removing proc " + app.toShortString() + " (" + name 5776 + "/" + uid + ")"); 5777 5778 mProcessNames.remove(name, uid); 5779 mIsolatedProcesses.remove(app.uid); 5780 if (mHeavyWeightProcess == app) { 5781 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5782 mHeavyWeightProcess.userId, 0)); 5783 mHeavyWeightProcess = null; 5784 } 5785 boolean needRestart = false; 5786 if (app.pid > 0 && app.pid != MY_PID) { 5787 int pid = app.pid; 5788 synchronized (mPidsSelfLocked) { 5789 mPidsSelfLocked.remove(pid); 5790 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5791 } 5792 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5793 if (app.isolated) { 5794 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5795 } 5796 app.kill(reason, true); 5797 handleAppDiedLocked(app, true, allowRestart); 5798 removeLruProcessLocked(app); 5799 5800 if (app.persistent && !app.isolated) { 5801 if (!callerWillRestart) { 5802 addAppLocked(app.info, false, null /* ABI override */); 5803 } else { 5804 needRestart = true; 5805 } 5806 } 5807 } else { 5808 mRemovedProcesses.add(app); 5809 } 5810 5811 return needRestart; 5812 } 5813 5814 private final void processStartTimedOutLocked(ProcessRecord app) { 5815 final int pid = app.pid; 5816 boolean gone = false; 5817 synchronized (mPidsSelfLocked) { 5818 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5819 if (knownApp != null && knownApp.thread == null) { 5820 mPidsSelfLocked.remove(pid); 5821 gone = true; 5822 } 5823 } 5824 5825 if (gone) { 5826 Slog.w(TAG, "Process " + app + " failed to attach"); 5827 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5828 pid, app.uid, app.processName); 5829 mProcessNames.remove(app.processName, app.uid); 5830 mIsolatedProcesses.remove(app.uid); 5831 if (mHeavyWeightProcess == app) { 5832 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5833 mHeavyWeightProcess.userId, 0)); 5834 mHeavyWeightProcess = null; 5835 } 5836 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5837 if (app.isolated) { 5838 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5839 } 5840 // Take care of any launching providers waiting for this process. 5841 checkAppInLaunchingProvidersLocked(app, true); 5842 // Take care of any services that are waiting for the process. 5843 mServices.processStartTimedOutLocked(app); 5844 app.kill("start timeout", true); 5845 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5846 Slog.w(TAG, "Unattached app died before backup, skipping"); 5847 try { 5848 IBackupManager bm = IBackupManager.Stub.asInterface( 5849 ServiceManager.getService(Context.BACKUP_SERVICE)); 5850 bm.agentDisconnected(app.info.packageName); 5851 } catch (RemoteException e) { 5852 // Can't happen; the backup manager is local 5853 } 5854 } 5855 if (isPendingBroadcastProcessLocked(pid)) { 5856 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5857 skipPendingBroadcastLocked(pid); 5858 } 5859 } else { 5860 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5861 } 5862 } 5863 5864 private final boolean attachApplicationLocked(IApplicationThread thread, 5865 int pid) { 5866 5867 // Find the application record that is being attached... either via 5868 // the pid if we are running in multiple processes, or just pull the 5869 // next app record if we are emulating process with anonymous threads. 5870 ProcessRecord app; 5871 if (pid != MY_PID && pid >= 0) { 5872 synchronized (mPidsSelfLocked) { 5873 app = mPidsSelfLocked.get(pid); 5874 } 5875 } else { 5876 app = null; 5877 } 5878 5879 if (app == null) { 5880 Slog.w(TAG, "No pending application record for pid " + pid 5881 + " (IApplicationThread " + thread + "); dropping process"); 5882 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5883 if (pid > 0 && pid != MY_PID) { 5884 Process.killProcessQuiet(pid); 5885 //TODO: Process.killProcessGroup(app.info.uid, pid); 5886 } else { 5887 try { 5888 thread.scheduleExit(); 5889 } catch (Exception e) { 5890 // Ignore exceptions. 5891 } 5892 } 5893 return false; 5894 } 5895 5896 // If this application record is still attached to a previous 5897 // process, clean it up now. 5898 if (app.thread != null) { 5899 handleAppDiedLocked(app, true, true); 5900 } 5901 5902 // Tell the process all about itself. 5903 5904 if (localLOGV) Slog.v( 5905 TAG, "Binding process pid " + pid + " to record " + app); 5906 5907 final String processName = app.processName; 5908 try { 5909 AppDeathRecipient adr = new AppDeathRecipient( 5910 app, pid, thread); 5911 thread.asBinder().linkToDeath(adr, 0); 5912 app.deathRecipient = adr; 5913 } catch (RemoteException e) { 5914 app.resetPackageList(mProcessStats); 5915 startProcessLocked(app, "link fail", processName); 5916 return false; 5917 } 5918 5919 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5920 5921 app.makeActive(thread, mProcessStats); 5922 app.curAdj = app.setAdj = -100; 5923 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5924 app.forcingToForeground = null; 5925 updateProcessForegroundLocked(app, false, false); 5926 app.hasShownUi = false; 5927 app.debugging = false; 5928 app.cached = false; 5929 5930 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5931 5932 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5933 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5934 5935 if (!normalMode) { 5936 Slog.i(TAG, "Launching preboot mode app: " + app); 5937 } 5938 5939 if (localLOGV) Slog.v( 5940 TAG, "New app record " + app 5941 + " thread=" + thread.asBinder() + " pid=" + pid); 5942 try { 5943 int testMode = IApplicationThread.DEBUG_OFF; 5944 if (mDebugApp != null && mDebugApp.equals(processName)) { 5945 testMode = mWaitForDebugger 5946 ? IApplicationThread.DEBUG_WAIT 5947 : IApplicationThread.DEBUG_ON; 5948 app.debugging = true; 5949 if (mDebugTransient) { 5950 mDebugApp = mOrigDebugApp; 5951 mWaitForDebugger = mOrigWaitForDebugger; 5952 } 5953 } 5954 String profileFile = app.instrumentationProfileFile; 5955 ParcelFileDescriptor profileFd = null; 5956 int samplingInterval = 0; 5957 boolean profileAutoStop = false; 5958 if (mProfileApp != null && mProfileApp.equals(processName)) { 5959 mProfileProc = app; 5960 profileFile = mProfileFile; 5961 profileFd = mProfileFd; 5962 samplingInterval = mSamplingInterval; 5963 profileAutoStop = mAutoStopProfiler; 5964 } 5965 boolean enableOpenGlTrace = false; 5966 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5967 enableOpenGlTrace = true; 5968 mOpenGlTraceApp = null; 5969 } 5970 5971 // If the app is being launched for restore or full backup, set it up specially 5972 boolean isRestrictedBackupMode = false; 5973 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5974 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5975 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5976 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5977 } 5978 5979 ensurePackageDexOpt(app.instrumentationInfo != null 5980 ? app.instrumentationInfo.packageName 5981 : app.info.packageName); 5982 if (app.instrumentationClass != null) { 5983 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5984 } 5985 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5986 + processName + " with config " + mConfiguration); 5987 ApplicationInfo appInfo = app.instrumentationInfo != null 5988 ? app.instrumentationInfo : app.info; 5989 app.compat = compatibilityInfoForPackageLocked(appInfo); 5990 if (profileFd != null) { 5991 profileFd = profileFd.dup(); 5992 } 5993 ProfilerInfo profilerInfo = profileFile == null ? null 5994 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5995 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5996 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5997 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5998 isRestrictedBackupMode || !normalMode, app.persistent, 5999 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6000 mCoreSettingsObserver.getCoreSettingsLocked()); 6001 updateLruProcessLocked(app, false, null); 6002 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6003 } catch (Exception e) { 6004 // todo: Yikes! What should we do? For now we will try to 6005 // start another process, but that could easily get us in 6006 // an infinite loop of restarting processes... 6007 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6008 6009 app.resetPackageList(mProcessStats); 6010 app.unlinkDeathRecipient(); 6011 startProcessLocked(app, "bind fail", processName); 6012 return false; 6013 } 6014 6015 // Remove this record from the list of starting applications. 6016 mPersistentStartingProcesses.remove(app); 6017 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6018 "Attach application locked removing on hold: " + app); 6019 mProcessesOnHold.remove(app); 6020 6021 boolean badApp = false; 6022 boolean didSomething = false; 6023 6024 // See if the top visible activity is waiting to run in this process... 6025 if (normalMode) { 6026 try { 6027 if (mStackSupervisor.attachApplicationLocked(app)) { 6028 didSomething = true; 6029 } 6030 } catch (Exception e) { 6031 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6032 badApp = true; 6033 } 6034 } 6035 6036 // Find any services that should be running in this process... 6037 if (!badApp) { 6038 try { 6039 didSomething |= mServices.attachApplicationLocked(app, processName); 6040 } catch (Exception e) { 6041 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6042 badApp = true; 6043 } 6044 } 6045 6046 // Check if a next-broadcast receiver is in this process... 6047 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6048 try { 6049 didSomething |= sendPendingBroadcastsLocked(app); 6050 } catch (Exception e) { 6051 // If the app died trying to launch the receiver we declare it 'bad' 6052 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6053 badApp = true; 6054 } 6055 } 6056 6057 // Check whether the next backup agent is in this process... 6058 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6059 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6060 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6061 try { 6062 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6063 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6064 mBackupTarget.backupMode); 6065 } catch (Exception e) { 6066 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6067 badApp = true; 6068 } 6069 } 6070 6071 if (badApp) { 6072 app.kill("error during init", true); 6073 handleAppDiedLocked(app, false, true); 6074 return false; 6075 } 6076 6077 if (!didSomething) { 6078 updateOomAdjLocked(); 6079 } 6080 6081 return true; 6082 } 6083 6084 @Override 6085 public final void attachApplication(IApplicationThread thread) { 6086 synchronized (this) { 6087 int callingPid = Binder.getCallingPid(); 6088 final long origId = Binder.clearCallingIdentity(); 6089 attachApplicationLocked(thread, callingPid); 6090 Binder.restoreCallingIdentity(origId); 6091 } 6092 } 6093 6094 @Override 6095 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6096 final long origId = Binder.clearCallingIdentity(); 6097 synchronized (this) { 6098 ActivityStack stack = ActivityRecord.getStackLocked(token); 6099 if (stack != null) { 6100 ActivityRecord r = 6101 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6102 if (stopProfiling) { 6103 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6104 try { 6105 mProfileFd.close(); 6106 } catch (IOException e) { 6107 } 6108 clearProfilerLocked(); 6109 } 6110 } 6111 } 6112 } 6113 Binder.restoreCallingIdentity(origId); 6114 } 6115 6116 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6117 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6118 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6119 } 6120 6121 void enableScreenAfterBoot() { 6122 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6123 SystemClock.uptimeMillis()); 6124 mWindowManager.enableScreenAfterBoot(); 6125 6126 synchronized (this) { 6127 updateEventDispatchingLocked(); 6128 } 6129 } 6130 6131 @Override 6132 public void showBootMessage(final CharSequence msg, final boolean always) { 6133 enforceNotIsolatedCaller("showBootMessage"); 6134 mWindowManager.showBootMessage(msg, always); 6135 } 6136 6137 @Override 6138 public void keyguardWaitingForActivityDrawn() { 6139 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6140 final long token = Binder.clearCallingIdentity(); 6141 try { 6142 synchronized (this) { 6143 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6144 mWindowManager.keyguardWaitingForActivityDrawn(); 6145 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6146 mLockScreenShown = LOCK_SCREEN_LEAVING; 6147 } 6148 } 6149 } finally { 6150 Binder.restoreCallingIdentity(token); 6151 } 6152 } 6153 6154 final void finishBooting() { 6155 synchronized (this) { 6156 if (!mBootAnimationComplete) { 6157 mCallFinishBooting = true; 6158 return; 6159 } 6160 mCallFinishBooting = false; 6161 } 6162 6163 ArraySet<String> completedIsas = new ArraySet<String>(); 6164 for (String abi : Build.SUPPORTED_ABIS) { 6165 Process.establishZygoteConnectionForAbi(abi); 6166 final String instructionSet = VMRuntime.getInstructionSet(abi); 6167 if (!completedIsas.contains(instructionSet)) { 6168 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6169 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6170 } 6171 completedIsas.add(instructionSet); 6172 } 6173 } 6174 6175 // Register receivers to handle package update events 6176 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6177 6178 // Let system services know. 6179 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6180 6181 synchronized (this) { 6182 // Ensure that any processes we had put on hold are now started 6183 // up. 6184 final int NP = mProcessesOnHold.size(); 6185 if (NP > 0) { 6186 ArrayList<ProcessRecord> procs = 6187 new ArrayList<ProcessRecord>(mProcessesOnHold); 6188 for (int ip=0; ip<NP; ip++) { 6189 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6190 + procs.get(ip)); 6191 startProcessLocked(procs.get(ip), "on-hold", null); 6192 } 6193 } 6194 6195 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6196 // Start looking for apps that are abusing wake locks. 6197 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6198 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6199 // Tell anyone interested that we are done booting! 6200 SystemProperties.set("sys.boot_completed", "1"); 6201 6202 // And trigger dev.bootcomplete if we are not showing encryption progress 6203 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6204 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6205 SystemProperties.set("dev.bootcomplete", "1"); 6206 } 6207 for (int i=0; i<mStartedUsers.size(); i++) { 6208 UserStartedState uss = mStartedUsers.valueAt(i); 6209 if (uss.mState == UserStartedState.STATE_BOOTING) { 6210 uss.mState = UserStartedState.STATE_RUNNING; 6211 final int userId = mStartedUsers.keyAt(i); 6212 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6213 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6214 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6215 broadcastIntentLocked(null, null, intent, null, 6216 new IIntentReceiver.Stub() { 6217 @Override 6218 public void performReceive(Intent intent, int resultCode, 6219 String data, Bundle extras, boolean ordered, 6220 boolean sticky, int sendingUser) { 6221 synchronized (ActivityManagerService.this) { 6222 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6223 true, false); 6224 } 6225 } 6226 }, 6227 0, null, null, 6228 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6229 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6230 userId); 6231 } 6232 } 6233 scheduleStartProfilesLocked(); 6234 } 6235 } 6236 } 6237 6238 @Override 6239 public void bootAnimationComplete() { 6240 final boolean callFinishBooting; 6241 synchronized (this) { 6242 callFinishBooting = mCallFinishBooting; 6243 mBootAnimationComplete = true; 6244 } 6245 if (callFinishBooting) { 6246 finishBooting(); 6247 } 6248 } 6249 6250 final void ensureBootCompleted() { 6251 boolean booting; 6252 boolean enableScreen; 6253 synchronized (this) { 6254 booting = mBooting; 6255 mBooting = false; 6256 enableScreen = !mBooted; 6257 mBooted = true; 6258 } 6259 6260 if (booting) { 6261 finishBooting(); 6262 } 6263 6264 if (enableScreen) { 6265 enableScreenAfterBoot(); 6266 } 6267 } 6268 6269 @Override 6270 public final void activityResumed(IBinder token) { 6271 final long origId = Binder.clearCallingIdentity(); 6272 synchronized(this) { 6273 ActivityStack stack = ActivityRecord.getStackLocked(token); 6274 if (stack != null) { 6275 ActivityRecord.activityResumedLocked(token); 6276 } 6277 } 6278 Binder.restoreCallingIdentity(origId); 6279 } 6280 6281 @Override 6282 public final void activityPaused(IBinder token) { 6283 final long origId = Binder.clearCallingIdentity(); 6284 synchronized(this) { 6285 ActivityStack stack = ActivityRecord.getStackLocked(token); 6286 if (stack != null) { 6287 stack.activityPausedLocked(token, false); 6288 } 6289 } 6290 Binder.restoreCallingIdentity(origId); 6291 } 6292 6293 @Override 6294 public final void activityStopped(IBinder token, Bundle icicle, 6295 PersistableBundle persistentState, CharSequence description) { 6296 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6297 6298 // Refuse possible leaked file descriptors 6299 if (icicle != null && icicle.hasFileDescriptors()) { 6300 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6301 } 6302 6303 final long origId = Binder.clearCallingIdentity(); 6304 6305 synchronized (this) { 6306 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6307 if (r != null) { 6308 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6309 } 6310 } 6311 6312 trimApplications(); 6313 6314 Binder.restoreCallingIdentity(origId); 6315 } 6316 6317 @Override 6318 public final void activityDestroyed(IBinder token) { 6319 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6320 synchronized (this) { 6321 ActivityStack stack = ActivityRecord.getStackLocked(token); 6322 if (stack != null) { 6323 stack.activityDestroyedLocked(token); 6324 } 6325 } 6326 } 6327 6328 @Override 6329 public final void backgroundResourcesReleased(IBinder token) { 6330 final long origId = Binder.clearCallingIdentity(); 6331 try { 6332 synchronized (this) { 6333 ActivityStack stack = ActivityRecord.getStackLocked(token); 6334 if (stack != null) { 6335 stack.backgroundResourcesReleased(token); 6336 } 6337 } 6338 } finally { 6339 Binder.restoreCallingIdentity(origId); 6340 } 6341 } 6342 6343 @Override 6344 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6345 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6346 } 6347 6348 @Override 6349 public final void notifyEnterAnimationComplete(IBinder token) { 6350 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6351 } 6352 6353 @Override 6354 public String getCallingPackage(IBinder token) { 6355 synchronized (this) { 6356 ActivityRecord r = getCallingRecordLocked(token); 6357 return r != null ? r.info.packageName : null; 6358 } 6359 } 6360 6361 @Override 6362 public ComponentName getCallingActivity(IBinder token) { 6363 synchronized (this) { 6364 ActivityRecord r = getCallingRecordLocked(token); 6365 return r != null ? r.intent.getComponent() : null; 6366 } 6367 } 6368 6369 private ActivityRecord getCallingRecordLocked(IBinder token) { 6370 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6371 if (r == null) { 6372 return null; 6373 } 6374 return r.resultTo; 6375 } 6376 6377 @Override 6378 public ComponentName getActivityClassForToken(IBinder token) { 6379 synchronized(this) { 6380 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6381 if (r == null) { 6382 return null; 6383 } 6384 return r.intent.getComponent(); 6385 } 6386 } 6387 6388 @Override 6389 public String getPackageForToken(IBinder token) { 6390 synchronized(this) { 6391 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6392 if (r == null) { 6393 return null; 6394 } 6395 return r.packageName; 6396 } 6397 } 6398 6399 @Override 6400 public IIntentSender getIntentSender(int type, 6401 String packageName, IBinder token, String resultWho, 6402 int requestCode, Intent[] intents, String[] resolvedTypes, 6403 int flags, Bundle options, int userId) { 6404 enforceNotIsolatedCaller("getIntentSender"); 6405 // Refuse possible leaked file descriptors 6406 if (intents != null) { 6407 if (intents.length < 1) { 6408 throw new IllegalArgumentException("Intents array length must be >= 1"); 6409 } 6410 for (int i=0; i<intents.length; i++) { 6411 Intent intent = intents[i]; 6412 if (intent != null) { 6413 if (intent.hasFileDescriptors()) { 6414 throw new IllegalArgumentException("File descriptors passed in Intent"); 6415 } 6416 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6417 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6418 throw new IllegalArgumentException( 6419 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6420 } 6421 intents[i] = new Intent(intent); 6422 } 6423 } 6424 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6425 throw new IllegalArgumentException( 6426 "Intent array length does not match resolvedTypes length"); 6427 } 6428 } 6429 if (options != null) { 6430 if (options.hasFileDescriptors()) { 6431 throw new IllegalArgumentException("File descriptors passed in options"); 6432 } 6433 } 6434 6435 synchronized(this) { 6436 int callingUid = Binder.getCallingUid(); 6437 int origUserId = userId; 6438 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6439 type == ActivityManager.INTENT_SENDER_BROADCAST, 6440 ALLOW_NON_FULL, "getIntentSender", null); 6441 if (origUserId == UserHandle.USER_CURRENT) { 6442 // We don't want to evaluate this until the pending intent is 6443 // actually executed. However, we do want to always do the 6444 // security checking for it above. 6445 userId = UserHandle.USER_CURRENT; 6446 } 6447 try { 6448 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6449 int uid = AppGlobals.getPackageManager() 6450 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6451 if (!UserHandle.isSameApp(callingUid, uid)) { 6452 String msg = "Permission Denial: getIntentSender() from pid=" 6453 + Binder.getCallingPid() 6454 + ", uid=" + Binder.getCallingUid() 6455 + ", (need uid=" + uid + ")" 6456 + " is not allowed to send as package " + packageName; 6457 Slog.w(TAG, msg); 6458 throw new SecurityException(msg); 6459 } 6460 } 6461 6462 return getIntentSenderLocked(type, packageName, callingUid, userId, 6463 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6464 6465 } catch (RemoteException e) { 6466 throw new SecurityException(e); 6467 } 6468 } 6469 } 6470 6471 IIntentSender getIntentSenderLocked(int type, String packageName, 6472 int callingUid, int userId, IBinder token, String resultWho, 6473 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6474 Bundle options) { 6475 if (DEBUG_MU) 6476 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6477 ActivityRecord activity = null; 6478 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6479 activity = ActivityRecord.isInStackLocked(token); 6480 if (activity == null) { 6481 return null; 6482 } 6483 if (activity.finishing) { 6484 return null; 6485 } 6486 } 6487 6488 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6489 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6490 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6491 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6492 |PendingIntent.FLAG_UPDATE_CURRENT); 6493 6494 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6495 type, packageName, activity, resultWho, 6496 requestCode, intents, resolvedTypes, flags, options, userId); 6497 WeakReference<PendingIntentRecord> ref; 6498 ref = mIntentSenderRecords.get(key); 6499 PendingIntentRecord rec = ref != null ? ref.get() : null; 6500 if (rec != null) { 6501 if (!cancelCurrent) { 6502 if (updateCurrent) { 6503 if (rec.key.requestIntent != null) { 6504 rec.key.requestIntent.replaceExtras(intents != null ? 6505 intents[intents.length - 1] : null); 6506 } 6507 if (intents != null) { 6508 intents[intents.length-1] = rec.key.requestIntent; 6509 rec.key.allIntents = intents; 6510 rec.key.allResolvedTypes = resolvedTypes; 6511 } else { 6512 rec.key.allIntents = null; 6513 rec.key.allResolvedTypes = null; 6514 } 6515 } 6516 return rec; 6517 } 6518 rec.canceled = true; 6519 mIntentSenderRecords.remove(key); 6520 } 6521 if (noCreate) { 6522 return rec; 6523 } 6524 rec = new PendingIntentRecord(this, key, callingUid); 6525 mIntentSenderRecords.put(key, rec.ref); 6526 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6527 if (activity.pendingResults == null) { 6528 activity.pendingResults 6529 = new HashSet<WeakReference<PendingIntentRecord>>(); 6530 } 6531 activity.pendingResults.add(rec.ref); 6532 } 6533 return rec; 6534 } 6535 6536 @Override 6537 public void cancelIntentSender(IIntentSender sender) { 6538 if (!(sender instanceof PendingIntentRecord)) { 6539 return; 6540 } 6541 synchronized(this) { 6542 PendingIntentRecord rec = (PendingIntentRecord)sender; 6543 try { 6544 int uid = AppGlobals.getPackageManager() 6545 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6546 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6547 String msg = "Permission Denial: cancelIntentSender() from pid=" 6548 + Binder.getCallingPid() 6549 + ", uid=" + Binder.getCallingUid() 6550 + " is not allowed to cancel packges " 6551 + rec.key.packageName; 6552 Slog.w(TAG, msg); 6553 throw new SecurityException(msg); 6554 } 6555 } catch (RemoteException e) { 6556 throw new SecurityException(e); 6557 } 6558 cancelIntentSenderLocked(rec, true); 6559 } 6560 } 6561 6562 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6563 rec.canceled = true; 6564 mIntentSenderRecords.remove(rec.key); 6565 if (cleanActivity && rec.key.activity != null) { 6566 rec.key.activity.pendingResults.remove(rec.ref); 6567 } 6568 } 6569 6570 @Override 6571 public String getPackageForIntentSender(IIntentSender pendingResult) { 6572 if (!(pendingResult instanceof PendingIntentRecord)) { 6573 return null; 6574 } 6575 try { 6576 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6577 return res.key.packageName; 6578 } catch (ClassCastException e) { 6579 } 6580 return null; 6581 } 6582 6583 @Override 6584 public int getUidForIntentSender(IIntentSender sender) { 6585 if (sender instanceof PendingIntentRecord) { 6586 try { 6587 PendingIntentRecord res = (PendingIntentRecord)sender; 6588 return res.uid; 6589 } catch (ClassCastException e) { 6590 } 6591 } 6592 return -1; 6593 } 6594 6595 @Override 6596 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6597 if (!(pendingResult instanceof PendingIntentRecord)) { 6598 return false; 6599 } 6600 try { 6601 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6602 if (res.key.allIntents == null) { 6603 return false; 6604 } 6605 for (int i=0; i<res.key.allIntents.length; i++) { 6606 Intent intent = res.key.allIntents[i]; 6607 if (intent.getPackage() != null && intent.getComponent() != null) { 6608 return false; 6609 } 6610 } 6611 return true; 6612 } catch (ClassCastException e) { 6613 } 6614 return false; 6615 } 6616 6617 @Override 6618 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6619 if (!(pendingResult instanceof PendingIntentRecord)) { 6620 return false; 6621 } 6622 try { 6623 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6624 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6625 return true; 6626 } 6627 return false; 6628 } catch (ClassCastException e) { 6629 } 6630 return false; 6631 } 6632 6633 @Override 6634 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6635 if (!(pendingResult instanceof PendingIntentRecord)) { 6636 return null; 6637 } 6638 try { 6639 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6640 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6641 } catch (ClassCastException e) { 6642 } 6643 return null; 6644 } 6645 6646 @Override 6647 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6648 if (!(pendingResult instanceof PendingIntentRecord)) { 6649 return null; 6650 } 6651 try { 6652 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6653 Intent intent = res.key.requestIntent; 6654 if (intent != null) { 6655 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6656 || res.lastTagPrefix.equals(prefix))) { 6657 return res.lastTag; 6658 } 6659 res.lastTagPrefix = prefix; 6660 StringBuilder sb = new StringBuilder(128); 6661 if (prefix != null) { 6662 sb.append(prefix); 6663 } 6664 if (intent.getAction() != null) { 6665 sb.append(intent.getAction()); 6666 } else if (intent.getComponent() != null) { 6667 intent.getComponent().appendShortString(sb); 6668 } else { 6669 sb.append("?"); 6670 } 6671 return res.lastTag = sb.toString(); 6672 } 6673 } catch (ClassCastException e) { 6674 } 6675 return null; 6676 } 6677 6678 @Override 6679 public void setProcessLimit(int max) { 6680 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6681 "setProcessLimit()"); 6682 synchronized (this) { 6683 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6684 mProcessLimitOverride = max; 6685 } 6686 trimApplications(); 6687 } 6688 6689 @Override 6690 public int getProcessLimit() { 6691 synchronized (this) { 6692 return mProcessLimitOverride; 6693 } 6694 } 6695 6696 void foregroundTokenDied(ForegroundToken token) { 6697 synchronized (ActivityManagerService.this) { 6698 synchronized (mPidsSelfLocked) { 6699 ForegroundToken cur 6700 = mForegroundProcesses.get(token.pid); 6701 if (cur != token) { 6702 return; 6703 } 6704 mForegroundProcesses.remove(token.pid); 6705 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6706 if (pr == null) { 6707 return; 6708 } 6709 pr.forcingToForeground = null; 6710 updateProcessForegroundLocked(pr, false, false); 6711 } 6712 updateOomAdjLocked(); 6713 } 6714 } 6715 6716 @Override 6717 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6718 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6719 "setProcessForeground()"); 6720 synchronized(this) { 6721 boolean changed = false; 6722 6723 synchronized (mPidsSelfLocked) { 6724 ProcessRecord pr = mPidsSelfLocked.get(pid); 6725 if (pr == null && isForeground) { 6726 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6727 return; 6728 } 6729 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6730 if (oldToken != null) { 6731 oldToken.token.unlinkToDeath(oldToken, 0); 6732 mForegroundProcesses.remove(pid); 6733 if (pr != null) { 6734 pr.forcingToForeground = null; 6735 } 6736 changed = true; 6737 } 6738 if (isForeground && token != null) { 6739 ForegroundToken newToken = new ForegroundToken() { 6740 @Override 6741 public void binderDied() { 6742 foregroundTokenDied(this); 6743 } 6744 }; 6745 newToken.pid = pid; 6746 newToken.token = token; 6747 try { 6748 token.linkToDeath(newToken, 0); 6749 mForegroundProcesses.put(pid, newToken); 6750 pr.forcingToForeground = token; 6751 changed = true; 6752 } catch (RemoteException e) { 6753 // If the process died while doing this, we will later 6754 // do the cleanup with the process death link. 6755 } 6756 } 6757 } 6758 6759 if (changed) { 6760 updateOomAdjLocked(); 6761 } 6762 } 6763 } 6764 6765 // ========================================================= 6766 // PERMISSIONS 6767 // ========================================================= 6768 6769 static class PermissionController extends IPermissionController.Stub { 6770 ActivityManagerService mActivityManagerService; 6771 PermissionController(ActivityManagerService activityManagerService) { 6772 mActivityManagerService = activityManagerService; 6773 } 6774 6775 @Override 6776 public boolean checkPermission(String permission, int pid, int uid) { 6777 return mActivityManagerService.checkPermission(permission, pid, 6778 uid) == PackageManager.PERMISSION_GRANTED; 6779 } 6780 } 6781 6782 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6783 @Override 6784 public int checkComponentPermission(String permission, int pid, int uid, 6785 int owningUid, boolean exported) { 6786 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6787 owningUid, exported); 6788 } 6789 6790 @Override 6791 public Object getAMSLock() { 6792 return ActivityManagerService.this; 6793 } 6794 } 6795 6796 /** 6797 * This can be called with or without the global lock held. 6798 */ 6799 int checkComponentPermission(String permission, int pid, int uid, 6800 int owningUid, boolean exported) { 6801 // We might be performing an operation on behalf of an indirect binder 6802 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6803 // client identity accordingly before proceeding. 6804 Identity tlsIdentity = sCallerIdentity.get(); 6805 if (tlsIdentity != null) { 6806 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6807 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6808 uid = tlsIdentity.uid; 6809 pid = tlsIdentity.pid; 6810 } 6811 6812 if (pid == MY_PID) { 6813 return PackageManager.PERMISSION_GRANTED; 6814 } 6815 6816 return ActivityManager.checkComponentPermission(permission, uid, 6817 owningUid, exported); 6818 } 6819 6820 /** 6821 * As the only public entry point for permissions checking, this method 6822 * can enforce the semantic that requesting a check on a null global 6823 * permission is automatically denied. (Internally a null permission 6824 * string is used when calling {@link #checkComponentPermission} in cases 6825 * when only uid-based security is needed.) 6826 * 6827 * This can be called with or without the global lock held. 6828 */ 6829 @Override 6830 public int checkPermission(String permission, int pid, int uid) { 6831 if (permission == null) { 6832 return PackageManager.PERMISSION_DENIED; 6833 } 6834 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6835 } 6836 6837 /** 6838 * Binder IPC calls go through the public entry point. 6839 * This can be called with or without the global lock held. 6840 */ 6841 int checkCallingPermission(String permission) { 6842 return checkPermission(permission, 6843 Binder.getCallingPid(), 6844 UserHandle.getAppId(Binder.getCallingUid())); 6845 } 6846 6847 /** 6848 * This can be called with or without the global lock held. 6849 */ 6850 void enforceCallingPermission(String permission, String func) { 6851 if (checkCallingPermission(permission) 6852 == PackageManager.PERMISSION_GRANTED) { 6853 return; 6854 } 6855 6856 String msg = "Permission Denial: " + func + " from pid=" 6857 + Binder.getCallingPid() 6858 + ", uid=" + Binder.getCallingUid() 6859 + " requires " + permission; 6860 Slog.w(TAG, msg); 6861 throw new SecurityException(msg); 6862 } 6863 6864 /** 6865 * Determine if UID is holding permissions required to access {@link Uri} in 6866 * the given {@link ProviderInfo}. Final permission checking is always done 6867 * in {@link ContentProvider}. 6868 */ 6869 private final boolean checkHoldingPermissionsLocked( 6870 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6871 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6872 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6873 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6874 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6875 != PERMISSION_GRANTED) { 6876 return false; 6877 } 6878 } 6879 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6880 } 6881 6882 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6883 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6884 if (pi.applicationInfo.uid == uid) { 6885 return true; 6886 } else if (!pi.exported) { 6887 return false; 6888 } 6889 6890 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6891 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6892 try { 6893 // check if target holds top-level <provider> permissions 6894 if (!readMet && pi.readPermission != null && considerUidPermissions 6895 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6896 readMet = true; 6897 } 6898 if (!writeMet && pi.writePermission != null && considerUidPermissions 6899 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6900 writeMet = true; 6901 } 6902 6903 // track if unprotected read/write is allowed; any denied 6904 // <path-permission> below removes this ability 6905 boolean allowDefaultRead = pi.readPermission == null; 6906 boolean allowDefaultWrite = pi.writePermission == null; 6907 6908 // check if target holds any <path-permission> that match uri 6909 final PathPermission[] pps = pi.pathPermissions; 6910 if (pps != null) { 6911 final String path = grantUri.uri.getPath(); 6912 int i = pps.length; 6913 while (i > 0 && (!readMet || !writeMet)) { 6914 i--; 6915 PathPermission pp = pps[i]; 6916 if (pp.match(path)) { 6917 if (!readMet) { 6918 final String pprperm = pp.getReadPermission(); 6919 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6920 + pprperm + " for " + pp.getPath() 6921 + ": match=" + pp.match(path) 6922 + " check=" + pm.checkUidPermission(pprperm, uid)); 6923 if (pprperm != null) { 6924 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6925 == PERMISSION_GRANTED) { 6926 readMet = true; 6927 } else { 6928 allowDefaultRead = false; 6929 } 6930 } 6931 } 6932 if (!writeMet) { 6933 final String ppwperm = pp.getWritePermission(); 6934 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6935 + ppwperm + " for " + pp.getPath() 6936 + ": match=" + pp.match(path) 6937 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6938 if (ppwperm != null) { 6939 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6940 == PERMISSION_GRANTED) { 6941 writeMet = true; 6942 } else { 6943 allowDefaultWrite = false; 6944 } 6945 } 6946 } 6947 } 6948 } 6949 } 6950 6951 // grant unprotected <provider> read/write, if not blocked by 6952 // <path-permission> above 6953 if (allowDefaultRead) readMet = true; 6954 if (allowDefaultWrite) writeMet = true; 6955 6956 } catch (RemoteException e) { 6957 return false; 6958 } 6959 6960 return readMet && writeMet; 6961 } 6962 6963 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6964 ProviderInfo pi = null; 6965 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6966 if (cpr != null) { 6967 pi = cpr.info; 6968 } else { 6969 try { 6970 pi = AppGlobals.getPackageManager().resolveContentProvider( 6971 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6972 } catch (RemoteException ex) { 6973 } 6974 } 6975 return pi; 6976 } 6977 6978 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6979 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6980 if (targetUris != null) { 6981 return targetUris.get(grantUri); 6982 } 6983 return null; 6984 } 6985 6986 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6987 String targetPkg, int targetUid, GrantUri grantUri) { 6988 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6989 if (targetUris == null) { 6990 targetUris = Maps.newArrayMap(); 6991 mGrantedUriPermissions.put(targetUid, targetUris); 6992 } 6993 6994 UriPermission perm = targetUris.get(grantUri); 6995 if (perm == null) { 6996 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6997 targetUris.put(grantUri, perm); 6998 } 6999 7000 return perm; 7001 } 7002 7003 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7004 final int modeFlags) { 7005 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7006 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7007 : UriPermission.STRENGTH_OWNED; 7008 7009 // Root gets to do everything. 7010 if (uid == 0) { 7011 return true; 7012 } 7013 7014 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7015 if (perms == null) return false; 7016 7017 // First look for exact match 7018 final UriPermission exactPerm = perms.get(grantUri); 7019 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7020 return true; 7021 } 7022 7023 // No exact match, look for prefixes 7024 final int N = perms.size(); 7025 for (int i = 0; i < N; i++) { 7026 final UriPermission perm = perms.valueAt(i); 7027 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7028 && perm.getStrength(modeFlags) >= minStrength) { 7029 return true; 7030 } 7031 } 7032 7033 return false; 7034 } 7035 7036 /** 7037 * @param uri This uri must NOT contain an embedded userId. 7038 * @param userId The userId in which the uri is to be resolved. 7039 */ 7040 @Override 7041 public int checkUriPermission(Uri uri, int pid, int uid, 7042 final int modeFlags, int userId) { 7043 enforceNotIsolatedCaller("checkUriPermission"); 7044 7045 // Another redirected-binder-call permissions check as in 7046 // {@link checkComponentPermission}. 7047 Identity tlsIdentity = sCallerIdentity.get(); 7048 if (tlsIdentity != null) { 7049 uid = tlsIdentity.uid; 7050 pid = tlsIdentity.pid; 7051 } 7052 7053 // Our own process gets to do everything. 7054 if (pid == MY_PID) { 7055 return PackageManager.PERMISSION_GRANTED; 7056 } 7057 synchronized (this) { 7058 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7059 ? PackageManager.PERMISSION_GRANTED 7060 : PackageManager.PERMISSION_DENIED; 7061 } 7062 } 7063 7064 /** 7065 * Check if the targetPkg can be granted permission to access uri by 7066 * the callingUid using the given modeFlags. Throws a security exception 7067 * if callingUid is not allowed to do this. Returns the uid of the target 7068 * if the URI permission grant should be performed; returns -1 if it is not 7069 * needed (for example targetPkg already has permission to access the URI). 7070 * If you already know the uid of the target, you can supply it in 7071 * lastTargetUid else set that to -1. 7072 */ 7073 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7074 final int modeFlags, int lastTargetUid) { 7075 if (!Intent.isAccessUriMode(modeFlags)) { 7076 return -1; 7077 } 7078 7079 if (targetPkg != null) { 7080 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7081 "Checking grant " + targetPkg + " permission to " + grantUri); 7082 } 7083 7084 final IPackageManager pm = AppGlobals.getPackageManager(); 7085 7086 // If this is not a content: uri, we can't do anything with it. 7087 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7088 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7089 "Can't grant URI permission for non-content URI: " + grantUri); 7090 return -1; 7091 } 7092 7093 final String authority = grantUri.uri.getAuthority(); 7094 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7095 if (pi == null) { 7096 Slog.w(TAG, "No content provider found for permission check: " + 7097 grantUri.uri.toSafeString()); 7098 return -1; 7099 } 7100 7101 int targetUid = lastTargetUid; 7102 if (targetUid < 0 && targetPkg != null) { 7103 try { 7104 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7105 if (targetUid < 0) { 7106 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7107 "Can't grant URI permission no uid for: " + targetPkg); 7108 return -1; 7109 } 7110 } catch (RemoteException ex) { 7111 return -1; 7112 } 7113 } 7114 7115 if (targetUid >= 0) { 7116 // First... does the target actually need this permission? 7117 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7118 // No need to grant the target this permission. 7119 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7120 "Target " + targetPkg + " already has full permission to " + grantUri); 7121 return -1; 7122 } 7123 } else { 7124 // First... there is no target package, so can anyone access it? 7125 boolean allowed = pi.exported; 7126 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7127 if (pi.readPermission != null) { 7128 allowed = false; 7129 } 7130 } 7131 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7132 if (pi.writePermission != null) { 7133 allowed = false; 7134 } 7135 } 7136 if (allowed) { 7137 return -1; 7138 } 7139 } 7140 7141 /* There is a special cross user grant if: 7142 * - The target is on another user. 7143 * - Apps on the current user can access the uri without any uid permissions. 7144 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7145 * grant uri permissions. 7146 */ 7147 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7148 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7149 modeFlags, false /*without considering the uid permissions*/); 7150 7151 // Second... is the provider allowing granting of URI permissions? 7152 if (!specialCrossUserGrant) { 7153 if (!pi.grantUriPermissions) { 7154 throw new SecurityException("Provider " + pi.packageName 7155 + "/" + pi.name 7156 + " does not allow granting of Uri permissions (uri " 7157 + grantUri + ")"); 7158 } 7159 if (pi.uriPermissionPatterns != null) { 7160 final int N = pi.uriPermissionPatterns.length; 7161 boolean allowed = false; 7162 for (int i=0; i<N; i++) { 7163 if (pi.uriPermissionPatterns[i] != null 7164 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7165 allowed = true; 7166 break; 7167 } 7168 } 7169 if (!allowed) { 7170 throw new SecurityException("Provider " + pi.packageName 7171 + "/" + pi.name 7172 + " does not allow granting of permission to path of Uri " 7173 + grantUri); 7174 } 7175 } 7176 } 7177 7178 // Third... does the caller itself have permission to access 7179 // this uri? 7180 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7181 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7182 // Require they hold a strong enough Uri permission 7183 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7184 throw new SecurityException("Uid " + callingUid 7185 + " does not have permission to uri " + grantUri); 7186 } 7187 } 7188 } 7189 return targetUid; 7190 } 7191 7192 /** 7193 * @param uri This uri must NOT contain an embedded userId. 7194 * @param userId The userId in which the uri is to be resolved. 7195 */ 7196 @Override 7197 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7198 final int modeFlags, int userId) { 7199 enforceNotIsolatedCaller("checkGrantUriPermission"); 7200 synchronized(this) { 7201 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7202 new GrantUri(userId, uri, false), modeFlags, -1); 7203 } 7204 } 7205 7206 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7207 final int modeFlags, UriPermissionOwner owner) { 7208 if (!Intent.isAccessUriMode(modeFlags)) { 7209 return; 7210 } 7211 7212 // So here we are: the caller has the assumed permission 7213 // to the uri, and the target doesn't. Let's now give this to 7214 // the target. 7215 7216 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7217 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7218 7219 final String authority = grantUri.uri.getAuthority(); 7220 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7221 if (pi == null) { 7222 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7223 return; 7224 } 7225 7226 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7227 grantUri.prefix = true; 7228 } 7229 final UriPermission perm = findOrCreateUriPermissionLocked( 7230 pi.packageName, targetPkg, targetUid, grantUri); 7231 perm.grantModes(modeFlags, owner); 7232 } 7233 7234 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7235 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7236 if (targetPkg == null) { 7237 throw new NullPointerException("targetPkg"); 7238 } 7239 int targetUid; 7240 final IPackageManager pm = AppGlobals.getPackageManager(); 7241 try { 7242 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7243 } catch (RemoteException ex) { 7244 return; 7245 } 7246 7247 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7248 targetUid); 7249 if (targetUid < 0) { 7250 return; 7251 } 7252 7253 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7254 owner); 7255 } 7256 7257 static class NeededUriGrants extends ArrayList<GrantUri> { 7258 final String targetPkg; 7259 final int targetUid; 7260 final int flags; 7261 7262 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7263 this.targetPkg = targetPkg; 7264 this.targetUid = targetUid; 7265 this.flags = flags; 7266 } 7267 } 7268 7269 /** 7270 * Like checkGrantUriPermissionLocked, but takes an Intent. 7271 */ 7272 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7273 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7274 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7275 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7276 + " clip=" + (intent != null ? intent.getClipData() : null) 7277 + " from " + intent + "; flags=0x" 7278 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7279 7280 if (targetPkg == null) { 7281 throw new NullPointerException("targetPkg"); 7282 } 7283 7284 if (intent == null) { 7285 return null; 7286 } 7287 Uri data = intent.getData(); 7288 ClipData clip = intent.getClipData(); 7289 if (data == null && clip == null) { 7290 return null; 7291 } 7292 // Default userId for uris in the intent (if they don't specify it themselves) 7293 int contentUserHint = intent.getContentUserHint(); 7294 if (contentUserHint == UserHandle.USER_CURRENT) { 7295 contentUserHint = UserHandle.getUserId(callingUid); 7296 } 7297 final IPackageManager pm = AppGlobals.getPackageManager(); 7298 int targetUid; 7299 if (needed != null) { 7300 targetUid = needed.targetUid; 7301 } else { 7302 try { 7303 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7304 } catch (RemoteException ex) { 7305 return null; 7306 } 7307 if (targetUid < 0) { 7308 if (DEBUG_URI_PERMISSION) { 7309 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7310 + " on user " + targetUserId); 7311 } 7312 return null; 7313 } 7314 } 7315 if (data != null) { 7316 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7317 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7318 targetUid); 7319 if (targetUid > 0) { 7320 if (needed == null) { 7321 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7322 } 7323 needed.add(grantUri); 7324 } 7325 } 7326 if (clip != null) { 7327 for (int i=0; i<clip.getItemCount(); i++) { 7328 Uri uri = clip.getItemAt(i).getUri(); 7329 if (uri != null) { 7330 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7331 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7332 targetUid); 7333 if (targetUid > 0) { 7334 if (needed == null) { 7335 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7336 } 7337 needed.add(grantUri); 7338 } 7339 } else { 7340 Intent clipIntent = clip.getItemAt(i).getIntent(); 7341 if (clipIntent != null) { 7342 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7343 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7344 if (newNeeded != null) { 7345 needed = newNeeded; 7346 } 7347 } 7348 } 7349 } 7350 } 7351 7352 return needed; 7353 } 7354 7355 /** 7356 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7357 */ 7358 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7359 UriPermissionOwner owner) { 7360 if (needed != null) { 7361 for (int i=0; i<needed.size(); i++) { 7362 GrantUri grantUri = needed.get(i); 7363 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7364 grantUri, needed.flags, owner); 7365 } 7366 } 7367 } 7368 7369 void grantUriPermissionFromIntentLocked(int callingUid, 7370 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7371 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7372 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7373 if (needed == null) { 7374 return; 7375 } 7376 7377 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7378 } 7379 7380 /** 7381 * @param uri This uri must NOT contain an embedded userId. 7382 * @param userId The userId in which the uri is to be resolved. 7383 */ 7384 @Override 7385 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7386 final int modeFlags, int userId) { 7387 enforceNotIsolatedCaller("grantUriPermission"); 7388 GrantUri grantUri = new GrantUri(userId, uri, false); 7389 synchronized(this) { 7390 final ProcessRecord r = getRecordForAppLocked(caller); 7391 if (r == null) { 7392 throw new SecurityException("Unable to find app for caller " 7393 + caller 7394 + " when granting permission to uri " + grantUri); 7395 } 7396 if (targetPkg == null) { 7397 throw new IllegalArgumentException("null target"); 7398 } 7399 if (grantUri == null) { 7400 throw new IllegalArgumentException("null uri"); 7401 } 7402 7403 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7404 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7405 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7406 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7407 7408 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7409 UserHandle.getUserId(r.uid)); 7410 } 7411 } 7412 7413 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7414 if (perm.modeFlags == 0) { 7415 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7416 perm.targetUid); 7417 if (perms != null) { 7418 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7419 "Removing " + perm.targetUid + " permission to " + perm.uri); 7420 7421 perms.remove(perm.uri); 7422 if (perms.isEmpty()) { 7423 mGrantedUriPermissions.remove(perm.targetUid); 7424 } 7425 } 7426 } 7427 } 7428 7429 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7430 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7431 7432 final IPackageManager pm = AppGlobals.getPackageManager(); 7433 final String authority = grantUri.uri.getAuthority(); 7434 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7435 if (pi == null) { 7436 Slog.w(TAG, "No content provider found for permission revoke: " 7437 + grantUri.toSafeString()); 7438 return; 7439 } 7440 7441 // Does the caller have this permission on the URI? 7442 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7443 // If they don't have direct access to the URI, then revoke any 7444 // ownerless URI permissions that have been granted to them. 7445 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7446 if (perms != null) { 7447 boolean persistChanged = false; 7448 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7449 final UriPermission perm = it.next(); 7450 if (perm.uri.sourceUserId == grantUri.sourceUserId 7451 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7452 if (DEBUG_URI_PERMISSION) 7453 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7454 " permission to " + perm.uri); 7455 persistChanged |= perm.revokeModes( 7456 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7457 if (perm.modeFlags == 0) { 7458 it.remove(); 7459 } 7460 } 7461 } 7462 if (perms.isEmpty()) { 7463 mGrantedUriPermissions.remove(callingUid); 7464 } 7465 if (persistChanged) { 7466 schedulePersistUriGrants(); 7467 } 7468 } 7469 return; 7470 } 7471 7472 boolean persistChanged = false; 7473 7474 // Go through all of the permissions and remove any that match. 7475 int N = mGrantedUriPermissions.size(); 7476 for (int i = 0; i < N; i++) { 7477 final int targetUid = mGrantedUriPermissions.keyAt(i); 7478 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7479 7480 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7481 final UriPermission perm = it.next(); 7482 if (perm.uri.sourceUserId == grantUri.sourceUserId 7483 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7484 if (DEBUG_URI_PERMISSION) 7485 Slog.v(TAG, 7486 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7487 persistChanged |= perm.revokeModes( 7488 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7489 if (perm.modeFlags == 0) { 7490 it.remove(); 7491 } 7492 } 7493 } 7494 7495 if (perms.isEmpty()) { 7496 mGrantedUriPermissions.remove(targetUid); 7497 N--; 7498 i--; 7499 } 7500 } 7501 7502 if (persistChanged) { 7503 schedulePersistUriGrants(); 7504 } 7505 } 7506 7507 /** 7508 * @param uri This uri must NOT contain an embedded userId. 7509 * @param userId The userId in which the uri is to be resolved. 7510 */ 7511 @Override 7512 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7513 int userId) { 7514 enforceNotIsolatedCaller("revokeUriPermission"); 7515 synchronized(this) { 7516 final ProcessRecord r = getRecordForAppLocked(caller); 7517 if (r == null) { 7518 throw new SecurityException("Unable to find app for caller " 7519 + caller 7520 + " when revoking permission to uri " + uri); 7521 } 7522 if (uri == null) { 7523 Slog.w(TAG, "revokeUriPermission: null uri"); 7524 return; 7525 } 7526 7527 if (!Intent.isAccessUriMode(modeFlags)) { 7528 return; 7529 } 7530 7531 final IPackageManager pm = AppGlobals.getPackageManager(); 7532 final String authority = uri.getAuthority(); 7533 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7534 if (pi == null) { 7535 Slog.w(TAG, "No content provider found for permission revoke: " 7536 + uri.toSafeString()); 7537 return; 7538 } 7539 7540 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7541 } 7542 } 7543 7544 /** 7545 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7546 * given package. 7547 * 7548 * @param packageName Package name to match, or {@code null} to apply to all 7549 * packages. 7550 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7551 * to all users. 7552 * @param persistable If persistable grants should be removed. 7553 */ 7554 private void removeUriPermissionsForPackageLocked( 7555 String packageName, int userHandle, boolean persistable) { 7556 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7557 throw new IllegalArgumentException("Must narrow by either package or user"); 7558 } 7559 7560 boolean persistChanged = false; 7561 7562 int N = mGrantedUriPermissions.size(); 7563 for (int i = 0; i < N; i++) { 7564 final int targetUid = mGrantedUriPermissions.keyAt(i); 7565 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7566 7567 // Only inspect grants matching user 7568 if (userHandle == UserHandle.USER_ALL 7569 || userHandle == UserHandle.getUserId(targetUid)) { 7570 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7571 final UriPermission perm = it.next(); 7572 7573 // Only inspect grants matching package 7574 if (packageName == null || perm.sourcePkg.equals(packageName) 7575 || perm.targetPkg.equals(packageName)) { 7576 persistChanged |= perm.revokeModes(persistable 7577 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7578 7579 // Only remove when no modes remain; any persisted grants 7580 // will keep this alive. 7581 if (perm.modeFlags == 0) { 7582 it.remove(); 7583 } 7584 } 7585 } 7586 7587 if (perms.isEmpty()) { 7588 mGrantedUriPermissions.remove(targetUid); 7589 N--; 7590 i--; 7591 } 7592 } 7593 } 7594 7595 if (persistChanged) { 7596 schedulePersistUriGrants(); 7597 } 7598 } 7599 7600 @Override 7601 public IBinder newUriPermissionOwner(String name) { 7602 enforceNotIsolatedCaller("newUriPermissionOwner"); 7603 synchronized(this) { 7604 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7605 return owner.getExternalTokenLocked(); 7606 } 7607 } 7608 7609 /** 7610 * @param uri This uri must NOT contain an embedded userId. 7611 * @param sourceUserId The userId in which the uri is to be resolved. 7612 * @param targetUserId The userId of the app that receives the grant. 7613 */ 7614 @Override 7615 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7616 final int modeFlags, int sourceUserId, int targetUserId) { 7617 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7618 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7619 synchronized(this) { 7620 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7621 if (owner == null) { 7622 throw new IllegalArgumentException("Unknown owner: " + token); 7623 } 7624 if (fromUid != Binder.getCallingUid()) { 7625 if (Binder.getCallingUid() != Process.myUid()) { 7626 // Only system code can grant URI permissions on behalf 7627 // of other users. 7628 throw new SecurityException("nice try"); 7629 } 7630 } 7631 if (targetPkg == null) { 7632 throw new IllegalArgumentException("null target"); 7633 } 7634 if (uri == null) { 7635 throw new IllegalArgumentException("null uri"); 7636 } 7637 7638 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7639 modeFlags, owner, targetUserId); 7640 } 7641 } 7642 7643 /** 7644 * @param uri This uri must NOT contain an embedded userId. 7645 * @param userId The userId in which the uri is to be resolved. 7646 */ 7647 @Override 7648 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7649 synchronized(this) { 7650 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7651 if (owner == null) { 7652 throw new IllegalArgumentException("Unknown owner: " + token); 7653 } 7654 7655 if (uri == null) { 7656 owner.removeUriPermissionsLocked(mode); 7657 } else { 7658 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7659 } 7660 } 7661 } 7662 7663 private void schedulePersistUriGrants() { 7664 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7665 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7666 10 * DateUtils.SECOND_IN_MILLIS); 7667 } 7668 } 7669 7670 private void writeGrantedUriPermissions() { 7671 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7672 7673 // Snapshot permissions so we can persist without lock 7674 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7675 synchronized (this) { 7676 final int size = mGrantedUriPermissions.size(); 7677 for (int i = 0; i < size; i++) { 7678 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7679 for (UriPermission perm : perms.values()) { 7680 if (perm.persistedModeFlags != 0) { 7681 persist.add(perm.snapshot()); 7682 } 7683 } 7684 } 7685 } 7686 7687 FileOutputStream fos = null; 7688 try { 7689 fos = mGrantFile.startWrite(); 7690 7691 XmlSerializer out = new FastXmlSerializer(); 7692 out.setOutput(fos, "utf-8"); 7693 out.startDocument(null, true); 7694 out.startTag(null, TAG_URI_GRANTS); 7695 for (UriPermission.Snapshot perm : persist) { 7696 out.startTag(null, TAG_URI_GRANT); 7697 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7698 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7699 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7700 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7701 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7702 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7703 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7704 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7705 out.endTag(null, TAG_URI_GRANT); 7706 } 7707 out.endTag(null, TAG_URI_GRANTS); 7708 out.endDocument(); 7709 7710 mGrantFile.finishWrite(fos); 7711 } catch (IOException e) { 7712 if (fos != null) { 7713 mGrantFile.failWrite(fos); 7714 } 7715 } 7716 } 7717 7718 private void readGrantedUriPermissionsLocked() { 7719 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7720 7721 final long now = System.currentTimeMillis(); 7722 7723 FileInputStream fis = null; 7724 try { 7725 fis = mGrantFile.openRead(); 7726 final XmlPullParser in = Xml.newPullParser(); 7727 in.setInput(fis, null); 7728 7729 int type; 7730 while ((type = in.next()) != END_DOCUMENT) { 7731 final String tag = in.getName(); 7732 if (type == START_TAG) { 7733 if (TAG_URI_GRANT.equals(tag)) { 7734 final int sourceUserId; 7735 final int targetUserId; 7736 final int userHandle = readIntAttribute(in, 7737 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7738 if (userHandle != UserHandle.USER_NULL) { 7739 // For backwards compatibility. 7740 sourceUserId = userHandle; 7741 targetUserId = userHandle; 7742 } else { 7743 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7744 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7745 } 7746 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7747 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7748 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7749 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7750 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7751 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7752 7753 // Sanity check that provider still belongs to source package 7754 final ProviderInfo pi = getProviderInfoLocked( 7755 uri.getAuthority(), sourceUserId); 7756 if (pi != null && sourcePkg.equals(pi.packageName)) { 7757 int targetUid = -1; 7758 try { 7759 targetUid = AppGlobals.getPackageManager() 7760 .getPackageUid(targetPkg, targetUserId); 7761 } catch (RemoteException e) { 7762 } 7763 if (targetUid != -1) { 7764 final UriPermission perm = findOrCreateUriPermissionLocked( 7765 sourcePkg, targetPkg, targetUid, 7766 new GrantUri(sourceUserId, uri, prefix)); 7767 perm.initPersistedModes(modeFlags, createdTime); 7768 } 7769 } else { 7770 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7771 + " but instead found " + pi); 7772 } 7773 } 7774 } 7775 } 7776 } catch (FileNotFoundException e) { 7777 // Missing grants is okay 7778 } catch (IOException e) { 7779 Slog.wtf(TAG, "Failed reading Uri grants", e); 7780 } catch (XmlPullParserException e) { 7781 Slog.wtf(TAG, "Failed reading Uri grants", e); 7782 } finally { 7783 IoUtils.closeQuietly(fis); 7784 } 7785 } 7786 7787 /** 7788 * @param uri This uri must NOT contain an embedded userId. 7789 * @param userId The userId in which the uri is to be resolved. 7790 */ 7791 @Override 7792 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7793 enforceNotIsolatedCaller("takePersistableUriPermission"); 7794 7795 Preconditions.checkFlagsArgument(modeFlags, 7796 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7797 7798 synchronized (this) { 7799 final int callingUid = Binder.getCallingUid(); 7800 boolean persistChanged = false; 7801 GrantUri grantUri = new GrantUri(userId, uri, false); 7802 7803 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7804 new GrantUri(userId, uri, false)); 7805 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7806 new GrantUri(userId, uri, true)); 7807 7808 final boolean exactValid = (exactPerm != null) 7809 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7810 final boolean prefixValid = (prefixPerm != null) 7811 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7812 7813 if (!(exactValid || prefixValid)) { 7814 throw new SecurityException("No persistable permission grants found for UID " 7815 + callingUid + " and Uri " + grantUri.toSafeString()); 7816 } 7817 7818 if (exactValid) { 7819 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7820 } 7821 if (prefixValid) { 7822 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7823 } 7824 7825 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7826 7827 if (persistChanged) { 7828 schedulePersistUriGrants(); 7829 } 7830 } 7831 } 7832 7833 /** 7834 * @param uri This uri must NOT contain an embedded userId. 7835 * @param userId The userId in which the uri is to be resolved. 7836 */ 7837 @Override 7838 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7839 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7840 7841 Preconditions.checkFlagsArgument(modeFlags, 7842 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7843 7844 synchronized (this) { 7845 final int callingUid = Binder.getCallingUid(); 7846 boolean persistChanged = false; 7847 7848 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7849 new GrantUri(userId, uri, false)); 7850 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7851 new GrantUri(userId, uri, true)); 7852 if (exactPerm == null && prefixPerm == null) { 7853 throw new SecurityException("No permission grants found for UID " + callingUid 7854 + " and Uri " + uri.toSafeString()); 7855 } 7856 7857 if (exactPerm != null) { 7858 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7859 removeUriPermissionIfNeededLocked(exactPerm); 7860 } 7861 if (prefixPerm != null) { 7862 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7863 removeUriPermissionIfNeededLocked(prefixPerm); 7864 } 7865 7866 if (persistChanged) { 7867 schedulePersistUriGrants(); 7868 } 7869 } 7870 } 7871 7872 /** 7873 * Prune any older {@link UriPermission} for the given UID until outstanding 7874 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7875 * 7876 * @return if any mutations occured that require persisting. 7877 */ 7878 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7879 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7880 if (perms == null) return false; 7881 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7882 7883 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7884 for (UriPermission perm : perms.values()) { 7885 if (perm.persistedModeFlags != 0) { 7886 persisted.add(perm); 7887 } 7888 } 7889 7890 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7891 if (trimCount <= 0) return false; 7892 7893 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7894 for (int i = 0; i < trimCount; i++) { 7895 final UriPermission perm = persisted.get(i); 7896 7897 if (DEBUG_URI_PERMISSION) { 7898 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7899 } 7900 7901 perm.releasePersistableModes(~0); 7902 removeUriPermissionIfNeededLocked(perm); 7903 } 7904 7905 return true; 7906 } 7907 7908 @Override 7909 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7910 String packageName, boolean incoming) { 7911 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7912 Preconditions.checkNotNull(packageName, "packageName"); 7913 7914 final int callingUid = Binder.getCallingUid(); 7915 final IPackageManager pm = AppGlobals.getPackageManager(); 7916 try { 7917 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7918 if (packageUid != callingUid) { 7919 throw new SecurityException( 7920 "Package " + packageName + " does not belong to calling UID " + callingUid); 7921 } 7922 } catch (RemoteException e) { 7923 throw new SecurityException("Failed to verify package name ownership"); 7924 } 7925 7926 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7927 synchronized (this) { 7928 if (incoming) { 7929 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7930 callingUid); 7931 if (perms == null) { 7932 Slog.w(TAG, "No permission grants found for " + packageName); 7933 } else { 7934 for (UriPermission perm : perms.values()) { 7935 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7936 result.add(perm.buildPersistedPublicApiObject()); 7937 } 7938 } 7939 } 7940 } else { 7941 final int size = mGrantedUriPermissions.size(); 7942 for (int i = 0; i < size; i++) { 7943 final ArrayMap<GrantUri, UriPermission> perms = 7944 mGrantedUriPermissions.valueAt(i); 7945 for (UriPermission perm : perms.values()) { 7946 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7947 result.add(perm.buildPersistedPublicApiObject()); 7948 } 7949 } 7950 } 7951 } 7952 } 7953 return new ParceledListSlice<android.content.UriPermission>(result); 7954 } 7955 7956 @Override 7957 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7958 synchronized (this) { 7959 ProcessRecord app = 7960 who != null ? getRecordForAppLocked(who) : null; 7961 if (app == null) return; 7962 7963 Message msg = Message.obtain(); 7964 msg.what = WAIT_FOR_DEBUGGER_MSG; 7965 msg.obj = app; 7966 msg.arg1 = waiting ? 1 : 0; 7967 mHandler.sendMessage(msg); 7968 } 7969 } 7970 7971 @Override 7972 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7973 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7974 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7975 outInfo.availMem = Process.getFreeMemory(); 7976 outInfo.totalMem = Process.getTotalMemory(); 7977 outInfo.threshold = homeAppMem; 7978 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7979 outInfo.hiddenAppThreshold = cachedAppMem; 7980 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7981 ProcessList.SERVICE_ADJ); 7982 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7983 ProcessList.VISIBLE_APP_ADJ); 7984 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7985 ProcessList.FOREGROUND_APP_ADJ); 7986 } 7987 7988 // ========================================================= 7989 // TASK MANAGEMENT 7990 // ========================================================= 7991 7992 @Override 7993 public List<IAppTask> getAppTasks(String callingPackage) { 7994 int callingUid = Binder.getCallingUid(); 7995 long ident = Binder.clearCallingIdentity(); 7996 7997 synchronized(this) { 7998 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7999 try { 8000 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8001 8002 final int N = mRecentTasks.size(); 8003 for (int i = 0; i < N; i++) { 8004 TaskRecord tr = mRecentTasks.get(i); 8005 // Skip tasks that do not match the caller. We don't need to verify 8006 // callingPackage, because we are also limiting to callingUid and know 8007 // that will limit to the correct security sandbox. 8008 if (tr.effectiveUid != callingUid) { 8009 continue; 8010 } 8011 Intent intent = tr.getBaseIntent(); 8012 if (intent == null || 8013 !callingPackage.equals(intent.getComponent().getPackageName())) { 8014 continue; 8015 } 8016 ActivityManager.RecentTaskInfo taskInfo = 8017 createRecentTaskInfoFromTaskRecord(tr); 8018 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8019 list.add(taskImpl); 8020 } 8021 } finally { 8022 Binder.restoreCallingIdentity(ident); 8023 } 8024 return list; 8025 } 8026 } 8027 8028 @Override 8029 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8030 final int callingUid = Binder.getCallingUid(); 8031 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8032 8033 synchronized(this) { 8034 if (localLOGV) Slog.v( 8035 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8036 8037 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8038 callingUid); 8039 8040 // TODO: Improve with MRU list from all ActivityStacks. 8041 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8042 } 8043 8044 return list; 8045 } 8046 8047 TaskRecord getMostRecentTask() { 8048 return mRecentTasks.get(0); 8049 } 8050 8051 /** 8052 * Creates a new RecentTaskInfo from a TaskRecord. 8053 */ 8054 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8055 // Update the task description to reflect any changes in the task stack 8056 tr.updateTaskDescription(); 8057 8058 // Compose the recent task info 8059 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8060 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8061 rti.persistentId = tr.taskId; 8062 rti.baseIntent = new Intent(tr.getBaseIntent()); 8063 rti.origActivity = tr.origActivity; 8064 rti.description = tr.lastDescription; 8065 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8066 rti.userId = tr.userId; 8067 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8068 rti.firstActiveTime = tr.firstActiveTime; 8069 rti.lastActiveTime = tr.lastActiveTime; 8070 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8071 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8072 return rti; 8073 } 8074 8075 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8076 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8077 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8078 if (!allowed) { 8079 if (checkPermission(android.Manifest.permission.GET_TASKS, 8080 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8081 // Temporary compatibility: some existing apps on the system image may 8082 // still be requesting the old permission and not switched to the new 8083 // one; if so, we'll still allow them full access. This means we need 8084 // to see if they are holding the old permission and are a system app. 8085 try { 8086 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8087 allowed = true; 8088 Slog.w(TAG, caller + ": caller " + callingUid 8089 + " is using old GET_TASKS but privileged; allowing"); 8090 } 8091 } catch (RemoteException e) { 8092 } 8093 } 8094 } 8095 if (!allowed) { 8096 Slog.w(TAG, caller + ": caller " + callingUid 8097 + " does not hold GET_TASKS; limiting output"); 8098 } 8099 return allowed; 8100 } 8101 8102 @Override 8103 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8104 final int callingUid = Binder.getCallingUid(); 8105 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8106 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8107 8108 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8109 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8110 synchronized (this) { 8111 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8112 callingUid); 8113 final boolean detailed = checkCallingPermission( 8114 android.Manifest.permission.GET_DETAILED_TASKS) 8115 == PackageManager.PERMISSION_GRANTED; 8116 8117 final int N = mRecentTasks.size(); 8118 ArrayList<ActivityManager.RecentTaskInfo> res 8119 = new ArrayList<ActivityManager.RecentTaskInfo>( 8120 maxNum < N ? maxNum : N); 8121 8122 final Set<Integer> includedUsers; 8123 if (includeProfiles) { 8124 includedUsers = getProfileIdsLocked(userId); 8125 } else { 8126 includedUsers = new HashSet<Integer>(); 8127 } 8128 includedUsers.add(Integer.valueOf(userId)); 8129 8130 for (int i=0; i<N && maxNum > 0; i++) { 8131 TaskRecord tr = mRecentTasks.get(i); 8132 // Only add calling user or related users recent tasks 8133 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8134 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8135 continue; 8136 } 8137 8138 // Return the entry if desired by the caller. We always return 8139 // the first entry, because callers always expect this to be the 8140 // foreground app. We may filter others if the caller has 8141 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8142 // we should exclude the entry. 8143 8144 if (i == 0 8145 || withExcluded 8146 || (tr.intent == null) 8147 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8148 == 0)) { 8149 if (!allowed) { 8150 // If the caller doesn't have the GET_TASKS permission, then only 8151 // allow them to see a small subset of tasks -- their own and home. 8152 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8153 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8154 continue; 8155 } 8156 } 8157 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8158 if (tr.stack != null && tr.stack.isHomeStack()) { 8159 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8160 continue; 8161 } 8162 } 8163 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8164 // Don't include auto remove tasks that are finished or finishing. 8165 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8166 + tr); 8167 continue; 8168 } 8169 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8170 && !tr.isAvailable) { 8171 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8172 continue; 8173 } 8174 8175 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8176 if (!detailed) { 8177 rti.baseIntent.replaceExtras((Bundle)null); 8178 } 8179 8180 res.add(rti); 8181 maxNum--; 8182 } 8183 } 8184 return res; 8185 } 8186 } 8187 8188 private TaskRecord taskForIdLocked(int id) { 8189 final TaskRecord task = recentTaskForIdLocked(id); 8190 if (task != null) { 8191 return task; 8192 } 8193 8194 // Don't give up. Sometimes it just hasn't made it to recents yet. 8195 return mStackSupervisor.anyTaskForIdLocked(id); 8196 } 8197 8198 private TaskRecord recentTaskForIdLocked(int id) { 8199 final int N = mRecentTasks.size(); 8200 for (int i=0; i<N; i++) { 8201 TaskRecord tr = mRecentTasks.get(i); 8202 if (tr.taskId == id) { 8203 return tr; 8204 } 8205 } 8206 return null; 8207 } 8208 8209 @Override 8210 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8211 synchronized (this) { 8212 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8213 "getTaskThumbnail()"); 8214 TaskRecord tr = recentTaskForIdLocked(id); 8215 if (tr != null) { 8216 return tr.getTaskThumbnailLocked(); 8217 } 8218 } 8219 return null; 8220 } 8221 8222 @Override 8223 public int addAppTask(IBinder activityToken, Intent intent, 8224 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8225 final int callingUid = Binder.getCallingUid(); 8226 final long callingIdent = Binder.clearCallingIdentity(); 8227 8228 try { 8229 synchronized (this) { 8230 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8231 if (r == null) { 8232 throw new IllegalArgumentException("Activity does not exist; token=" 8233 + activityToken); 8234 } 8235 ComponentName comp = intent.getComponent(); 8236 if (comp == null) { 8237 throw new IllegalArgumentException("Intent " + intent 8238 + " must specify explicit component"); 8239 } 8240 if (thumbnail.getWidth() != mThumbnailWidth 8241 || thumbnail.getHeight() != mThumbnailHeight) { 8242 throw new IllegalArgumentException("Bad thumbnail size: got " 8243 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8244 + mThumbnailWidth + "x" + mThumbnailHeight); 8245 } 8246 if (intent.getSelector() != null) { 8247 intent.setSelector(null); 8248 } 8249 if (intent.getSourceBounds() != null) { 8250 intent.setSourceBounds(null); 8251 } 8252 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8253 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8254 // The caller has added this as an auto-remove task... that makes no 8255 // sense, so turn off auto-remove. 8256 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8257 } 8258 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8259 // Must be a new task. 8260 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8261 } 8262 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8263 mLastAddedTaskActivity = null; 8264 } 8265 ActivityInfo ainfo = mLastAddedTaskActivity; 8266 if (ainfo == null) { 8267 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8268 comp, 0, UserHandle.getUserId(callingUid)); 8269 if (ainfo.applicationInfo.uid != callingUid) { 8270 throw new SecurityException( 8271 "Can't add task for another application: target uid=" 8272 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8273 } 8274 } 8275 8276 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8277 intent, description); 8278 8279 int trimIdx = trimRecentsForTask(task, false); 8280 if (trimIdx >= 0) { 8281 // If this would have caused a trim, then we'll abort because that 8282 // means it would be added at the end of the list but then just removed. 8283 return -1; 8284 } 8285 8286 final int N = mRecentTasks.size(); 8287 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8288 final TaskRecord tr = mRecentTasks.remove(N - 1); 8289 tr.removedFromRecents(mTaskPersister); 8290 } 8291 8292 task.inRecents = true; 8293 mRecentTasks.add(task); 8294 r.task.stack.addTask(task, false, false); 8295 8296 task.setLastThumbnail(thumbnail); 8297 task.freeLastThumbnail(); 8298 8299 return task.taskId; 8300 } 8301 } finally { 8302 Binder.restoreCallingIdentity(callingIdent); 8303 } 8304 } 8305 8306 @Override 8307 public Point getAppTaskThumbnailSize() { 8308 synchronized (this) { 8309 return new Point(mThumbnailWidth, mThumbnailHeight); 8310 } 8311 } 8312 8313 @Override 8314 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8315 synchronized (this) { 8316 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8317 if (r != null) { 8318 r.setTaskDescription(td); 8319 r.task.updateTaskDescription(); 8320 } 8321 } 8322 } 8323 8324 @Override 8325 public Bitmap getTaskDescriptionIcon(String filename) { 8326 if (!FileUtils.isValidExtFilename(filename) 8327 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8328 throw new IllegalArgumentException("Bad filename: " + filename); 8329 } 8330 return mTaskPersister.getTaskDescriptionIcon(filename); 8331 } 8332 8333 @Override 8334 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8335 throws RemoteException { 8336 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8337 opts.getCustomInPlaceResId() == 0) { 8338 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8339 "with valid animation"); 8340 } 8341 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8342 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8343 opts.getCustomInPlaceResId()); 8344 mWindowManager.executeAppTransition(); 8345 } 8346 8347 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8348 mRecentTasks.remove(tr); 8349 tr.removedFromRecents(mTaskPersister); 8350 ComponentName component = tr.getBaseIntent().getComponent(); 8351 if (component == null) { 8352 Slog.w(TAG, "No component for base intent of task: " + tr); 8353 return; 8354 } 8355 8356 if (!killProcess) { 8357 return; 8358 } 8359 8360 // Determine if the process(es) for this task should be killed. 8361 final String pkg = component.getPackageName(); 8362 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8363 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8364 for (int i = 0; i < pmap.size(); i++) { 8365 8366 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8367 for (int j = 0; j < uids.size(); j++) { 8368 ProcessRecord proc = uids.valueAt(j); 8369 if (proc.userId != tr.userId) { 8370 // Don't kill process for a different user. 8371 continue; 8372 } 8373 if (proc == mHomeProcess) { 8374 // Don't kill the home process along with tasks from the same package. 8375 continue; 8376 } 8377 if (!proc.pkgList.containsKey(pkg)) { 8378 // Don't kill process that is not associated with this task. 8379 continue; 8380 } 8381 8382 for (int k = 0; k < proc.activities.size(); k++) { 8383 TaskRecord otherTask = proc.activities.get(k).task; 8384 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8385 // Don't kill process(es) that has an activity in a different task that is 8386 // also in recents. 8387 return; 8388 } 8389 } 8390 8391 // Add process to kill list. 8392 procsToKill.add(proc); 8393 } 8394 } 8395 8396 // Find any running services associated with this app and stop if needed. 8397 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8398 8399 // Kill the running processes. 8400 for (int i = 0; i < procsToKill.size(); i++) { 8401 ProcessRecord pr = procsToKill.get(i); 8402 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8403 pr.kill("remove task", true); 8404 } else { 8405 pr.waitingToKill = "remove task"; 8406 } 8407 } 8408 } 8409 8410 /** 8411 * Removes the task with the specified task id. 8412 * 8413 * @param taskId Identifier of the task to be removed. 8414 * @param killProcess Kill any process associated with the task if possible. 8415 * @return Returns true if the given task was found and removed. 8416 */ 8417 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8418 TaskRecord tr = taskForIdLocked(taskId); 8419 if (tr != null) { 8420 tr.removeTaskActivitiesLocked(); 8421 cleanUpRemovedTaskLocked(tr, killProcess); 8422 if (tr.isPersistable) { 8423 notifyTaskPersisterLocked(null, true); 8424 } 8425 return true; 8426 } 8427 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8428 return false; 8429 } 8430 8431 @Override 8432 public boolean removeTask(int taskId) { 8433 synchronized (this) { 8434 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8435 "removeTask()"); 8436 long ident = Binder.clearCallingIdentity(); 8437 try { 8438 return removeTaskByIdLocked(taskId, true); 8439 } finally { 8440 Binder.restoreCallingIdentity(ident); 8441 } 8442 } 8443 } 8444 8445 /** 8446 * TODO: Add mController hook 8447 */ 8448 @Override 8449 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8450 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8451 "moveTaskToFront()"); 8452 8453 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8454 synchronized(this) { 8455 moveTaskToFrontLocked(taskId, flags, options); 8456 } 8457 } 8458 8459 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8460 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8461 Binder.getCallingUid(), -1, -1, "Task to front")) { 8462 ActivityOptions.abort(options); 8463 return; 8464 } 8465 final long origId = Binder.clearCallingIdentity(); 8466 try { 8467 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8468 if (task == null) { 8469 return; 8470 } 8471 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8472 mStackSupervisor.showLockTaskToast(); 8473 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8474 return; 8475 } 8476 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8477 if (prev != null && prev.isRecentsActivity()) { 8478 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8479 } 8480 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8481 } finally { 8482 Binder.restoreCallingIdentity(origId); 8483 } 8484 ActivityOptions.abort(options); 8485 } 8486 8487 @Override 8488 public void moveTaskToBack(int taskId) { 8489 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8490 "moveTaskToBack()"); 8491 8492 synchronized(this) { 8493 TaskRecord tr = taskForIdLocked(taskId); 8494 if (tr != null) { 8495 if (tr == mStackSupervisor.mLockTaskModeTask) { 8496 mStackSupervisor.showLockTaskToast(); 8497 return; 8498 } 8499 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8500 ActivityStack stack = tr.stack; 8501 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8502 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8503 Binder.getCallingUid(), -1, -1, "Task to back")) { 8504 return; 8505 } 8506 } 8507 final long origId = Binder.clearCallingIdentity(); 8508 try { 8509 stack.moveTaskToBackLocked(taskId, null); 8510 } finally { 8511 Binder.restoreCallingIdentity(origId); 8512 } 8513 } 8514 } 8515 } 8516 8517 /** 8518 * Moves an activity, and all of the other activities within the same task, to the bottom 8519 * of the history stack. The activity's order within the task is unchanged. 8520 * 8521 * @param token A reference to the activity we wish to move 8522 * @param nonRoot If false then this only works if the activity is the root 8523 * of a task; if true it will work for any activity in a task. 8524 * @return Returns true if the move completed, false if not. 8525 */ 8526 @Override 8527 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8528 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8529 synchronized(this) { 8530 final long origId = Binder.clearCallingIdentity(); 8531 try { 8532 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8533 if (taskId >= 0) { 8534 if ((mStackSupervisor.mLockTaskModeTask != null) 8535 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8536 mStackSupervisor.showLockTaskToast(); 8537 return false; 8538 } 8539 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8540 } 8541 } finally { 8542 Binder.restoreCallingIdentity(origId); 8543 } 8544 } 8545 return false; 8546 } 8547 8548 @Override 8549 public void moveTaskBackwards(int task) { 8550 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8551 "moveTaskBackwards()"); 8552 8553 synchronized(this) { 8554 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8555 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8556 return; 8557 } 8558 final long origId = Binder.clearCallingIdentity(); 8559 moveTaskBackwardsLocked(task); 8560 Binder.restoreCallingIdentity(origId); 8561 } 8562 } 8563 8564 private final void moveTaskBackwardsLocked(int task) { 8565 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8566 } 8567 8568 @Override 8569 public IBinder getHomeActivityToken() throws RemoteException { 8570 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8571 "getHomeActivityToken()"); 8572 synchronized (this) { 8573 return mStackSupervisor.getHomeActivityToken(); 8574 } 8575 } 8576 8577 @Override 8578 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8579 IActivityContainerCallback callback) throws RemoteException { 8580 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8581 "createActivityContainer()"); 8582 synchronized (this) { 8583 if (parentActivityToken == null) { 8584 throw new IllegalArgumentException("parent token must not be null"); 8585 } 8586 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8587 if (r == null) { 8588 return null; 8589 } 8590 if (callback == null) { 8591 throw new IllegalArgumentException("callback must not be null"); 8592 } 8593 return mStackSupervisor.createActivityContainer(r, callback); 8594 } 8595 } 8596 8597 @Override 8598 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8600 "deleteActivityContainer()"); 8601 synchronized (this) { 8602 mStackSupervisor.deleteActivityContainer(container); 8603 } 8604 } 8605 8606 @Override 8607 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8608 throws RemoteException { 8609 synchronized (this) { 8610 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8611 if (stack != null) { 8612 return stack.mActivityContainer; 8613 } 8614 return null; 8615 } 8616 } 8617 8618 @Override 8619 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8621 "moveTaskToStack()"); 8622 if (stackId == HOME_STACK_ID) { 8623 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8624 new RuntimeException("here").fillInStackTrace()); 8625 } 8626 synchronized (this) { 8627 long ident = Binder.clearCallingIdentity(); 8628 try { 8629 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8630 + stackId + " toTop=" + toTop); 8631 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8632 } finally { 8633 Binder.restoreCallingIdentity(ident); 8634 } 8635 } 8636 } 8637 8638 @Override 8639 public void resizeStack(int stackBoxId, Rect bounds) { 8640 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8641 "resizeStackBox()"); 8642 long ident = Binder.clearCallingIdentity(); 8643 try { 8644 mWindowManager.resizeStack(stackBoxId, bounds); 8645 } finally { 8646 Binder.restoreCallingIdentity(ident); 8647 } 8648 } 8649 8650 @Override 8651 public List<StackInfo> getAllStackInfos() { 8652 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8653 "getAllStackInfos()"); 8654 long ident = Binder.clearCallingIdentity(); 8655 try { 8656 synchronized (this) { 8657 return mStackSupervisor.getAllStackInfosLocked(); 8658 } 8659 } finally { 8660 Binder.restoreCallingIdentity(ident); 8661 } 8662 } 8663 8664 @Override 8665 public StackInfo getStackInfo(int stackId) { 8666 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8667 "getStackInfo()"); 8668 long ident = Binder.clearCallingIdentity(); 8669 try { 8670 synchronized (this) { 8671 return mStackSupervisor.getStackInfoLocked(stackId); 8672 } 8673 } finally { 8674 Binder.restoreCallingIdentity(ident); 8675 } 8676 } 8677 8678 @Override 8679 public boolean isInHomeStack(int taskId) { 8680 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8681 "getStackInfo()"); 8682 long ident = Binder.clearCallingIdentity(); 8683 try { 8684 synchronized (this) { 8685 TaskRecord tr = taskForIdLocked(taskId); 8686 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8687 } 8688 } finally { 8689 Binder.restoreCallingIdentity(ident); 8690 } 8691 } 8692 8693 @Override 8694 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8695 synchronized(this) { 8696 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8697 } 8698 } 8699 8700 private boolean isLockTaskAuthorized(String pkg) { 8701 final DevicePolicyManager dpm = (DevicePolicyManager) 8702 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8703 try { 8704 int uid = mContext.getPackageManager().getPackageUid(pkg, 8705 Binder.getCallingUserHandle().getIdentifier()); 8706 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8707 } catch (NameNotFoundException e) { 8708 return false; 8709 } 8710 } 8711 8712 void startLockTaskMode(TaskRecord task) { 8713 final String pkg; 8714 synchronized (this) { 8715 pkg = task.intent.getComponent().getPackageName(); 8716 } 8717 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8718 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8719 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8720 StatusBarManagerInternal.class); 8721 if (statusBarManager != null) { 8722 statusBarManager.showScreenPinningRequest(); 8723 } 8724 return; 8725 } 8726 long ident = Binder.clearCallingIdentity(); 8727 try { 8728 synchronized (this) { 8729 // Since we lost lock on task, make sure it is still there. 8730 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8731 if (task != null) { 8732 if (!isSystemInitiated 8733 && ((mStackSupervisor.getFocusedStack() == null) 8734 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8735 throw new IllegalArgumentException("Invalid task, not in foreground"); 8736 } 8737 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8738 } 8739 } 8740 } finally { 8741 Binder.restoreCallingIdentity(ident); 8742 } 8743 } 8744 8745 @Override 8746 public void startLockTaskMode(int taskId) { 8747 final TaskRecord task; 8748 long ident = Binder.clearCallingIdentity(); 8749 try { 8750 synchronized (this) { 8751 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8752 } 8753 } finally { 8754 Binder.restoreCallingIdentity(ident); 8755 } 8756 if (task != null) { 8757 startLockTaskMode(task); 8758 } 8759 } 8760 8761 @Override 8762 public void startLockTaskMode(IBinder token) { 8763 final TaskRecord task; 8764 long ident = Binder.clearCallingIdentity(); 8765 try { 8766 synchronized (this) { 8767 final ActivityRecord r = ActivityRecord.forToken(token); 8768 if (r == null) { 8769 return; 8770 } 8771 task = r.task; 8772 } 8773 } finally { 8774 Binder.restoreCallingIdentity(ident); 8775 } 8776 if (task != null) { 8777 startLockTaskMode(task); 8778 } 8779 } 8780 8781 @Override 8782 public void startLockTaskModeOnCurrent() throws RemoteException { 8783 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8784 "startLockTaskModeOnCurrent"); 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 ActivityRecord r = null; 8788 synchronized (this) { 8789 r = mStackSupervisor.topRunningActivityLocked(); 8790 } 8791 startLockTaskMode(r.task); 8792 } finally { 8793 Binder.restoreCallingIdentity(ident); 8794 } 8795 } 8796 8797 @Override 8798 public void stopLockTaskMode() { 8799 // Verify that the user matches the package of the intent for the TaskRecord 8800 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8801 // and stopLockTaskMode. 8802 final int callingUid = Binder.getCallingUid(); 8803 if (callingUid != Process.SYSTEM_UID) { 8804 try { 8805 String pkg = 8806 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8807 int uid = mContext.getPackageManager().getPackageUid(pkg, 8808 Binder.getCallingUserHandle().getIdentifier()); 8809 if (uid != callingUid) { 8810 throw new SecurityException("Invalid uid, expected " + uid); 8811 } 8812 } catch (NameNotFoundException e) { 8813 Log.d(TAG, "stopLockTaskMode " + e); 8814 return; 8815 } 8816 } 8817 long ident = Binder.clearCallingIdentity(); 8818 try { 8819 Log.d(TAG, "stopLockTaskMode"); 8820 // Stop lock task 8821 synchronized (this) { 8822 mStackSupervisor.setLockTaskModeLocked(null, false); 8823 } 8824 } finally { 8825 Binder.restoreCallingIdentity(ident); 8826 } 8827 } 8828 8829 @Override 8830 public void stopLockTaskModeOnCurrent() throws RemoteException { 8831 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8832 "stopLockTaskModeOnCurrent"); 8833 long ident = Binder.clearCallingIdentity(); 8834 try { 8835 stopLockTaskMode(); 8836 } finally { 8837 Binder.restoreCallingIdentity(ident); 8838 } 8839 } 8840 8841 @Override 8842 public boolean isInLockTaskMode() { 8843 synchronized (this) { 8844 return mStackSupervisor.isInLockTaskMode(); 8845 } 8846 } 8847 8848 // ========================================================= 8849 // CONTENT PROVIDERS 8850 // ========================================================= 8851 8852 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8853 List<ProviderInfo> providers = null; 8854 try { 8855 providers = AppGlobals.getPackageManager(). 8856 queryContentProviders(app.processName, app.uid, 8857 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8858 } catch (RemoteException ex) { 8859 } 8860 if (DEBUG_MU) 8861 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8862 int userId = app.userId; 8863 if (providers != null) { 8864 int N = providers.size(); 8865 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8866 for (int i=0; i<N; i++) { 8867 ProviderInfo cpi = 8868 (ProviderInfo)providers.get(i); 8869 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8870 cpi.name, cpi.flags); 8871 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8872 // This is a singleton provider, but a user besides the 8873 // default user is asking to initialize a process it runs 8874 // in... well, no, it doesn't actually run in this process, 8875 // it runs in the process of the default user. Get rid of it. 8876 providers.remove(i); 8877 N--; 8878 i--; 8879 continue; 8880 } 8881 8882 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8883 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8884 if (cpr == null) { 8885 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8886 mProviderMap.putProviderByClass(comp, cpr); 8887 } 8888 if (DEBUG_MU) 8889 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8890 app.pubProviders.put(cpi.name, cpr); 8891 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8892 // Don't add this if it is a platform component that is marked 8893 // to run in multiple processes, because this is actually 8894 // part of the framework so doesn't make sense to track as a 8895 // separate apk in the process. 8896 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8897 mProcessStats); 8898 } 8899 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8900 } 8901 } 8902 return providers; 8903 } 8904 8905 /** 8906 * Check if {@link ProcessRecord} has a possible chance at accessing the 8907 * given {@link ProviderInfo}. Final permission checking is always done 8908 * in {@link ContentProvider}. 8909 */ 8910 private final String checkContentProviderPermissionLocked( 8911 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8912 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8913 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8914 boolean checkedGrants = false; 8915 if (checkUser) { 8916 // Looking for cross-user grants before enforcing the typical cross-users permissions 8917 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8918 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8919 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8920 return null; 8921 } 8922 checkedGrants = true; 8923 } 8924 userId = handleIncomingUser(callingPid, callingUid, userId, 8925 false, ALLOW_NON_FULL, 8926 "checkContentProviderPermissionLocked " + cpi.authority, null); 8927 if (userId != tmpTargetUserId) { 8928 // When we actually went to determine the final targer user ID, this ended 8929 // up different than our initial check for the authority. This is because 8930 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8931 // SELF. So we need to re-check the grants again. 8932 checkedGrants = false; 8933 } 8934 } 8935 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8936 cpi.applicationInfo.uid, cpi.exported) 8937 == PackageManager.PERMISSION_GRANTED) { 8938 return null; 8939 } 8940 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8941 cpi.applicationInfo.uid, cpi.exported) 8942 == PackageManager.PERMISSION_GRANTED) { 8943 return null; 8944 } 8945 8946 PathPermission[] pps = cpi.pathPermissions; 8947 if (pps != null) { 8948 int i = pps.length; 8949 while (i > 0) { 8950 i--; 8951 PathPermission pp = pps[i]; 8952 String pprperm = pp.getReadPermission(); 8953 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8954 cpi.applicationInfo.uid, cpi.exported) 8955 == PackageManager.PERMISSION_GRANTED) { 8956 return null; 8957 } 8958 String ppwperm = pp.getWritePermission(); 8959 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8960 cpi.applicationInfo.uid, cpi.exported) 8961 == PackageManager.PERMISSION_GRANTED) { 8962 return null; 8963 } 8964 } 8965 } 8966 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8967 return null; 8968 } 8969 8970 String msg; 8971 if (!cpi.exported) { 8972 msg = "Permission Denial: opening provider " + cpi.name 8973 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8974 + ", uid=" + callingUid + ") that is not exported from uid " 8975 + cpi.applicationInfo.uid; 8976 } else { 8977 msg = "Permission Denial: opening provider " + cpi.name 8978 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8979 + ", uid=" + callingUid + ") requires " 8980 + cpi.readPermission + " or " + cpi.writePermission; 8981 } 8982 Slog.w(TAG, msg); 8983 return msg; 8984 } 8985 8986 /** 8987 * Returns if the ContentProvider has granted a uri to callingUid 8988 */ 8989 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8990 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8991 if (perms != null) { 8992 for (int i=perms.size()-1; i>=0; i--) { 8993 GrantUri grantUri = perms.keyAt(i); 8994 if (grantUri.sourceUserId == userId || !checkUser) { 8995 if (matchesProvider(grantUri.uri, cpi)) { 8996 return true; 8997 } 8998 } 8999 } 9000 } 9001 return false; 9002 } 9003 9004 /** 9005 * Returns true if the uri authority is one of the authorities specified in the provider. 9006 */ 9007 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9008 String uriAuth = uri.getAuthority(); 9009 String cpiAuth = cpi.authority; 9010 if (cpiAuth.indexOf(';') == -1) { 9011 return cpiAuth.equals(uriAuth); 9012 } 9013 String[] cpiAuths = cpiAuth.split(";"); 9014 int length = cpiAuths.length; 9015 for (int i = 0; i < length; i++) { 9016 if (cpiAuths[i].equals(uriAuth)) return true; 9017 } 9018 return false; 9019 } 9020 9021 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9022 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9023 if (r != null) { 9024 for (int i=0; i<r.conProviders.size(); i++) { 9025 ContentProviderConnection conn = r.conProviders.get(i); 9026 if (conn.provider == cpr) { 9027 if (DEBUG_PROVIDER) Slog.v(TAG, 9028 "Adding provider requested by " 9029 + r.processName + " from process " 9030 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9031 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9032 if (stable) { 9033 conn.stableCount++; 9034 conn.numStableIncs++; 9035 } else { 9036 conn.unstableCount++; 9037 conn.numUnstableIncs++; 9038 } 9039 return conn; 9040 } 9041 } 9042 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9043 if (stable) { 9044 conn.stableCount = 1; 9045 conn.numStableIncs = 1; 9046 } else { 9047 conn.unstableCount = 1; 9048 conn.numUnstableIncs = 1; 9049 } 9050 cpr.connections.add(conn); 9051 r.conProviders.add(conn); 9052 return conn; 9053 } 9054 cpr.addExternalProcessHandleLocked(externalProcessToken); 9055 return null; 9056 } 9057 9058 boolean decProviderCountLocked(ContentProviderConnection conn, 9059 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9060 if (conn != null) { 9061 cpr = conn.provider; 9062 if (DEBUG_PROVIDER) Slog.v(TAG, 9063 "Removing provider requested by " 9064 + conn.client.processName + " from process " 9065 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9066 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9067 if (stable) { 9068 conn.stableCount--; 9069 } else { 9070 conn.unstableCount--; 9071 } 9072 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9073 cpr.connections.remove(conn); 9074 conn.client.conProviders.remove(conn); 9075 return true; 9076 } 9077 return false; 9078 } 9079 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9080 return false; 9081 } 9082 9083 private void checkTime(long startTime, String where) { 9084 long now = SystemClock.elapsedRealtime(); 9085 if ((now-startTime) > 1000) { 9086 // If we are taking more than a second, log about it. 9087 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9088 } 9089 } 9090 9091 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9092 String name, IBinder token, boolean stable, int userId) { 9093 ContentProviderRecord cpr; 9094 ContentProviderConnection conn = null; 9095 ProviderInfo cpi = null; 9096 9097 synchronized(this) { 9098 long startTime = SystemClock.elapsedRealtime(); 9099 9100 ProcessRecord r = null; 9101 if (caller != null) { 9102 r = getRecordForAppLocked(caller); 9103 if (r == null) { 9104 throw new SecurityException( 9105 "Unable to find app for caller " + caller 9106 + " (pid=" + Binder.getCallingPid() 9107 + ") when getting content provider " + name); 9108 } 9109 } 9110 9111 boolean checkCrossUser = true; 9112 9113 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9114 9115 // First check if this content provider has been published... 9116 cpr = mProviderMap.getProviderByName(name, userId); 9117 // If that didn't work, check if it exists for user 0 and then 9118 // verify that it's a singleton provider before using it. 9119 if (cpr == null && userId != UserHandle.USER_OWNER) { 9120 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9121 if (cpr != null) { 9122 cpi = cpr.info; 9123 if (isSingleton(cpi.processName, cpi.applicationInfo, 9124 cpi.name, cpi.flags) 9125 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9126 userId = UserHandle.USER_OWNER; 9127 checkCrossUser = false; 9128 } else { 9129 cpr = null; 9130 cpi = null; 9131 } 9132 } 9133 } 9134 9135 boolean providerRunning = cpr != null; 9136 if (providerRunning) { 9137 cpi = cpr.info; 9138 String msg; 9139 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9140 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9141 != null) { 9142 throw new SecurityException(msg); 9143 } 9144 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9145 9146 if (r != null && cpr.canRunHere(r)) { 9147 // This provider has been published or is in the process 9148 // of being published... but it is also allowed to run 9149 // in the caller's process, so don't make a connection 9150 // and just let the caller instantiate its own instance. 9151 ContentProviderHolder holder = cpr.newHolder(null); 9152 // don't give caller the provider object, it needs 9153 // to make its own. 9154 holder.provider = null; 9155 return holder; 9156 } 9157 9158 final long origId = Binder.clearCallingIdentity(); 9159 9160 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9161 9162 // In this case the provider instance already exists, so we can 9163 // return it right away. 9164 conn = incProviderCountLocked(r, cpr, token, stable); 9165 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9166 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9167 // If this is a perceptible app accessing the provider, 9168 // make sure to count it as being accessed and thus 9169 // back up on the LRU list. This is good because 9170 // content providers are often expensive to start. 9171 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9172 updateLruProcessLocked(cpr.proc, false, null); 9173 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9174 } 9175 } 9176 9177 if (cpr.proc != null) { 9178 if (false) { 9179 if (cpr.name.flattenToShortString().equals( 9180 "com.android.providers.calendar/.CalendarProvider2")) { 9181 Slog.v(TAG, "****************** KILLING " 9182 + cpr.name.flattenToShortString()); 9183 Process.killProcess(cpr.proc.pid); 9184 } 9185 } 9186 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9187 boolean success = updateOomAdjLocked(cpr.proc); 9188 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9189 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9190 // NOTE: there is still a race here where a signal could be 9191 // pending on the process even though we managed to update its 9192 // adj level. Not sure what to do about this, but at least 9193 // the race is now smaller. 9194 if (!success) { 9195 // Uh oh... it looks like the provider's process 9196 // has been killed on us. We need to wait for a new 9197 // process to be started, and make sure its death 9198 // doesn't kill our process. 9199 Slog.i(TAG, 9200 "Existing provider " + cpr.name.flattenToShortString() 9201 + " is crashing; detaching " + r); 9202 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9203 checkTime(startTime, "getContentProviderImpl: before appDied"); 9204 appDiedLocked(cpr.proc); 9205 checkTime(startTime, "getContentProviderImpl: after appDied"); 9206 if (!lastRef) { 9207 // This wasn't the last ref our process had on 9208 // the provider... we have now been killed, bail. 9209 return null; 9210 } 9211 providerRunning = false; 9212 conn = null; 9213 } 9214 } 9215 9216 Binder.restoreCallingIdentity(origId); 9217 } 9218 9219 boolean singleton; 9220 if (!providerRunning) { 9221 try { 9222 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9223 cpi = AppGlobals.getPackageManager(). 9224 resolveContentProvider(name, 9225 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9226 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9227 } catch (RemoteException ex) { 9228 } 9229 if (cpi == null) { 9230 return null; 9231 } 9232 // If the provider is a singleton AND 9233 // (it's a call within the same user || the provider is a 9234 // privileged app) 9235 // Then allow connecting to the singleton provider 9236 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9237 cpi.name, cpi.flags) 9238 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9239 if (singleton) { 9240 userId = UserHandle.USER_OWNER; 9241 } 9242 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9243 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9244 9245 String msg; 9246 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9247 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9248 != null) { 9249 throw new SecurityException(msg); 9250 } 9251 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9252 9253 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9254 && !cpi.processName.equals("system")) { 9255 // If this content provider does not run in the system 9256 // process, and the system is not yet ready to run other 9257 // processes, then fail fast instead of hanging. 9258 throw new IllegalArgumentException( 9259 "Attempt to launch content provider before system ready"); 9260 } 9261 9262 // Make sure that the user who owns this provider is started. If not, 9263 // we don't want to allow it to run. 9264 if (mStartedUsers.get(userId) == null) { 9265 Slog.w(TAG, "Unable to launch app " 9266 + cpi.applicationInfo.packageName + "/" 9267 + cpi.applicationInfo.uid + " for provider " 9268 + name + ": user " + userId + " is stopped"); 9269 return null; 9270 } 9271 9272 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9273 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9274 cpr = mProviderMap.getProviderByClass(comp, userId); 9275 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9276 final boolean firstClass = cpr == null; 9277 if (firstClass) { 9278 final long ident = Binder.clearCallingIdentity(); 9279 try { 9280 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9281 ApplicationInfo ai = 9282 AppGlobals.getPackageManager(). 9283 getApplicationInfo( 9284 cpi.applicationInfo.packageName, 9285 STOCK_PM_FLAGS, userId); 9286 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9287 if (ai == null) { 9288 Slog.w(TAG, "No package info for content provider " 9289 + cpi.name); 9290 return null; 9291 } 9292 ai = getAppInfoForUser(ai, userId); 9293 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9294 } catch (RemoteException ex) { 9295 // pm is in same process, this will never happen. 9296 } finally { 9297 Binder.restoreCallingIdentity(ident); 9298 } 9299 } 9300 9301 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9302 9303 if (r != null && cpr.canRunHere(r)) { 9304 // If this is a multiprocess provider, then just return its 9305 // info and allow the caller to instantiate it. Only do 9306 // this if the provider is the same user as the caller's 9307 // process, or can run as root (so can be in any process). 9308 return cpr.newHolder(null); 9309 } 9310 9311 if (DEBUG_PROVIDER) { 9312 RuntimeException e = new RuntimeException("here"); 9313 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9314 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9315 } 9316 9317 // This is single process, and our app is now connecting to it. 9318 // See if we are already in the process of launching this 9319 // provider. 9320 final int N = mLaunchingProviders.size(); 9321 int i; 9322 for (i=0; i<N; i++) { 9323 if (mLaunchingProviders.get(i) == cpr) { 9324 break; 9325 } 9326 } 9327 9328 // If the provider is not already being launched, then get it 9329 // started. 9330 if (i >= N) { 9331 final long origId = Binder.clearCallingIdentity(); 9332 9333 try { 9334 // Content provider is now in use, its package can't be stopped. 9335 try { 9336 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9337 AppGlobals.getPackageManager().setPackageStoppedState( 9338 cpr.appInfo.packageName, false, userId); 9339 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9340 } catch (RemoteException e) { 9341 } catch (IllegalArgumentException e) { 9342 Slog.w(TAG, "Failed trying to unstop package " 9343 + cpr.appInfo.packageName + ": " + e); 9344 } 9345 9346 // Use existing process if already started 9347 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9348 ProcessRecord proc = getProcessRecordLocked( 9349 cpi.processName, cpr.appInfo.uid, false); 9350 if (proc != null && proc.thread != null) { 9351 if (DEBUG_PROVIDER) { 9352 Slog.d(TAG, "Installing in existing process " + proc); 9353 } 9354 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9355 proc.pubProviders.put(cpi.name, cpr); 9356 try { 9357 proc.thread.scheduleInstallProvider(cpi); 9358 } catch (RemoteException e) { 9359 } 9360 } else { 9361 checkTime(startTime, "getContentProviderImpl: before start process"); 9362 proc = startProcessLocked(cpi.processName, 9363 cpr.appInfo, false, 0, "content provider", 9364 new ComponentName(cpi.applicationInfo.packageName, 9365 cpi.name), false, false, false); 9366 checkTime(startTime, "getContentProviderImpl: after start process"); 9367 if (proc == null) { 9368 Slog.w(TAG, "Unable to launch app " 9369 + cpi.applicationInfo.packageName + "/" 9370 + cpi.applicationInfo.uid + " for provider " 9371 + name + ": process is bad"); 9372 return null; 9373 } 9374 } 9375 cpr.launchingApp = proc; 9376 mLaunchingProviders.add(cpr); 9377 } finally { 9378 Binder.restoreCallingIdentity(origId); 9379 } 9380 } 9381 9382 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9383 9384 // Make sure the provider is published (the same provider class 9385 // may be published under multiple names). 9386 if (firstClass) { 9387 mProviderMap.putProviderByClass(comp, cpr); 9388 } 9389 9390 mProviderMap.putProviderByName(name, cpr); 9391 conn = incProviderCountLocked(r, cpr, token, stable); 9392 if (conn != null) { 9393 conn.waiting = true; 9394 } 9395 } 9396 checkTime(startTime, "getContentProviderImpl: done!"); 9397 } 9398 9399 // Wait for the provider to be published... 9400 synchronized (cpr) { 9401 while (cpr.provider == null) { 9402 if (cpr.launchingApp == null) { 9403 Slog.w(TAG, "Unable to launch app " 9404 + cpi.applicationInfo.packageName + "/" 9405 + cpi.applicationInfo.uid + " for provider " 9406 + name + ": launching app became null"); 9407 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9408 UserHandle.getUserId(cpi.applicationInfo.uid), 9409 cpi.applicationInfo.packageName, 9410 cpi.applicationInfo.uid, name); 9411 return null; 9412 } 9413 try { 9414 if (DEBUG_MU) { 9415 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9416 + cpr.launchingApp); 9417 } 9418 if (conn != null) { 9419 conn.waiting = true; 9420 } 9421 cpr.wait(); 9422 } catch (InterruptedException ex) { 9423 } finally { 9424 if (conn != null) { 9425 conn.waiting = false; 9426 } 9427 } 9428 } 9429 } 9430 return cpr != null ? cpr.newHolder(conn) : null; 9431 } 9432 9433 @Override 9434 public final ContentProviderHolder getContentProvider( 9435 IApplicationThread caller, String name, int userId, boolean stable) { 9436 enforceNotIsolatedCaller("getContentProvider"); 9437 if (caller == null) { 9438 String msg = "null IApplicationThread when getting content provider " 9439 + name; 9440 Slog.w(TAG, msg); 9441 throw new SecurityException(msg); 9442 } 9443 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9444 // with cross-user grant. 9445 return getContentProviderImpl(caller, name, null, stable, userId); 9446 } 9447 9448 public ContentProviderHolder getContentProviderExternal( 9449 String name, int userId, IBinder token) { 9450 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9451 "Do not have permission in call getContentProviderExternal()"); 9452 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9453 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9454 return getContentProviderExternalUnchecked(name, token, userId); 9455 } 9456 9457 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9458 IBinder token, int userId) { 9459 return getContentProviderImpl(null, name, token, true, userId); 9460 } 9461 9462 /** 9463 * Drop a content provider from a ProcessRecord's bookkeeping 9464 */ 9465 public void removeContentProvider(IBinder connection, boolean stable) { 9466 enforceNotIsolatedCaller("removeContentProvider"); 9467 long ident = Binder.clearCallingIdentity(); 9468 try { 9469 synchronized (this) { 9470 ContentProviderConnection conn; 9471 try { 9472 conn = (ContentProviderConnection)connection; 9473 } catch (ClassCastException e) { 9474 String msg ="removeContentProvider: " + connection 9475 + " not a ContentProviderConnection"; 9476 Slog.w(TAG, msg); 9477 throw new IllegalArgumentException(msg); 9478 } 9479 if (conn == null) { 9480 throw new NullPointerException("connection is null"); 9481 } 9482 if (decProviderCountLocked(conn, null, null, stable)) { 9483 updateOomAdjLocked(); 9484 } 9485 } 9486 } finally { 9487 Binder.restoreCallingIdentity(ident); 9488 } 9489 } 9490 9491 public void removeContentProviderExternal(String name, IBinder token) { 9492 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9493 "Do not have permission in call removeContentProviderExternal()"); 9494 int userId = UserHandle.getCallingUserId(); 9495 long ident = Binder.clearCallingIdentity(); 9496 try { 9497 removeContentProviderExternalUnchecked(name, token, userId); 9498 } finally { 9499 Binder.restoreCallingIdentity(ident); 9500 } 9501 } 9502 9503 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9504 synchronized (this) { 9505 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9506 if(cpr == null) { 9507 //remove from mProvidersByClass 9508 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9509 return; 9510 } 9511 9512 //update content provider record entry info 9513 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9514 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9515 if (localCpr.hasExternalProcessHandles()) { 9516 if (localCpr.removeExternalProcessHandleLocked(token)) { 9517 updateOomAdjLocked(); 9518 } else { 9519 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9520 + " with no external reference for token: " 9521 + token + "."); 9522 } 9523 } else { 9524 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9525 + " with no external references."); 9526 } 9527 } 9528 } 9529 9530 public final void publishContentProviders(IApplicationThread caller, 9531 List<ContentProviderHolder> providers) { 9532 if (providers == null) { 9533 return; 9534 } 9535 9536 enforceNotIsolatedCaller("publishContentProviders"); 9537 synchronized (this) { 9538 final ProcessRecord r = getRecordForAppLocked(caller); 9539 if (DEBUG_MU) 9540 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9541 if (r == null) { 9542 throw new SecurityException( 9543 "Unable to find app for caller " + caller 9544 + " (pid=" + Binder.getCallingPid() 9545 + ") when publishing content providers"); 9546 } 9547 9548 final long origId = Binder.clearCallingIdentity(); 9549 9550 final int N = providers.size(); 9551 for (int i=0; i<N; i++) { 9552 ContentProviderHolder src = providers.get(i); 9553 if (src == null || src.info == null || src.provider == null) { 9554 continue; 9555 } 9556 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9557 if (DEBUG_MU) 9558 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9559 if (dst != null) { 9560 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9561 mProviderMap.putProviderByClass(comp, dst); 9562 String names[] = dst.info.authority.split(";"); 9563 for (int j = 0; j < names.length; j++) { 9564 mProviderMap.putProviderByName(names[j], dst); 9565 } 9566 9567 int NL = mLaunchingProviders.size(); 9568 int j; 9569 for (j=0; j<NL; j++) { 9570 if (mLaunchingProviders.get(j) == dst) { 9571 mLaunchingProviders.remove(j); 9572 j--; 9573 NL--; 9574 } 9575 } 9576 synchronized (dst) { 9577 dst.provider = src.provider; 9578 dst.proc = r; 9579 dst.notifyAll(); 9580 } 9581 updateOomAdjLocked(r); 9582 } 9583 } 9584 9585 Binder.restoreCallingIdentity(origId); 9586 } 9587 } 9588 9589 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9590 ContentProviderConnection conn; 9591 try { 9592 conn = (ContentProviderConnection)connection; 9593 } catch (ClassCastException e) { 9594 String msg ="refContentProvider: " + connection 9595 + " not a ContentProviderConnection"; 9596 Slog.w(TAG, msg); 9597 throw new IllegalArgumentException(msg); 9598 } 9599 if (conn == null) { 9600 throw new NullPointerException("connection is null"); 9601 } 9602 9603 synchronized (this) { 9604 if (stable > 0) { 9605 conn.numStableIncs += stable; 9606 } 9607 stable = conn.stableCount + stable; 9608 if (stable < 0) { 9609 throw new IllegalStateException("stableCount < 0: " + stable); 9610 } 9611 9612 if (unstable > 0) { 9613 conn.numUnstableIncs += unstable; 9614 } 9615 unstable = conn.unstableCount + unstable; 9616 if (unstable < 0) { 9617 throw new IllegalStateException("unstableCount < 0: " + unstable); 9618 } 9619 9620 if ((stable+unstable) <= 0) { 9621 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9622 + stable + " unstable=" + unstable); 9623 } 9624 conn.stableCount = stable; 9625 conn.unstableCount = unstable; 9626 return !conn.dead; 9627 } 9628 } 9629 9630 public void unstableProviderDied(IBinder connection) { 9631 ContentProviderConnection conn; 9632 try { 9633 conn = (ContentProviderConnection)connection; 9634 } catch (ClassCastException e) { 9635 String msg ="refContentProvider: " + connection 9636 + " not a ContentProviderConnection"; 9637 Slog.w(TAG, msg); 9638 throw new IllegalArgumentException(msg); 9639 } 9640 if (conn == null) { 9641 throw new NullPointerException("connection is null"); 9642 } 9643 9644 // Safely retrieve the content provider associated with the connection. 9645 IContentProvider provider; 9646 synchronized (this) { 9647 provider = conn.provider.provider; 9648 } 9649 9650 if (provider == null) { 9651 // Um, yeah, we're way ahead of you. 9652 return; 9653 } 9654 9655 // Make sure the caller is being honest with us. 9656 if (provider.asBinder().pingBinder()) { 9657 // Er, no, still looks good to us. 9658 synchronized (this) { 9659 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9660 + " says " + conn + " died, but we don't agree"); 9661 return; 9662 } 9663 } 9664 9665 // Well look at that! It's dead! 9666 synchronized (this) { 9667 if (conn.provider.provider != provider) { 9668 // But something changed... good enough. 9669 return; 9670 } 9671 9672 ProcessRecord proc = conn.provider.proc; 9673 if (proc == null || proc.thread == null) { 9674 // Seems like the process is already cleaned up. 9675 return; 9676 } 9677 9678 // As far as we're concerned, this is just like receiving a 9679 // death notification... just a bit prematurely. 9680 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9681 + ") early provider death"); 9682 final long ident = Binder.clearCallingIdentity(); 9683 try { 9684 appDiedLocked(proc); 9685 } finally { 9686 Binder.restoreCallingIdentity(ident); 9687 } 9688 } 9689 } 9690 9691 @Override 9692 public void appNotRespondingViaProvider(IBinder connection) { 9693 enforceCallingPermission( 9694 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9695 9696 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9697 if (conn == null) { 9698 Slog.w(TAG, "ContentProviderConnection is null"); 9699 return; 9700 } 9701 9702 final ProcessRecord host = conn.provider.proc; 9703 if (host == null) { 9704 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9705 return; 9706 } 9707 9708 final long token = Binder.clearCallingIdentity(); 9709 try { 9710 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9711 } finally { 9712 Binder.restoreCallingIdentity(token); 9713 } 9714 } 9715 9716 public final void installSystemProviders() { 9717 List<ProviderInfo> providers; 9718 synchronized (this) { 9719 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9720 providers = generateApplicationProvidersLocked(app); 9721 if (providers != null) { 9722 for (int i=providers.size()-1; i>=0; i--) { 9723 ProviderInfo pi = (ProviderInfo)providers.get(i); 9724 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9725 Slog.w(TAG, "Not installing system proc provider " + pi.name 9726 + ": not system .apk"); 9727 providers.remove(i); 9728 } 9729 } 9730 } 9731 } 9732 if (providers != null) { 9733 mSystemThread.installSystemProviders(providers); 9734 } 9735 9736 mCoreSettingsObserver = new CoreSettingsObserver(this); 9737 9738 //mUsageStatsService.monitorPackages(); 9739 } 9740 9741 /** 9742 * Allows apps to retrieve the MIME type of a URI. 9743 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9744 * users, then it does not need permission to access the ContentProvider. 9745 * Either, it needs cross-user uri grants. 9746 * 9747 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9748 * 9749 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9750 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9751 */ 9752 public String getProviderMimeType(Uri uri, int userId) { 9753 enforceNotIsolatedCaller("getProviderMimeType"); 9754 final String name = uri.getAuthority(); 9755 int callingUid = Binder.getCallingUid(); 9756 int callingPid = Binder.getCallingPid(); 9757 long ident = 0; 9758 boolean clearedIdentity = false; 9759 userId = unsafeConvertIncomingUser(userId); 9760 if (canClearIdentity(callingPid, callingUid, userId)) { 9761 clearedIdentity = true; 9762 ident = Binder.clearCallingIdentity(); 9763 } 9764 ContentProviderHolder holder = null; 9765 try { 9766 holder = getContentProviderExternalUnchecked(name, null, userId); 9767 if (holder != null) { 9768 return holder.provider.getType(uri); 9769 } 9770 } catch (RemoteException e) { 9771 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9772 return null; 9773 } finally { 9774 // We need to clear the identity to call removeContentProviderExternalUnchecked 9775 if (!clearedIdentity) { 9776 ident = Binder.clearCallingIdentity(); 9777 } 9778 try { 9779 if (holder != null) { 9780 removeContentProviderExternalUnchecked(name, null, userId); 9781 } 9782 } finally { 9783 Binder.restoreCallingIdentity(ident); 9784 } 9785 } 9786 9787 return null; 9788 } 9789 9790 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9791 if (UserHandle.getUserId(callingUid) == userId) { 9792 return true; 9793 } 9794 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9795 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9796 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9797 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9798 return true; 9799 } 9800 return false; 9801 } 9802 9803 // ========================================================= 9804 // GLOBAL MANAGEMENT 9805 // ========================================================= 9806 9807 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9808 boolean isolated, int isolatedUid) { 9809 String proc = customProcess != null ? customProcess : info.processName; 9810 BatteryStatsImpl.Uid.Proc ps = null; 9811 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9812 int uid = info.uid; 9813 if (isolated) { 9814 if (isolatedUid == 0) { 9815 int userId = UserHandle.getUserId(uid); 9816 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9817 while (true) { 9818 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9819 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9820 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9821 } 9822 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9823 mNextIsolatedProcessUid++; 9824 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9825 // No process for this uid, use it. 9826 break; 9827 } 9828 stepsLeft--; 9829 if (stepsLeft <= 0) { 9830 return null; 9831 } 9832 } 9833 } else { 9834 // Special case for startIsolatedProcess (internal only), where 9835 // the uid of the isolated process is specified by the caller. 9836 uid = isolatedUid; 9837 } 9838 } 9839 return new ProcessRecord(stats, info, proc, uid); 9840 } 9841 9842 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9843 String abiOverride) { 9844 ProcessRecord app; 9845 if (!isolated) { 9846 app = getProcessRecordLocked(info.processName, info.uid, true); 9847 } else { 9848 app = null; 9849 } 9850 9851 if (app == null) { 9852 app = newProcessRecordLocked(info, null, isolated, 0); 9853 mProcessNames.put(info.processName, app.uid, app); 9854 if (isolated) { 9855 mIsolatedProcesses.put(app.uid, app); 9856 } 9857 updateLruProcessLocked(app, false, null); 9858 updateOomAdjLocked(); 9859 } 9860 9861 // This package really, really can not be stopped. 9862 try { 9863 AppGlobals.getPackageManager().setPackageStoppedState( 9864 info.packageName, false, UserHandle.getUserId(app.uid)); 9865 } catch (RemoteException e) { 9866 } catch (IllegalArgumentException e) { 9867 Slog.w(TAG, "Failed trying to unstop package " 9868 + info.packageName + ": " + e); 9869 } 9870 9871 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9872 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9873 app.persistent = true; 9874 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9875 } 9876 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9877 mPersistentStartingProcesses.add(app); 9878 startProcessLocked(app, "added application", app.processName, abiOverride, 9879 null /* entryPoint */, null /* entryPointArgs */); 9880 } 9881 9882 return app; 9883 } 9884 9885 public void unhandledBack() { 9886 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9887 "unhandledBack()"); 9888 9889 synchronized(this) { 9890 final long origId = Binder.clearCallingIdentity(); 9891 try { 9892 getFocusedStack().unhandledBackLocked(); 9893 } finally { 9894 Binder.restoreCallingIdentity(origId); 9895 } 9896 } 9897 } 9898 9899 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9900 enforceNotIsolatedCaller("openContentUri"); 9901 final int userId = UserHandle.getCallingUserId(); 9902 String name = uri.getAuthority(); 9903 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9904 ParcelFileDescriptor pfd = null; 9905 if (cph != null) { 9906 // We record the binder invoker's uid in thread-local storage before 9907 // going to the content provider to open the file. Later, in the code 9908 // that handles all permissions checks, we look for this uid and use 9909 // that rather than the Activity Manager's own uid. The effect is that 9910 // we do the check against the caller's permissions even though it looks 9911 // to the content provider like the Activity Manager itself is making 9912 // the request. 9913 sCallerIdentity.set(new Identity( 9914 Binder.getCallingPid(), Binder.getCallingUid())); 9915 try { 9916 pfd = cph.provider.openFile(null, uri, "r", null); 9917 } catch (FileNotFoundException e) { 9918 // do nothing; pfd will be returned null 9919 } finally { 9920 // Ensure that whatever happens, we clean up the identity state 9921 sCallerIdentity.remove(); 9922 } 9923 9924 // We've got the fd now, so we're done with the provider. 9925 removeContentProviderExternalUnchecked(name, null, userId); 9926 } else { 9927 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9928 } 9929 return pfd; 9930 } 9931 9932 // Actually is sleeping or shutting down or whatever else in the future 9933 // is an inactive state. 9934 public boolean isSleepingOrShuttingDown() { 9935 return isSleeping() || mShuttingDown; 9936 } 9937 9938 public boolean isSleeping() { 9939 return mSleeping; 9940 } 9941 9942 void goingToSleep() { 9943 synchronized(this) { 9944 mWentToSleep = true; 9945 goToSleepIfNeededLocked(); 9946 } 9947 } 9948 9949 void finishRunningVoiceLocked() { 9950 if (mRunningVoice) { 9951 mRunningVoice = false; 9952 goToSleepIfNeededLocked(); 9953 } 9954 } 9955 9956 void goToSleepIfNeededLocked() { 9957 if (mWentToSleep && !mRunningVoice) { 9958 if (!mSleeping) { 9959 mSleeping = true; 9960 mStackSupervisor.goingToSleepLocked(); 9961 9962 // Initialize the wake times of all processes. 9963 checkExcessivePowerUsageLocked(false); 9964 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9965 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9966 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9967 } 9968 } 9969 } 9970 9971 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9972 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9973 // Never persist the home stack. 9974 return; 9975 } 9976 mTaskPersister.wakeup(task, flush); 9977 } 9978 9979 @Override 9980 public boolean shutdown(int timeout) { 9981 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9982 != PackageManager.PERMISSION_GRANTED) { 9983 throw new SecurityException("Requires permission " 9984 + android.Manifest.permission.SHUTDOWN); 9985 } 9986 9987 boolean timedout = false; 9988 9989 synchronized(this) { 9990 mShuttingDown = true; 9991 updateEventDispatchingLocked(); 9992 timedout = mStackSupervisor.shutdownLocked(timeout); 9993 } 9994 9995 mAppOpsService.shutdown(); 9996 if (mUsageStatsService != null) { 9997 mUsageStatsService.prepareShutdown(); 9998 } 9999 mBatteryStatsService.shutdown(); 10000 synchronized (this) { 10001 mProcessStats.shutdownLocked(); 10002 } 10003 notifyTaskPersisterLocked(null, true); 10004 10005 return timedout; 10006 } 10007 10008 public final void activitySlept(IBinder token) { 10009 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10010 10011 final long origId = Binder.clearCallingIdentity(); 10012 10013 synchronized (this) { 10014 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10015 if (r != null) { 10016 mStackSupervisor.activitySleptLocked(r); 10017 } 10018 } 10019 10020 Binder.restoreCallingIdentity(origId); 10021 } 10022 10023 private String lockScreenShownToString() { 10024 switch (mLockScreenShown) { 10025 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10026 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10027 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10028 default: return "Unknown=" + mLockScreenShown; 10029 } 10030 } 10031 10032 void logLockScreen(String msg) { 10033 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10034 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10035 mWentToSleep + " mSleeping=" + mSleeping); 10036 } 10037 10038 void comeOutOfSleepIfNeededLocked() { 10039 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10040 if (mSleeping) { 10041 mSleeping = false; 10042 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10043 } 10044 } 10045 } 10046 10047 void wakingUp() { 10048 synchronized(this) { 10049 mWentToSleep = false; 10050 comeOutOfSleepIfNeededLocked(); 10051 } 10052 } 10053 10054 void startRunningVoiceLocked() { 10055 if (!mRunningVoice) { 10056 mRunningVoice = true; 10057 comeOutOfSleepIfNeededLocked(); 10058 } 10059 } 10060 10061 private void updateEventDispatchingLocked() { 10062 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10063 } 10064 10065 public void setLockScreenShown(boolean shown) { 10066 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10067 != PackageManager.PERMISSION_GRANTED) { 10068 throw new SecurityException("Requires permission " 10069 + android.Manifest.permission.DEVICE_POWER); 10070 } 10071 10072 synchronized(this) { 10073 long ident = Binder.clearCallingIdentity(); 10074 try { 10075 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10076 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10077 comeOutOfSleepIfNeededLocked(); 10078 } finally { 10079 Binder.restoreCallingIdentity(ident); 10080 } 10081 } 10082 } 10083 10084 @Override 10085 public void stopAppSwitches() { 10086 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10087 != PackageManager.PERMISSION_GRANTED) { 10088 throw new SecurityException("Requires permission " 10089 + android.Manifest.permission.STOP_APP_SWITCHES); 10090 } 10091 10092 synchronized(this) { 10093 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10094 + APP_SWITCH_DELAY_TIME; 10095 mDidAppSwitch = false; 10096 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10097 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10098 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10099 } 10100 } 10101 10102 public void resumeAppSwitches() { 10103 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10104 != PackageManager.PERMISSION_GRANTED) { 10105 throw new SecurityException("Requires permission " 10106 + android.Manifest.permission.STOP_APP_SWITCHES); 10107 } 10108 10109 synchronized(this) { 10110 // Note that we don't execute any pending app switches... we will 10111 // let those wait until either the timeout, or the next start 10112 // activity request. 10113 mAppSwitchesAllowedTime = 0; 10114 } 10115 } 10116 10117 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10118 int callingPid, int callingUid, String name) { 10119 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10120 return true; 10121 } 10122 10123 int perm = checkComponentPermission( 10124 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10125 sourceUid, -1, true); 10126 if (perm == PackageManager.PERMISSION_GRANTED) { 10127 return true; 10128 } 10129 10130 // If the actual IPC caller is different from the logical source, then 10131 // also see if they are allowed to control app switches. 10132 if (callingUid != -1 && callingUid != sourceUid) { 10133 perm = checkComponentPermission( 10134 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10135 callingUid, -1, true); 10136 if (perm == PackageManager.PERMISSION_GRANTED) { 10137 return true; 10138 } 10139 } 10140 10141 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10142 return false; 10143 } 10144 10145 public void setDebugApp(String packageName, boolean waitForDebugger, 10146 boolean persistent) { 10147 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10148 "setDebugApp()"); 10149 10150 long ident = Binder.clearCallingIdentity(); 10151 try { 10152 // Note that this is not really thread safe if there are multiple 10153 // callers into it at the same time, but that's not a situation we 10154 // care about. 10155 if (persistent) { 10156 final ContentResolver resolver = mContext.getContentResolver(); 10157 Settings.Global.putString( 10158 resolver, Settings.Global.DEBUG_APP, 10159 packageName); 10160 Settings.Global.putInt( 10161 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10162 waitForDebugger ? 1 : 0); 10163 } 10164 10165 synchronized (this) { 10166 if (!persistent) { 10167 mOrigDebugApp = mDebugApp; 10168 mOrigWaitForDebugger = mWaitForDebugger; 10169 } 10170 mDebugApp = packageName; 10171 mWaitForDebugger = waitForDebugger; 10172 mDebugTransient = !persistent; 10173 if (packageName != null) { 10174 forceStopPackageLocked(packageName, -1, false, false, true, true, 10175 false, UserHandle.USER_ALL, "set debug app"); 10176 } 10177 } 10178 } finally { 10179 Binder.restoreCallingIdentity(ident); 10180 } 10181 } 10182 10183 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10184 synchronized (this) { 10185 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10186 if (!isDebuggable) { 10187 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10188 throw new SecurityException("Process not debuggable: " + app.packageName); 10189 } 10190 } 10191 10192 mOpenGlTraceApp = processName; 10193 } 10194 } 10195 10196 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10197 synchronized (this) { 10198 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10199 if (!isDebuggable) { 10200 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10201 throw new SecurityException("Process not debuggable: " + app.packageName); 10202 } 10203 } 10204 mProfileApp = processName; 10205 mProfileFile = profilerInfo.profileFile; 10206 if (mProfileFd != null) { 10207 try { 10208 mProfileFd.close(); 10209 } catch (IOException e) { 10210 } 10211 mProfileFd = null; 10212 } 10213 mProfileFd = profilerInfo.profileFd; 10214 mSamplingInterval = profilerInfo.samplingInterval; 10215 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10216 mProfileType = 0; 10217 } 10218 } 10219 10220 @Override 10221 public void setAlwaysFinish(boolean enabled) { 10222 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10223 "setAlwaysFinish()"); 10224 10225 Settings.Global.putInt( 10226 mContext.getContentResolver(), 10227 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10228 10229 synchronized (this) { 10230 mAlwaysFinishActivities = enabled; 10231 } 10232 } 10233 10234 @Override 10235 public void setActivityController(IActivityController controller) { 10236 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10237 "setActivityController()"); 10238 synchronized (this) { 10239 mController = controller; 10240 Watchdog.getInstance().setActivityController(controller); 10241 } 10242 } 10243 10244 @Override 10245 public void setUserIsMonkey(boolean userIsMonkey) { 10246 synchronized (this) { 10247 synchronized (mPidsSelfLocked) { 10248 final int callingPid = Binder.getCallingPid(); 10249 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10250 if (precessRecord == null) { 10251 throw new SecurityException("Unknown process: " + callingPid); 10252 } 10253 if (precessRecord.instrumentationUiAutomationConnection == null) { 10254 throw new SecurityException("Only an instrumentation process " 10255 + "with a UiAutomation can call setUserIsMonkey"); 10256 } 10257 } 10258 mUserIsMonkey = userIsMonkey; 10259 } 10260 } 10261 10262 @Override 10263 public boolean isUserAMonkey() { 10264 synchronized (this) { 10265 // If there is a controller also implies the user is a monkey. 10266 return (mUserIsMonkey || mController != null); 10267 } 10268 } 10269 10270 public void requestBugReport() { 10271 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10272 SystemProperties.set("ctl.start", "bugreport"); 10273 } 10274 10275 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10276 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10277 } 10278 10279 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10280 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10281 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10282 } 10283 return KEY_DISPATCHING_TIMEOUT; 10284 } 10285 10286 @Override 10287 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10288 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10289 != PackageManager.PERMISSION_GRANTED) { 10290 throw new SecurityException("Requires permission " 10291 + android.Manifest.permission.FILTER_EVENTS); 10292 } 10293 ProcessRecord proc; 10294 long timeout; 10295 synchronized (this) { 10296 synchronized (mPidsSelfLocked) { 10297 proc = mPidsSelfLocked.get(pid); 10298 } 10299 timeout = getInputDispatchingTimeoutLocked(proc); 10300 } 10301 10302 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10303 return -1; 10304 } 10305 10306 return timeout; 10307 } 10308 10309 /** 10310 * Handle input dispatching timeouts. 10311 * Returns whether input dispatching should be aborted or not. 10312 */ 10313 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10314 final ActivityRecord activity, final ActivityRecord parent, 10315 final boolean aboveSystem, String reason) { 10316 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10317 != PackageManager.PERMISSION_GRANTED) { 10318 throw new SecurityException("Requires permission " 10319 + android.Manifest.permission.FILTER_EVENTS); 10320 } 10321 10322 final String annotation; 10323 if (reason == null) { 10324 annotation = "Input dispatching timed out"; 10325 } else { 10326 annotation = "Input dispatching timed out (" + reason + ")"; 10327 } 10328 10329 if (proc != null) { 10330 synchronized (this) { 10331 if (proc.debugging) { 10332 return false; 10333 } 10334 10335 if (mDidDexOpt) { 10336 // Give more time since we were dexopting. 10337 mDidDexOpt = false; 10338 return false; 10339 } 10340 10341 if (proc.instrumentationClass != null) { 10342 Bundle info = new Bundle(); 10343 info.putString("shortMsg", "keyDispatchingTimedOut"); 10344 info.putString("longMsg", annotation); 10345 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10346 return true; 10347 } 10348 } 10349 mHandler.post(new Runnable() { 10350 @Override 10351 public void run() { 10352 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10353 } 10354 }); 10355 } 10356 10357 return true; 10358 } 10359 10360 public Bundle getAssistContextExtras(int requestType) { 10361 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10362 UserHandle.getCallingUserId()); 10363 if (pae == null) { 10364 return null; 10365 } 10366 synchronized (pae) { 10367 while (!pae.haveResult) { 10368 try { 10369 pae.wait(); 10370 } catch (InterruptedException e) { 10371 } 10372 } 10373 if (pae.result != null) { 10374 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10375 } 10376 } 10377 synchronized (this) { 10378 mPendingAssistExtras.remove(pae); 10379 mHandler.removeCallbacks(pae); 10380 } 10381 return pae.extras; 10382 } 10383 10384 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10385 int userHandle) { 10386 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10387 "getAssistContextExtras()"); 10388 PendingAssistExtras pae; 10389 Bundle extras = new Bundle(); 10390 synchronized (this) { 10391 ActivityRecord activity = getFocusedStack().mResumedActivity; 10392 if (activity == null) { 10393 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10394 return null; 10395 } 10396 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10397 if (activity.app == null || activity.app.thread == null) { 10398 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10399 return null; 10400 } 10401 if (activity.app.pid == Binder.getCallingPid()) { 10402 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10403 return null; 10404 } 10405 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10406 try { 10407 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10408 requestType); 10409 mPendingAssistExtras.add(pae); 10410 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10411 } catch (RemoteException e) { 10412 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10413 return null; 10414 } 10415 return pae; 10416 } 10417 } 10418 10419 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10420 PendingAssistExtras pae = (PendingAssistExtras)token; 10421 synchronized (pae) { 10422 pae.result = extras; 10423 pae.haveResult = true; 10424 pae.notifyAll(); 10425 if (pae.intent == null) { 10426 // Caller is just waiting for the result. 10427 return; 10428 } 10429 } 10430 10431 // We are now ready to launch the assist activity. 10432 synchronized (this) { 10433 boolean exists = mPendingAssistExtras.remove(pae); 10434 mHandler.removeCallbacks(pae); 10435 if (!exists) { 10436 // Timed out. 10437 return; 10438 } 10439 } 10440 pae.intent.replaceExtras(extras); 10441 if (pae.hint != null) { 10442 pae.intent.putExtra(pae.hint, true); 10443 } 10444 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10445 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10446 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10447 closeSystemDialogs("assist"); 10448 try { 10449 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10450 } catch (ActivityNotFoundException e) { 10451 Slog.w(TAG, "No activity to handle assist action.", e); 10452 } 10453 } 10454 10455 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10456 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10457 } 10458 10459 public void registerProcessObserver(IProcessObserver observer) { 10460 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10461 "registerProcessObserver()"); 10462 synchronized (this) { 10463 mProcessObservers.register(observer); 10464 } 10465 } 10466 10467 @Override 10468 public void unregisterProcessObserver(IProcessObserver observer) { 10469 synchronized (this) { 10470 mProcessObservers.unregister(observer); 10471 } 10472 } 10473 10474 @Override 10475 public boolean convertFromTranslucent(IBinder token) { 10476 final long origId = Binder.clearCallingIdentity(); 10477 try { 10478 synchronized (this) { 10479 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10480 if (r == null) { 10481 return false; 10482 } 10483 final boolean translucentChanged = r.changeWindowTranslucency(true); 10484 if (translucentChanged) { 10485 r.task.stack.releaseBackgroundResources(); 10486 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10487 } 10488 mWindowManager.setAppFullscreen(token, true); 10489 return translucentChanged; 10490 } 10491 } finally { 10492 Binder.restoreCallingIdentity(origId); 10493 } 10494 } 10495 10496 @Override 10497 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10498 final long origId = Binder.clearCallingIdentity(); 10499 try { 10500 synchronized (this) { 10501 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10502 if (r == null) { 10503 return false; 10504 } 10505 int index = r.task.mActivities.lastIndexOf(r); 10506 if (index > 0) { 10507 ActivityRecord under = r.task.mActivities.get(index - 1); 10508 under.returningOptions = options; 10509 } 10510 final boolean translucentChanged = r.changeWindowTranslucency(false); 10511 if (translucentChanged) { 10512 r.task.stack.convertToTranslucent(r); 10513 } 10514 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10515 mWindowManager.setAppFullscreen(token, false); 10516 return translucentChanged; 10517 } 10518 } finally { 10519 Binder.restoreCallingIdentity(origId); 10520 } 10521 } 10522 10523 @Override 10524 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10525 final long origId = Binder.clearCallingIdentity(); 10526 try { 10527 synchronized (this) { 10528 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10529 if (r != null) { 10530 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10531 } 10532 } 10533 return false; 10534 } finally { 10535 Binder.restoreCallingIdentity(origId); 10536 } 10537 } 10538 10539 @Override 10540 public boolean isBackgroundVisibleBehind(IBinder token) { 10541 final long origId = Binder.clearCallingIdentity(); 10542 try { 10543 synchronized (this) { 10544 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10545 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10546 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10547 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10548 return visible; 10549 } 10550 } finally { 10551 Binder.restoreCallingIdentity(origId); 10552 } 10553 } 10554 10555 @Override 10556 public ActivityOptions getActivityOptions(IBinder token) { 10557 final long origId = Binder.clearCallingIdentity(); 10558 try { 10559 synchronized (this) { 10560 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10561 if (r != null) { 10562 final ActivityOptions activityOptions = r.pendingOptions; 10563 r.pendingOptions = null; 10564 return activityOptions; 10565 } 10566 return null; 10567 } 10568 } finally { 10569 Binder.restoreCallingIdentity(origId); 10570 } 10571 } 10572 10573 @Override 10574 public void setImmersive(IBinder token, boolean immersive) { 10575 synchronized(this) { 10576 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10577 if (r == null) { 10578 throw new IllegalArgumentException(); 10579 } 10580 r.immersive = immersive; 10581 10582 // update associated state if we're frontmost 10583 if (r == mFocusedActivity) { 10584 if (DEBUG_IMMERSIVE) { 10585 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10586 } 10587 applyUpdateLockStateLocked(r); 10588 } 10589 } 10590 } 10591 10592 @Override 10593 public boolean isImmersive(IBinder token) { 10594 synchronized (this) { 10595 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10596 if (r == null) { 10597 throw new IllegalArgumentException(); 10598 } 10599 return r.immersive; 10600 } 10601 } 10602 10603 public boolean isTopActivityImmersive() { 10604 enforceNotIsolatedCaller("startActivity"); 10605 synchronized (this) { 10606 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10607 return (r != null) ? r.immersive : false; 10608 } 10609 } 10610 10611 @Override 10612 public boolean isTopOfTask(IBinder token) { 10613 synchronized (this) { 10614 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10615 if (r == null) { 10616 throw new IllegalArgumentException(); 10617 } 10618 return r.task.getTopActivity() == r; 10619 } 10620 } 10621 10622 public final void enterSafeMode() { 10623 synchronized(this) { 10624 // It only makes sense to do this before the system is ready 10625 // and started launching other packages. 10626 if (!mSystemReady) { 10627 try { 10628 AppGlobals.getPackageManager().enterSafeMode(); 10629 } catch (RemoteException e) { 10630 } 10631 } 10632 10633 mSafeMode = true; 10634 } 10635 } 10636 10637 public final void showSafeModeOverlay() { 10638 View v = LayoutInflater.from(mContext).inflate( 10639 com.android.internal.R.layout.safe_mode, null); 10640 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10641 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10642 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10643 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10644 lp.gravity = Gravity.BOTTOM | Gravity.START; 10645 lp.format = v.getBackground().getOpacity(); 10646 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10647 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10648 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10649 ((WindowManager)mContext.getSystemService( 10650 Context.WINDOW_SERVICE)).addView(v, lp); 10651 } 10652 10653 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10654 if (!(sender instanceof PendingIntentRecord)) { 10655 return; 10656 } 10657 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10658 synchronized (stats) { 10659 if (mBatteryStatsService.isOnBattery()) { 10660 mBatteryStatsService.enforceCallingPermission(); 10661 PendingIntentRecord rec = (PendingIntentRecord)sender; 10662 int MY_UID = Binder.getCallingUid(); 10663 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10664 BatteryStatsImpl.Uid.Pkg pkg = 10665 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10666 sourcePkg != null ? sourcePkg : rec.key.packageName); 10667 pkg.incWakeupsLocked(); 10668 } 10669 } 10670 } 10671 10672 public boolean killPids(int[] pids, String pReason, boolean secure) { 10673 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10674 throw new SecurityException("killPids only available to the system"); 10675 } 10676 String reason = (pReason == null) ? "Unknown" : pReason; 10677 // XXX Note: don't acquire main activity lock here, because the window 10678 // manager calls in with its locks held. 10679 10680 boolean killed = false; 10681 synchronized (mPidsSelfLocked) { 10682 int[] types = new int[pids.length]; 10683 int worstType = 0; 10684 for (int i=0; i<pids.length; i++) { 10685 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10686 if (proc != null) { 10687 int type = proc.setAdj; 10688 types[i] = type; 10689 if (type > worstType) { 10690 worstType = type; 10691 } 10692 } 10693 } 10694 10695 // If the worst oom_adj is somewhere in the cached proc LRU range, 10696 // then constrain it so we will kill all cached procs. 10697 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10698 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10699 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10700 } 10701 10702 // If this is not a secure call, don't let it kill processes that 10703 // are important. 10704 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10705 worstType = ProcessList.SERVICE_ADJ; 10706 } 10707 10708 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10709 for (int i=0; i<pids.length; i++) { 10710 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10711 if (proc == null) { 10712 continue; 10713 } 10714 int adj = proc.setAdj; 10715 if (adj >= worstType && !proc.killedByAm) { 10716 proc.kill(reason, true); 10717 killed = true; 10718 } 10719 } 10720 } 10721 return killed; 10722 } 10723 10724 @Override 10725 public void killUid(int uid, String reason) { 10726 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10727 throw new SecurityException("killUid only available to the system"); 10728 } 10729 synchronized (this) { 10730 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10731 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10732 reason != null ? reason : "kill uid"); 10733 } 10734 } 10735 10736 @Override 10737 public boolean killProcessesBelowForeground(String reason) { 10738 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10739 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10740 } 10741 10742 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10743 } 10744 10745 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10746 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10747 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10748 } 10749 10750 boolean killed = false; 10751 synchronized (mPidsSelfLocked) { 10752 final int size = mPidsSelfLocked.size(); 10753 for (int i = 0; i < size; i++) { 10754 final int pid = mPidsSelfLocked.keyAt(i); 10755 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10756 if (proc == null) continue; 10757 10758 final int adj = proc.setAdj; 10759 if (adj > belowAdj && !proc.killedByAm) { 10760 proc.kill(reason, true); 10761 killed = true; 10762 } 10763 } 10764 } 10765 return killed; 10766 } 10767 10768 @Override 10769 public void hang(final IBinder who, boolean allowRestart) { 10770 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10771 != PackageManager.PERMISSION_GRANTED) { 10772 throw new SecurityException("Requires permission " 10773 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10774 } 10775 10776 final IBinder.DeathRecipient death = new DeathRecipient() { 10777 @Override 10778 public void binderDied() { 10779 synchronized (this) { 10780 notifyAll(); 10781 } 10782 } 10783 }; 10784 10785 try { 10786 who.linkToDeath(death, 0); 10787 } catch (RemoteException e) { 10788 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10789 return; 10790 } 10791 10792 synchronized (this) { 10793 Watchdog.getInstance().setAllowRestart(allowRestart); 10794 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10795 synchronized (death) { 10796 while (who.isBinderAlive()) { 10797 try { 10798 death.wait(); 10799 } catch (InterruptedException e) { 10800 } 10801 } 10802 } 10803 Watchdog.getInstance().setAllowRestart(true); 10804 } 10805 } 10806 10807 @Override 10808 public void restart() { 10809 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10810 != PackageManager.PERMISSION_GRANTED) { 10811 throw new SecurityException("Requires permission " 10812 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10813 } 10814 10815 Log.i(TAG, "Sending shutdown broadcast..."); 10816 10817 BroadcastReceiver br = new BroadcastReceiver() { 10818 @Override public void onReceive(Context context, Intent intent) { 10819 // Now the broadcast is done, finish up the low-level shutdown. 10820 Log.i(TAG, "Shutting down activity manager..."); 10821 shutdown(10000); 10822 Log.i(TAG, "Shutdown complete, restarting!"); 10823 Process.killProcess(Process.myPid()); 10824 System.exit(10); 10825 } 10826 }; 10827 10828 // First send the high-level shut down broadcast. 10829 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10830 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10831 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10832 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10833 mContext.sendOrderedBroadcastAsUser(intent, 10834 UserHandle.ALL, null, br, mHandler, 0, null, null); 10835 */ 10836 br.onReceive(mContext, intent); 10837 } 10838 10839 private long getLowRamTimeSinceIdle(long now) { 10840 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10841 } 10842 10843 @Override 10844 public void performIdleMaintenance() { 10845 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10846 != PackageManager.PERMISSION_GRANTED) { 10847 throw new SecurityException("Requires permission " 10848 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10849 } 10850 10851 synchronized (this) { 10852 final long now = SystemClock.uptimeMillis(); 10853 final long timeSinceLastIdle = now - mLastIdleTime; 10854 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10855 mLastIdleTime = now; 10856 mLowRamTimeSinceLastIdle = 0; 10857 if (mLowRamStartTime != 0) { 10858 mLowRamStartTime = now; 10859 } 10860 10861 StringBuilder sb = new StringBuilder(128); 10862 sb.append("Idle maintenance over "); 10863 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10864 sb.append(" low RAM for "); 10865 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10866 Slog.i(TAG, sb.toString()); 10867 10868 // If at least 1/3 of our time since the last idle period has been spent 10869 // with RAM low, then we want to kill processes. 10870 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10871 10872 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10873 ProcessRecord proc = mLruProcesses.get(i); 10874 if (proc.notCachedSinceIdle) { 10875 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10876 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10877 if (doKilling && proc.initialIdlePss != 0 10878 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10879 proc.kill("idle maint (pss " + proc.lastPss 10880 + " from " + proc.initialIdlePss + ")", true); 10881 } 10882 } 10883 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10884 proc.notCachedSinceIdle = true; 10885 proc.initialIdlePss = 0; 10886 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10887 isSleeping(), now); 10888 } 10889 } 10890 10891 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10892 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10893 } 10894 } 10895 10896 private void retrieveSettings() { 10897 final ContentResolver resolver = mContext.getContentResolver(); 10898 String debugApp = Settings.Global.getString( 10899 resolver, Settings.Global.DEBUG_APP); 10900 boolean waitForDebugger = Settings.Global.getInt( 10901 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10902 boolean alwaysFinishActivities = Settings.Global.getInt( 10903 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10904 boolean forceRtl = Settings.Global.getInt( 10905 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10906 // Transfer any global setting for forcing RTL layout, into a System Property 10907 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10908 10909 Configuration configuration = new Configuration(); 10910 Settings.System.getConfiguration(resolver, configuration); 10911 if (forceRtl) { 10912 // This will take care of setting the correct layout direction flags 10913 configuration.setLayoutDirection(configuration.locale); 10914 } 10915 10916 synchronized (this) { 10917 mDebugApp = mOrigDebugApp = debugApp; 10918 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10919 mAlwaysFinishActivities = alwaysFinishActivities; 10920 // This happens before any activities are started, so we can 10921 // change mConfiguration in-place. 10922 updateConfigurationLocked(configuration, null, false, true); 10923 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10924 } 10925 } 10926 10927 /** Loads resources after the current configuration has been set. */ 10928 private void loadResourcesOnSystemReady() { 10929 final Resources res = mContext.getResources(); 10930 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10931 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10932 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10933 } 10934 10935 public boolean testIsSystemReady() { 10936 // no need to synchronize(this) just to read & return the value 10937 return mSystemReady; 10938 } 10939 10940 private static File getCalledPreBootReceiversFile() { 10941 File dataDir = Environment.getDataDirectory(); 10942 File systemDir = new File(dataDir, "system"); 10943 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10944 return fname; 10945 } 10946 10947 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10948 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10949 File file = getCalledPreBootReceiversFile(); 10950 FileInputStream fis = null; 10951 try { 10952 fis = new FileInputStream(file); 10953 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10954 int fvers = dis.readInt(); 10955 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10956 String vers = dis.readUTF(); 10957 String codename = dis.readUTF(); 10958 String build = dis.readUTF(); 10959 if (android.os.Build.VERSION.RELEASE.equals(vers) 10960 && android.os.Build.VERSION.CODENAME.equals(codename) 10961 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10962 int num = dis.readInt(); 10963 while (num > 0) { 10964 num--; 10965 String pkg = dis.readUTF(); 10966 String cls = dis.readUTF(); 10967 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10968 } 10969 } 10970 } 10971 } catch (FileNotFoundException e) { 10972 } catch (IOException e) { 10973 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10974 } finally { 10975 if (fis != null) { 10976 try { 10977 fis.close(); 10978 } catch (IOException e) { 10979 } 10980 } 10981 } 10982 return lastDoneReceivers; 10983 } 10984 10985 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10986 File file = getCalledPreBootReceiversFile(); 10987 FileOutputStream fos = null; 10988 DataOutputStream dos = null; 10989 try { 10990 fos = new FileOutputStream(file); 10991 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10992 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10993 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10994 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10995 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10996 dos.writeInt(list.size()); 10997 for (int i=0; i<list.size(); i++) { 10998 dos.writeUTF(list.get(i).getPackageName()); 10999 dos.writeUTF(list.get(i).getClassName()); 11000 } 11001 } catch (IOException e) { 11002 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11003 file.delete(); 11004 } finally { 11005 FileUtils.sync(fos); 11006 if (dos != null) { 11007 try { 11008 dos.close(); 11009 } catch (IOException e) { 11010 // TODO Auto-generated catch block 11011 e.printStackTrace(); 11012 } 11013 } 11014 } 11015 } 11016 11017 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11018 ArrayList<ComponentName> doneReceivers, int userId) { 11019 boolean waitingUpdate = false; 11020 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11021 List<ResolveInfo> ris = null; 11022 try { 11023 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11024 intent, null, 0, userId); 11025 } catch (RemoteException e) { 11026 } 11027 if (ris != null) { 11028 for (int i=ris.size()-1; i>=0; i--) { 11029 if ((ris.get(i).activityInfo.applicationInfo.flags 11030 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11031 ris.remove(i); 11032 } 11033 } 11034 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11035 11036 // For User 0, load the version number. When delivering to a new user, deliver 11037 // to all receivers. 11038 if (userId == UserHandle.USER_OWNER) { 11039 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11040 for (int i=0; i<ris.size(); i++) { 11041 ActivityInfo ai = ris.get(i).activityInfo; 11042 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11043 if (lastDoneReceivers.contains(comp)) { 11044 // We already did the pre boot receiver for this app with the current 11045 // platform version, so don't do it again... 11046 ris.remove(i); 11047 i--; 11048 // ...however, do keep it as one that has been done, so we don't 11049 // forget about it when rewriting the file of last done receivers. 11050 doneReceivers.add(comp); 11051 } 11052 } 11053 } 11054 11055 // If primary user, send broadcast to all available users, else just to userId 11056 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11057 : new int[] { userId }; 11058 for (int i = 0; i < ris.size(); i++) { 11059 ActivityInfo ai = ris.get(i).activityInfo; 11060 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11061 doneReceivers.add(comp); 11062 intent.setComponent(comp); 11063 for (int j=0; j<users.length; j++) { 11064 IIntentReceiver finisher = null; 11065 // On last receiver and user, set up a completion callback 11066 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11067 finisher = new IIntentReceiver.Stub() { 11068 public void performReceive(Intent intent, int resultCode, 11069 String data, Bundle extras, boolean ordered, 11070 boolean sticky, int sendingUser) { 11071 // The raw IIntentReceiver interface is called 11072 // with the AM lock held, so redispatch to 11073 // execute our code without the lock. 11074 mHandler.post(onFinishCallback); 11075 } 11076 }; 11077 } 11078 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11079 + " for user " + users[j]); 11080 broadcastIntentLocked(null, null, intent, null, finisher, 11081 0, null, null, null, AppOpsManager.OP_NONE, 11082 true, false, MY_PID, Process.SYSTEM_UID, 11083 users[j]); 11084 if (finisher != null) { 11085 waitingUpdate = true; 11086 } 11087 } 11088 } 11089 } 11090 11091 return waitingUpdate; 11092 } 11093 11094 public void systemReady(final Runnable goingCallback) { 11095 synchronized(this) { 11096 if (mSystemReady) { 11097 // If we're done calling all the receivers, run the next "boot phase" passed in 11098 // by the SystemServer 11099 if (goingCallback != null) { 11100 goingCallback.run(); 11101 } 11102 return; 11103 } 11104 11105 // Make sure we have the current profile info, since it is needed for 11106 // security checks. 11107 updateCurrentProfileIdsLocked(); 11108 11109 if (mRecentTasks == null) { 11110 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11111 if (!mRecentTasks.isEmpty()) { 11112 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11113 } 11114 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11115 mTaskPersister.startPersisting(); 11116 } 11117 11118 // Check to see if there are any update receivers to run. 11119 if (!mDidUpdate) { 11120 if (mWaitingUpdate) { 11121 return; 11122 } 11123 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11124 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11125 public void run() { 11126 synchronized (ActivityManagerService.this) { 11127 mDidUpdate = true; 11128 } 11129 writeLastDonePreBootReceivers(doneReceivers); 11130 showBootMessage(mContext.getText( 11131 R.string.android_upgrading_complete), 11132 false); 11133 systemReady(goingCallback); 11134 } 11135 }, doneReceivers, UserHandle.USER_OWNER); 11136 11137 if (mWaitingUpdate) { 11138 return; 11139 } 11140 mDidUpdate = true; 11141 } 11142 11143 mAppOpsService.systemReady(); 11144 mSystemReady = true; 11145 } 11146 11147 ArrayList<ProcessRecord> procsToKill = null; 11148 synchronized(mPidsSelfLocked) { 11149 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11150 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11151 if (!isAllowedWhileBooting(proc.info)){ 11152 if (procsToKill == null) { 11153 procsToKill = new ArrayList<ProcessRecord>(); 11154 } 11155 procsToKill.add(proc); 11156 } 11157 } 11158 } 11159 11160 synchronized(this) { 11161 if (procsToKill != null) { 11162 for (int i=procsToKill.size()-1; i>=0; i--) { 11163 ProcessRecord proc = procsToKill.get(i); 11164 Slog.i(TAG, "Removing system update proc: " + proc); 11165 removeProcessLocked(proc, true, false, "system update done"); 11166 } 11167 } 11168 11169 // Now that we have cleaned up any update processes, we 11170 // are ready to start launching real processes and know that 11171 // we won't trample on them any more. 11172 mProcessesReady = true; 11173 } 11174 11175 Slog.i(TAG, "System now ready"); 11176 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11177 SystemClock.uptimeMillis()); 11178 11179 synchronized(this) { 11180 // Make sure we have no pre-ready processes sitting around. 11181 11182 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11183 ResolveInfo ri = mContext.getPackageManager() 11184 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11185 STOCK_PM_FLAGS); 11186 CharSequence errorMsg = null; 11187 if (ri != null) { 11188 ActivityInfo ai = ri.activityInfo; 11189 ApplicationInfo app = ai.applicationInfo; 11190 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11191 mTopAction = Intent.ACTION_FACTORY_TEST; 11192 mTopData = null; 11193 mTopComponent = new ComponentName(app.packageName, 11194 ai.name); 11195 } else { 11196 errorMsg = mContext.getResources().getText( 11197 com.android.internal.R.string.factorytest_not_system); 11198 } 11199 } else { 11200 errorMsg = mContext.getResources().getText( 11201 com.android.internal.R.string.factorytest_no_action); 11202 } 11203 if (errorMsg != null) { 11204 mTopAction = null; 11205 mTopData = null; 11206 mTopComponent = null; 11207 Message msg = Message.obtain(); 11208 msg.what = SHOW_FACTORY_ERROR_MSG; 11209 msg.getData().putCharSequence("msg", errorMsg); 11210 mHandler.sendMessage(msg); 11211 } 11212 } 11213 } 11214 11215 retrieveSettings(); 11216 loadResourcesOnSystemReady(); 11217 11218 synchronized (this) { 11219 readGrantedUriPermissionsLocked(); 11220 } 11221 11222 if (goingCallback != null) goingCallback.run(); 11223 11224 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11225 Integer.toString(mCurrentUserId), mCurrentUserId); 11226 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11227 Integer.toString(mCurrentUserId), mCurrentUserId); 11228 mSystemServiceManager.startUser(mCurrentUserId); 11229 11230 synchronized (this) { 11231 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11232 try { 11233 List apps = AppGlobals.getPackageManager(). 11234 getPersistentApplications(STOCK_PM_FLAGS); 11235 if (apps != null) { 11236 int N = apps.size(); 11237 int i; 11238 for (i=0; i<N; i++) { 11239 ApplicationInfo info 11240 = (ApplicationInfo)apps.get(i); 11241 if (info != null && 11242 !info.packageName.equals("android")) { 11243 addAppLocked(info, false, null /* ABI override */); 11244 } 11245 } 11246 } 11247 } catch (RemoteException ex) { 11248 // pm is in same process, this will never happen. 11249 } 11250 } 11251 11252 // Start up initial activity. 11253 mBooting = true; 11254 startHomeActivityLocked(mCurrentUserId); 11255 11256 try { 11257 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11258 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11259 + " data partition or your device will be unstable."); 11260 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11261 } 11262 } catch (RemoteException e) { 11263 } 11264 11265 if (!Build.isFingerprintConsistent()) { 11266 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11267 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11268 } 11269 11270 long ident = Binder.clearCallingIdentity(); 11271 try { 11272 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11274 | Intent.FLAG_RECEIVER_FOREGROUND); 11275 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11276 broadcastIntentLocked(null, null, intent, 11277 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11278 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11279 intent = new Intent(Intent.ACTION_USER_STARTING); 11280 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11281 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11282 broadcastIntentLocked(null, null, intent, 11283 null, new IIntentReceiver.Stub() { 11284 @Override 11285 public void performReceive(Intent intent, int resultCode, String data, 11286 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11287 throws RemoteException { 11288 } 11289 }, 0, null, null, 11290 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11291 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11292 } catch (Throwable t) { 11293 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11294 } finally { 11295 Binder.restoreCallingIdentity(ident); 11296 } 11297 mStackSupervisor.resumeTopActivitiesLocked(); 11298 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11299 } 11300 } 11301 11302 private boolean makeAppCrashingLocked(ProcessRecord app, 11303 String shortMsg, String longMsg, String stackTrace) { 11304 app.crashing = true; 11305 app.crashingReport = generateProcessError(app, 11306 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11307 startAppProblemLocked(app); 11308 app.stopFreezingAllLocked(); 11309 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11310 } 11311 11312 private void makeAppNotRespondingLocked(ProcessRecord app, 11313 String activity, String shortMsg, String longMsg) { 11314 app.notResponding = true; 11315 app.notRespondingReport = generateProcessError(app, 11316 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11317 activity, shortMsg, longMsg, null); 11318 startAppProblemLocked(app); 11319 app.stopFreezingAllLocked(); 11320 } 11321 11322 /** 11323 * Generate a process error record, suitable for attachment to a ProcessRecord. 11324 * 11325 * @param app The ProcessRecord in which the error occurred. 11326 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11327 * ActivityManager.AppErrorStateInfo 11328 * @param activity The activity associated with the crash, if known. 11329 * @param shortMsg Short message describing the crash. 11330 * @param longMsg Long message describing the crash. 11331 * @param stackTrace Full crash stack trace, may be null. 11332 * 11333 * @return Returns a fully-formed AppErrorStateInfo record. 11334 */ 11335 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11336 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11337 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11338 11339 report.condition = condition; 11340 report.processName = app.processName; 11341 report.pid = app.pid; 11342 report.uid = app.info.uid; 11343 report.tag = activity; 11344 report.shortMsg = shortMsg; 11345 report.longMsg = longMsg; 11346 report.stackTrace = stackTrace; 11347 11348 return report; 11349 } 11350 11351 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11352 synchronized (this) { 11353 app.crashing = false; 11354 app.crashingReport = null; 11355 app.notResponding = false; 11356 app.notRespondingReport = null; 11357 if (app.anrDialog == fromDialog) { 11358 app.anrDialog = null; 11359 } 11360 if (app.waitDialog == fromDialog) { 11361 app.waitDialog = null; 11362 } 11363 if (app.pid > 0 && app.pid != MY_PID) { 11364 handleAppCrashLocked(app, null, null, null); 11365 app.kill("user request after error", true); 11366 } 11367 } 11368 } 11369 11370 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11371 String stackTrace) { 11372 long now = SystemClock.uptimeMillis(); 11373 11374 Long crashTime; 11375 if (!app.isolated) { 11376 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11377 } else { 11378 crashTime = null; 11379 } 11380 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11381 // This process loses! 11382 Slog.w(TAG, "Process " + app.info.processName 11383 + " has crashed too many times: killing!"); 11384 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11385 app.userId, app.info.processName, app.uid); 11386 mStackSupervisor.handleAppCrashLocked(app); 11387 if (!app.persistent) { 11388 // We don't want to start this process again until the user 11389 // explicitly does so... but for persistent process, we really 11390 // need to keep it running. If a persistent process is actually 11391 // repeatedly crashing, then badness for everyone. 11392 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11393 app.info.processName); 11394 if (!app.isolated) { 11395 // XXX We don't have a way to mark isolated processes 11396 // as bad, since they don't have a peristent identity. 11397 mBadProcesses.put(app.info.processName, app.uid, 11398 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11399 mProcessCrashTimes.remove(app.info.processName, app.uid); 11400 } 11401 app.bad = true; 11402 app.removed = true; 11403 // Don't let services in this process be restarted and potentially 11404 // annoy the user repeatedly. Unless it is persistent, since those 11405 // processes run critical code. 11406 removeProcessLocked(app, false, false, "crash"); 11407 mStackSupervisor.resumeTopActivitiesLocked(); 11408 return false; 11409 } 11410 mStackSupervisor.resumeTopActivitiesLocked(); 11411 } else { 11412 mStackSupervisor.finishTopRunningActivityLocked(app); 11413 } 11414 11415 // Bump up the crash count of any services currently running in the proc. 11416 for (int i=app.services.size()-1; i>=0; i--) { 11417 // Any services running in the application need to be placed 11418 // back in the pending list. 11419 ServiceRecord sr = app.services.valueAt(i); 11420 sr.crashCount++; 11421 } 11422 11423 // If the crashing process is what we consider to be the "home process" and it has been 11424 // replaced by a third-party app, clear the package preferred activities from packages 11425 // with a home activity running in the process to prevent a repeatedly crashing app 11426 // from blocking the user to manually clear the list. 11427 final ArrayList<ActivityRecord> activities = app.activities; 11428 if (app == mHomeProcess && activities.size() > 0 11429 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11430 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11431 final ActivityRecord r = activities.get(activityNdx); 11432 if (r.isHomeActivity()) { 11433 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11434 try { 11435 ActivityThread.getPackageManager() 11436 .clearPackagePreferredActivities(r.packageName); 11437 } catch (RemoteException c) { 11438 // pm is in same process, this will never happen. 11439 } 11440 } 11441 } 11442 } 11443 11444 if (!app.isolated) { 11445 // XXX Can't keep track of crash times for isolated processes, 11446 // because they don't have a perisistent identity. 11447 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11448 } 11449 11450 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11451 return true; 11452 } 11453 11454 void startAppProblemLocked(ProcessRecord app) { 11455 // If this app is not running under the current user, then we 11456 // can't give it a report button because that would require 11457 // launching the report UI under a different user. 11458 app.errorReportReceiver = null; 11459 11460 for (int userId : mCurrentProfileIds) { 11461 if (app.userId == userId) { 11462 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11463 mContext, app.info.packageName, app.info.flags); 11464 } 11465 } 11466 skipCurrentReceiverLocked(app); 11467 } 11468 11469 void skipCurrentReceiverLocked(ProcessRecord app) { 11470 for (BroadcastQueue queue : mBroadcastQueues) { 11471 queue.skipCurrentReceiverLocked(app); 11472 } 11473 } 11474 11475 /** 11476 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11477 * The application process will exit immediately after this call returns. 11478 * @param app object of the crashing app, null for the system server 11479 * @param crashInfo describing the exception 11480 */ 11481 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11482 ProcessRecord r = findAppProcess(app, "Crash"); 11483 final String processName = app == null ? "system_server" 11484 : (r == null ? "unknown" : r.processName); 11485 11486 handleApplicationCrashInner("crash", r, processName, crashInfo); 11487 } 11488 11489 /* Native crash reporting uses this inner version because it needs to be somewhat 11490 * decoupled from the AM-managed cleanup lifecycle 11491 */ 11492 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11493 ApplicationErrorReport.CrashInfo crashInfo) { 11494 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11495 UserHandle.getUserId(Binder.getCallingUid()), processName, 11496 r == null ? -1 : r.info.flags, 11497 crashInfo.exceptionClassName, 11498 crashInfo.exceptionMessage, 11499 crashInfo.throwFileName, 11500 crashInfo.throwLineNumber); 11501 11502 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11503 11504 crashApplication(r, crashInfo); 11505 } 11506 11507 public void handleApplicationStrictModeViolation( 11508 IBinder app, 11509 int violationMask, 11510 StrictMode.ViolationInfo info) { 11511 ProcessRecord r = findAppProcess(app, "StrictMode"); 11512 if (r == null) { 11513 return; 11514 } 11515 11516 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11517 Integer stackFingerprint = info.hashCode(); 11518 boolean logIt = true; 11519 synchronized (mAlreadyLoggedViolatedStacks) { 11520 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11521 logIt = false; 11522 // TODO: sub-sample into EventLog for these, with 11523 // the info.durationMillis? Then we'd get 11524 // the relative pain numbers, without logging all 11525 // the stack traces repeatedly. We'd want to do 11526 // likewise in the client code, which also does 11527 // dup suppression, before the Binder call. 11528 } else { 11529 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11530 mAlreadyLoggedViolatedStacks.clear(); 11531 } 11532 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11533 } 11534 } 11535 if (logIt) { 11536 logStrictModeViolationToDropBox(r, info); 11537 } 11538 } 11539 11540 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11541 AppErrorResult result = new AppErrorResult(); 11542 synchronized (this) { 11543 final long origId = Binder.clearCallingIdentity(); 11544 11545 Message msg = Message.obtain(); 11546 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11547 HashMap<String, Object> data = new HashMap<String, Object>(); 11548 data.put("result", result); 11549 data.put("app", r); 11550 data.put("violationMask", violationMask); 11551 data.put("info", info); 11552 msg.obj = data; 11553 mHandler.sendMessage(msg); 11554 11555 Binder.restoreCallingIdentity(origId); 11556 } 11557 int res = result.get(); 11558 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11559 } 11560 } 11561 11562 // Depending on the policy in effect, there could be a bunch of 11563 // these in quick succession so we try to batch these together to 11564 // minimize disk writes, number of dropbox entries, and maximize 11565 // compression, by having more fewer, larger records. 11566 private void logStrictModeViolationToDropBox( 11567 ProcessRecord process, 11568 StrictMode.ViolationInfo info) { 11569 if (info == null) { 11570 return; 11571 } 11572 final boolean isSystemApp = process == null || 11573 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11574 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11575 final String processName = process == null ? "unknown" : process.processName; 11576 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11577 final DropBoxManager dbox = (DropBoxManager) 11578 mContext.getSystemService(Context.DROPBOX_SERVICE); 11579 11580 // Exit early if the dropbox isn't configured to accept this report type. 11581 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11582 11583 boolean bufferWasEmpty; 11584 boolean needsFlush; 11585 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11586 synchronized (sb) { 11587 bufferWasEmpty = sb.length() == 0; 11588 appendDropBoxProcessHeaders(process, processName, sb); 11589 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11590 sb.append("System-App: ").append(isSystemApp).append("\n"); 11591 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11592 if (info.violationNumThisLoop != 0) { 11593 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11594 } 11595 if (info.numAnimationsRunning != 0) { 11596 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11597 } 11598 if (info.broadcastIntentAction != null) { 11599 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11600 } 11601 if (info.durationMillis != -1) { 11602 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11603 } 11604 if (info.numInstances != -1) { 11605 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11606 } 11607 if (info.tags != null) { 11608 for (String tag : info.tags) { 11609 sb.append("Span-Tag: ").append(tag).append("\n"); 11610 } 11611 } 11612 sb.append("\n"); 11613 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11614 sb.append(info.crashInfo.stackTrace); 11615 } 11616 sb.append("\n"); 11617 11618 // Only buffer up to ~64k. Various logging bits truncate 11619 // things at 128k. 11620 needsFlush = (sb.length() > 64 * 1024); 11621 } 11622 11623 // Flush immediately if the buffer's grown too large, or this 11624 // is a non-system app. Non-system apps are isolated with a 11625 // different tag & policy and not batched. 11626 // 11627 // Batching is useful during internal testing with 11628 // StrictMode settings turned up high. Without batching, 11629 // thousands of separate files could be created on boot. 11630 if (!isSystemApp || needsFlush) { 11631 new Thread("Error dump: " + dropboxTag) { 11632 @Override 11633 public void run() { 11634 String report; 11635 synchronized (sb) { 11636 report = sb.toString(); 11637 sb.delete(0, sb.length()); 11638 sb.trimToSize(); 11639 } 11640 if (report.length() != 0) { 11641 dbox.addText(dropboxTag, report); 11642 } 11643 } 11644 }.start(); 11645 return; 11646 } 11647 11648 // System app batching: 11649 if (!bufferWasEmpty) { 11650 // An existing dropbox-writing thread is outstanding, so 11651 // we don't need to start it up. The existing thread will 11652 // catch the buffer appends we just did. 11653 return; 11654 } 11655 11656 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11657 // (After this point, we shouldn't access AMS internal data structures.) 11658 new Thread("Error dump: " + dropboxTag) { 11659 @Override 11660 public void run() { 11661 // 5 second sleep to let stacks arrive and be batched together 11662 try { 11663 Thread.sleep(5000); // 5 seconds 11664 } catch (InterruptedException e) {} 11665 11666 String errorReport; 11667 synchronized (mStrictModeBuffer) { 11668 errorReport = mStrictModeBuffer.toString(); 11669 if (errorReport.length() == 0) { 11670 return; 11671 } 11672 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11673 mStrictModeBuffer.trimToSize(); 11674 } 11675 dbox.addText(dropboxTag, errorReport); 11676 } 11677 }.start(); 11678 } 11679 11680 /** 11681 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11682 * @param app object of the crashing app, null for the system server 11683 * @param tag reported by the caller 11684 * @param system whether this wtf is coming from the system 11685 * @param crashInfo describing the context of the error 11686 * @return true if the process should exit immediately (WTF is fatal) 11687 */ 11688 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11689 final ApplicationErrorReport.CrashInfo crashInfo) { 11690 final int callingUid = Binder.getCallingUid(); 11691 final int callingPid = Binder.getCallingPid(); 11692 11693 if (system) { 11694 // If this is coming from the system, we could very well have low-level 11695 // system locks held, so we want to do this all asynchronously. And we 11696 // never want this to become fatal, so there is that too. 11697 mHandler.post(new Runnable() { 11698 @Override public void run() { 11699 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11700 } 11701 }); 11702 return false; 11703 } 11704 11705 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11706 crashInfo); 11707 11708 if (r != null && r.pid != Process.myPid() && 11709 Settings.Global.getInt(mContext.getContentResolver(), 11710 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11711 crashApplication(r, crashInfo); 11712 return true; 11713 } else { 11714 return false; 11715 } 11716 } 11717 11718 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11719 final ApplicationErrorReport.CrashInfo crashInfo) { 11720 final ProcessRecord r = findAppProcess(app, "WTF"); 11721 final String processName = app == null ? "system_server" 11722 : (r == null ? "unknown" : r.processName); 11723 11724 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11725 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11726 11727 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11728 11729 return r; 11730 } 11731 11732 /** 11733 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11734 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11735 */ 11736 private ProcessRecord findAppProcess(IBinder app, String reason) { 11737 if (app == null) { 11738 return null; 11739 } 11740 11741 synchronized (this) { 11742 final int NP = mProcessNames.getMap().size(); 11743 for (int ip=0; ip<NP; ip++) { 11744 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11745 final int NA = apps.size(); 11746 for (int ia=0; ia<NA; ia++) { 11747 ProcessRecord p = apps.valueAt(ia); 11748 if (p.thread != null && p.thread.asBinder() == app) { 11749 return p; 11750 } 11751 } 11752 } 11753 11754 Slog.w(TAG, "Can't find mystery application for " + reason 11755 + " from pid=" + Binder.getCallingPid() 11756 + " uid=" + Binder.getCallingUid() + ": " + app); 11757 return null; 11758 } 11759 } 11760 11761 /** 11762 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11763 * to append various headers to the dropbox log text. 11764 */ 11765 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11766 StringBuilder sb) { 11767 // Watchdog thread ends up invoking this function (with 11768 // a null ProcessRecord) to add the stack file to dropbox. 11769 // Do not acquire a lock on this (am) in such cases, as it 11770 // could cause a potential deadlock, if and when watchdog 11771 // is invoked due to unavailability of lock on am and it 11772 // would prevent watchdog from killing system_server. 11773 if (process == null) { 11774 sb.append("Process: ").append(processName).append("\n"); 11775 return; 11776 } 11777 // Note: ProcessRecord 'process' is guarded by the service 11778 // instance. (notably process.pkgList, which could otherwise change 11779 // concurrently during execution of this method) 11780 synchronized (this) { 11781 sb.append("Process: ").append(processName).append("\n"); 11782 int flags = process.info.flags; 11783 IPackageManager pm = AppGlobals.getPackageManager(); 11784 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11785 for (int ip=0; ip<process.pkgList.size(); ip++) { 11786 String pkg = process.pkgList.keyAt(ip); 11787 sb.append("Package: ").append(pkg); 11788 try { 11789 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11790 if (pi != null) { 11791 sb.append(" v").append(pi.versionCode); 11792 if (pi.versionName != null) { 11793 sb.append(" (").append(pi.versionName).append(")"); 11794 } 11795 } 11796 } catch (RemoteException e) { 11797 Slog.e(TAG, "Error getting package info: " + pkg, e); 11798 } 11799 sb.append("\n"); 11800 } 11801 } 11802 } 11803 11804 private static String processClass(ProcessRecord process) { 11805 if (process == null || process.pid == MY_PID) { 11806 return "system_server"; 11807 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11808 return "system_app"; 11809 } else { 11810 return "data_app"; 11811 } 11812 } 11813 11814 /** 11815 * Write a description of an error (crash, WTF, ANR) to the drop box. 11816 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11817 * @param process which caused the error, null means the system server 11818 * @param activity which triggered the error, null if unknown 11819 * @param parent activity related to the error, null if unknown 11820 * @param subject line related to the error, null if absent 11821 * @param report in long form describing the error, null if absent 11822 * @param logFile to include in the report, null if none 11823 * @param crashInfo giving an application stack trace, null if absent 11824 */ 11825 public void addErrorToDropBox(String eventType, 11826 ProcessRecord process, String processName, ActivityRecord activity, 11827 ActivityRecord parent, String subject, 11828 final String report, final File logFile, 11829 final ApplicationErrorReport.CrashInfo crashInfo) { 11830 // NOTE -- this must never acquire the ActivityManagerService lock, 11831 // otherwise the watchdog may be prevented from resetting the system. 11832 11833 final String dropboxTag = processClass(process) + "_" + eventType; 11834 final DropBoxManager dbox = (DropBoxManager) 11835 mContext.getSystemService(Context.DROPBOX_SERVICE); 11836 11837 // Exit early if the dropbox isn't configured to accept this report type. 11838 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11839 11840 final StringBuilder sb = new StringBuilder(1024); 11841 appendDropBoxProcessHeaders(process, processName, sb); 11842 if (activity != null) { 11843 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11844 } 11845 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11846 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11847 } 11848 if (parent != null && parent != activity) { 11849 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11850 } 11851 if (subject != null) { 11852 sb.append("Subject: ").append(subject).append("\n"); 11853 } 11854 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11855 if (Debug.isDebuggerConnected()) { 11856 sb.append("Debugger: Connected\n"); 11857 } 11858 sb.append("\n"); 11859 11860 // Do the rest in a worker thread to avoid blocking the caller on I/O 11861 // (After this point, we shouldn't access AMS internal data structures.) 11862 Thread worker = new Thread("Error dump: " + dropboxTag) { 11863 @Override 11864 public void run() { 11865 if (report != null) { 11866 sb.append(report); 11867 } 11868 if (logFile != null) { 11869 try { 11870 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11871 "\n\n[[TRUNCATED]]")); 11872 } catch (IOException e) { 11873 Slog.e(TAG, "Error reading " + logFile, e); 11874 } 11875 } 11876 if (crashInfo != null && crashInfo.stackTrace != null) { 11877 sb.append(crashInfo.stackTrace); 11878 } 11879 11880 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11881 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11882 if (lines > 0) { 11883 sb.append("\n"); 11884 11885 // Merge several logcat streams, and take the last N lines 11886 InputStreamReader input = null; 11887 try { 11888 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11889 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11890 "-b", "crash", 11891 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11892 11893 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11894 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11895 input = new InputStreamReader(logcat.getInputStream()); 11896 11897 int num; 11898 char[] buf = new char[8192]; 11899 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11900 } catch (IOException e) { 11901 Slog.e(TAG, "Error running logcat", e); 11902 } finally { 11903 if (input != null) try { input.close(); } catch (IOException e) {} 11904 } 11905 } 11906 11907 dbox.addText(dropboxTag, sb.toString()); 11908 } 11909 }; 11910 11911 if (process == null) { 11912 // If process is null, we are being called from some internal code 11913 // and may be about to die -- run this synchronously. 11914 worker.run(); 11915 } else { 11916 worker.start(); 11917 } 11918 } 11919 11920 /** 11921 * Bring up the "unexpected error" dialog box for a crashing app. 11922 * Deal with edge cases (intercepts from instrumented applications, 11923 * ActivityController, error intent receivers, that sort of thing). 11924 * @param r the application crashing 11925 * @param crashInfo describing the failure 11926 */ 11927 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11928 long timeMillis = System.currentTimeMillis(); 11929 String shortMsg = crashInfo.exceptionClassName; 11930 String longMsg = crashInfo.exceptionMessage; 11931 String stackTrace = crashInfo.stackTrace; 11932 if (shortMsg != null && longMsg != null) { 11933 longMsg = shortMsg + ": " + longMsg; 11934 } else if (shortMsg != null) { 11935 longMsg = shortMsg; 11936 } 11937 11938 AppErrorResult result = new AppErrorResult(); 11939 synchronized (this) { 11940 if (mController != null) { 11941 try { 11942 String name = r != null ? r.processName : null; 11943 int pid = r != null ? r.pid : Binder.getCallingPid(); 11944 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11945 if (!mController.appCrashed(name, pid, 11946 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11947 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11948 && "Native crash".equals(crashInfo.exceptionClassName)) { 11949 Slog.w(TAG, "Skip killing native crashed app " + name 11950 + "(" + pid + ") during testing"); 11951 } else { 11952 Slog.w(TAG, "Force-killing crashed app " + name 11953 + " at watcher's request"); 11954 if (r != null) { 11955 r.kill("crash", true); 11956 } else { 11957 // Huh. 11958 Process.killProcess(pid); 11959 Process.killProcessGroup(uid, pid); 11960 } 11961 } 11962 return; 11963 } 11964 } catch (RemoteException e) { 11965 mController = null; 11966 Watchdog.getInstance().setActivityController(null); 11967 } 11968 } 11969 11970 final long origId = Binder.clearCallingIdentity(); 11971 11972 // If this process is running instrumentation, finish it. 11973 if (r != null && r.instrumentationClass != null) { 11974 Slog.w(TAG, "Error in app " + r.processName 11975 + " running instrumentation " + r.instrumentationClass + ":"); 11976 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11977 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11978 Bundle info = new Bundle(); 11979 info.putString("shortMsg", shortMsg); 11980 info.putString("longMsg", longMsg); 11981 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11982 Binder.restoreCallingIdentity(origId); 11983 return; 11984 } 11985 11986 // If we can't identify the process or it's already exceeded its crash quota, 11987 // quit right away without showing a crash dialog. 11988 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11989 Binder.restoreCallingIdentity(origId); 11990 return; 11991 } 11992 11993 Message msg = Message.obtain(); 11994 msg.what = SHOW_ERROR_MSG; 11995 HashMap data = new HashMap(); 11996 data.put("result", result); 11997 data.put("app", r); 11998 msg.obj = data; 11999 mHandler.sendMessage(msg); 12000 12001 Binder.restoreCallingIdentity(origId); 12002 } 12003 12004 int res = result.get(); 12005 12006 Intent appErrorIntent = null; 12007 synchronized (this) { 12008 if (r != null && !r.isolated) { 12009 // XXX Can't keep track of crash time for isolated processes, 12010 // since they don't have a persistent identity. 12011 mProcessCrashTimes.put(r.info.processName, r.uid, 12012 SystemClock.uptimeMillis()); 12013 } 12014 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12015 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12016 } 12017 } 12018 12019 if (appErrorIntent != null) { 12020 try { 12021 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12022 } catch (ActivityNotFoundException e) { 12023 Slog.w(TAG, "bug report receiver dissappeared", e); 12024 } 12025 } 12026 } 12027 12028 Intent createAppErrorIntentLocked(ProcessRecord r, 12029 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12030 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12031 if (report == null) { 12032 return null; 12033 } 12034 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12035 result.setComponent(r.errorReportReceiver); 12036 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12037 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12038 return result; 12039 } 12040 12041 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12042 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12043 if (r.errorReportReceiver == null) { 12044 return null; 12045 } 12046 12047 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12048 return null; 12049 } 12050 12051 ApplicationErrorReport report = new ApplicationErrorReport(); 12052 report.packageName = r.info.packageName; 12053 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12054 report.processName = r.processName; 12055 report.time = timeMillis; 12056 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12057 12058 if (r.crashing || r.forceCrashReport) { 12059 report.type = ApplicationErrorReport.TYPE_CRASH; 12060 report.crashInfo = crashInfo; 12061 } else if (r.notResponding) { 12062 report.type = ApplicationErrorReport.TYPE_ANR; 12063 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12064 12065 report.anrInfo.activity = r.notRespondingReport.tag; 12066 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12067 report.anrInfo.info = r.notRespondingReport.longMsg; 12068 } 12069 12070 return report; 12071 } 12072 12073 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12074 enforceNotIsolatedCaller("getProcessesInErrorState"); 12075 // assume our apps are happy - lazy create the list 12076 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12077 12078 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12079 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12080 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12081 12082 synchronized (this) { 12083 12084 // iterate across all processes 12085 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12086 ProcessRecord app = mLruProcesses.get(i); 12087 if (!allUsers && app.userId != userId) { 12088 continue; 12089 } 12090 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12091 // This one's in trouble, so we'll generate a report for it 12092 // crashes are higher priority (in case there's a crash *and* an anr) 12093 ActivityManager.ProcessErrorStateInfo report = null; 12094 if (app.crashing) { 12095 report = app.crashingReport; 12096 } else if (app.notResponding) { 12097 report = app.notRespondingReport; 12098 } 12099 12100 if (report != null) { 12101 if (errList == null) { 12102 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12103 } 12104 errList.add(report); 12105 } else { 12106 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12107 " crashing = " + app.crashing + 12108 " notResponding = " + app.notResponding); 12109 } 12110 } 12111 } 12112 } 12113 12114 return errList; 12115 } 12116 12117 static int procStateToImportance(int procState, int memAdj, 12118 ActivityManager.RunningAppProcessInfo currApp) { 12119 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12120 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12121 currApp.lru = memAdj; 12122 } else { 12123 currApp.lru = 0; 12124 } 12125 return imp; 12126 } 12127 12128 private void fillInProcMemInfo(ProcessRecord app, 12129 ActivityManager.RunningAppProcessInfo outInfo) { 12130 outInfo.pid = app.pid; 12131 outInfo.uid = app.info.uid; 12132 if (mHeavyWeightProcess == app) { 12133 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12134 } 12135 if (app.persistent) { 12136 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12137 } 12138 if (app.activities.size() > 0) { 12139 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12140 } 12141 outInfo.lastTrimLevel = app.trimMemoryLevel; 12142 int adj = app.curAdj; 12143 int procState = app.curProcState; 12144 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12145 outInfo.importanceReasonCode = app.adjTypeCode; 12146 outInfo.processState = app.curProcState; 12147 } 12148 12149 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12150 enforceNotIsolatedCaller("getRunningAppProcesses"); 12151 // Lazy instantiation of list 12152 List<ActivityManager.RunningAppProcessInfo> runList = null; 12153 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12154 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12155 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12156 synchronized (this) { 12157 // Iterate across all processes 12158 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12159 ProcessRecord app = mLruProcesses.get(i); 12160 if (!allUsers && app.userId != userId) { 12161 continue; 12162 } 12163 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12164 // Generate process state info for running application 12165 ActivityManager.RunningAppProcessInfo currApp = 12166 new ActivityManager.RunningAppProcessInfo(app.processName, 12167 app.pid, app.getPackageList()); 12168 fillInProcMemInfo(app, currApp); 12169 if (app.adjSource instanceof ProcessRecord) { 12170 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12171 currApp.importanceReasonImportance = 12172 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12173 app.adjSourceProcState); 12174 } else if (app.adjSource instanceof ActivityRecord) { 12175 ActivityRecord r = (ActivityRecord)app.adjSource; 12176 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12177 } 12178 if (app.adjTarget instanceof ComponentName) { 12179 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12180 } 12181 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12182 // + " lru=" + currApp.lru); 12183 if (runList == null) { 12184 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12185 } 12186 runList.add(currApp); 12187 } 12188 } 12189 } 12190 return runList; 12191 } 12192 12193 public List<ApplicationInfo> getRunningExternalApplications() { 12194 enforceNotIsolatedCaller("getRunningExternalApplications"); 12195 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12196 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12197 if (runningApps != null && runningApps.size() > 0) { 12198 Set<String> extList = new HashSet<String>(); 12199 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12200 if (app.pkgList != null) { 12201 for (String pkg : app.pkgList) { 12202 extList.add(pkg); 12203 } 12204 } 12205 } 12206 IPackageManager pm = AppGlobals.getPackageManager(); 12207 for (String pkg : extList) { 12208 try { 12209 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12210 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12211 retList.add(info); 12212 } 12213 } catch (RemoteException e) { 12214 } 12215 } 12216 } 12217 return retList; 12218 } 12219 12220 @Override 12221 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12222 enforceNotIsolatedCaller("getMyMemoryState"); 12223 synchronized (this) { 12224 ProcessRecord proc; 12225 synchronized (mPidsSelfLocked) { 12226 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12227 } 12228 fillInProcMemInfo(proc, outInfo); 12229 } 12230 } 12231 12232 @Override 12233 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12234 if (checkCallingPermission(android.Manifest.permission.DUMP) 12235 != PackageManager.PERMISSION_GRANTED) { 12236 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12237 + Binder.getCallingPid() 12238 + ", uid=" + Binder.getCallingUid() 12239 + " without permission " 12240 + android.Manifest.permission.DUMP); 12241 return; 12242 } 12243 12244 boolean dumpAll = false; 12245 boolean dumpClient = false; 12246 String dumpPackage = null; 12247 12248 int opti = 0; 12249 while (opti < args.length) { 12250 String opt = args[opti]; 12251 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12252 break; 12253 } 12254 opti++; 12255 if ("-a".equals(opt)) { 12256 dumpAll = true; 12257 } else if ("-c".equals(opt)) { 12258 dumpClient = true; 12259 } else if ("-h".equals(opt)) { 12260 pw.println("Activity manager dump options:"); 12261 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12262 pw.println(" cmd may be one of:"); 12263 pw.println(" a[ctivities]: activity stack state"); 12264 pw.println(" r[recents]: recent activities state"); 12265 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12266 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12267 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12268 pw.println(" o[om]: out of memory management"); 12269 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12270 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12271 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12272 pw.println(" service [COMP_SPEC]: service client-side state"); 12273 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12274 pw.println(" all: dump all activities"); 12275 pw.println(" top: dump the top activity"); 12276 pw.println(" write: write all pending state to storage"); 12277 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12278 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12279 pw.println(" a partial substring in a component name, a"); 12280 pw.println(" hex object identifier."); 12281 pw.println(" -a: include all available server state."); 12282 pw.println(" -c: include client state."); 12283 return; 12284 } else { 12285 pw.println("Unknown argument: " + opt + "; use -h for help"); 12286 } 12287 } 12288 12289 long origId = Binder.clearCallingIdentity(); 12290 boolean more = false; 12291 // Is the caller requesting to dump a particular piece of data? 12292 if (opti < args.length) { 12293 String cmd = args[opti]; 12294 opti++; 12295 if ("activities".equals(cmd) || "a".equals(cmd)) { 12296 synchronized (this) { 12297 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12298 } 12299 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12300 synchronized (this) { 12301 dumpRecentsLocked(fd, pw, args, opti, true, null); 12302 } 12303 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12304 String[] newArgs; 12305 String name; 12306 if (opti >= args.length) { 12307 name = null; 12308 newArgs = EMPTY_STRING_ARRAY; 12309 } else { 12310 name = args[opti]; 12311 opti++; 12312 newArgs = new String[args.length - opti]; 12313 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12314 args.length - opti); 12315 } 12316 synchronized (this) { 12317 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12318 } 12319 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12320 String[] newArgs; 12321 String name; 12322 if (opti >= args.length) { 12323 name = null; 12324 newArgs = EMPTY_STRING_ARRAY; 12325 } else { 12326 name = args[opti]; 12327 opti++; 12328 newArgs = new String[args.length - opti]; 12329 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12330 args.length - opti); 12331 } 12332 synchronized (this) { 12333 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12334 } 12335 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12336 String[] newArgs; 12337 String name; 12338 if (opti >= args.length) { 12339 name = null; 12340 newArgs = EMPTY_STRING_ARRAY; 12341 } else { 12342 name = args[opti]; 12343 opti++; 12344 newArgs = new String[args.length - opti]; 12345 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12346 args.length - opti); 12347 } 12348 synchronized (this) { 12349 dumpProcessesLocked(fd, pw, args, opti, true, name); 12350 } 12351 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12352 synchronized (this) { 12353 dumpOomLocked(fd, pw, args, opti, true); 12354 } 12355 } else if ("provider".equals(cmd)) { 12356 String[] newArgs; 12357 String name; 12358 if (opti >= args.length) { 12359 name = null; 12360 newArgs = EMPTY_STRING_ARRAY; 12361 } else { 12362 name = args[opti]; 12363 opti++; 12364 newArgs = new String[args.length - opti]; 12365 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12366 } 12367 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12368 pw.println("No providers match: " + name); 12369 pw.println("Use -h for help."); 12370 } 12371 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12372 synchronized (this) { 12373 dumpProvidersLocked(fd, pw, args, opti, true, null); 12374 } 12375 } else if ("service".equals(cmd)) { 12376 String[] newArgs; 12377 String name; 12378 if (opti >= args.length) { 12379 name = null; 12380 newArgs = EMPTY_STRING_ARRAY; 12381 } else { 12382 name = args[opti]; 12383 opti++; 12384 newArgs = new String[args.length - opti]; 12385 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12386 args.length - opti); 12387 } 12388 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12389 pw.println("No services match: " + name); 12390 pw.println("Use -h for help."); 12391 } 12392 } else if ("package".equals(cmd)) { 12393 String[] newArgs; 12394 if (opti >= args.length) { 12395 pw.println("package: no package name specified"); 12396 pw.println("Use -h for help."); 12397 } else { 12398 dumpPackage = args[opti]; 12399 opti++; 12400 newArgs = new String[args.length - opti]; 12401 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12402 args.length - opti); 12403 args = newArgs; 12404 opti = 0; 12405 more = true; 12406 } 12407 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12408 synchronized (this) { 12409 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12410 } 12411 } else if ("write".equals(cmd)) { 12412 mTaskPersister.flush(); 12413 pw.println("All tasks persisted."); 12414 return; 12415 } else { 12416 // Dumping a single activity? 12417 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12418 pw.println("Bad activity command, or no activities match: " + cmd); 12419 pw.println("Use -h for help."); 12420 } 12421 } 12422 if (!more) { 12423 Binder.restoreCallingIdentity(origId); 12424 return; 12425 } 12426 } 12427 12428 // No piece of data specified, dump everything. 12429 synchronized (this) { 12430 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12431 pw.println(); 12432 if (dumpAll) { 12433 pw.println("-------------------------------------------------------------------------------"); 12434 } 12435 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12436 pw.println(); 12437 if (dumpAll) { 12438 pw.println("-------------------------------------------------------------------------------"); 12439 } 12440 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12441 pw.println(); 12442 if (dumpAll) { 12443 pw.println("-------------------------------------------------------------------------------"); 12444 } 12445 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12446 pw.println(); 12447 if (dumpAll) { 12448 pw.println("-------------------------------------------------------------------------------"); 12449 } 12450 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12451 pw.println(); 12452 if (dumpAll) { 12453 pw.println("-------------------------------------------------------------------------------"); 12454 } 12455 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12456 pw.println(); 12457 if (dumpAll) { 12458 pw.println("-------------------------------------------------------------------------------"); 12459 } 12460 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12461 } 12462 Binder.restoreCallingIdentity(origId); 12463 } 12464 12465 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12466 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12467 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12468 12469 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12470 dumpPackage); 12471 boolean needSep = printedAnything; 12472 12473 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12474 dumpPackage, needSep, " mFocusedActivity: "); 12475 if (printed) { 12476 printedAnything = true; 12477 needSep = false; 12478 } 12479 12480 if (dumpPackage == null) { 12481 if (needSep) { 12482 pw.println(); 12483 } 12484 needSep = true; 12485 printedAnything = true; 12486 mStackSupervisor.dump(pw, " "); 12487 } 12488 12489 if (!printedAnything) { 12490 pw.println(" (nothing)"); 12491 } 12492 } 12493 12494 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12495 int opti, boolean dumpAll, String dumpPackage) { 12496 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12497 12498 boolean printedAnything = false; 12499 12500 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12501 boolean printedHeader = false; 12502 12503 final int N = mRecentTasks.size(); 12504 for (int i=0; i<N; i++) { 12505 TaskRecord tr = mRecentTasks.get(i); 12506 if (dumpPackage != null) { 12507 if (tr.realActivity == null || 12508 !dumpPackage.equals(tr.realActivity)) { 12509 continue; 12510 } 12511 } 12512 if (!printedHeader) { 12513 pw.println(" Recent tasks:"); 12514 printedHeader = true; 12515 printedAnything = true; 12516 } 12517 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12518 pw.println(tr); 12519 if (dumpAll) { 12520 mRecentTasks.get(i).dump(pw, " "); 12521 } 12522 } 12523 } 12524 12525 if (!printedAnything) { 12526 pw.println(" (nothing)"); 12527 } 12528 } 12529 12530 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12531 int opti, boolean dumpAll, String dumpPackage) { 12532 boolean needSep = false; 12533 boolean printedAnything = false; 12534 int numPers = 0; 12535 12536 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12537 12538 if (dumpAll) { 12539 final int NP = mProcessNames.getMap().size(); 12540 for (int ip=0; ip<NP; ip++) { 12541 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12542 final int NA = procs.size(); 12543 for (int ia=0; ia<NA; ia++) { 12544 ProcessRecord r = procs.valueAt(ia); 12545 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12546 continue; 12547 } 12548 if (!needSep) { 12549 pw.println(" All known processes:"); 12550 needSep = true; 12551 printedAnything = true; 12552 } 12553 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12554 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12555 pw.print(" "); pw.println(r); 12556 r.dump(pw, " "); 12557 if (r.persistent) { 12558 numPers++; 12559 } 12560 } 12561 } 12562 } 12563 12564 if (mIsolatedProcesses.size() > 0) { 12565 boolean printed = false; 12566 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12567 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12568 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12569 continue; 12570 } 12571 if (!printed) { 12572 if (needSep) { 12573 pw.println(); 12574 } 12575 pw.println(" Isolated process list (sorted by uid):"); 12576 printedAnything = true; 12577 printed = true; 12578 needSep = true; 12579 } 12580 pw.println(String.format("%sIsolated #%2d: %s", 12581 " ", i, r.toString())); 12582 } 12583 } 12584 12585 if (mLruProcesses.size() > 0) { 12586 if (needSep) { 12587 pw.println(); 12588 } 12589 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12590 pw.print(" total, non-act at "); 12591 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12592 pw.print(", non-svc at "); 12593 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12594 pw.println("):"); 12595 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12596 needSep = true; 12597 printedAnything = true; 12598 } 12599 12600 if (dumpAll || dumpPackage != null) { 12601 synchronized (mPidsSelfLocked) { 12602 boolean printed = false; 12603 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12604 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12605 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12606 continue; 12607 } 12608 if (!printed) { 12609 if (needSep) pw.println(); 12610 needSep = true; 12611 pw.println(" PID mappings:"); 12612 printed = true; 12613 printedAnything = true; 12614 } 12615 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12616 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12617 } 12618 } 12619 } 12620 12621 if (mForegroundProcesses.size() > 0) { 12622 synchronized (mPidsSelfLocked) { 12623 boolean printed = false; 12624 for (int i=0; i<mForegroundProcesses.size(); i++) { 12625 ProcessRecord r = mPidsSelfLocked.get( 12626 mForegroundProcesses.valueAt(i).pid); 12627 if (dumpPackage != null && (r == null 12628 || !r.pkgList.containsKey(dumpPackage))) { 12629 continue; 12630 } 12631 if (!printed) { 12632 if (needSep) pw.println(); 12633 needSep = true; 12634 pw.println(" Foreground Processes:"); 12635 printed = true; 12636 printedAnything = true; 12637 } 12638 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12639 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12640 } 12641 } 12642 } 12643 12644 if (mPersistentStartingProcesses.size() > 0) { 12645 if (needSep) pw.println(); 12646 needSep = true; 12647 printedAnything = true; 12648 pw.println(" Persisent processes that are starting:"); 12649 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12650 "Starting Norm", "Restarting PERS", dumpPackage); 12651 } 12652 12653 if (mRemovedProcesses.size() > 0) { 12654 if (needSep) pw.println(); 12655 needSep = true; 12656 printedAnything = true; 12657 pw.println(" Processes that are being removed:"); 12658 dumpProcessList(pw, this, mRemovedProcesses, " ", 12659 "Removed Norm", "Removed PERS", dumpPackage); 12660 } 12661 12662 if (mProcessesOnHold.size() > 0) { 12663 if (needSep) pw.println(); 12664 needSep = true; 12665 printedAnything = true; 12666 pw.println(" Processes that are on old until the system is ready:"); 12667 dumpProcessList(pw, this, mProcessesOnHold, " ", 12668 "OnHold Norm", "OnHold PERS", dumpPackage); 12669 } 12670 12671 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12672 12673 if (mProcessCrashTimes.getMap().size() > 0) { 12674 boolean printed = false; 12675 long now = SystemClock.uptimeMillis(); 12676 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12677 final int NP = pmap.size(); 12678 for (int ip=0; ip<NP; ip++) { 12679 String pname = pmap.keyAt(ip); 12680 SparseArray<Long> uids = pmap.valueAt(ip); 12681 final int N = uids.size(); 12682 for (int i=0; i<N; i++) { 12683 int puid = uids.keyAt(i); 12684 ProcessRecord r = mProcessNames.get(pname, puid); 12685 if (dumpPackage != null && (r == null 12686 || !r.pkgList.containsKey(dumpPackage))) { 12687 continue; 12688 } 12689 if (!printed) { 12690 if (needSep) pw.println(); 12691 needSep = true; 12692 pw.println(" Time since processes crashed:"); 12693 printed = true; 12694 printedAnything = true; 12695 } 12696 pw.print(" Process "); pw.print(pname); 12697 pw.print(" uid "); pw.print(puid); 12698 pw.print(": last crashed "); 12699 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12700 pw.println(" ago"); 12701 } 12702 } 12703 } 12704 12705 if (mBadProcesses.getMap().size() > 0) { 12706 boolean printed = false; 12707 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12708 final int NP = pmap.size(); 12709 for (int ip=0; ip<NP; ip++) { 12710 String pname = pmap.keyAt(ip); 12711 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12712 final int N = uids.size(); 12713 for (int i=0; i<N; i++) { 12714 int puid = uids.keyAt(i); 12715 ProcessRecord r = mProcessNames.get(pname, puid); 12716 if (dumpPackage != null && (r == null 12717 || !r.pkgList.containsKey(dumpPackage))) { 12718 continue; 12719 } 12720 if (!printed) { 12721 if (needSep) pw.println(); 12722 needSep = true; 12723 pw.println(" Bad processes:"); 12724 printedAnything = true; 12725 } 12726 BadProcessInfo info = uids.valueAt(i); 12727 pw.print(" Bad process "); pw.print(pname); 12728 pw.print(" uid "); pw.print(puid); 12729 pw.print(": crashed at time "); pw.println(info.time); 12730 if (info.shortMsg != null) { 12731 pw.print(" Short msg: "); pw.println(info.shortMsg); 12732 } 12733 if (info.longMsg != null) { 12734 pw.print(" Long msg: "); pw.println(info.longMsg); 12735 } 12736 if (info.stack != null) { 12737 pw.println(" Stack:"); 12738 int lastPos = 0; 12739 for (int pos=0; pos<info.stack.length(); pos++) { 12740 if (info.stack.charAt(pos) == '\n') { 12741 pw.print(" "); 12742 pw.write(info.stack, lastPos, pos-lastPos); 12743 pw.println(); 12744 lastPos = pos+1; 12745 } 12746 } 12747 if (lastPos < info.stack.length()) { 12748 pw.print(" "); 12749 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12750 pw.println(); 12751 } 12752 } 12753 } 12754 } 12755 } 12756 12757 if (dumpPackage == null) { 12758 pw.println(); 12759 needSep = false; 12760 pw.println(" mStartedUsers:"); 12761 for (int i=0; i<mStartedUsers.size(); i++) { 12762 UserStartedState uss = mStartedUsers.valueAt(i); 12763 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12764 pw.print(": "); uss.dump("", pw); 12765 } 12766 pw.print(" mStartedUserArray: ["); 12767 for (int i=0; i<mStartedUserArray.length; i++) { 12768 if (i > 0) pw.print(", "); 12769 pw.print(mStartedUserArray[i]); 12770 } 12771 pw.println("]"); 12772 pw.print(" mUserLru: ["); 12773 for (int i=0; i<mUserLru.size(); i++) { 12774 if (i > 0) pw.print(", "); 12775 pw.print(mUserLru.get(i)); 12776 } 12777 pw.println("]"); 12778 if (dumpAll) { 12779 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12780 } 12781 synchronized (mUserProfileGroupIdsSelfLocked) { 12782 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12783 pw.println(" mUserProfileGroupIds:"); 12784 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12785 pw.print(" User #"); 12786 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12787 pw.print(" -> profile #"); 12788 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12789 } 12790 } 12791 } 12792 } 12793 if (mHomeProcess != null && (dumpPackage == null 12794 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12795 if (needSep) { 12796 pw.println(); 12797 needSep = false; 12798 } 12799 pw.println(" mHomeProcess: " + mHomeProcess); 12800 } 12801 if (mPreviousProcess != null && (dumpPackage == null 12802 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12803 if (needSep) { 12804 pw.println(); 12805 needSep = false; 12806 } 12807 pw.println(" mPreviousProcess: " + mPreviousProcess); 12808 } 12809 if (dumpAll) { 12810 StringBuilder sb = new StringBuilder(128); 12811 sb.append(" mPreviousProcessVisibleTime: "); 12812 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12813 pw.println(sb); 12814 } 12815 if (mHeavyWeightProcess != null && (dumpPackage == null 12816 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12817 if (needSep) { 12818 pw.println(); 12819 needSep = false; 12820 } 12821 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12822 } 12823 if (dumpPackage == null) { 12824 pw.println(" mConfiguration: " + mConfiguration); 12825 } 12826 if (dumpAll) { 12827 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12828 if (mCompatModePackages.getPackages().size() > 0) { 12829 boolean printed = false; 12830 for (Map.Entry<String, Integer> entry 12831 : mCompatModePackages.getPackages().entrySet()) { 12832 String pkg = entry.getKey(); 12833 int mode = entry.getValue(); 12834 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12835 continue; 12836 } 12837 if (!printed) { 12838 pw.println(" mScreenCompatPackages:"); 12839 printed = true; 12840 } 12841 pw.print(" "); pw.print(pkg); pw.print(": "); 12842 pw.print(mode); pw.println(); 12843 } 12844 } 12845 } 12846 if (dumpPackage == null) { 12847 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12848 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12849 + " mLockScreenShown " + lockScreenShownToString()); 12850 } 12851 if (mShuttingDown || mRunningVoice) { 12852 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12853 } 12854 } 12855 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12856 || mOrigWaitForDebugger) { 12857 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12858 || dumpPackage.equals(mOrigDebugApp)) { 12859 if (needSep) { 12860 pw.println(); 12861 needSep = false; 12862 } 12863 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12864 + " mDebugTransient=" + mDebugTransient 12865 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12866 } 12867 } 12868 if (mOpenGlTraceApp != null) { 12869 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12870 if (needSep) { 12871 pw.println(); 12872 needSep = false; 12873 } 12874 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12875 } 12876 } 12877 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12878 || mProfileFd != null) { 12879 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12880 if (needSep) { 12881 pw.println(); 12882 needSep = false; 12883 } 12884 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12885 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12886 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12887 + mAutoStopProfiler); 12888 pw.println(" mProfileType=" + mProfileType); 12889 } 12890 } 12891 if (dumpPackage == null) { 12892 if (mAlwaysFinishActivities || mController != null) { 12893 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12894 + " mController=" + mController); 12895 } 12896 if (dumpAll) { 12897 pw.println(" Total persistent processes: " + numPers); 12898 pw.println(" mProcessesReady=" + mProcessesReady 12899 + " mSystemReady=" + mSystemReady 12900 + " mBooted=" + mBooted 12901 + " mFactoryTest=" + mFactoryTest); 12902 pw.println(" mBooting=" + mBooting 12903 + " mCallFinishBooting=" + mCallFinishBooting 12904 + " mBootAnimationComplete=" + mBootAnimationComplete); 12905 pw.print(" mLastPowerCheckRealtime="); 12906 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12907 pw.println(""); 12908 pw.print(" mLastPowerCheckUptime="); 12909 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12910 pw.println(""); 12911 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12912 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12913 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12914 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12915 + " (" + mLruProcesses.size() + " total)" 12916 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12917 + " mNumServiceProcs=" + mNumServiceProcs 12918 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12919 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12920 + " mLastMemoryLevel" + mLastMemoryLevel 12921 + " mLastNumProcesses" + mLastNumProcesses); 12922 long now = SystemClock.uptimeMillis(); 12923 pw.print(" mLastIdleTime="); 12924 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12925 pw.print(" mLowRamSinceLastIdle="); 12926 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12927 pw.println(); 12928 } 12929 } 12930 12931 if (!printedAnything) { 12932 pw.println(" (nothing)"); 12933 } 12934 } 12935 12936 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12937 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12938 if (mProcessesToGc.size() > 0) { 12939 boolean printed = false; 12940 long now = SystemClock.uptimeMillis(); 12941 for (int i=0; i<mProcessesToGc.size(); i++) { 12942 ProcessRecord proc = mProcessesToGc.get(i); 12943 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12944 continue; 12945 } 12946 if (!printed) { 12947 if (needSep) pw.println(); 12948 needSep = true; 12949 pw.println(" Processes that are waiting to GC:"); 12950 printed = true; 12951 } 12952 pw.print(" Process "); pw.println(proc); 12953 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12954 pw.print(", last gced="); 12955 pw.print(now-proc.lastRequestedGc); 12956 pw.print(" ms ago, last lowMem="); 12957 pw.print(now-proc.lastLowMemory); 12958 pw.println(" ms ago"); 12959 12960 } 12961 } 12962 return needSep; 12963 } 12964 12965 void printOomLevel(PrintWriter pw, String name, int adj) { 12966 pw.print(" "); 12967 if (adj >= 0) { 12968 pw.print(' '); 12969 if (adj < 10) pw.print(' '); 12970 } else { 12971 if (adj > -10) pw.print(' '); 12972 } 12973 pw.print(adj); 12974 pw.print(": "); 12975 pw.print(name); 12976 pw.print(" ("); 12977 pw.print(mProcessList.getMemLevel(adj)/1024); 12978 pw.println(" kB)"); 12979 } 12980 12981 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12982 int opti, boolean dumpAll) { 12983 boolean needSep = false; 12984 12985 if (mLruProcesses.size() > 0) { 12986 if (needSep) pw.println(); 12987 needSep = true; 12988 pw.println(" OOM levels:"); 12989 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12990 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12991 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12992 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12993 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12994 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12995 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12996 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12997 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12998 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12999 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13000 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13001 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13002 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13003 13004 if (needSep) pw.println(); 13005 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13006 pw.print(" total, non-act at "); 13007 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13008 pw.print(", non-svc at "); 13009 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13010 pw.println("):"); 13011 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13012 needSep = true; 13013 } 13014 13015 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13016 13017 pw.println(); 13018 pw.println(" mHomeProcess: " + mHomeProcess); 13019 pw.println(" mPreviousProcess: " + mPreviousProcess); 13020 if (mHeavyWeightProcess != null) { 13021 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13022 } 13023 13024 return true; 13025 } 13026 13027 /** 13028 * There are three ways to call this: 13029 * - no provider specified: dump all the providers 13030 * - a flattened component name that matched an existing provider was specified as the 13031 * first arg: dump that one provider 13032 * - the first arg isn't the flattened component name of an existing provider: 13033 * dump all providers whose component contains the first arg as a substring 13034 */ 13035 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13036 int opti, boolean dumpAll) { 13037 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13038 } 13039 13040 static class ItemMatcher { 13041 ArrayList<ComponentName> components; 13042 ArrayList<String> strings; 13043 ArrayList<Integer> objects; 13044 boolean all; 13045 13046 ItemMatcher() { 13047 all = true; 13048 } 13049 13050 void build(String name) { 13051 ComponentName componentName = ComponentName.unflattenFromString(name); 13052 if (componentName != null) { 13053 if (components == null) { 13054 components = new ArrayList<ComponentName>(); 13055 } 13056 components.add(componentName); 13057 all = false; 13058 } else { 13059 int objectId = 0; 13060 // Not a '/' separated full component name; maybe an object ID? 13061 try { 13062 objectId = Integer.parseInt(name, 16); 13063 if (objects == null) { 13064 objects = new ArrayList<Integer>(); 13065 } 13066 objects.add(objectId); 13067 all = false; 13068 } catch (RuntimeException e) { 13069 // Not an integer; just do string match. 13070 if (strings == null) { 13071 strings = new ArrayList<String>(); 13072 } 13073 strings.add(name); 13074 all = false; 13075 } 13076 } 13077 } 13078 13079 int build(String[] args, int opti) { 13080 for (; opti<args.length; opti++) { 13081 String name = args[opti]; 13082 if ("--".equals(name)) { 13083 return opti+1; 13084 } 13085 build(name); 13086 } 13087 return opti; 13088 } 13089 13090 boolean match(Object object, ComponentName comp) { 13091 if (all) { 13092 return true; 13093 } 13094 if (components != null) { 13095 for (int i=0; i<components.size(); i++) { 13096 if (components.get(i).equals(comp)) { 13097 return true; 13098 } 13099 } 13100 } 13101 if (objects != null) { 13102 for (int i=0; i<objects.size(); i++) { 13103 if (System.identityHashCode(object) == objects.get(i)) { 13104 return true; 13105 } 13106 } 13107 } 13108 if (strings != null) { 13109 String flat = comp.flattenToString(); 13110 for (int i=0; i<strings.size(); i++) { 13111 if (flat.contains(strings.get(i))) { 13112 return true; 13113 } 13114 } 13115 } 13116 return false; 13117 } 13118 } 13119 13120 /** 13121 * There are three things that cmd can be: 13122 * - a flattened component name that matches an existing activity 13123 * - the cmd arg isn't the flattened component name of an existing activity: 13124 * dump all activity whose component contains the cmd as a substring 13125 * - A hex number of the ActivityRecord object instance. 13126 */ 13127 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13128 int opti, boolean dumpAll) { 13129 ArrayList<ActivityRecord> activities; 13130 13131 synchronized (this) { 13132 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13133 } 13134 13135 if (activities.size() <= 0) { 13136 return false; 13137 } 13138 13139 String[] newArgs = new String[args.length - opti]; 13140 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13141 13142 TaskRecord lastTask = null; 13143 boolean needSep = false; 13144 for (int i=activities.size()-1; i>=0; i--) { 13145 ActivityRecord r = activities.get(i); 13146 if (needSep) { 13147 pw.println(); 13148 } 13149 needSep = true; 13150 synchronized (this) { 13151 if (lastTask != r.task) { 13152 lastTask = r.task; 13153 pw.print("TASK "); pw.print(lastTask.affinity); 13154 pw.print(" id="); pw.println(lastTask.taskId); 13155 if (dumpAll) { 13156 lastTask.dump(pw, " "); 13157 } 13158 } 13159 } 13160 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13161 } 13162 return true; 13163 } 13164 13165 /** 13166 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13167 * there is a thread associated with the activity. 13168 */ 13169 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13170 final ActivityRecord r, String[] args, boolean dumpAll) { 13171 String innerPrefix = prefix + " "; 13172 synchronized (this) { 13173 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13174 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13175 pw.print(" pid="); 13176 if (r.app != null) pw.println(r.app.pid); 13177 else pw.println("(not running)"); 13178 if (dumpAll) { 13179 r.dump(pw, innerPrefix); 13180 } 13181 } 13182 if (r.app != null && r.app.thread != null) { 13183 // flush anything that is already in the PrintWriter since the thread is going 13184 // to write to the file descriptor directly 13185 pw.flush(); 13186 try { 13187 TransferPipe tp = new TransferPipe(); 13188 try { 13189 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13190 r.appToken, innerPrefix, args); 13191 tp.go(fd); 13192 } finally { 13193 tp.kill(); 13194 } 13195 } catch (IOException e) { 13196 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13197 } catch (RemoteException e) { 13198 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13199 } 13200 } 13201 } 13202 13203 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13204 int opti, boolean dumpAll, String dumpPackage) { 13205 boolean needSep = false; 13206 boolean onlyHistory = false; 13207 boolean printedAnything = false; 13208 13209 if ("history".equals(dumpPackage)) { 13210 if (opti < args.length && "-s".equals(args[opti])) { 13211 dumpAll = false; 13212 } 13213 onlyHistory = true; 13214 dumpPackage = null; 13215 } 13216 13217 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13218 if (!onlyHistory && dumpAll) { 13219 if (mRegisteredReceivers.size() > 0) { 13220 boolean printed = false; 13221 Iterator it = mRegisteredReceivers.values().iterator(); 13222 while (it.hasNext()) { 13223 ReceiverList r = (ReceiverList)it.next(); 13224 if (dumpPackage != null && (r.app == null || 13225 !dumpPackage.equals(r.app.info.packageName))) { 13226 continue; 13227 } 13228 if (!printed) { 13229 pw.println(" Registered Receivers:"); 13230 needSep = true; 13231 printed = true; 13232 printedAnything = true; 13233 } 13234 pw.print(" * "); pw.println(r); 13235 r.dump(pw, " "); 13236 } 13237 } 13238 13239 if (mReceiverResolver.dump(pw, needSep ? 13240 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13241 " ", dumpPackage, false)) { 13242 needSep = true; 13243 printedAnything = true; 13244 } 13245 } 13246 13247 for (BroadcastQueue q : mBroadcastQueues) { 13248 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13249 printedAnything |= needSep; 13250 } 13251 13252 needSep = true; 13253 13254 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13255 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13256 if (needSep) { 13257 pw.println(); 13258 } 13259 needSep = true; 13260 printedAnything = true; 13261 pw.print(" Sticky broadcasts for user "); 13262 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13263 StringBuilder sb = new StringBuilder(128); 13264 for (Map.Entry<String, ArrayList<Intent>> ent 13265 : mStickyBroadcasts.valueAt(user).entrySet()) { 13266 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13267 if (dumpAll) { 13268 pw.println(":"); 13269 ArrayList<Intent> intents = ent.getValue(); 13270 final int N = intents.size(); 13271 for (int i=0; i<N; i++) { 13272 sb.setLength(0); 13273 sb.append(" Intent: "); 13274 intents.get(i).toShortString(sb, false, true, false, false); 13275 pw.println(sb.toString()); 13276 Bundle bundle = intents.get(i).getExtras(); 13277 if (bundle != null) { 13278 pw.print(" "); 13279 pw.println(bundle.toString()); 13280 } 13281 } 13282 } else { 13283 pw.println(""); 13284 } 13285 } 13286 } 13287 } 13288 13289 if (!onlyHistory && dumpAll) { 13290 pw.println(); 13291 for (BroadcastQueue queue : mBroadcastQueues) { 13292 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13293 + queue.mBroadcastsScheduled); 13294 } 13295 pw.println(" mHandler:"); 13296 mHandler.dump(new PrintWriterPrinter(pw), " "); 13297 needSep = true; 13298 printedAnything = true; 13299 } 13300 13301 if (!printedAnything) { 13302 pw.println(" (nothing)"); 13303 } 13304 } 13305 13306 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13307 int opti, boolean dumpAll, String dumpPackage) { 13308 boolean needSep; 13309 boolean printedAnything = false; 13310 13311 ItemMatcher matcher = new ItemMatcher(); 13312 matcher.build(args, opti); 13313 13314 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13315 13316 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13317 printedAnything |= needSep; 13318 13319 if (mLaunchingProviders.size() > 0) { 13320 boolean printed = false; 13321 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13322 ContentProviderRecord r = mLaunchingProviders.get(i); 13323 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13324 continue; 13325 } 13326 if (!printed) { 13327 if (needSep) pw.println(); 13328 needSep = true; 13329 pw.println(" Launching content providers:"); 13330 printed = true; 13331 printedAnything = true; 13332 } 13333 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13334 pw.println(r); 13335 } 13336 } 13337 13338 if (mGrantedUriPermissions.size() > 0) { 13339 boolean printed = false; 13340 int dumpUid = -2; 13341 if (dumpPackage != null) { 13342 try { 13343 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13344 } catch (NameNotFoundException e) { 13345 dumpUid = -1; 13346 } 13347 } 13348 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13349 int uid = mGrantedUriPermissions.keyAt(i); 13350 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13351 continue; 13352 } 13353 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13354 if (!printed) { 13355 if (needSep) pw.println(); 13356 needSep = true; 13357 pw.println(" Granted Uri Permissions:"); 13358 printed = true; 13359 printedAnything = true; 13360 } 13361 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13362 for (UriPermission perm : perms.values()) { 13363 pw.print(" "); pw.println(perm); 13364 if (dumpAll) { 13365 perm.dump(pw, " "); 13366 } 13367 } 13368 } 13369 } 13370 13371 if (!printedAnything) { 13372 pw.println(" (nothing)"); 13373 } 13374 } 13375 13376 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13377 int opti, boolean dumpAll, String dumpPackage) { 13378 boolean printed = false; 13379 13380 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13381 13382 if (mIntentSenderRecords.size() > 0) { 13383 Iterator<WeakReference<PendingIntentRecord>> it 13384 = mIntentSenderRecords.values().iterator(); 13385 while (it.hasNext()) { 13386 WeakReference<PendingIntentRecord> ref = it.next(); 13387 PendingIntentRecord rec = ref != null ? ref.get(): null; 13388 if (dumpPackage != null && (rec == null 13389 || !dumpPackage.equals(rec.key.packageName))) { 13390 continue; 13391 } 13392 printed = true; 13393 if (rec != null) { 13394 pw.print(" * "); pw.println(rec); 13395 if (dumpAll) { 13396 rec.dump(pw, " "); 13397 } 13398 } else { 13399 pw.print(" * "); pw.println(ref); 13400 } 13401 } 13402 } 13403 13404 if (!printed) { 13405 pw.println(" (nothing)"); 13406 } 13407 } 13408 13409 private static final int dumpProcessList(PrintWriter pw, 13410 ActivityManagerService service, List list, 13411 String prefix, String normalLabel, String persistentLabel, 13412 String dumpPackage) { 13413 int numPers = 0; 13414 final int N = list.size()-1; 13415 for (int i=N; i>=0; i--) { 13416 ProcessRecord r = (ProcessRecord)list.get(i); 13417 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13418 continue; 13419 } 13420 pw.println(String.format("%s%s #%2d: %s", 13421 prefix, (r.persistent ? persistentLabel : normalLabel), 13422 i, r.toString())); 13423 if (r.persistent) { 13424 numPers++; 13425 } 13426 } 13427 return numPers; 13428 } 13429 13430 private static final boolean dumpProcessOomList(PrintWriter pw, 13431 ActivityManagerService service, List<ProcessRecord> origList, 13432 String prefix, String normalLabel, String persistentLabel, 13433 boolean inclDetails, String dumpPackage) { 13434 13435 ArrayList<Pair<ProcessRecord, Integer>> list 13436 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13437 for (int i=0; i<origList.size(); i++) { 13438 ProcessRecord r = origList.get(i); 13439 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13440 continue; 13441 } 13442 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13443 } 13444 13445 if (list.size() <= 0) { 13446 return false; 13447 } 13448 13449 Comparator<Pair<ProcessRecord, Integer>> comparator 13450 = new Comparator<Pair<ProcessRecord, Integer>>() { 13451 @Override 13452 public int compare(Pair<ProcessRecord, Integer> object1, 13453 Pair<ProcessRecord, Integer> object2) { 13454 if (object1.first.setAdj != object2.first.setAdj) { 13455 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13456 } 13457 if (object1.second.intValue() != object2.second.intValue()) { 13458 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13459 } 13460 return 0; 13461 } 13462 }; 13463 13464 Collections.sort(list, comparator); 13465 13466 final long curRealtime = SystemClock.elapsedRealtime(); 13467 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13468 final long curUptime = SystemClock.uptimeMillis(); 13469 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13470 13471 for (int i=list.size()-1; i>=0; i--) { 13472 ProcessRecord r = list.get(i).first; 13473 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13474 char schedGroup; 13475 switch (r.setSchedGroup) { 13476 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13477 schedGroup = 'B'; 13478 break; 13479 case Process.THREAD_GROUP_DEFAULT: 13480 schedGroup = 'F'; 13481 break; 13482 default: 13483 schedGroup = '?'; 13484 break; 13485 } 13486 char foreground; 13487 if (r.foregroundActivities) { 13488 foreground = 'A'; 13489 } else if (r.foregroundServices) { 13490 foreground = 'S'; 13491 } else { 13492 foreground = ' '; 13493 } 13494 String procState = ProcessList.makeProcStateString(r.curProcState); 13495 pw.print(prefix); 13496 pw.print(r.persistent ? persistentLabel : normalLabel); 13497 pw.print(" #"); 13498 int num = (origList.size()-1)-list.get(i).second; 13499 if (num < 10) pw.print(' '); 13500 pw.print(num); 13501 pw.print(": "); 13502 pw.print(oomAdj); 13503 pw.print(' '); 13504 pw.print(schedGroup); 13505 pw.print('/'); 13506 pw.print(foreground); 13507 pw.print('/'); 13508 pw.print(procState); 13509 pw.print(" trm:"); 13510 if (r.trimMemoryLevel < 10) pw.print(' '); 13511 pw.print(r.trimMemoryLevel); 13512 pw.print(' '); 13513 pw.print(r.toShortString()); 13514 pw.print(" ("); 13515 pw.print(r.adjType); 13516 pw.println(')'); 13517 if (r.adjSource != null || r.adjTarget != null) { 13518 pw.print(prefix); 13519 pw.print(" "); 13520 if (r.adjTarget instanceof ComponentName) { 13521 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13522 } else if (r.adjTarget != null) { 13523 pw.print(r.adjTarget.toString()); 13524 } else { 13525 pw.print("{null}"); 13526 } 13527 pw.print("<="); 13528 if (r.adjSource instanceof ProcessRecord) { 13529 pw.print("Proc{"); 13530 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13531 pw.println("}"); 13532 } else if (r.adjSource != null) { 13533 pw.println(r.adjSource.toString()); 13534 } else { 13535 pw.println("{null}"); 13536 } 13537 } 13538 if (inclDetails) { 13539 pw.print(prefix); 13540 pw.print(" "); 13541 pw.print("oom: max="); pw.print(r.maxAdj); 13542 pw.print(" curRaw="); pw.print(r.curRawAdj); 13543 pw.print(" setRaw="); pw.print(r.setRawAdj); 13544 pw.print(" cur="); pw.print(r.curAdj); 13545 pw.print(" set="); pw.println(r.setAdj); 13546 pw.print(prefix); 13547 pw.print(" "); 13548 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13549 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13550 pw.print(" lastPss="); pw.print(r.lastPss); 13551 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13552 pw.print(prefix); 13553 pw.print(" "); 13554 pw.print("cached="); pw.print(r.cached); 13555 pw.print(" empty="); pw.print(r.empty); 13556 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13557 13558 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13559 if (r.lastWakeTime != 0) { 13560 long wtime; 13561 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13562 synchronized (stats) { 13563 wtime = stats.getProcessWakeTime(r.info.uid, 13564 r.pid, curRealtime); 13565 } 13566 long timeUsed = wtime - r.lastWakeTime; 13567 pw.print(prefix); 13568 pw.print(" "); 13569 pw.print("keep awake over "); 13570 TimeUtils.formatDuration(realtimeSince, pw); 13571 pw.print(" used "); 13572 TimeUtils.formatDuration(timeUsed, pw); 13573 pw.print(" ("); 13574 pw.print((timeUsed*100)/realtimeSince); 13575 pw.println("%)"); 13576 } 13577 if (r.lastCpuTime != 0) { 13578 long timeUsed = r.curCpuTime - r.lastCpuTime; 13579 pw.print(prefix); 13580 pw.print(" "); 13581 pw.print("run cpu over "); 13582 TimeUtils.formatDuration(uptimeSince, pw); 13583 pw.print(" used "); 13584 TimeUtils.formatDuration(timeUsed, pw); 13585 pw.print(" ("); 13586 pw.print((timeUsed*100)/uptimeSince); 13587 pw.println("%)"); 13588 } 13589 } 13590 } 13591 } 13592 return true; 13593 } 13594 13595 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13596 String[] args) { 13597 ArrayList<ProcessRecord> procs; 13598 synchronized (this) { 13599 if (args != null && args.length > start 13600 && args[start].charAt(0) != '-') { 13601 procs = new ArrayList<ProcessRecord>(); 13602 int pid = -1; 13603 try { 13604 pid = Integer.parseInt(args[start]); 13605 } catch (NumberFormatException e) { 13606 } 13607 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13608 ProcessRecord proc = mLruProcesses.get(i); 13609 if (proc.pid == pid) { 13610 procs.add(proc); 13611 } else if (allPkgs && proc.pkgList != null 13612 && proc.pkgList.containsKey(args[start])) { 13613 procs.add(proc); 13614 } else if (proc.processName.equals(args[start])) { 13615 procs.add(proc); 13616 } 13617 } 13618 if (procs.size() <= 0) { 13619 return null; 13620 } 13621 } else { 13622 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13623 } 13624 } 13625 return procs; 13626 } 13627 13628 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13629 PrintWriter pw, String[] args) { 13630 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13631 if (procs == null) { 13632 pw.println("No process found for: " + args[0]); 13633 return; 13634 } 13635 13636 long uptime = SystemClock.uptimeMillis(); 13637 long realtime = SystemClock.elapsedRealtime(); 13638 pw.println("Applications Graphics Acceleration Info:"); 13639 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13640 13641 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13642 ProcessRecord r = procs.get(i); 13643 if (r.thread != null) { 13644 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13645 pw.flush(); 13646 try { 13647 TransferPipe tp = new TransferPipe(); 13648 try { 13649 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13650 tp.go(fd); 13651 } finally { 13652 tp.kill(); 13653 } 13654 } catch (IOException e) { 13655 pw.println("Failure while dumping the app: " + r); 13656 pw.flush(); 13657 } catch (RemoteException e) { 13658 pw.println("Got a RemoteException while dumping the app " + r); 13659 pw.flush(); 13660 } 13661 } 13662 } 13663 } 13664 13665 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13666 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13667 if (procs == null) { 13668 pw.println("No process found for: " + args[0]); 13669 return; 13670 } 13671 13672 pw.println("Applications Database Info:"); 13673 13674 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13675 ProcessRecord r = procs.get(i); 13676 if (r.thread != null) { 13677 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13678 pw.flush(); 13679 try { 13680 TransferPipe tp = new TransferPipe(); 13681 try { 13682 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13683 tp.go(fd); 13684 } finally { 13685 tp.kill(); 13686 } 13687 } catch (IOException e) { 13688 pw.println("Failure while dumping the app: " + r); 13689 pw.flush(); 13690 } catch (RemoteException e) { 13691 pw.println("Got a RemoteException while dumping the app " + r); 13692 pw.flush(); 13693 } 13694 } 13695 } 13696 } 13697 13698 final static class MemItem { 13699 final boolean isProc; 13700 final String label; 13701 final String shortLabel; 13702 final long pss; 13703 final int id; 13704 final boolean hasActivities; 13705 ArrayList<MemItem> subitems; 13706 13707 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13708 boolean _hasActivities) { 13709 isProc = true; 13710 label = _label; 13711 shortLabel = _shortLabel; 13712 pss = _pss; 13713 id = _id; 13714 hasActivities = _hasActivities; 13715 } 13716 13717 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13718 isProc = false; 13719 label = _label; 13720 shortLabel = _shortLabel; 13721 pss = _pss; 13722 id = _id; 13723 hasActivities = false; 13724 } 13725 } 13726 13727 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13728 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13729 if (sort && !isCompact) { 13730 Collections.sort(items, new Comparator<MemItem>() { 13731 @Override 13732 public int compare(MemItem lhs, MemItem rhs) { 13733 if (lhs.pss < rhs.pss) { 13734 return 1; 13735 } else if (lhs.pss > rhs.pss) { 13736 return -1; 13737 } 13738 return 0; 13739 } 13740 }); 13741 } 13742 13743 for (int i=0; i<items.size(); i++) { 13744 MemItem mi = items.get(i); 13745 if (!isCompact) { 13746 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13747 } else if (mi.isProc) { 13748 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13749 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13750 pw.println(mi.hasActivities ? ",a" : ",e"); 13751 } else { 13752 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13753 pw.println(mi.pss); 13754 } 13755 if (mi.subitems != null) { 13756 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13757 true, isCompact); 13758 } 13759 } 13760 } 13761 13762 // These are in KB. 13763 static final long[] DUMP_MEM_BUCKETS = new long[] { 13764 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13765 120*1024, 160*1024, 200*1024, 13766 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13767 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13768 }; 13769 13770 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13771 boolean stackLike) { 13772 int start = label.lastIndexOf('.'); 13773 if (start >= 0) start++; 13774 else start = 0; 13775 int end = label.length(); 13776 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13777 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13778 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13779 out.append(bucket); 13780 out.append(stackLike ? "MB." : "MB "); 13781 out.append(label, start, end); 13782 return; 13783 } 13784 } 13785 out.append(memKB/1024); 13786 out.append(stackLike ? "MB." : "MB "); 13787 out.append(label, start, end); 13788 } 13789 13790 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13791 ProcessList.NATIVE_ADJ, 13792 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13793 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13794 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13795 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13796 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13797 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13798 }; 13799 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13800 "Native", 13801 "System", "Persistent", "Persistent Service", "Foreground", 13802 "Visible", "Perceptible", 13803 "Heavy Weight", "Backup", 13804 "A Services", "Home", 13805 "Previous", "B Services", "Cached" 13806 }; 13807 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13808 "native", 13809 "sys", "pers", "persvc", "fore", 13810 "vis", "percept", 13811 "heavy", "backup", 13812 "servicea", "home", 13813 "prev", "serviceb", "cached" 13814 }; 13815 13816 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13817 long realtime, boolean isCheckinRequest, boolean isCompact) { 13818 if (isCheckinRequest || isCompact) { 13819 // short checkin version 13820 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13821 } else { 13822 pw.println("Applications Memory Usage (kB):"); 13823 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13824 } 13825 } 13826 13827 private static final int KSM_SHARED = 0; 13828 private static final int KSM_SHARING = 1; 13829 private static final int KSM_UNSHARED = 2; 13830 private static final int KSM_VOLATILE = 3; 13831 13832 private final long[] getKsmInfo() { 13833 long[] longOut = new long[4]; 13834 final int[] SINGLE_LONG_FORMAT = new int[] { 13835 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13836 }; 13837 long[] longTmp = new long[1]; 13838 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13839 SINGLE_LONG_FORMAT, null, longTmp, null); 13840 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13841 longTmp[0] = 0; 13842 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13843 SINGLE_LONG_FORMAT, null, longTmp, null); 13844 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13845 longTmp[0] = 0; 13846 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13847 SINGLE_LONG_FORMAT, null, longTmp, null); 13848 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13849 longTmp[0] = 0; 13850 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13851 SINGLE_LONG_FORMAT, null, longTmp, null); 13852 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13853 return longOut; 13854 } 13855 13856 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13857 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13858 boolean dumpDetails = false; 13859 boolean dumpFullDetails = false; 13860 boolean dumpDalvik = false; 13861 boolean oomOnly = false; 13862 boolean isCompact = false; 13863 boolean localOnly = false; 13864 boolean packages = false; 13865 13866 int opti = 0; 13867 while (opti < args.length) { 13868 String opt = args[opti]; 13869 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13870 break; 13871 } 13872 opti++; 13873 if ("-a".equals(opt)) { 13874 dumpDetails = true; 13875 dumpFullDetails = true; 13876 dumpDalvik = true; 13877 } else if ("-d".equals(opt)) { 13878 dumpDalvik = true; 13879 } else if ("-c".equals(opt)) { 13880 isCompact = true; 13881 } else if ("--oom".equals(opt)) { 13882 oomOnly = true; 13883 } else if ("--local".equals(opt)) { 13884 localOnly = true; 13885 } else if ("--package".equals(opt)) { 13886 packages = true; 13887 } else if ("-h".equals(opt)) { 13888 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13889 pw.println(" -a: include all available information for each process."); 13890 pw.println(" -d: include dalvik details when dumping process details."); 13891 pw.println(" -c: dump in a compact machine-parseable representation."); 13892 pw.println(" --oom: only show processes organized by oom adj."); 13893 pw.println(" --local: only collect details locally, don't call process."); 13894 pw.println(" --package: interpret process arg as package, dumping all"); 13895 pw.println(" processes that have loaded that package."); 13896 pw.println("If [process] is specified it can be the name or "); 13897 pw.println("pid of a specific process to dump."); 13898 return; 13899 } else { 13900 pw.println("Unknown argument: " + opt + "; use -h for help"); 13901 } 13902 } 13903 13904 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13905 long uptime = SystemClock.uptimeMillis(); 13906 long realtime = SystemClock.elapsedRealtime(); 13907 final long[] tmpLong = new long[1]; 13908 13909 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13910 if (procs == null) { 13911 // No Java processes. Maybe they want to print a native process. 13912 if (args != null && args.length > opti 13913 && args[opti].charAt(0) != '-') { 13914 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13915 = new ArrayList<ProcessCpuTracker.Stats>(); 13916 updateCpuStatsNow(); 13917 int findPid = -1; 13918 try { 13919 findPid = Integer.parseInt(args[opti]); 13920 } catch (NumberFormatException e) { 13921 } 13922 synchronized (mProcessCpuTracker) { 13923 final int N = mProcessCpuTracker.countStats(); 13924 for (int i=0; i<N; i++) { 13925 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13926 if (st.pid == findPid || (st.baseName != null 13927 && st.baseName.equals(args[opti]))) { 13928 nativeProcs.add(st); 13929 } 13930 } 13931 } 13932 if (nativeProcs.size() > 0) { 13933 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13934 isCompact); 13935 Debug.MemoryInfo mi = null; 13936 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13937 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13938 final int pid = r.pid; 13939 if (!isCheckinRequest && dumpDetails) { 13940 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13941 } 13942 if (mi == null) { 13943 mi = new Debug.MemoryInfo(); 13944 } 13945 if (dumpDetails || (!brief && !oomOnly)) { 13946 Debug.getMemoryInfo(pid, mi); 13947 } else { 13948 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13949 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13950 } 13951 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13952 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13953 if (isCheckinRequest) { 13954 pw.println(); 13955 } 13956 } 13957 return; 13958 } 13959 } 13960 pw.println("No process found for: " + args[opti]); 13961 return; 13962 } 13963 13964 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13965 dumpDetails = true; 13966 } 13967 13968 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13969 13970 String[] innerArgs = new String[args.length-opti]; 13971 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13972 13973 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13974 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13975 long nativePss = 0; 13976 long dalvikPss = 0; 13977 long otherPss = 0; 13978 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13979 13980 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13981 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13982 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13983 13984 long totalPss = 0; 13985 long cachedPss = 0; 13986 13987 Debug.MemoryInfo mi = null; 13988 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13989 final ProcessRecord r = procs.get(i); 13990 final IApplicationThread thread; 13991 final int pid; 13992 final int oomAdj; 13993 final boolean hasActivities; 13994 synchronized (this) { 13995 thread = r.thread; 13996 pid = r.pid; 13997 oomAdj = r.getSetAdjWithServices(); 13998 hasActivities = r.activities.size() > 0; 13999 } 14000 if (thread != null) { 14001 if (!isCheckinRequest && dumpDetails) { 14002 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14003 } 14004 if (mi == null) { 14005 mi = new Debug.MemoryInfo(); 14006 } 14007 if (dumpDetails || (!brief && !oomOnly)) { 14008 Debug.getMemoryInfo(pid, mi); 14009 } else { 14010 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14011 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14012 } 14013 if (dumpDetails) { 14014 if (localOnly) { 14015 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14016 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14017 if (isCheckinRequest) { 14018 pw.println(); 14019 } 14020 } else { 14021 try { 14022 pw.flush(); 14023 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14024 dumpDalvik, innerArgs); 14025 } catch (RemoteException e) { 14026 if (!isCheckinRequest) { 14027 pw.println("Got RemoteException!"); 14028 pw.flush(); 14029 } 14030 } 14031 } 14032 } 14033 14034 final long myTotalPss = mi.getTotalPss(); 14035 final long myTotalUss = mi.getTotalUss(); 14036 14037 synchronized (this) { 14038 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14039 // Record this for posterity if the process has been stable. 14040 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14041 } 14042 } 14043 14044 if (!isCheckinRequest && mi != null) { 14045 totalPss += myTotalPss; 14046 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14047 (hasActivities ? " / activities)" : ")"), 14048 r.processName, myTotalPss, pid, hasActivities); 14049 procMems.add(pssItem); 14050 procMemsMap.put(pid, pssItem); 14051 14052 nativePss += mi.nativePss; 14053 dalvikPss += mi.dalvikPss; 14054 otherPss += mi.otherPss; 14055 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14056 long mem = mi.getOtherPss(j); 14057 miscPss[j] += mem; 14058 otherPss -= mem; 14059 } 14060 14061 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14062 cachedPss += myTotalPss; 14063 } 14064 14065 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14066 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14067 || oomIndex == (oomPss.length-1)) { 14068 oomPss[oomIndex] += myTotalPss; 14069 if (oomProcs[oomIndex] == null) { 14070 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14071 } 14072 oomProcs[oomIndex].add(pssItem); 14073 break; 14074 } 14075 } 14076 } 14077 } 14078 } 14079 14080 long nativeProcTotalPss = 0; 14081 14082 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14083 // If we are showing aggregations, also look for native processes to 14084 // include so that our aggregations are more accurate. 14085 updateCpuStatsNow(); 14086 synchronized (mProcessCpuTracker) { 14087 final int N = mProcessCpuTracker.countStats(); 14088 for (int i=0; i<N; i++) { 14089 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14090 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14091 if (mi == null) { 14092 mi = new Debug.MemoryInfo(); 14093 } 14094 if (!brief && !oomOnly) { 14095 Debug.getMemoryInfo(st.pid, mi); 14096 } else { 14097 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14098 mi.nativePrivateDirty = (int)tmpLong[0]; 14099 } 14100 14101 final long myTotalPss = mi.getTotalPss(); 14102 totalPss += myTotalPss; 14103 nativeProcTotalPss += myTotalPss; 14104 14105 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14106 st.name, myTotalPss, st.pid, false); 14107 procMems.add(pssItem); 14108 14109 nativePss += mi.nativePss; 14110 dalvikPss += mi.dalvikPss; 14111 otherPss += mi.otherPss; 14112 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14113 long mem = mi.getOtherPss(j); 14114 miscPss[j] += mem; 14115 otherPss -= mem; 14116 } 14117 oomPss[0] += myTotalPss; 14118 if (oomProcs[0] == null) { 14119 oomProcs[0] = new ArrayList<MemItem>(); 14120 } 14121 oomProcs[0].add(pssItem); 14122 } 14123 } 14124 } 14125 14126 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14127 14128 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14129 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14130 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14131 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14132 String label = Debug.MemoryInfo.getOtherLabel(j); 14133 catMems.add(new MemItem(label, label, miscPss[j], j)); 14134 } 14135 14136 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14137 for (int j=0; j<oomPss.length; j++) { 14138 if (oomPss[j] != 0) { 14139 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14140 : DUMP_MEM_OOM_LABEL[j]; 14141 MemItem item = new MemItem(label, label, oomPss[j], 14142 DUMP_MEM_OOM_ADJ[j]); 14143 item.subitems = oomProcs[j]; 14144 oomMems.add(item); 14145 } 14146 } 14147 14148 if (!brief && !oomOnly && !isCompact) { 14149 pw.println(); 14150 pw.println("Total PSS by process:"); 14151 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14152 pw.println(); 14153 } 14154 if (!isCompact) { 14155 pw.println("Total PSS by OOM adjustment:"); 14156 } 14157 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14158 if (!brief && !oomOnly) { 14159 PrintWriter out = categoryPw != null ? categoryPw : pw; 14160 if (!isCompact) { 14161 out.println(); 14162 out.println("Total PSS by category:"); 14163 } 14164 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14165 } 14166 if (!isCompact) { 14167 pw.println(); 14168 } 14169 MemInfoReader memInfo = new MemInfoReader(); 14170 memInfo.readMemInfo(); 14171 if (nativeProcTotalPss > 0) { 14172 synchronized (this) { 14173 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14174 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14175 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14176 } 14177 } 14178 if (!brief) { 14179 if (!isCompact) { 14180 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14181 pw.print(" kB (status "); 14182 switch (mLastMemoryLevel) { 14183 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14184 pw.println("normal)"); 14185 break; 14186 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14187 pw.println("moderate)"); 14188 break; 14189 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14190 pw.println("low)"); 14191 break; 14192 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14193 pw.println("critical)"); 14194 break; 14195 default: 14196 pw.print(mLastMemoryLevel); 14197 pw.println(")"); 14198 break; 14199 } 14200 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14201 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14202 pw.print(cachedPss); pw.print(" cached pss + "); 14203 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14204 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14205 } else { 14206 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14207 pw.print(cachedPss + memInfo.getCachedSizeKb() 14208 + memInfo.getFreeSizeKb()); pw.print(","); 14209 pw.println(totalPss - cachedPss); 14210 } 14211 } 14212 if (!isCompact) { 14213 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14214 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14215 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14216 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14217 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14218 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14219 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14220 } 14221 if (!brief) { 14222 if (memInfo.getZramTotalSizeKb() != 0) { 14223 if (!isCompact) { 14224 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14225 pw.print(" kB physical used for "); 14226 pw.print(memInfo.getSwapTotalSizeKb() 14227 - memInfo.getSwapFreeSizeKb()); 14228 pw.print(" kB in swap ("); 14229 pw.print(memInfo.getSwapTotalSizeKb()); 14230 pw.println(" kB total swap)"); 14231 } else { 14232 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14233 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14234 pw.println(memInfo.getSwapFreeSizeKb()); 14235 } 14236 } 14237 final long[] ksm = getKsmInfo(); 14238 if (!isCompact) { 14239 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14240 || ksm[KSM_VOLATILE] != 0) { 14241 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14242 pw.print(" kB saved from shared "); 14243 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14244 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14245 pw.print(" kB unshared; "); 14246 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14247 } 14248 pw.print(" Tuning: "); 14249 pw.print(ActivityManager.staticGetMemoryClass()); 14250 pw.print(" (large "); 14251 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14252 pw.print("), oom "); 14253 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14254 pw.print(" kB"); 14255 pw.print(", restore limit "); 14256 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14257 pw.print(" kB"); 14258 if (ActivityManager.isLowRamDeviceStatic()) { 14259 pw.print(" (low-ram)"); 14260 } 14261 if (ActivityManager.isHighEndGfx()) { 14262 pw.print(" (high-end-gfx)"); 14263 } 14264 pw.println(); 14265 } else { 14266 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14267 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14268 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14269 pw.print("tuning,"); 14270 pw.print(ActivityManager.staticGetMemoryClass()); 14271 pw.print(','); 14272 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14273 pw.print(','); 14274 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14275 if (ActivityManager.isLowRamDeviceStatic()) { 14276 pw.print(",low-ram"); 14277 } 14278 if (ActivityManager.isHighEndGfx()) { 14279 pw.print(",high-end-gfx"); 14280 } 14281 pw.println(); 14282 } 14283 } 14284 } 14285 } 14286 14287 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14288 String name) { 14289 sb.append(" "); 14290 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14291 sb.append(' '); 14292 sb.append(ProcessList.makeProcStateString(procState)); 14293 sb.append(' '); 14294 ProcessList.appendRamKb(sb, pss); 14295 sb.append(" kB: "); 14296 sb.append(name); 14297 } 14298 14299 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14300 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14301 sb.append(" ("); 14302 sb.append(mi.pid); 14303 sb.append(") "); 14304 sb.append(mi.adjType); 14305 sb.append('\n'); 14306 if (mi.adjReason != null) { 14307 sb.append(" "); 14308 sb.append(mi.adjReason); 14309 sb.append('\n'); 14310 } 14311 } 14312 14313 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14314 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14315 for (int i=0, N=memInfos.size(); i<N; i++) { 14316 ProcessMemInfo mi = memInfos.get(i); 14317 infoMap.put(mi.pid, mi); 14318 } 14319 updateCpuStatsNow(); 14320 synchronized (mProcessCpuTracker) { 14321 final int N = mProcessCpuTracker.countStats(); 14322 for (int i=0; i<N; i++) { 14323 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14324 if (st.vsize > 0) { 14325 long pss = Debug.getPss(st.pid, null); 14326 if (pss > 0) { 14327 if (infoMap.indexOfKey(st.pid) < 0) { 14328 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14329 ProcessList.NATIVE_ADJ, -1, "native", null); 14330 mi.pss = pss; 14331 memInfos.add(mi); 14332 } 14333 } 14334 } 14335 } 14336 } 14337 14338 long totalPss = 0; 14339 for (int i=0, N=memInfos.size(); i<N; i++) { 14340 ProcessMemInfo mi = memInfos.get(i); 14341 if (mi.pss == 0) { 14342 mi.pss = Debug.getPss(mi.pid, null); 14343 } 14344 totalPss += mi.pss; 14345 } 14346 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14347 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14348 if (lhs.oomAdj != rhs.oomAdj) { 14349 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14350 } 14351 if (lhs.pss != rhs.pss) { 14352 return lhs.pss < rhs.pss ? 1 : -1; 14353 } 14354 return 0; 14355 } 14356 }); 14357 14358 StringBuilder tag = new StringBuilder(128); 14359 StringBuilder stack = new StringBuilder(128); 14360 tag.append("Low on memory -- "); 14361 appendMemBucket(tag, totalPss, "total", false); 14362 appendMemBucket(stack, totalPss, "total", true); 14363 14364 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14365 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14366 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14367 14368 boolean firstLine = true; 14369 int lastOomAdj = Integer.MIN_VALUE; 14370 long extraNativeRam = 0; 14371 long cachedPss = 0; 14372 for (int i=0, N=memInfos.size(); i<N; i++) { 14373 ProcessMemInfo mi = memInfos.get(i); 14374 14375 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14376 cachedPss += mi.pss; 14377 } 14378 14379 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14380 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14381 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14382 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14383 if (lastOomAdj != mi.oomAdj) { 14384 lastOomAdj = mi.oomAdj; 14385 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14386 tag.append(" / "); 14387 } 14388 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14389 if (firstLine) { 14390 stack.append(":"); 14391 firstLine = false; 14392 } 14393 stack.append("\n\t at "); 14394 } else { 14395 stack.append("$"); 14396 } 14397 } else { 14398 tag.append(" "); 14399 stack.append("$"); 14400 } 14401 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14402 appendMemBucket(tag, mi.pss, mi.name, false); 14403 } 14404 appendMemBucket(stack, mi.pss, mi.name, true); 14405 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14406 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14407 stack.append("("); 14408 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14409 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14410 stack.append(DUMP_MEM_OOM_LABEL[k]); 14411 stack.append(":"); 14412 stack.append(DUMP_MEM_OOM_ADJ[k]); 14413 } 14414 } 14415 stack.append(")"); 14416 } 14417 } 14418 14419 appendMemInfo(fullNativeBuilder, mi); 14420 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14421 // The short form only has native processes that are >= 1MB. 14422 if (mi.pss >= 1000) { 14423 appendMemInfo(shortNativeBuilder, mi); 14424 } else { 14425 extraNativeRam += mi.pss; 14426 } 14427 } else { 14428 // Short form has all other details, but if we have collected RAM 14429 // from smaller native processes let's dump a summary of that. 14430 if (extraNativeRam > 0) { 14431 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14432 -1, extraNativeRam, "(Other native)"); 14433 shortNativeBuilder.append('\n'); 14434 extraNativeRam = 0; 14435 } 14436 appendMemInfo(fullJavaBuilder, mi); 14437 } 14438 } 14439 14440 fullJavaBuilder.append(" "); 14441 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14442 fullJavaBuilder.append(" kB: TOTAL\n"); 14443 14444 MemInfoReader memInfo = new MemInfoReader(); 14445 memInfo.readMemInfo(); 14446 final long[] infos = memInfo.getRawInfo(); 14447 14448 StringBuilder memInfoBuilder = new StringBuilder(1024); 14449 Debug.getMemInfo(infos); 14450 memInfoBuilder.append(" MemInfo: "); 14451 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14452 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14453 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14454 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14455 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14456 memInfoBuilder.append(" "); 14457 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14458 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14459 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14460 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14461 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14462 memInfoBuilder.append(" ZRAM: "); 14463 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14464 memInfoBuilder.append(" kB RAM, "); 14465 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14466 memInfoBuilder.append(" kB swap total, "); 14467 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14468 memInfoBuilder.append(" kB swap free\n"); 14469 } 14470 final long[] ksm = getKsmInfo(); 14471 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14472 || ksm[KSM_VOLATILE] != 0) { 14473 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14474 memInfoBuilder.append(" kB saved from shared "); 14475 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14476 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14477 memInfoBuilder.append(" kB unshared; "); 14478 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14479 } 14480 memInfoBuilder.append(" Free RAM: "); 14481 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14482 + memInfo.getFreeSizeKb()); 14483 memInfoBuilder.append(" kB\n"); 14484 memInfoBuilder.append(" Used RAM: "); 14485 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14486 memInfoBuilder.append(" kB\n"); 14487 memInfoBuilder.append(" Lost RAM: "); 14488 memInfoBuilder.append(memInfo.getTotalSizeKb() 14489 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14490 - memInfo.getKernelUsedSizeKb()); 14491 memInfoBuilder.append(" kB\n"); 14492 Slog.i(TAG, "Low on memory:"); 14493 Slog.i(TAG, shortNativeBuilder.toString()); 14494 Slog.i(TAG, fullJavaBuilder.toString()); 14495 Slog.i(TAG, memInfoBuilder.toString()); 14496 14497 StringBuilder dropBuilder = new StringBuilder(1024); 14498 /* 14499 StringWriter oomSw = new StringWriter(); 14500 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14501 StringWriter catSw = new StringWriter(); 14502 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14503 String[] emptyArgs = new String[] { }; 14504 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14505 oomPw.flush(); 14506 String oomString = oomSw.toString(); 14507 */ 14508 dropBuilder.append("Low on memory:"); 14509 dropBuilder.append(stack); 14510 dropBuilder.append('\n'); 14511 dropBuilder.append(fullNativeBuilder); 14512 dropBuilder.append(fullJavaBuilder); 14513 dropBuilder.append('\n'); 14514 dropBuilder.append(memInfoBuilder); 14515 dropBuilder.append('\n'); 14516 /* 14517 dropBuilder.append(oomString); 14518 dropBuilder.append('\n'); 14519 */ 14520 StringWriter catSw = new StringWriter(); 14521 synchronized (ActivityManagerService.this) { 14522 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14523 String[] emptyArgs = new String[] { }; 14524 catPw.println(); 14525 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14526 catPw.println(); 14527 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14528 false, false, null); 14529 catPw.println(); 14530 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14531 catPw.flush(); 14532 } 14533 dropBuilder.append(catSw.toString()); 14534 addErrorToDropBox("lowmem", null, "system_server", null, 14535 null, tag.toString(), dropBuilder.toString(), null, null); 14536 //Slog.i(TAG, "Sent to dropbox:"); 14537 //Slog.i(TAG, dropBuilder.toString()); 14538 synchronized (ActivityManagerService.this) { 14539 long now = SystemClock.uptimeMillis(); 14540 if (mLastMemUsageReportTime < now) { 14541 mLastMemUsageReportTime = now; 14542 } 14543 } 14544 } 14545 14546 /** 14547 * Searches array of arguments for the specified string 14548 * @param args array of argument strings 14549 * @param value value to search for 14550 * @return true if the value is contained in the array 14551 */ 14552 private static boolean scanArgs(String[] args, String value) { 14553 if (args != null) { 14554 for (String arg : args) { 14555 if (value.equals(arg)) { 14556 return true; 14557 } 14558 } 14559 } 14560 return false; 14561 } 14562 14563 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14564 ContentProviderRecord cpr, boolean always) { 14565 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14566 14567 if (!inLaunching || always) { 14568 synchronized (cpr) { 14569 cpr.launchingApp = null; 14570 cpr.notifyAll(); 14571 } 14572 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14573 String names[] = cpr.info.authority.split(";"); 14574 for (int j = 0; j < names.length; j++) { 14575 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14576 } 14577 } 14578 14579 for (int i=0; i<cpr.connections.size(); i++) { 14580 ContentProviderConnection conn = cpr.connections.get(i); 14581 if (conn.waiting) { 14582 // If this connection is waiting for the provider, then we don't 14583 // need to mess with its process unless we are always removing 14584 // or for some reason the provider is not currently launching. 14585 if (inLaunching && !always) { 14586 continue; 14587 } 14588 } 14589 ProcessRecord capp = conn.client; 14590 conn.dead = true; 14591 if (conn.stableCount > 0) { 14592 if (!capp.persistent && capp.thread != null 14593 && capp.pid != 0 14594 && capp.pid != MY_PID) { 14595 capp.kill("depends on provider " 14596 + cpr.name.flattenToShortString() 14597 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14598 } 14599 } else if (capp.thread != null && conn.provider.provider != null) { 14600 try { 14601 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14602 } catch (RemoteException e) { 14603 } 14604 // In the protocol here, we don't expect the client to correctly 14605 // clean up this connection, we'll just remove it. 14606 cpr.connections.remove(i); 14607 conn.client.conProviders.remove(conn); 14608 } 14609 } 14610 14611 if (inLaunching && always) { 14612 mLaunchingProviders.remove(cpr); 14613 } 14614 return inLaunching; 14615 } 14616 14617 /** 14618 * Main code for cleaning up a process when it has gone away. This is 14619 * called both as a result of the process dying, or directly when stopping 14620 * a process when running in single process mode. 14621 * 14622 * @return Returns true if the given process has been restarted, so the 14623 * app that was passed in must remain on the process lists. 14624 */ 14625 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14626 boolean restarting, boolean allowRestart, int index) { 14627 if (index >= 0) { 14628 removeLruProcessLocked(app); 14629 ProcessList.remove(app.pid); 14630 } 14631 14632 mProcessesToGc.remove(app); 14633 mPendingPssProcesses.remove(app); 14634 14635 // Dismiss any open dialogs. 14636 if (app.crashDialog != null && !app.forceCrashReport) { 14637 app.crashDialog.dismiss(); 14638 app.crashDialog = null; 14639 } 14640 if (app.anrDialog != null) { 14641 app.anrDialog.dismiss(); 14642 app.anrDialog = null; 14643 } 14644 if (app.waitDialog != null) { 14645 app.waitDialog.dismiss(); 14646 app.waitDialog = null; 14647 } 14648 14649 app.crashing = false; 14650 app.notResponding = false; 14651 14652 app.resetPackageList(mProcessStats); 14653 app.unlinkDeathRecipient(); 14654 app.makeInactive(mProcessStats); 14655 app.waitingToKill = null; 14656 app.forcingToForeground = null; 14657 updateProcessForegroundLocked(app, false, false); 14658 app.foregroundActivities = false; 14659 app.hasShownUi = false; 14660 app.treatLikeActivity = false; 14661 app.hasAboveClient = false; 14662 app.hasClientActivities = false; 14663 14664 mServices.killServicesLocked(app, allowRestart); 14665 14666 boolean restart = false; 14667 14668 // Remove published content providers. 14669 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14670 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14671 final boolean always = app.bad || !allowRestart; 14672 if (removeDyingProviderLocked(app, cpr, always) || always) { 14673 // We left the provider in the launching list, need to 14674 // restart it. 14675 restart = true; 14676 } 14677 14678 cpr.provider = null; 14679 cpr.proc = null; 14680 } 14681 app.pubProviders.clear(); 14682 14683 // Take care of any launching providers waiting for this process. 14684 if (checkAppInLaunchingProvidersLocked(app, false)) { 14685 restart = true; 14686 } 14687 14688 // Unregister from connected content providers. 14689 if (!app.conProviders.isEmpty()) { 14690 for (int i=0; i<app.conProviders.size(); i++) { 14691 ContentProviderConnection conn = app.conProviders.get(i); 14692 conn.provider.connections.remove(conn); 14693 } 14694 app.conProviders.clear(); 14695 } 14696 14697 // At this point there may be remaining entries in mLaunchingProviders 14698 // where we were the only one waiting, so they are no longer of use. 14699 // Look for these and clean up if found. 14700 // XXX Commented out for now. Trying to figure out a way to reproduce 14701 // the actual situation to identify what is actually going on. 14702 if (false) { 14703 for (int i=0; i<mLaunchingProviders.size(); i++) { 14704 ContentProviderRecord cpr = (ContentProviderRecord) 14705 mLaunchingProviders.get(i); 14706 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14707 synchronized (cpr) { 14708 cpr.launchingApp = null; 14709 cpr.notifyAll(); 14710 } 14711 } 14712 } 14713 } 14714 14715 skipCurrentReceiverLocked(app); 14716 14717 // Unregister any receivers. 14718 for (int i=app.receivers.size()-1; i>=0; i--) { 14719 removeReceiverLocked(app.receivers.valueAt(i)); 14720 } 14721 app.receivers.clear(); 14722 14723 // If the app is undergoing backup, tell the backup manager about it 14724 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14725 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14726 + mBackupTarget.appInfo + " died during backup"); 14727 try { 14728 IBackupManager bm = IBackupManager.Stub.asInterface( 14729 ServiceManager.getService(Context.BACKUP_SERVICE)); 14730 bm.agentDisconnected(app.info.packageName); 14731 } catch (RemoteException e) { 14732 // can't happen; backup manager is local 14733 } 14734 } 14735 14736 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14737 ProcessChangeItem item = mPendingProcessChanges.get(i); 14738 if (item.pid == app.pid) { 14739 mPendingProcessChanges.remove(i); 14740 mAvailProcessChanges.add(item); 14741 } 14742 } 14743 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14744 14745 // If the caller is restarting this app, then leave it in its 14746 // current lists and let the caller take care of it. 14747 if (restarting) { 14748 return false; 14749 } 14750 14751 if (!app.persistent || app.isolated) { 14752 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14753 "Removing non-persistent process during cleanup: " + app); 14754 mProcessNames.remove(app.processName, app.uid); 14755 mIsolatedProcesses.remove(app.uid); 14756 if (mHeavyWeightProcess == app) { 14757 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14758 mHeavyWeightProcess.userId, 0)); 14759 mHeavyWeightProcess = null; 14760 } 14761 } else if (!app.removed) { 14762 // This app is persistent, so we need to keep its record around. 14763 // If it is not already on the pending app list, add it there 14764 // and start a new process for it. 14765 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14766 mPersistentStartingProcesses.add(app); 14767 restart = true; 14768 } 14769 } 14770 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14771 "Clean-up removing on hold: " + app); 14772 mProcessesOnHold.remove(app); 14773 14774 if (app == mHomeProcess) { 14775 mHomeProcess = null; 14776 } 14777 if (app == mPreviousProcess) { 14778 mPreviousProcess = null; 14779 } 14780 14781 if (restart && !app.isolated) { 14782 // We have components that still need to be running in the 14783 // process, so re-launch it. 14784 if (index < 0) { 14785 ProcessList.remove(app.pid); 14786 } 14787 mProcessNames.put(app.processName, app.uid, app); 14788 startProcessLocked(app, "restart", app.processName); 14789 return true; 14790 } else if (app.pid > 0 && app.pid != MY_PID) { 14791 // Goodbye! 14792 boolean removed; 14793 synchronized (mPidsSelfLocked) { 14794 mPidsSelfLocked.remove(app.pid); 14795 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14796 } 14797 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14798 if (app.isolated) { 14799 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14800 } 14801 app.setPid(0); 14802 } 14803 return false; 14804 } 14805 14806 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14807 // Look through the content providers we are waiting to have launched, 14808 // and if any run in this process then either schedule a restart of 14809 // the process or kill the client waiting for it if this process has 14810 // gone bad. 14811 int NL = mLaunchingProviders.size(); 14812 boolean restart = false; 14813 for (int i=0; i<NL; i++) { 14814 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14815 if (cpr.launchingApp == app) { 14816 if (!alwaysBad && !app.bad) { 14817 restart = true; 14818 } else { 14819 removeDyingProviderLocked(app, cpr, true); 14820 // cpr should have been removed from mLaunchingProviders 14821 NL = mLaunchingProviders.size(); 14822 i--; 14823 } 14824 } 14825 } 14826 return restart; 14827 } 14828 14829 // ========================================================= 14830 // SERVICES 14831 // ========================================================= 14832 14833 @Override 14834 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14835 int flags) { 14836 enforceNotIsolatedCaller("getServices"); 14837 synchronized (this) { 14838 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14839 } 14840 } 14841 14842 @Override 14843 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14844 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14845 synchronized (this) { 14846 return mServices.getRunningServiceControlPanelLocked(name); 14847 } 14848 } 14849 14850 @Override 14851 public ComponentName startService(IApplicationThread caller, Intent service, 14852 String resolvedType, int userId) { 14853 enforceNotIsolatedCaller("startService"); 14854 // Refuse possible leaked file descriptors 14855 if (service != null && service.hasFileDescriptors() == true) { 14856 throw new IllegalArgumentException("File descriptors passed in Intent"); 14857 } 14858 14859 if (DEBUG_SERVICE) 14860 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14861 synchronized(this) { 14862 final int callingPid = Binder.getCallingPid(); 14863 final int callingUid = Binder.getCallingUid(); 14864 final long origId = Binder.clearCallingIdentity(); 14865 ComponentName res = mServices.startServiceLocked(caller, service, 14866 resolvedType, callingPid, callingUid, userId); 14867 Binder.restoreCallingIdentity(origId); 14868 return res; 14869 } 14870 } 14871 14872 ComponentName startServiceInPackage(int uid, 14873 Intent service, String resolvedType, int userId) { 14874 synchronized(this) { 14875 if (DEBUG_SERVICE) 14876 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14877 final long origId = Binder.clearCallingIdentity(); 14878 ComponentName res = mServices.startServiceLocked(null, service, 14879 resolvedType, -1, uid, userId); 14880 Binder.restoreCallingIdentity(origId); 14881 return res; 14882 } 14883 } 14884 14885 @Override 14886 public int stopService(IApplicationThread caller, Intent service, 14887 String resolvedType, int userId) { 14888 enforceNotIsolatedCaller("stopService"); 14889 // Refuse possible leaked file descriptors 14890 if (service != null && service.hasFileDescriptors() == true) { 14891 throw new IllegalArgumentException("File descriptors passed in Intent"); 14892 } 14893 14894 synchronized(this) { 14895 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14896 } 14897 } 14898 14899 @Override 14900 public IBinder peekService(Intent service, String resolvedType) { 14901 enforceNotIsolatedCaller("peekService"); 14902 // Refuse possible leaked file descriptors 14903 if (service != null && service.hasFileDescriptors() == true) { 14904 throw new IllegalArgumentException("File descriptors passed in Intent"); 14905 } 14906 synchronized(this) { 14907 return mServices.peekServiceLocked(service, resolvedType); 14908 } 14909 } 14910 14911 @Override 14912 public boolean stopServiceToken(ComponentName className, IBinder token, 14913 int startId) { 14914 synchronized(this) { 14915 return mServices.stopServiceTokenLocked(className, token, startId); 14916 } 14917 } 14918 14919 @Override 14920 public void setServiceForeground(ComponentName className, IBinder token, 14921 int id, Notification notification, boolean removeNotification) { 14922 synchronized(this) { 14923 mServices.setServiceForegroundLocked(className, token, id, notification, 14924 removeNotification); 14925 } 14926 } 14927 14928 @Override 14929 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14930 boolean requireFull, String name, String callerPackage) { 14931 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14932 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14933 } 14934 14935 int unsafeConvertIncomingUser(int userId) { 14936 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14937 ? mCurrentUserId : userId; 14938 } 14939 14940 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14941 int allowMode, String name, String callerPackage) { 14942 final int callingUserId = UserHandle.getUserId(callingUid); 14943 if (callingUserId == userId) { 14944 return userId; 14945 } 14946 14947 // Note that we may be accessing mCurrentUserId outside of a lock... 14948 // shouldn't be a big deal, if this is being called outside 14949 // of a locked context there is intrinsically a race with 14950 // the value the caller will receive and someone else changing it. 14951 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14952 // we will switch to the calling user if access to the current user fails. 14953 int targetUserId = unsafeConvertIncomingUser(userId); 14954 14955 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14956 final boolean allow; 14957 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14958 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14959 // If the caller has this permission, they always pass go. And collect $200. 14960 allow = true; 14961 } else if (allowMode == ALLOW_FULL_ONLY) { 14962 // We require full access, sucks to be you. 14963 allow = false; 14964 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14965 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14966 // If the caller does not have either permission, they are always doomed. 14967 allow = false; 14968 } else if (allowMode == ALLOW_NON_FULL) { 14969 // We are blanket allowing non-full access, you lucky caller! 14970 allow = true; 14971 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14972 // We may or may not allow this depending on whether the two users are 14973 // in the same profile. 14974 synchronized (mUserProfileGroupIdsSelfLocked) { 14975 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14976 UserInfo.NO_PROFILE_GROUP_ID); 14977 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14978 UserInfo.NO_PROFILE_GROUP_ID); 14979 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14980 && callingProfile == targetProfile; 14981 } 14982 } else { 14983 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14984 } 14985 if (!allow) { 14986 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14987 // In this case, they would like to just execute as their 14988 // owner user instead of failing. 14989 targetUserId = callingUserId; 14990 } else { 14991 StringBuilder builder = new StringBuilder(128); 14992 builder.append("Permission Denial: "); 14993 builder.append(name); 14994 if (callerPackage != null) { 14995 builder.append(" from "); 14996 builder.append(callerPackage); 14997 } 14998 builder.append(" asks to run as user "); 14999 builder.append(userId); 15000 builder.append(" but is calling from user "); 15001 builder.append(UserHandle.getUserId(callingUid)); 15002 builder.append("; this requires "); 15003 builder.append(INTERACT_ACROSS_USERS_FULL); 15004 if (allowMode != ALLOW_FULL_ONLY) { 15005 builder.append(" or "); 15006 builder.append(INTERACT_ACROSS_USERS); 15007 } 15008 String msg = builder.toString(); 15009 Slog.w(TAG, msg); 15010 throw new SecurityException(msg); 15011 } 15012 } 15013 } 15014 if (!allowAll && targetUserId < 0) { 15015 throw new IllegalArgumentException( 15016 "Call does not support special user #" + targetUserId); 15017 } 15018 // Check shell permission 15019 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15020 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15021 targetUserId)) { 15022 throw new SecurityException("Shell does not have permission to access user " 15023 + targetUserId + "\n " + Debug.getCallers(3)); 15024 } 15025 } 15026 return targetUserId; 15027 } 15028 15029 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15030 String className, int flags) { 15031 boolean result = false; 15032 // For apps that don't have pre-defined UIDs, check for permission 15033 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15034 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15035 if (ActivityManager.checkUidPermission( 15036 INTERACT_ACROSS_USERS, 15037 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15038 ComponentName comp = new ComponentName(aInfo.packageName, className); 15039 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15040 + " requests FLAG_SINGLE_USER, but app does not hold " 15041 + INTERACT_ACROSS_USERS; 15042 Slog.w(TAG, msg); 15043 throw new SecurityException(msg); 15044 } 15045 // Permission passed 15046 result = true; 15047 } 15048 } else if ("system".equals(componentProcessName)) { 15049 result = true; 15050 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15051 // Phone app and persistent apps are allowed to export singleuser providers. 15052 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15053 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15054 } 15055 if (DEBUG_MU) { 15056 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15057 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15058 } 15059 return result; 15060 } 15061 15062 /** 15063 * Checks to see if the caller is in the same app as the singleton 15064 * component, or the component is in a special app. It allows special apps 15065 * to export singleton components but prevents exporting singleton 15066 * components for regular apps. 15067 */ 15068 boolean isValidSingletonCall(int callingUid, int componentUid) { 15069 int componentAppId = UserHandle.getAppId(componentUid); 15070 return UserHandle.isSameApp(callingUid, componentUid) 15071 || componentAppId == Process.SYSTEM_UID 15072 || componentAppId == Process.PHONE_UID 15073 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15074 == PackageManager.PERMISSION_GRANTED; 15075 } 15076 15077 public int bindService(IApplicationThread caller, IBinder token, 15078 Intent service, String resolvedType, 15079 IServiceConnection connection, int flags, int userId) { 15080 enforceNotIsolatedCaller("bindService"); 15081 15082 // Refuse possible leaked file descriptors 15083 if (service != null && service.hasFileDescriptors() == true) { 15084 throw new IllegalArgumentException("File descriptors passed in Intent"); 15085 } 15086 15087 synchronized(this) { 15088 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15089 connection, flags, userId); 15090 } 15091 } 15092 15093 public boolean unbindService(IServiceConnection connection) { 15094 synchronized (this) { 15095 return mServices.unbindServiceLocked(connection); 15096 } 15097 } 15098 15099 public void publishService(IBinder token, Intent intent, IBinder service) { 15100 // Refuse possible leaked file descriptors 15101 if (intent != null && intent.hasFileDescriptors() == true) { 15102 throw new IllegalArgumentException("File descriptors passed in Intent"); 15103 } 15104 15105 synchronized(this) { 15106 if (!(token instanceof ServiceRecord)) { 15107 throw new IllegalArgumentException("Invalid service token"); 15108 } 15109 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15110 } 15111 } 15112 15113 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15114 // Refuse possible leaked file descriptors 15115 if (intent != null && intent.hasFileDescriptors() == true) { 15116 throw new IllegalArgumentException("File descriptors passed in Intent"); 15117 } 15118 15119 synchronized(this) { 15120 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15121 } 15122 } 15123 15124 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15125 synchronized(this) { 15126 if (!(token instanceof ServiceRecord)) { 15127 throw new IllegalArgumentException("Invalid service token"); 15128 } 15129 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15130 } 15131 } 15132 15133 // ========================================================= 15134 // BACKUP AND RESTORE 15135 // ========================================================= 15136 15137 // Cause the target app to be launched if necessary and its backup agent 15138 // instantiated. The backup agent will invoke backupAgentCreated() on the 15139 // activity manager to announce its creation. 15140 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15141 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15142 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15143 15144 synchronized(this) { 15145 // !!! TODO: currently no check here that we're already bound 15146 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15147 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15148 synchronized (stats) { 15149 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15150 } 15151 15152 // Backup agent is now in use, its package can't be stopped. 15153 try { 15154 AppGlobals.getPackageManager().setPackageStoppedState( 15155 app.packageName, false, UserHandle.getUserId(app.uid)); 15156 } catch (RemoteException e) { 15157 } catch (IllegalArgumentException e) { 15158 Slog.w(TAG, "Failed trying to unstop package " 15159 + app.packageName + ": " + e); 15160 } 15161 15162 BackupRecord r = new BackupRecord(ss, app, backupMode); 15163 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15164 ? new ComponentName(app.packageName, app.backupAgentName) 15165 : new ComponentName("android", "FullBackupAgent"); 15166 // startProcessLocked() returns existing proc's record if it's already running 15167 ProcessRecord proc = startProcessLocked(app.processName, app, 15168 false, 0, "backup", hostingName, false, false, false); 15169 if (proc == null) { 15170 Slog.e(TAG, "Unable to start backup agent process " + r); 15171 return false; 15172 } 15173 15174 r.app = proc; 15175 mBackupTarget = r; 15176 mBackupAppName = app.packageName; 15177 15178 // Try not to kill the process during backup 15179 updateOomAdjLocked(proc); 15180 15181 // If the process is already attached, schedule the creation of the backup agent now. 15182 // If it is not yet live, this will be done when it attaches to the framework. 15183 if (proc.thread != null) { 15184 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15185 try { 15186 proc.thread.scheduleCreateBackupAgent(app, 15187 compatibilityInfoForPackageLocked(app), backupMode); 15188 } catch (RemoteException e) { 15189 // Will time out on the backup manager side 15190 } 15191 } else { 15192 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15193 } 15194 // Invariants: at this point, the target app process exists and the application 15195 // is either already running or in the process of coming up. mBackupTarget and 15196 // mBackupAppName describe the app, so that when it binds back to the AM we 15197 // know that it's scheduled for a backup-agent operation. 15198 } 15199 15200 return true; 15201 } 15202 15203 @Override 15204 public void clearPendingBackup() { 15205 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15206 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15207 15208 synchronized (this) { 15209 mBackupTarget = null; 15210 mBackupAppName = null; 15211 } 15212 } 15213 15214 // A backup agent has just come up 15215 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15216 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15217 + " = " + agent); 15218 15219 synchronized(this) { 15220 if (!agentPackageName.equals(mBackupAppName)) { 15221 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15222 return; 15223 } 15224 } 15225 15226 long oldIdent = Binder.clearCallingIdentity(); 15227 try { 15228 IBackupManager bm = IBackupManager.Stub.asInterface( 15229 ServiceManager.getService(Context.BACKUP_SERVICE)); 15230 bm.agentConnected(agentPackageName, agent); 15231 } catch (RemoteException e) { 15232 // can't happen; the backup manager service is local 15233 } catch (Exception e) { 15234 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15235 e.printStackTrace(); 15236 } finally { 15237 Binder.restoreCallingIdentity(oldIdent); 15238 } 15239 } 15240 15241 // done with this agent 15242 public void unbindBackupAgent(ApplicationInfo appInfo) { 15243 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15244 if (appInfo == null) { 15245 Slog.w(TAG, "unbind backup agent for null app"); 15246 return; 15247 } 15248 15249 synchronized(this) { 15250 try { 15251 if (mBackupAppName == null) { 15252 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15253 return; 15254 } 15255 15256 if (!mBackupAppName.equals(appInfo.packageName)) { 15257 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15258 return; 15259 } 15260 15261 // Not backing this app up any more; reset its OOM adjustment 15262 final ProcessRecord proc = mBackupTarget.app; 15263 updateOomAdjLocked(proc); 15264 15265 // If the app crashed during backup, 'thread' will be null here 15266 if (proc.thread != null) { 15267 try { 15268 proc.thread.scheduleDestroyBackupAgent(appInfo, 15269 compatibilityInfoForPackageLocked(appInfo)); 15270 } catch (Exception e) { 15271 Slog.e(TAG, "Exception when unbinding backup agent:"); 15272 e.printStackTrace(); 15273 } 15274 } 15275 } finally { 15276 mBackupTarget = null; 15277 mBackupAppName = null; 15278 } 15279 } 15280 } 15281 // ========================================================= 15282 // BROADCASTS 15283 // ========================================================= 15284 15285 private final List getStickiesLocked(String action, IntentFilter filter, 15286 List cur, int userId) { 15287 final ContentResolver resolver = mContext.getContentResolver(); 15288 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15289 if (stickies == null) { 15290 return cur; 15291 } 15292 final ArrayList<Intent> list = stickies.get(action); 15293 if (list == null) { 15294 return cur; 15295 } 15296 int N = list.size(); 15297 for (int i=0; i<N; i++) { 15298 Intent intent = list.get(i); 15299 if (filter.match(resolver, intent, true, TAG) >= 0) { 15300 if (cur == null) { 15301 cur = new ArrayList<Intent>(); 15302 } 15303 cur.add(intent); 15304 } 15305 } 15306 return cur; 15307 } 15308 15309 boolean isPendingBroadcastProcessLocked(int pid) { 15310 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15311 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15312 } 15313 15314 void skipPendingBroadcastLocked(int pid) { 15315 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15316 for (BroadcastQueue queue : mBroadcastQueues) { 15317 queue.skipPendingBroadcastLocked(pid); 15318 } 15319 } 15320 15321 // The app just attached; send any pending broadcasts that it should receive 15322 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15323 boolean didSomething = false; 15324 for (BroadcastQueue queue : mBroadcastQueues) { 15325 didSomething |= queue.sendPendingBroadcastsLocked(app); 15326 } 15327 return didSomething; 15328 } 15329 15330 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15331 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15332 enforceNotIsolatedCaller("registerReceiver"); 15333 int callingUid; 15334 int callingPid; 15335 synchronized(this) { 15336 ProcessRecord callerApp = null; 15337 if (caller != null) { 15338 callerApp = getRecordForAppLocked(caller); 15339 if (callerApp == null) { 15340 throw new SecurityException( 15341 "Unable to find app for caller " + caller 15342 + " (pid=" + Binder.getCallingPid() 15343 + ") when registering receiver " + receiver); 15344 } 15345 if (callerApp.info.uid != Process.SYSTEM_UID && 15346 !callerApp.pkgList.containsKey(callerPackage) && 15347 !"android".equals(callerPackage)) { 15348 throw new SecurityException("Given caller package " + callerPackage 15349 + " is not running in process " + callerApp); 15350 } 15351 callingUid = callerApp.info.uid; 15352 callingPid = callerApp.pid; 15353 } else { 15354 callerPackage = null; 15355 callingUid = Binder.getCallingUid(); 15356 callingPid = Binder.getCallingPid(); 15357 } 15358 15359 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15360 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15361 15362 List allSticky = null; 15363 15364 // Look for any matching sticky broadcasts... 15365 Iterator actions = filter.actionsIterator(); 15366 if (actions != null) { 15367 while (actions.hasNext()) { 15368 String action = (String)actions.next(); 15369 allSticky = getStickiesLocked(action, filter, allSticky, 15370 UserHandle.USER_ALL); 15371 allSticky = getStickiesLocked(action, filter, allSticky, 15372 UserHandle.getUserId(callingUid)); 15373 } 15374 } else { 15375 allSticky = getStickiesLocked(null, filter, allSticky, 15376 UserHandle.USER_ALL); 15377 allSticky = getStickiesLocked(null, filter, allSticky, 15378 UserHandle.getUserId(callingUid)); 15379 } 15380 15381 // The first sticky in the list is returned directly back to 15382 // the client. 15383 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15384 15385 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15386 + ": " + sticky); 15387 15388 if (receiver == null) { 15389 return sticky; 15390 } 15391 15392 ReceiverList rl 15393 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15394 if (rl == null) { 15395 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15396 userId, receiver); 15397 if (rl.app != null) { 15398 rl.app.receivers.add(rl); 15399 } else { 15400 try { 15401 receiver.asBinder().linkToDeath(rl, 0); 15402 } catch (RemoteException e) { 15403 return sticky; 15404 } 15405 rl.linkedToDeath = true; 15406 } 15407 mRegisteredReceivers.put(receiver.asBinder(), rl); 15408 } else if (rl.uid != callingUid) { 15409 throw new IllegalArgumentException( 15410 "Receiver requested to register for uid " + callingUid 15411 + " was previously registered for uid " + rl.uid); 15412 } else if (rl.pid != callingPid) { 15413 throw new IllegalArgumentException( 15414 "Receiver requested to register for pid " + callingPid 15415 + " was previously registered for pid " + rl.pid); 15416 } else if (rl.userId != userId) { 15417 throw new IllegalArgumentException( 15418 "Receiver requested to register for user " + userId 15419 + " was previously registered for user " + rl.userId); 15420 } 15421 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15422 permission, callingUid, userId); 15423 rl.add(bf); 15424 if (!bf.debugCheck()) { 15425 Slog.w(TAG, "==> For Dynamic broadast"); 15426 } 15427 mReceiverResolver.addFilter(bf); 15428 15429 // Enqueue broadcasts for all existing stickies that match 15430 // this filter. 15431 if (allSticky != null) { 15432 ArrayList receivers = new ArrayList(); 15433 receivers.add(bf); 15434 15435 int N = allSticky.size(); 15436 for (int i=0; i<N; i++) { 15437 Intent intent = (Intent)allSticky.get(i); 15438 BroadcastQueue queue = broadcastQueueForIntent(intent); 15439 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15440 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15441 null, null, false, true, true, -1); 15442 queue.enqueueParallelBroadcastLocked(r); 15443 queue.scheduleBroadcastsLocked(); 15444 } 15445 } 15446 15447 return sticky; 15448 } 15449 } 15450 15451 public void unregisterReceiver(IIntentReceiver receiver) { 15452 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15453 15454 final long origId = Binder.clearCallingIdentity(); 15455 try { 15456 boolean doTrim = false; 15457 15458 synchronized(this) { 15459 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15460 if (rl != null) { 15461 if (rl.curBroadcast != null) { 15462 BroadcastRecord r = rl.curBroadcast; 15463 final boolean doNext = finishReceiverLocked( 15464 receiver.asBinder(), r.resultCode, r.resultData, 15465 r.resultExtras, r.resultAbort); 15466 if (doNext) { 15467 doTrim = true; 15468 r.queue.processNextBroadcast(false); 15469 } 15470 } 15471 15472 if (rl.app != null) { 15473 rl.app.receivers.remove(rl); 15474 } 15475 removeReceiverLocked(rl); 15476 if (rl.linkedToDeath) { 15477 rl.linkedToDeath = false; 15478 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15479 } 15480 } 15481 } 15482 15483 // If we actually concluded any broadcasts, we might now be able 15484 // to trim the recipients' apps from our working set 15485 if (doTrim) { 15486 trimApplications(); 15487 return; 15488 } 15489 15490 } finally { 15491 Binder.restoreCallingIdentity(origId); 15492 } 15493 } 15494 15495 void removeReceiverLocked(ReceiverList rl) { 15496 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15497 int N = rl.size(); 15498 for (int i=0; i<N; i++) { 15499 mReceiverResolver.removeFilter(rl.get(i)); 15500 } 15501 } 15502 15503 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15504 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15505 ProcessRecord r = mLruProcesses.get(i); 15506 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15507 try { 15508 r.thread.dispatchPackageBroadcast(cmd, packages); 15509 } catch (RemoteException ex) { 15510 } 15511 } 15512 } 15513 } 15514 15515 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15516 int callingUid, int[] users) { 15517 List<ResolveInfo> receivers = null; 15518 try { 15519 HashSet<ComponentName> singleUserReceivers = null; 15520 boolean scannedFirstReceivers = false; 15521 for (int user : users) { 15522 // Skip users that have Shell restrictions 15523 if (callingUid == Process.SHELL_UID 15524 && getUserManagerLocked().hasUserRestriction( 15525 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15526 continue; 15527 } 15528 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15529 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15530 if (user != 0 && newReceivers != null) { 15531 // If this is not the primary user, we need to check for 15532 // any receivers that should be filtered out. 15533 for (int i=0; i<newReceivers.size(); i++) { 15534 ResolveInfo ri = newReceivers.get(i); 15535 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15536 newReceivers.remove(i); 15537 i--; 15538 } 15539 } 15540 } 15541 if (newReceivers != null && newReceivers.size() == 0) { 15542 newReceivers = null; 15543 } 15544 if (receivers == null) { 15545 receivers = newReceivers; 15546 } else if (newReceivers != null) { 15547 // We need to concatenate the additional receivers 15548 // found with what we have do far. This would be easy, 15549 // but we also need to de-dup any receivers that are 15550 // singleUser. 15551 if (!scannedFirstReceivers) { 15552 // Collect any single user receivers we had already retrieved. 15553 scannedFirstReceivers = true; 15554 for (int i=0; i<receivers.size(); i++) { 15555 ResolveInfo ri = receivers.get(i); 15556 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15557 ComponentName cn = new ComponentName( 15558 ri.activityInfo.packageName, ri.activityInfo.name); 15559 if (singleUserReceivers == null) { 15560 singleUserReceivers = new HashSet<ComponentName>(); 15561 } 15562 singleUserReceivers.add(cn); 15563 } 15564 } 15565 } 15566 // Add the new results to the existing results, tracking 15567 // and de-dupping single user receivers. 15568 for (int i=0; i<newReceivers.size(); i++) { 15569 ResolveInfo ri = newReceivers.get(i); 15570 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15571 ComponentName cn = new ComponentName( 15572 ri.activityInfo.packageName, ri.activityInfo.name); 15573 if (singleUserReceivers == null) { 15574 singleUserReceivers = new HashSet<ComponentName>(); 15575 } 15576 if (!singleUserReceivers.contains(cn)) { 15577 singleUserReceivers.add(cn); 15578 receivers.add(ri); 15579 } 15580 } else { 15581 receivers.add(ri); 15582 } 15583 } 15584 } 15585 } 15586 } catch (RemoteException ex) { 15587 // pm is in same process, this will never happen. 15588 } 15589 return receivers; 15590 } 15591 15592 private final int broadcastIntentLocked(ProcessRecord callerApp, 15593 String callerPackage, Intent intent, String resolvedType, 15594 IIntentReceiver resultTo, int resultCode, String resultData, 15595 Bundle map, String requiredPermission, int appOp, 15596 boolean ordered, boolean sticky, int callingPid, int callingUid, 15597 int userId) { 15598 intent = new Intent(intent); 15599 15600 // By default broadcasts do not go to stopped apps. 15601 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15602 15603 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15604 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15605 + " ordered=" + ordered + " userid=" + userId); 15606 if ((resultTo != null) && !ordered) { 15607 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15608 } 15609 15610 userId = handleIncomingUser(callingPid, callingUid, userId, 15611 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15612 15613 // Make sure that the user who is receiving this broadcast is started. 15614 // If not, we will just skip it. 15615 15616 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15617 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15618 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15619 Slog.w(TAG, "Skipping broadcast of " + intent 15620 + ": user " + userId + " is stopped"); 15621 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15622 } 15623 } 15624 15625 /* 15626 * Prevent non-system code (defined here to be non-persistent 15627 * processes) from sending protected broadcasts. 15628 */ 15629 int callingAppId = UserHandle.getAppId(callingUid); 15630 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15631 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15632 || callingAppId == Process.NFC_UID || callingUid == 0) { 15633 // Always okay. 15634 } else if (callerApp == null || !callerApp.persistent) { 15635 try { 15636 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15637 intent.getAction())) { 15638 String msg = "Permission Denial: not allowed to send broadcast " 15639 + intent.getAction() + " from pid=" 15640 + callingPid + ", uid=" + callingUid; 15641 Slog.w(TAG, msg); 15642 throw new SecurityException(msg); 15643 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15644 // Special case for compatibility: we don't want apps to send this, 15645 // but historically it has not been protected and apps may be using it 15646 // to poke their own app widget. So, instead of making it protected, 15647 // just limit it to the caller. 15648 if (callerApp == null) { 15649 String msg = "Permission Denial: not allowed to send broadcast " 15650 + intent.getAction() + " from unknown caller."; 15651 Slog.w(TAG, msg); 15652 throw new SecurityException(msg); 15653 } else if (intent.getComponent() != null) { 15654 // They are good enough to send to an explicit component... verify 15655 // it is being sent to the calling app. 15656 if (!intent.getComponent().getPackageName().equals( 15657 callerApp.info.packageName)) { 15658 String msg = "Permission Denial: not allowed to send broadcast " 15659 + intent.getAction() + " to " 15660 + intent.getComponent().getPackageName() + " from " 15661 + callerApp.info.packageName; 15662 Slog.w(TAG, msg); 15663 throw new SecurityException(msg); 15664 } 15665 } else { 15666 // Limit broadcast to their own package. 15667 intent.setPackage(callerApp.info.packageName); 15668 } 15669 } 15670 } catch (RemoteException e) { 15671 Slog.w(TAG, "Remote exception", e); 15672 return ActivityManager.BROADCAST_SUCCESS; 15673 } 15674 } 15675 15676 // Handle special intents: if this broadcast is from the package 15677 // manager about a package being removed, we need to remove all of 15678 // its activities from the history stack. 15679 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15680 intent.getAction()); 15681 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15682 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15683 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15684 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15685 || uidRemoved) { 15686 if (checkComponentPermission( 15687 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15688 callingPid, callingUid, -1, true) 15689 == PackageManager.PERMISSION_GRANTED) { 15690 if (uidRemoved) { 15691 final Bundle intentExtras = intent.getExtras(); 15692 final int uid = intentExtras != null 15693 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15694 if (uid >= 0) { 15695 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15696 synchronized (bs) { 15697 bs.removeUidStatsLocked(uid); 15698 } 15699 mAppOpsService.uidRemoved(uid); 15700 } 15701 } else { 15702 // If resources are unavailable just force stop all 15703 // those packages and flush the attribute cache as well. 15704 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15705 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15706 if (list != null && (list.length > 0)) { 15707 for (String pkg : list) { 15708 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15709 "storage unmount"); 15710 } 15711 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15712 sendPackageBroadcastLocked( 15713 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15714 } 15715 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15716 intent.getAction())) { 15717 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15718 } else { 15719 Uri data = intent.getData(); 15720 String ssp; 15721 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15722 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15723 intent.getAction()); 15724 boolean fullUninstall = removed && 15725 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15726 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15727 forceStopPackageLocked(ssp, UserHandle.getAppId( 15728 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15729 false, fullUninstall, userId, 15730 removed ? "pkg removed" : "pkg changed"); 15731 } 15732 if (removed) { 15733 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15734 new String[] {ssp}, userId); 15735 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15736 mAppOpsService.packageRemoved( 15737 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15738 15739 // Remove all permissions granted from/to this package 15740 removeUriPermissionsForPackageLocked(ssp, userId, true); 15741 } 15742 } 15743 } 15744 } 15745 } 15746 } else { 15747 String msg = "Permission Denial: " + intent.getAction() 15748 + " broadcast from " + callerPackage + " (pid=" + callingPid 15749 + ", uid=" + callingUid + ")" 15750 + " requires " 15751 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15752 Slog.w(TAG, msg); 15753 throw new SecurityException(msg); 15754 } 15755 15756 // Special case for adding a package: by default turn on compatibility 15757 // mode. 15758 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15759 Uri data = intent.getData(); 15760 String ssp; 15761 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15762 mCompatModePackages.handlePackageAddedLocked(ssp, 15763 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15764 } 15765 } 15766 15767 /* 15768 * If this is the time zone changed action, queue up a message that will reset the timezone 15769 * of all currently running processes. This message will get queued up before the broadcast 15770 * happens. 15771 */ 15772 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15773 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15774 } 15775 15776 /* 15777 * If the user set the time, let all running processes know. 15778 */ 15779 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15780 final int is24Hour = intent.getBooleanExtra( 15781 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15782 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15783 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15784 synchronized (stats) { 15785 stats.noteCurrentTimeChangedLocked(); 15786 } 15787 } 15788 15789 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15790 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15791 } 15792 15793 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15794 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15795 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15796 } 15797 15798 // Add to the sticky list if requested. 15799 if (sticky) { 15800 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15801 callingPid, callingUid) 15802 != PackageManager.PERMISSION_GRANTED) { 15803 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15804 + callingPid + ", uid=" + callingUid 15805 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15806 Slog.w(TAG, msg); 15807 throw new SecurityException(msg); 15808 } 15809 if (requiredPermission != null) { 15810 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15811 + " and enforce permission " + requiredPermission); 15812 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15813 } 15814 if (intent.getComponent() != null) { 15815 throw new SecurityException( 15816 "Sticky broadcasts can't target a specific component"); 15817 } 15818 // We use userId directly here, since the "all" target is maintained 15819 // as a separate set of sticky broadcasts. 15820 if (userId != UserHandle.USER_ALL) { 15821 // But first, if this is not a broadcast to all users, then 15822 // make sure it doesn't conflict with an existing broadcast to 15823 // all users. 15824 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15825 UserHandle.USER_ALL); 15826 if (stickies != null) { 15827 ArrayList<Intent> list = stickies.get(intent.getAction()); 15828 if (list != null) { 15829 int N = list.size(); 15830 int i; 15831 for (i=0; i<N; i++) { 15832 if (intent.filterEquals(list.get(i))) { 15833 throw new IllegalArgumentException( 15834 "Sticky broadcast " + intent + " for user " 15835 + userId + " conflicts with existing global broadcast"); 15836 } 15837 } 15838 } 15839 } 15840 } 15841 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15842 if (stickies == null) { 15843 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15844 mStickyBroadcasts.put(userId, stickies); 15845 } 15846 ArrayList<Intent> list = stickies.get(intent.getAction()); 15847 if (list == null) { 15848 list = new ArrayList<Intent>(); 15849 stickies.put(intent.getAction(), list); 15850 } 15851 int N = list.size(); 15852 int i; 15853 for (i=0; i<N; i++) { 15854 if (intent.filterEquals(list.get(i))) { 15855 // This sticky already exists, replace it. 15856 list.set(i, new Intent(intent)); 15857 break; 15858 } 15859 } 15860 if (i >= N) { 15861 list.add(new Intent(intent)); 15862 } 15863 } 15864 15865 int[] users; 15866 if (userId == UserHandle.USER_ALL) { 15867 // Caller wants broadcast to go to all started users. 15868 users = mStartedUserArray; 15869 } else { 15870 // Caller wants broadcast to go to one specific user. 15871 users = new int[] {userId}; 15872 } 15873 15874 // Figure out who all will receive this broadcast. 15875 List receivers = null; 15876 List<BroadcastFilter> registeredReceivers = null; 15877 // Need to resolve the intent to interested receivers... 15878 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15879 == 0) { 15880 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15881 } 15882 if (intent.getComponent() == null) { 15883 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15884 // Query one target user at a time, excluding shell-restricted users 15885 UserManagerService ums = getUserManagerLocked(); 15886 for (int i = 0; i < users.length; i++) { 15887 if (ums.hasUserRestriction( 15888 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15889 continue; 15890 } 15891 List<BroadcastFilter> registeredReceiversForUser = 15892 mReceiverResolver.queryIntent(intent, 15893 resolvedType, false, users[i]); 15894 if (registeredReceivers == null) { 15895 registeredReceivers = registeredReceiversForUser; 15896 } else if (registeredReceiversForUser != null) { 15897 registeredReceivers.addAll(registeredReceiversForUser); 15898 } 15899 } 15900 } else { 15901 registeredReceivers = mReceiverResolver.queryIntent(intent, 15902 resolvedType, false, userId); 15903 } 15904 } 15905 15906 final boolean replacePending = 15907 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15908 15909 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15910 + " replacePending=" + replacePending); 15911 15912 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15913 if (!ordered && NR > 0) { 15914 // If we are not serializing this broadcast, then send the 15915 // registered receivers separately so they don't wait for the 15916 // components to be launched. 15917 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15918 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15919 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15920 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15921 ordered, sticky, false, userId); 15922 if (DEBUG_BROADCAST) Slog.v( 15923 TAG, "Enqueueing parallel broadcast " + r); 15924 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15925 if (!replaced) { 15926 queue.enqueueParallelBroadcastLocked(r); 15927 queue.scheduleBroadcastsLocked(); 15928 } 15929 registeredReceivers = null; 15930 NR = 0; 15931 } 15932 15933 // Merge into one list. 15934 int ir = 0; 15935 if (receivers != null) { 15936 // A special case for PACKAGE_ADDED: do not allow the package 15937 // being added to see this broadcast. This prevents them from 15938 // using this as a back door to get run as soon as they are 15939 // installed. Maybe in the future we want to have a special install 15940 // broadcast or such for apps, but we'd like to deliberately make 15941 // this decision. 15942 String skipPackages[] = null; 15943 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15944 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15945 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15946 Uri data = intent.getData(); 15947 if (data != null) { 15948 String pkgName = data.getSchemeSpecificPart(); 15949 if (pkgName != null) { 15950 skipPackages = new String[] { pkgName }; 15951 } 15952 } 15953 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15954 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15955 } 15956 if (skipPackages != null && (skipPackages.length > 0)) { 15957 for (String skipPackage : skipPackages) { 15958 if (skipPackage != null) { 15959 int NT = receivers.size(); 15960 for (int it=0; it<NT; it++) { 15961 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15962 if (curt.activityInfo.packageName.equals(skipPackage)) { 15963 receivers.remove(it); 15964 it--; 15965 NT--; 15966 } 15967 } 15968 } 15969 } 15970 } 15971 15972 int NT = receivers != null ? receivers.size() : 0; 15973 int it = 0; 15974 ResolveInfo curt = null; 15975 BroadcastFilter curr = null; 15976 while (it < NT && ir < NR) { 15977 if (curt == null) { 15978 curt = (ResolveInfo)receivers.get(it); 15979 } 15980 if (curr == null) { 15981 curr = registeredReceivers.get(ir); 15982 } 15983 if (curr.getPriority() >= curt.priority) { 15984 // Insert this broadcast record into the final list. 15985 receivers.add(it, curr); 15986 ir++; 15987 curr = null; 15988 it++; 15989 NT++; 15990 } else { 15991 // Skip to the next ResolveInfo in the final list. 15992 it++; 15993 curt = null; 15994 } 15995 } 15996 } 15997 while (ir < NR) { 15998 if (receivers == null) { 15999 receivers = new ArrayList(); 16000 } 16001 receivers.add(registeredReceivers.get(ir)); 16002 ir++; 16003 } 16004 16005 if ((receivers != null && receivers.size() > 0) 16006 || resultTo != null) { 16007 BroadcastQueue queue = broadcastQueueForIntent(intent); 16008 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16009 callerPackage, callingPid, callingUid, resolvedType, 16010 requiredPermission, appOp, receivers, resultTo, resultCode, 16011 resultData, map, ordered, sticky, false, userId); 16012 if (DEBUG_BROADCAST) Slog.v( 16013 TAG, "Enqueueing ordered broadcast " + r 16014 + ": prev had " + queue.mOrderedBroadcasts.size()); 16015 if (DEBUG_BROADCAST) { 16016 int seq = r.intent.getIntExtra("seq", -1); 16017 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16018 } 16019 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16020 if (!replaced) { 16021 queue.enqueueOrderedBroadcastLocked(r); 16022 queue.scheduleBroadcastsLocked(); 16023 } 16024 } 16025 16026 return ActivityManager.BROADCAST_SUCCESS; 16027 } 16028 16029 final Intent verifyBroadcastLocked(Intent intent) { 16030 // Refuse possible leaked file descriptors 16031 if (intent != null && intent.hasFileDescriptors() == true) { 16032 throw new IllegalArgumentException("File descriptors passed in Intent"); 16033 } 16034 16035 int flags = intent.getFlags(); 16036 16037 if (!mProcessesReady) { 16038 // if the caller really truly claims to know what they're doing, go 16039 // ahead and allow the broadcast without launching any receivers 16040 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16041 intent = new Intent(intent); 16042 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16043 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16044 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16045 + " before boot completion"); 16046 throw new IllegalStateException("Cannot broadcast before boot completed"); 16047 } 16048 } 16049 16050 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16051 throw new IllegalArgumentException( 16052 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16053 } 16054 16055 return intent; 16056 } 16057 16058 public final int broadcastIntent(IApplicationThread caller, 16059 Intent intent, String resolvedType, IIntentReceiver resultTo, 16060 int resultCode, String resultData, Bundle map, 16061 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16062 enforceNotIsolatedCaller("broadcastIntent"); 16063 synchronized(this) { 16064 intent = verifyBroadcastLocked(intent); 16065 16066 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16067 final int callingPid = Binder.getCallingPid(); 16068 final int callingUid = Binder.getCallingUid(); 16069 final long origId = Binder.clearCallingIdentity(); 16070 int res = broadcastIntentLocked(callerApp, 16071 callerApp != null ? callerApp.info.packageName : null, 16072 intent, resolvedType, resultTo, 16073 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16074 callingPid, callingUid, userId); 16075 Binder.restoreCallingIdentity(origId); 16076 return res; 16077 } 16078 } 16079 16080 int broadcastIntentInPackage(String packageName, int uid, 16081 Intent intent, String resolvedType, IIntentReceiver resultTo, 16082 int resultCode, String resultData, Bundle map, 16083 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16084 synchronized(this) { 16085 intent = verifyBroadcastLocked(intent); 16086 16087 final long origId = Binder.clearCallingIdentity(); 16088 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16089 resultTo, resultCode, resultData, map, requiredPermission, 16090 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16091 Binder.restoreCallingIdentity(origId); 16092 return res; 16093 } 16094 } 16095 16096 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16097 // Refuse possible leaked file descriptors 16098 if (intent != null && intent.hasFileDescriptors() == true) { 16099 throw new IllegalArgumentException("File descriptors passed in Intent"); 16100 } 16101 16102 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16103 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16104 16105 synchronized(this) { 16106 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16107 != PackageManager.PERMISSION_GRANTED) { 16108 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16109 + Binder.getCallingPid() 16110 + ", uid=" + Binder.getCallingUid() 16111 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16112 Slog.w(TAG, msg); 16113 throw new SecurityException(msg); 16114 } 16115 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16116 if (stickies != null) { 16117 ArrayList<Intent> list = stickies.get(intent.getAction()); 16118 if (list != null) { 16119 int N = list.size(); 16120 int i; 16121 for (i=0; i<N; i++) { 16122 if (intent.filterEquals(list.get(i))) { 16123 list.remove(i); 16124 break; 16125 } 16126 } 16127 if (list.size() <= 0) { 16128 stickies.remove(intent.getAction()); 16129 } 16130 } 16131 if (stickies.size() <= 0) { 16132 mStickyBroadcasts.remove(userId); 16133 } 16134 } 16135 } 16136 } 16137 16138 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16139 String resultData, Bundle resultExtras, boolean resultAbort) { 16140 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16141 if (r == null) { 16142 Slog.w(TAG, "finishReceiver called but not found on queue"); 16143 return false; 16144 } 16145 16146 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16147 } 16148 16149 void backgroundServicesFinishedLocked(int userId) { 16150 for (BroadcastQueue queue : mBroadcastQueues) { 16151 queue.backgroundServicesFinishedLocked(userId); 16152 } 16153 } 16154 16155 public void finishReceiver(IBinder who, int resultCode, String resultData, 16156 Bundle resultExtras, boolean resultAbort) { 16157 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16158 16159 // Refuse possible leaked file descriptors 16160 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16161 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16162 } 16163 16164 final long origId = Binder.clearCallingIdentity(); 16165 try { 16166 boolean doNext = false; 16167 BroadcastRecord r; 16168 16169 synchronized(this) { 16170 r = broadcastRecordForReceiverLocked(who); 16171 if (r != null) { 16172 doNext = r.queue.finishReceiverLocked(r, resultCode, 16173 resultData, resultExtras, resultAbort, true); 16174 } 16175 } 16176 16177 if (doNext) { 16178 r.queue.processNextBroadcast(false); 16179 } 16180 trimApplications(); 16181 } finally { 16182 Binder.restoreCallingIdentity(origId); 16183 } 16184 } 16185 16186 // ========================================================= 16187 // INSTRUMENTATION 16188 // ========================================================= 16189 16190 public boolean startInstrumentation(ComponentName className, 16191 String profileFile, int flags, Bundle arguments, 16192 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16193 int userId, String abiOverride) { 16194 enforceNotIsolatedCaller("startInstrumentation"); 16195 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16196 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16197 // Refuse possible leaked file descriptors 16198 if (arguments != null && arguments.hasFileDescriptors()) { 16199 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16200 } 16201 16202 synchronized(this) { 16203 InstrumentationInfo ii = null; 16204 ApplicationInfo ai = null; 16205 try { 16206 ii = mContext.getPackageManager().getInstrumentationInfo( 16207 className, STOCK_PM_FLAGS); 16208 ai = AppGlobals.getPackageManager().getApplicationInfo( 16209 ii.targetPackage, STOCK_PM_FLAGS, userId); 16210 } catch (PackageManager.NameNotFoundException e) { 16211 } catch (RemoteException e) { 16212 } 16213 if (ii == null) { 16214 reportStartInstrumentationFailure(watcher, className, 16215 "Unable to find instrumentation info for: " + className); 16216 return false; 16217 } 16218 if (ai == null) { 16219 reportStartInstrumentationFailure(watcher, className, 16220 "Unable to find instrumentation target package: " + ii.targetPackage); 16221 return false; 16222 } 16223 16224 int match = mContext.getPackageManager().checkSignatures( 16225 ii.targetPackage, ii.packageName); 16226 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16227 String msg = "Permission Denial: starting instrumentation " 16228 + className + " from pid=" 16229 + Binder.getCallingPid() 16230 + ", uid=" + Binder.getCallingPid() 16231 + " not allowed because package " + ii.packageName 16232 + " does not have a signature matching the target " 16233 + ii.targetPackage; 16234 reportStartInstrumentationFailure(watcher, className, msg); 16235 throw new SecurityException(msg); 16236 } 16237 16238 final long origId = Binder.clearCallingIdentity(); 16239 // Instrumentation can kill and relaunch even persistent processes 16240 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16241 "start instr"); 16242 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16243 app.instrumentationClass = className; 16244 app.instrumentationInfo = ai; 16245 app.instrumentationProfileFile = profileFile; 16246 app.instrumentationArguments = arguments; 16247 app.instrumentationWatcher = watcher; 16248 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16249 app.instrumentationResultClass = className; 16250 Binder.restoreCallingIdentity(origId); 16251 } 16252 16253 return true; 16254 } 16255 16256 /** 16257 * Report errors that occur while attempting to start Instrumentation. Always writes the 16258 * error to the logs, but if somebody is watching, send the report there too. This enables 16259 * the "am" command to report errors with more information. 16260 * 16261 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16262 * @param cn The component name of the instrumentation. 16263 * @param report The error report. 16264 */ 16265 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16266 ComponentName cn, String report) { 16267 Slog.w(TAG, report); 16268 try { 16269 if (watcher != null) { 16270 Bundle results = new Bundle(); 16271 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16272 results.putString("Error", report); 16273 watcher.instrumentationStatus(cn, -1, results); 16274 } 16275 } catch (RemoteException e) { 16276 Slog.w(TAG, e); 16277 } 16278 } 16279 16280 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16281 if (app.instrumentationWatcher != null) { 16282 try { 16283 // NOTE: IInstrumentationWatcher *must* be oneway here 16284 app.instrumentationWatcher.instrumentationFinished( 16285 app.instrumentationClass, 16286 resultCode, 16287 results); 16288 } catch (RemoteException e) { 16289 } 16290 } 16291 if (app.instrumentationUiAutomationConnection != null) { 16292 try { 16293 app.instrumentationUiAutomationConnection.shutdown(); 16294 } catch (RemoteException re) { 16295 /* ignore */ 16296 } 16297 // Only a UiAutomation can set this flag and now that 16298 // it is finished we make sure it is reset to its default. 16299 mUserIsMonkey = false; 16300 } 16301 app.instrumentationWatcher = null; 16302 app.instrumentationUiAutomationConnection = null; 16303 app.instrumentationClass = null; 16304 app.instrumentationInfo = null; 16305 app.instrumentationProfileFile = null; 16306 app.instrumentationArguments = null; 16307 16308 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16309 "finished inst"); 16310 } 16311 16312 public void finishInstrumentation(IApplicationThread target, 16313 int resultCode, Bundle results) { 16314 int userId = UserHandle.getCallingUserId(); 16315 // Refuse possible leaked file descriptors 16316 if (results != null && results.hasFileDescriptors()) { 16317 throw new IllegalArgumentException("File descriptors passed in Intent"); 16318 } 16319 16320 synchronized(this) { 16321 ProcessRecord app = getRecordForAppLocked(target); 16322 if (app == null) { 16323 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16324 return; 16325 } 16326 final long origId = Binder.clearCallingIdentity(); 16327 finishInstrumentationLocked(app, resultCode, results); 16328 Binder.restoreCallingIdentity(origId); 16329 } 16330 } 16331 16332 // ========================================================= 16333 // CONFIGURATION 16334 // ========================================================= 16335 16336 public ConfigurationInfo getDeviceConfigurationInfo() { 16337 ConfigurationInfo config = new ConfigurationInfo(); 16338 synchronized (this) { 16339 config.reqTouchScreen = mConfiguration.touchscreen; 16340 config.reqKeyboardType = mConfiguration.keyboard; 16341 config.reqNavigation = mConfiguration.navigation; 16342 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16343 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16344 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16345 } 16346 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16347 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16348 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16349 } 16350 config.reqGlEsVersion = GL_ES_VERSION; 16351 } 16352 return config; 16353 } 16354 16355 ActivityStack getFocusedStack() { 16356 return mStackSupervisor.getFocusedStack(); 16357 } 16358 16359 public Configuration getConfiguration() { 16360 Configuration ci; 16361 synchronized(this) { 16362 ci = new Configuration(mConfiguration); 16363 } 16364 return ci; 16365 } 16366 16367 public void updatePersistentConfiguration(Configuration values) { 16368 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16369 "updateConfiguration()"); 16370 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16371 "updateConfiguration()"); 16372 if (values == null) { 16373 throw new NullPointerException("Configuration must not be null"); 16374 } 16375 16376 synchronized(this) { 16377 final long origId = Binder.clearCallingIdentity(); 16378 updateConfigurationLocked(values, null, true, false); 16379 Binder.restoreCallingIdentity(origId); 16380 } 16381 } 16382 16383 public void updateConfiguration(Configuration values) { 16384 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16385 "updateConfiguration()"); 16386 16387 synchronized(this) { 16388 if (values == null && mWindowManager != null) { 16389 // sentinel: fetch the current configuration from the window manager 16390 values = mWindowManager.computeNewConfiguration(); 16391 } 16392 16393 if (mWindowManager != null) { 16394 mProcessList.applyDisplaySize(mWindowManager); 16395 } 16396 16397 final long origId = Binder.clearCallingIdentity(); 16398 if (values != null) { 16399 Settings.System.clearConfiguration(values); 16400 } 16401 updateConfigurationLocked(values, null, false, false); 16402 Binder.restoreCallingIdentity(origId); 16403 } 16404 } 16405 16406 /** 16407 * Do either or both things: (1) change the current configuration, and (2) 16408 * make sure the given activity is running with the (now) current 16409 * configuration. Returns true if the activity has been left running, or 16410 * false if <var>starting</var> is being destroyed to match the new 16411 * configuration. 16412 * @param persistent TODO 16413 */ 16414 boolean updateConfigurationLocked(Configuration values, 16415 ActivityRecord starting, boolean persistent, boolean initLocale) { 16416 int changes = 0; 16417 16418 if (values != null) { 16419 Configuration newConfig = new Configuration(mConfiguration); 16420 changes = newConfig.updateFrom(values); 16421 if (changes != 0) { 16422 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16423 Slog.i(TAG, "Updating configuration to: " + values); 16424 } 16425 16426 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16427 16428 if (values.locale != null && !initLocale) { 16429 saveLocaleLocked(values.locale, 16430 !values.locale.equals(mConfiguration.locale), 16431 values.userSetLocale); 16432 } 16433 16434 mConfigurationSeq++; 16435 if (mConfigurationSeq <= 0) { 16436 mConfigurationSeq = 1; 16437 } 16438 newConfig.seq = mConfigurationSeq; 16439 mConfiguration = newConfig; 16440 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16441 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16442 //mUsageStatsService.noteStartConfig(newConfig); 16443 16444 final Configuration configCopy = new Configuration(mConfiguration); 16445 16446 // TODO: If our config changes, should we auto dismiss any currently 16447 // showing dialogs? 16448 mShowDialogs = shouldShowDialogs(newConfig); 16449 16450 AttributeCache ac = AttributeCache.instance(); 16451 if (ac != null) { 16452 ac.updateConfiguration(configCopy); 16453 } 16454 16455 // Make sure all resources in our process are updated 16456 // right now, so that anyone who is going to retrieve 16457 // resource values after we return will be sure to get 16458 // the new ones. This is especially important during 16459 // boot, where the first config change needs to guarantee 16460 // all resources have that config before following boot 16461 // code is executed. 16462 mSystemThread.applyConfigurationToResources(configCopy); 16463 16464 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16465 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16466 msg.obj = new Configuration(configCopy); 16467 mHandler.sendMessage(msg); 16468 } 16469 16470 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16471 ProcessRecord app = mLruProcesses.get(i); 16472 try { 16473 if (app.thread != null) { 16474 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16475 + app.processName + " new config " + mConfiguration); 16476 app.thread.scheduleConfigurationChanged(configCopy); 16477 } 16478 } catch (Exception e) { 16479 } 16480 } 16481 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16482 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16483 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16484 | Intent.FLAG_RECEIVER_FOREGROUND); 16485 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16486 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16487 Process.SYSTEM_UID, UserHandle.USER_ALL); 16488 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16489 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16490 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16491 broadcastIntentLocked(null, null, intent, 16492 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16493 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16494 } 16495 } 16496 } 16497 16498 boolean kept = true; 16499 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16500 // mainStack is null during startup. 16501 if (mainStack != null) { 16502 if (changes != 0 && starting == null) { 16503 // If the configuration changed, and the caller is not already 16504 // in the process of starting an activity, then find the top 16505 // activity to check if its configuration needs to change. 16506 starting = mainStack.topRunningActivityLocked(null); 16507 } 16508 16509 if (starting != null) { 16510 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16511 // And we need to make sure at this point that all other activities 16512 // are made visible with the correct configuration. 16513 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16514 } 16515 } 16516 16517 if (values != null && mWindowManager != null) { 16518 mWindowManager.setNewConfiguration(mConfiguration); 16519 } 16520 16521 return kept; 16522 } 16523 16524 /** 16525 * Decide based on the configuration whether we should shouw the ANR, 16526 * crash, etc dialogs. The idea is that if there is no affordnace to 16527 * press the on-screen buttons, we shouldn't show the dialog. 16528 * 16529 * A thought: SystemUI might also want to get told about this, the Power 16530 * dialog / global actions also might want different behaviors. 16531 */ 16532 private static final boolean shouldShowDialogs(Configuration config) { 16533 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16534 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16535 } 16536 16537 /** 16538 * Save the locale. You must be inside a synchronized (this) block. 16539 */ 16540 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16541 if(isDiff) { 16542 SystemProperties.set("user.language", l.getLanguage()); 16543 SystemProperties.set("user.region", l.getCountry()); 16544 } 16545 16546 if(isPersist) { 16547 SystemProperties.set("persist.sys.language", l.getLanguage()); 16548 SystemProperties.set("persist.sys.country", l.getCountry()); 16549 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16550 16551 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16552 } 16553 } 16554 16555 @Override 16556 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16557 synchronized (this) { 16558 ActivityRecord srec = ActivityRecord.forToken(token); 16559 if (srec.task != null && srec.task.stack != null) { 16560 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16561 } 16562 } 16563 return false; 16564 } 16565 16566 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16567 Intent resultData) { 16568 16569 synchronized (this) { 16570 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16571 if (stack != null) { 16572 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16573 } 16574 return false; 16575 } 16576 } 16577 16578 public int getLaunchedFromUid(IBinder activityToken) { 16579 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16580 if (srec == null) { 16581 return -1; 16582 } 16583 return srec.launchedFromUid; 16584 } 16585 16586 public String getLaunchedFromPackage(IBinder activityToken) { 16587 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16588 if (srec == null) { 16589 return null; 16590 } 16591 return srec.launchedFromPackage; 16592 } 16593 16594 // ========================================================= 16595 // LIFETIME MANAGEMENT 16596 // ========================================================= 16597 16598 // Returns which broadcast queue the app is the current [or imminent] receiver 16599 // on, or 'null' if the app is not an active broadcast recipient. 16600 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16601 BroadcastRecord r = app.curReceiver; 16602 if (r != null) { 16603 return r.queue; 16604 } 16605 16606 // It's not the current receiver, but it might be starting up to become one 16607 synchronized (this) { 16608 for (BroadcastQueue queue : mBroadcastQueues) { 16609 r = queue.mPendingBroadcast; 16610 if (r != null && r.curApp == app) { 16611 // found it; report which queue it's in 16612 return queue; 16613 } 16614 } 16615 } 16616 16617 return null; 16618 } 16619 16620 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16621 boolean doingAll, long now) { 16622 if (mAdjSeq == app.adjSeq) { 16623 // This adjustment has already been computed. 16624 return app.curRawAdj; 16625 } 16626 16627 if (app.thread == null) { 16628 app.adjSeq = mAdjSeq; 16629 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16630 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16631 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16632 } 16633 16634 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16635 app.adjSource = null; 16636 app.adjTarget = null; 16637 app.empty = false; 16638 app.cached = false; 16639 16640 final int activitiesSize = app.activities.size(); 16641 16642 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16643 // The max adjustment doesn't allow this app to be anything 16644 // below foreground, so it is not worth doing work for it. 16645 app.adjType = "fixed"; 16646 app.adjSeq = mAdjSeq; 16647 app.curRawAdj = app.maxAdj; 16648 app.foregroundActivities = false; 16649 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16650 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16651 // System processes can do UI, and when they do we want to have 16652 // them trim their memory after the user leaves the UI. To 16653 // facilitate this, here we need to determine whether or not it 16654 // is currently showing UI. 16655 app.systemNoUi = true; 16656 if (app == TOP_APP) { 16657 app.systemNoUi = false; 16658 } else if (activitiesSize > 0) { 16659 for (int j = 0; j < activitiesSize; j++) { 16660 final ActivityRecord r = app.activities.get(j); 16661 if (r.visible) { 16662 app.systemNoUi = false; 16663 } 16664 } 16665 } 16666 if (!app.systemNoUi) { 16667 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16668 } 16669 return (app.curAdj=app.maxAdj); 16670 } 16671 16672 app.systemNoUi = false; 16673 16674 // Determine the importance of the process, starting with most 16675 // important to least, and assign an appropriate OOM adjustment. 16676 int adj; 16677 int schedGroup; 16678 int procState; 16679 boolean foregroundActivities = false; 16680 BroadcastQueue queue; 16681 if (app == TOP_APP) { 16682 // The last app on the list is the foreground app. 16683 adj = ProcessList.FOREGROUND_APP_ADJ; 16684 schedGroup = Process.THREAD_GROUP_DEFAULT; 16685 app.adjType = "top-activity"; 16686 foregroundActivities = true; 16687 procState = ActivityManager.PROCESS_STATE_TOP; 16688 } else if (app.instrumentationClass != null) { 16689 // Don't want to kill running instrumentation. 16690 adj = ProcessList.FOREGROUND_APP_ADJ; 16691 schedGroup = Process.THREAD_GROUP_DEFAULT; 16692 app.adjType = "instrumentation"; 16693 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16694 } else if ((queue = isReceivingBroadcast(app)) != null) { 16695 // An app that is currently receiving a broadcast also 16696 // counts as being in the foreground for OOM killer purposes. 16697 // It's placed in a sched group based on the nature of the 16698 // broadcast as reflected by which queue it's active in. 16699 adj = ProcessList.FOREGROUND_APP_ADJ; 16700 schedGroup = (queue == mFgBroadcastQueue) 16701 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16702 app.adjType = "broadcast"; 16703 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16704 } else if (app.executingServices.size() > 0) { 16705 // An app that is currently executing a service callback also 16706 // counts as being in the foreground. 16707 adj = ProcessList.FOREGROUND_APP_ADJ; 16708 schedGroup = app.execServicesFg ? 16709 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16710 app.adjType = "exec-service"; 16711 procState = ActivityManager.PROCESS_STATE_SERVICE; 16712 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16713 } else { 16714 // As far as we know the process is empty. We may change our mind later. 16715 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16716 // At this point we don't actually know the adjustment. Use the cached adj 16717 // value that the caller wants us to. 16718 adj = cachedAdj; 16719 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16720 app.cached = true; 16721 app.empty = true; 16722 app.adjType = "cch-empty"; 16723 } 16724 16725 // Examine all activities if not already foreground. 16726 if (!foregroundActivities && activitiesSize > 0) { 16727 for (int j = 0; j < activitiesSize; j++) { 16728 final ActivityRecord r = app.activities.get(j); 16729 if (r.app != app) { 16730 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16731 + app + "?!?"); 16732 continue; 16733 } 16734 if (r.visible) { 16735 // App has a visible activity; only upgrade adjustment. 16736 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16737 adj = ProcessList.VISIBLE_APP_ADJ; 16738 app.adjType = "visible"; 16739 } 16740 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16741 procState = ActivityManager.PROCESS_STATE_TOP; 16742 } 16743 schedGroup = Process.THREAD_GROUP_DEFAULT; 16744 app.cached = false; 16745 app.empty = false; 16746 foregroundActivities = true; 16747 break; 16748 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16749 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16750 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16751 app.adjType = "pausing"; 16752 } 16753 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16754 procState = ActivityManager.PROCESS_STATE_TOP; 16755 } 16756 schedGroup = Process.THREAD_GROUP_DEFAULT; 16757 app.cached = false; 16758 app.empty = false; 16759 foregroundActivities = true; 16760 } else if (r.state == ActivityState.STOPPING) { 16761 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16762 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16763 app.adjType = "stopping"; 16764 } 16765 // For the process state, we will at this point consider the 16766 // process to be cached. It will be cached either as an activity 16767 // or empty depending on whether the activity is finishing. We do 16768 // this so that we can treat the process as cached for purposes of 16769 // memory trimming (determing current memory level, trim command to 16770 // send to process) since there can be an arbitrary number of stopping 16771 // processes and they should soon all go into the cached state. 16772 if (!r.finishing) { 16773 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16774 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16775 } 16776 } 16777 app.cached = false; 16778 app.empty = false; 16779 foregroundActivities = true; 16780 } else { 16781 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16782 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16783 app.adjType = "cch-act"; 16784 } 16785 } 16786 } 16787 } 16788 16789 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16790 if (app.foregroundServices) { 16791 // The user is aware of this app, so make it visible. 16792 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16793 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16794 app.cached = false; 16795 app.adjType = "fg-service"; 16796 schedGroup = Process.THREAD_GROUP_DEFAULT; 16797 } else if (app.forcingToForeground != null) { 16798 // The user is aware of this app, so make it visible. 16799 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16800 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16801 app.cached = false; 16802 app.adjType = "force-fg"; 16803 app.adjSource = app.forcingToForeground; 16804 schedGroup = Process.THREAD_GROUP_DEFAULT; 16805 } 16806 } 16807 16808 if (app == mHeavyWeightProcess) { 16809 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16810 // We don't want to kill the current heavy-weight process. 16811 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16812 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16813 app.cached = false; 16814 app.adjType = "heavy"; 16815 } 16816 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16817 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16818 } 16819 } 16820 16821 if (app == mHomeProcess) { 16822 if (adj > ProcessList.HOME_APP_ADJ) { 16823 // This process is hosting what we currently consider to be the 16824 // home app, so we don't want to let it go into the background. 16825 adj = ProcessList.HOME_APP_ADJ; 16826 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16827 app.cached = false; 16828 app.adjType = "home"; 16829 } 16830 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16831 procState = ActivityManager.PROCESS_STATE_HOME; 16832 } 16833 } 16834 16835 if (app == mPreviousProcess && app.activities.size() > 0) { 16836 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16837 // This was the previous process that showed UI to the user. 16838 // We want to try to keep it around more aggressively, to give 16839 // a good experience around switching between two apps. 16840 adj = ProcessList.PREVIOUS_APP_ADJ; 16841 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16842 app.cached = false; 16843 app.adjType = "previous"; 16844 } 16845 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16846 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16847 } 16848 } 16849 16850 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16851 + " reason=" + app.adjType); 16852 16853 // By default, we use the computed adjustment. It may be changed if 16854 // there are applications dependent on our services or providers, but 16855 // this gives us a baseline and makes sure we don't get into an 16856 // infinite recursion. 16857 app.adjSeq = mAdjSeq; 16858 app.curRawAdj = adj; 16859 app.hasStartedServices = false; 16860 16861 if (mBackupTarget != null && app == mBackupTarget.app) { 16862 // If possible we want to avoid killing apps while they're being backed up 16863 if (adj > ProcessList.BACKUP_APP_ADJ) { 16864 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16865 adj = ProcessList.BACKUP_APP_ADJ; 16866 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16867 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16868 } 16869 app.adjType = "backup"; 16870 app.cached = false; 16871 } 16872 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16873 procState = ActivityManager.PROCESS_STATE_BACKUP; 16874 } 16875 } 16876 16877 boolean mayBeTop = false; 16878 16879 for (int is = app.services.size()-1; 16880 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16881 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16882 || procState > ActivityManager.PROCESS_STATE_TOP); 16883 is--) { 16884 ServiceRecord s = app.services.valueAt(is); 16885 if (s.startRequested) { 16886 app.hasStartedServices = true; 16887 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16888 procState = ActivityManager.PROCESS_STATE_SERVICE; 16889 } 16890 if (app.hasShownUi && app != mHomeProcess) { 16891 // If this process has shown some UI, let it immediately 16892 // go to the LRU list because it may be pretty heavy with 16893 // UI stuff. We'll tag it with a label just to help 16894 // debug and understand what is going on. 16895 if (adj > ProcessList.SERVICE_ADJ) { 16896 app.adjType = "cch-started-ui-services"; 16897 } 16898 } else { 16899 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16900 // This service has seen some activity within 16901 // recent memory, so we will keep its process ahead 16902 // of the background processes. 16903 if (adj > ProcessList.SERVICE_ADJ) { 16904 adj = ProcessList.SERVICE_ADJ; 16905 app.adjType = "started-services"; 16906 app.cached = false; 16907 } 16908 } 16909 // If we have let the service slide into the background 16910 // state, still have some text describing what it is doing 16911 // even though the service no longer has an impact. 16912 if (adj > ProcessList.SERVICE_ADJ) { 16913 app.adjType = "cch-started-services"; 16914 } 16915 } 16916 } 16917 for (int conni = s.connections.size()-1; 16918 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16919 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16920 || procState > ActivityManager.PROCESS_STATE_TOP); 16921 conni--) { 16922 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16923 for (int i = 0; 16924 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16925 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16926 || procState > ActivityManager.PROCESS_STATE_TOP); 16927 i++) { 16928 // XXX should compute this based on the max of 16929 // all connected clients. 16930 ConnectionRecord cr = clist.get(i); 16931 if (cr.binding.client == app) { 16932 // Binding to ourself is not interesting. 16933 continue; 16934 } 16935 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16936 ProcessRecord client = cr.binding.client; 16937 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16938 TOP_APP, doingAll, now); 16939 int clientProcState = client.curProcState; 16940 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16941 // If the other app is cached for any reason, for purposes here 16942 // we are going to consider it empty. The specific cached state 16943 // doesn't propagate except under certain conditions. 16944 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16945 } 16946 String adjType = null; 16947 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16948 // Not doing bind OOM management, so treat 16949 // this guy more like a started service. 16950 if (app.hasShownUi && app != mHomeProcess) { 16951 // If this process has shown some UI, let it immediately 16952 // go to the LRU list because it may be pretty heavy with 16953 // UI stuff. We'll tag it with a label just to help 16954 // debug and understand what is going on. 16955 if (adj > clientAdj) { 16956 adjType = "cch-bound-ui-services"; 16957 } 16958 app.cached = false; 16959 clientAdj = adj; 16960 clientProcState = procState; 16961 } else { 16962 if (now >= (s.lastActivity 16963 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16964 // This service has not seen activity within 16965 // recent memory, so allow it to drop to the 16966 // LRU list if there is no other reason to keep 16967 // it around. We'll also tag it with a label just 16968 // to help debug and undertand what is going on. 16969 if (adj > clientAdj) { 16970 adjType = "cch-bound-services"; 16971 } 16972 clientAdj = adj; 16973 } 16974 } 16975 } 16976 if (adj > clientAdj) { 16977 // If this process has recently shown UI, and 16978 // the process that is binding to it is less 16979 // important than being visible, then we don't 16980 // care about the binding as much as we care 16981 // about letting this process get into the LRU 16982 // list to be killed and restarted if needed for 16983 // memory. 16984 if (app.hasShownUi && app != mHomeProcess 16985 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16986 adjType = "cch-bound-ui-services"; 16987 } else { 16988 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16989 |Context.BIND_IMPORTANT)) != 0) { 16990 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16991 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16992 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16993 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16994 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16995 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16996 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16997 adj = clientAdj; 16998 } else { 16999 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17000 adj = ProcessList.VISIBLE_APP_ADJ; 17001 } 17002 } 17003 if (!client.cached) { 17004 app.cached = false; 17005 } 17006 adjType = "service"; 17007 } 17008 } 17009 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17010 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17011 schedGroup = Process.THREAD_GROUP_DEFAULT; 17012 } 17013 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17014 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17015 // Special handling of clients who are in the top state. 17016 // We *may* want to consider this process to be in the 17017 // top state as well, but only if there is not another 17018 // reason for it to be running. Being on the top is a 17019 // special state, meaning you are specifically running 17020 // for the current top app. If the process is already 17021 // running in the background for some other reason, it 17022 // is more important to continue considering it to be 17023 // in the background state. 17024 mayBeTop = true; 17025 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17026 } else { 17027 // Special handling for above-top states (persistent 17028 // processes). These should not bring the current process 17029 // into the top state, since they are not on top. Instead 17030 // give them the best state after that. 17031 clientProcState = 17032 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17033 } 17034 } 17035 } else { 17036 if (clientProcState < 17037 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17038 clientProcState = 17039 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17040 } 17041 } 17042 if (procState > clientProcState) { 17043 procState = clientProcState; 17044 } 17045 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17046 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17047 app.pendingUiClean = true; 17048 } 17049 if (adjType != null) { 17050 app.adjType = adjType; 17051 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17052 .REASON_SERVICE_IN_USE; 17053 app.adjSource = cr.binding.client; 17054 app.adjSourceProcState = clientProcState; 17055 app.adjTarget = s.name; 17056 } 17057 } 17058 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17059 app.treatLikeActivity = true; 17060 } 17061 final ActivityRecord a = cr.activity; 17062 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17063 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17064 (a.visible || a.state == ActivityState.RESUMED 17065 || a.state == ActivityState.PAUSING)) { 17066 adj = ProcessList.FOREGROUND_APP_ADJ; 17067 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17068 schedGroup = Process.THREAD_GROUP_DEFAULT; 17069 } 17070 app.cached = false; 17071 app.adjType = "service"; 17072 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17073 .REASON_SERVICE_IN_USE; 17074 app.adjSource = a; 17075 app.adjSourceProcState = procState; 17076 app.adjTarget = s.name; 17077 } 17078 } 17079 } 17080 } 17081 } 17082 17083 for (int provi = app.pubProviders.size()-1; 17084 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17085 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17086 || procState > ActivityManager.PROCESS_STATE_TOP); 17087 provi--) { 17088 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17089 for (int i = cpr.connections.size()-1; 17090 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17091 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17092 || procState > ActivityManager.PROCESS_STATE_TOP); 17093 i--) { 17094 ContentProviderConnection conn = cpr.connections.get(i); 17095 ProcessRecord client = conn.client; 17096 if (client == app) { 17097 // Being our own client is not interesting. 17098 continue; 17099 } 17100 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17101 int clientProcState = client.curProcState; 17102 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17103 // If the other app is cached for any reason, for purposes here 17104 // we are going to consider it empty. 17105 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17106 } 17107 if (adj > clientAdj) { 17108 if (app.hasShownUi && app != mHomeProcess 17109 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17110 app.adjType = "cch-ui-provider"; 17111 } else { 17112 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17113 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17114 app.adjType = "provider"; 17115 } 17116 app.cached &= client.cached; 17117 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17118 .REASON_PROVIDER_IN_USE; 17119 app.adjSource = client; 17120 app.adjSourceProcState = clientProcState; 17121 app.adjTarget = cpr.name; 17122 } 17123 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17124 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17125 // Special handling of clients who are in the top state. 17126 // We *may* want to consider this process to be in the 17127 // top state as well, but only if there is not another 17128 // reason for it to be running. Being on the top is a 17129 // special state, meaning you are specifically running 17130 // for the current top app. If the process is already 17131 // running in the background for some other reason, it 17132 // is more important to continue considering it to be 17133 // in the background state. 17134 mayBeTop = true; 17135 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17136 } else { 17137 // Special handling for above-top states (persistent 17138 // processes). These should not bring the current process 17139 // into the top state, since they are not on top. Instead 17140 // give them the best state after that. 17141 clientProcState = 17142 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17143 } 17144 } 17145 if (procState > clientProcState) { 17146 procState = clientProcState; 17147 } 17148 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17149 schedGroup = Process.THREAD_GROUP_DEFAULT; 17150 } 17151 } 17152 // If the provider has external (non-framework) process 17153 // dependencies, ensure that its adjustment is at least 17154 // FOREGROUND_APP_ADJ. 17155 if (cpr.hasExternalProcessHandles()) { 17156 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17157 adj = ProcessList.FOREGROUND_APP_ADJ; 17158 schedGroup = Process.THREAD_GROUP_DEFAULT; 17159 app.cached = false; 17160 app.adjType = "provider"; 17161 app.adjTarget = cpr.name; 17162 } 17163 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17164 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17165 } 17166 } 17167 } 17168 17169 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17170 // A client of one of our services or providers is in the top state. We 17171 // *may* want to be in the top state, but not if we are already running in 17172 // the background for some other reason. For the decision here, we are going 17173 // to pick out a few specific states that we want to remain in when a client 17174 // is top (states that tend to be longer-term) and otherwise allow it to go 17175 // to the top state. 17176 switch (procState) { 17177 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17178 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17179 case ActivityManager.PROCESS_STATE_SERVICE: 17180 // These all are longer-term states, so pull them up to the top 17181 // of the background states, but not all the way to the top state. 17182 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17183 break; 17184 default: 17185 // Otherwise, top is a better choice, so take it. 17186 procState = ActivityManager.PROCESS_STATE_TOP; 17187 break; 17188 } 17189 } 17190 17191 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17192 if (app.hasClientActivities) { 17193 // This is a cached process, but with client activities. Mark it so. 17194 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17195 app.adjType = "cch-client-act"; 17196 } else if (app.treatLikeActivity) { 17197 // This is a cached process, but somebody wants us to treat it like it has 17198 // an activity, okay! 17199 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17200 app.adjType = "cch-as-act"; 17201 } 17202 } 17203 17204 if (adj == ProcessList.SERVICE_ADJ) { 17205 if (doingAll) { 17206 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17207 mNewNumServiceProcs++; 17208 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17209 if (!app.serviceb) { 17210 // This service isn't far enough down on the LRU list to 17211 // normally be a B service, but if we are low on RAM and it 17212 // is large we want to force it down since we would prefer to 17213 // keep launcher over it. 17214 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17215 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17216 app.serviceHighRam = true; 17217 app.serviceb = true; 17218 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17219 } else { 17220 mNewNumAServiceProcs++; 17221 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17222 } 17223 } else { 17224 app.serviceHighRam = false; 17225 } 17226 } 17227 if (app.serviceb) { 17228 adj = ProcessList.SERVICE_B_ADJ; 17229 } 17230 } 17231 17232 app.curRawAdj = adj; 17233 17234 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17235 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17236 if (adj > app.maxAdj) { 17237 adj = app.maxAdj; 17238 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17239 schedGroup = Process.THREAD_GROUP_DEFAULT; 17240 } 17241 } 17242 17243 // Do final modification to adj. Everything we do between here and applying 17244 // the final setAdj must be done in this function, because we will also use 17245 // it when computing the final cached adj later. Note that we don't need to 17246 // worry about this for max adj above, since max adj will always be used to 17247 // keep it out of the cached vaues. 17248 app.curAdj = app.modifyRawOomAdj(adj); 17249 app.curSchedGroup = schedGroup; 17250 app.curProcState = procState; 17251 app.foregroundActivities = foregroundActivities; 17252 17253 return app.curRawAdj; 17254 } 17255 17256 /** 17257 * Schedule PSS collection of a process. 17258 */ 17259 void requestPssLocked(ProcessRecord proc, int procState) { 17260 if (mPendingPssProcesses.contains(proc)) { 17261 return; 17262 } 17263 if (mPendingPssProcesses.size() == 0) { 17264 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17265 } 17266 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17267 proc.pssProcState = procState; 17268 mPendingPssProcesses.add(proc); 17269 } 17270 17271 /** 17272 * Schedule PSS collection of all processes. 17273 */ 17274 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17275 if (!always) { 17276 if (now < (mLastFullPssTime + 17277 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17278 return; 17279 } 17280 } 17281 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17282 mLastFullPssTime = now; 17283 mFullPssPending = true; 17284 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17285 mPendingPssProcesses.clear(); 17286 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17287 ProcessRecord app = mLruProcesses.get(i); 17288 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17289 app.pssProcState = app.setProcState; 17290 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17291 isSleeping(), now); 17292 mPendingPssProcesses.add(app); 17293 } 17294 } 17295 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17296 } 17297 17298 /** 17299 * Ask a given process to GC right now. 17300 */ 17301 final void performAppGcLocked(ProcessRecord app) { 17302 try { 17303 app.lastRequestedGc = SystemClock.uptimeMillis(); 17304 if (app.thread != null) { 17305 if (app.reportLowMemory) { 17306 app.reportLowMemory = false; 17307 app.thread.scheduleLowMemory(); 17308 } else { 17309 app.thread.processInBackground(); 17310 } 17311 } 17312 } catch (Exception e) { 17313 // whatever. 17314 } 17315 } 17316 17317 /** 17318 * Returns true if things are idle enough to perform GCs. 17319 */ 17320 private final boolean canGcNowLocked() { 17321 boolean processingBroadcasts = false; 17322 for (BroadcastQueue q : mBroadcastQueues) { 17323 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17324 processingBroadcasts = true; 17325 } 17326 } 17327 return !processingBroadcasts 17328 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17329 } 17330 17331 /** 17332 * Perform GCs on all processes that are waiting for it, but only 17333 * if things are idle. 17334 */ 17335 final void performAppGcsLocked() { 17336 final int N = mProcessesToGc.size(); 17337 if (N <= 0) { 17338 return; 17339 } 17340 if (canGcNowLocked()) { 17341 while (mProcessesToGc.size() > 0) { 17342 ProcessRecord proc = mProcessesToGc.remove(0); 17343 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17344 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17345 <= SystemClock.uptimeMillis()) { 17346 // To avoid spamming the system, we will GC processes one 17347 // at a time, waiting a few seconds between each. 17348 performAppGcLocked(proc); 17349 scheduleAppGcsLocked(); 17350 return; 17351 } else { 17352 // It hasn't been long enough since we last GCed this 17353 // process... put it in the list to wait for its time. 17354 addProcessToGcListLocked(proc); 17355 break; 17356 } 17357 } 17358 } 17359 17360 scheduleAppGcsLocked(); 17361 } 17362 } 17363 17364 /** 17365 * If all looks good, perform GCs on all processes waiting for them. 17366 */ 17367 final void performAppGcsIfAppropriateLocked() { 17368 if (canGcNowLocked()) { 17369 performAppGcsLocked(); 17370 return; 17371 } 17372 // Still not idle, wait some more. 17373 scheduleAppGcsLocked(); 17374 } 17375 17376 /** 17377 * Schedule the execution of all pending app GCs. 17378 */ 17379 final void scheduleAppGcsLocked() { 17380 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17381 17382 if (mProcessesToGc.size() > 0) { 17383 // Schedule a GC for the time to the next process. 17384 ProcessRecord proc = mProcessesToGc.get(0); 17385 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17386 17387 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17388 long now = SystemClock.uptimeMillis(); 17389 if (when < (now+GC_TIMEOUT)) { 17390 when = now + GC_TIMEOUT; 17391 } 17392 mHandler.sendMessageAtTime(msg, when); 17393 } 17394 } 17395 17396 /** 17397 * Add a process to the array of processes waiting to be GCed. Keeps the 17398 * list in sorted order by the last GC time. The process can't already be 17399 * on the list. 17400 */ 17401 final void addProcessToGcListLocked(ProcessRecord proc) { 17402 boolean added = false; 17403 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17404 if (mProcessesToGc.get(i).lastRequestedGc < 17405 proc.lastRequestedGc) { 17406 added = true; 17407 mProcessesToGc.add(i+1, proc); 17408 break; 17409 } 17410 } 17411 if (!added) { 17412 mProcessesToGc.add(0, proc); 17413 } 17414 } 17415 17416 /** 17417 * Set up to ask a process to GC itself. This will either do it 17418 * immediately, or put it on the list of processes to gc the next 17419 * time things are idle. 17420 */ 17421 final void scheduleAppGcLocked(ProcessRecord app) { 17422 long now = SystemClock.uptimeMillis(); 17423 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17424 return; 17425 } 17426 if (!mProcessesToGc.contains(app)) { 17427 addProcessToGcListLocked(app); 17428 scheduleAppGcsLocked(); 17429 } 17430 } 17431 17432 final void checkExcessivePowerUsageLocked(boolean doKills) { 17433 updateCpuStatsNow(); 17434 17435 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17436 boolean doWakeKills = doKills; 17437 boolean doCpuKills = doKills; 17438 if (mLastPowerCheckRealtime == 0) { 17439 doWakeKills = false; 17440 } 17441 if (mLastPowerCheckUptime == 0) { 17442 doCpuKills = false; 17443 } 17444 if (stats.isScreenOn()) { 17445 doWakeKills = false; 17446 } 17447 final long curRealtime = SystemClock.elapsedRealtime(); 17448 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17449 final long curUptime = SystemClock.uptimeMillis(); 17450 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17451 mLastPowerCheckRealtime = curRealtime; 17452 mLastPowerCheckUptime = curUptime; 17453 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17454 doWakeKills = false; 17455 } 17456 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17457 doCpuKills = false; 17458 } 17459 int i = mLruProcesses.size(); 17460 while (i > 0) { 17461 i--; 17462 ProcessRecord app = mLruProcesses.get(i); 17463 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17464 long wtime; 17465 synchronized (stats) { 17466 wtime = stats.getProcessWakeTime(app.info.uid, 17467 app.pid, curRealtime); 17468 } 17469 long wtimeUsed = wtime - app.lastWakeTime; 17470 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17471 if (DEBUG_POWER) { 17472 StringBuilder sb = new StringBuilder(128); 17473 sb.append("Wake for "); 17474 app.toShortString(sb); 17475 sb.append(": over "); 17476 TimeUtils.formatDuration(realtimeSince, sb); 17477 sb.append(" used "); 17478 TimeUtils.formatDuration(wtimeUsed, sb); 17479 sb.append(" ("); 17480 sb.append((wtimeUsed*100)/realtimeSince); 17481 sb.append("%)"); 17482 Slog.i(TAG, sb.toString()); 17483 sb.setLength(0); 17484 sb.append("CPU for "); 17485 app.toShortString(sb); 17486 sb.append(": over "); 17487 TimeUtils.formatDuration(uptimeSince, sb); 17488 sb.append(" used "); 17489 TimeUtils.formatDuration(cputimeUsed, sb); 17490 sb.append(" ("); 17491 sb.append((cputimeUsed*100)/uptimeSince); 17492 sb.append("%)"); 17493 Slog.i(TAG, sb.toString()); 17494 } 17495 // If a process has held a wake lock for more 17496 // than 50% of the time during this period, 17497 // that sounds bad. Kill! 17498 if (doWakeKills && realtimeSince > 0 17499 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17500 synchronized (stats) { 17501 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17502 realtimeSince, wtimeUsed); 17503 } 17504 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17505 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17506 } else if (doCpuKills && uptimeSince > 0 17507 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17508 synchronized (stats) { 17509 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17510 uptimeSince, cputimeUsed); 17511 } 17512 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17513 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17514 } else { 17515 app.lastWakeTime = wtime; 17516 app.lastCpuTime = app.curCpuTime; 17517 } 17518 } 17519 } 17520 } 17521 17522 private final boolean applyOomAdjLocked(ProcessRecord app, 17523 ProcessRecord TOP_APP, boolean doingAll, long now) { 17524 boolean success = true; 17525 17526 if (app.curRawAdj != app.setRawAdj) { 17527 app.setRawAdj = app.curRawAdj; 17528 } 17529 17530 int changes = 0; 17531 17532 if (app.curAdj != app.setAdj) { 17533 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17534 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17535 TAG, "Set " + app.pid + " " + app.processName + 17536 " adj " + app.curAdj + ": " + app.adjType); 17537 app.setAdj = app.curAdj; 17538 } 17539 17540 if (app.setSchedGroup != app.curSchedGroup) { 17541 app.setSchedGroup = app.curSchedGroup; 17542 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17543 "Setting process group of " + app.processName 17544 + " to " + app.curSchedGroup); 17545 if (app.waitingToKill != null && 17546 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17547 app.kill(app.waitingToKill, true); 17548 success = false; 17549 } else { 17550 if (true) { 17551 long oldId = Binder.clearCallingIdentity(); 17552 try { 17553 Process.setProcessGroup(app.pid, app.curSchedGroup); 17554 } catch (Exception e) { 17555 Slog.w(TAG, "Failed setting process group of " + app.pid 17556 + " to " + app.curSchedGroup); 17557 e.printStackTrace(); 17558 } finally { 17559 Binder.restoreCallingIdentity(oldId); 17560 } 17561 } else { 17562 if (app.thread != null) { 17563 try { 17564 app.thread.setSchedulingGroup(app.curSchedGroup); 17565 } catch (RemoteException e) { 17566 } 17567 } 17568 } 17569 Process.setSwappiness(app.pid, 17570 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17571 } 17572 } 17573 if (app.repForegroundActivities != app.foregroundActivities) { 17574 app.repForegroundActivities = app.foregroundActivities; 17575 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17576 } 17577 if (app.repProcState != app.curProcState) { 17578 app.repProcState = app.curProcState; 17579 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17580 if (app.thread != null) { 17581 try { 17582 if (false) { 17583 //RuntimeException h = new RuntimeException("here"); 17584 Slog.i(TAG, "Sending new process state " + app.repProcState 17585 + " to " + app /*, h*/); 17586 } 17587 app.thread.setProcessState(app.repProcState); 17588 } catch (RemoteException e) { 17589 } 17590 } 17591 } 17592 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17593 app.setProcState)) { 17594 app.lastStateTime = now; 17595 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17596 isSleeping(), now); 17597 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17598 + ProcessList.makeProcStateString(app.setProcState) + " to " 17599 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17600 + (app.nextPssTime-now) + ": " + app); 17601 } else { 17602 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17603 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17604 requestPssLocked(app, app.setProcState); 17605 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17606 isSleeping(), now); 17607 } else if (false && DEBUG_PSS) { 17608 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17609 } 17610 } 17611 if (app.setProcState != app.curProcState) { 17612 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17613 "Proc state change of " + app.processName 17614 + " to " + app.curProcState); 17615 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17616 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17617 if (setImportant && !curImportant) { 17618 // This app is no longer something we consider important enough to allow to 17619 // use arbitrary amounts of battery power. Note 17620 // its current wake lock time to later know to kill it if 17621 // it is not behaving well. 17622 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17623 synchronized (stats) { 17624 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17625 app.pid, SystemClock.elapsedRealtime()); 17626 } 17627 app.lastCpuTime = app.curCpuTime; 17628 17629 } 17630 app.setProcState = app.curProcState; 17631 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17632 app.notCachedSinceIdle = false; 17633 } 17634 if (!doingAll) { 17635 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17636 } else { 17637 app.procStateChanged = true; 17638 } 17639 } 17640 17641 if (changes != 0) { 17642 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17643 int i = mPendingProcessChanges.size()-1; 17644 ProcessChangeItem item = null; 17645 while (i >= 0) { 17646 item = mPendingProcessChanges.get(i); 17647 if (item.pid == app.pid) { 17648 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17649 break; 17650 } 17651 i--; 17652 } 17653 if (i < 0) { 17654 // No existing item in pending changes; need a new one. 17655 final int NA = mAvailProcessChanges.size(); 17656 if (NA > 0) { 17657 item = mAvailProcessChanges.remove(NA-1); 17658 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17659 } else { 17660 item = new ProcessChangeItem(); 17661 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17662 } 17663 item.changes = 0; 17664 item.pid = app.pid; 17665 item.uid = app.info.uid; 17666 if (mPendingProcessChanges.size() == 0) { 17667 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17668 "*** Enqueueing dispatch processes changed!"); 17669 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17670 } 17671 mPendingProcessChanges.add(item); 17672 } 17673 item.changes |= changes; 17674 item.processState = app.repProcState; 17675 item.foregroundActivities = app.repForegroundActivities; 17676 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17677 + Integer.toHexString(System.identityHashCode(item)) 17678 + " " + app.toShortString() + ": changes=" + item.changes 17679 + " procState=" + item.processState 17680 + " foreground=" + item.foregroundActivities 17681 + " type=" + app.adjType + " source=" + app.adjSource 17682 + " target=" + app.adjTarget); 17683 } 17684 17685 return success; 17686 } 17687 17688 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17689 if (proc.thread != null) { 17690 if (proc.baseProcessTracker != null) { 17691 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17692 } 17693 if (proc.repProcState >= 0) { 17694 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17695 proc.repProcState); 17696 } 17697 } 17698 } 17699 17700 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17701 ProcessRecord TOP_APP, boolean doingAll, long now) { 17702 if (app.thread == null) { 17703 return false; 17704 } 17705 17706 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17707 17708 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17709 } 17710 17711 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17712 boolean oomAdj) { 17713 if (isForeground != proc.foregroundServices) { 17714 proc.foregroundServices = isForeground; 17715 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17716 proc.info.uid); 17717 if (isForeground) { 17718 if (curProcs == null) { 17719 curProcs = new ArrayList<ProcessRecord>(); 17720 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17721 } 17722 if (!curProcs.contains(proc)) { 17723 curProcs.add(proc); 17724 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17725 proc.info.packageName, proc.info.uid); 17726 } 17727 } else { 17728 if (curProcs != null) { 17729 if (curProcs.remove(proc)) { 17730 mBatteryStatsService.noteEvent( 17731 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17732 proc.info.packageName, proc.info.uid); 17733 if (curProcs.size() <= 0) { 17734 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17735 } 17736 } 17737 } 17738 } 17739 if (oomAdj) { 17740 updateOomAdjLocked(); 17741 } 17742 } 17743 } 17744 17745 private final ActivityRecord resumedAppLocked() { 17746 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17747 String pkg; 17748 int uid; 17749 if (act != null) { 17750 pkg = act.packageName; 17751 uid = act.info.applicationInfo.uid; 17752 } else { 17753 pkg = null; 17754 uid = -1; 17755 } 17756 // Has the UID or resumed package name changed? 17757 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17758 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17759 if (mCurResumedPackage != null) { 17760 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17761 mCurResumedPackage, mCurResumedUid); 17762 } 17763 mCurResumedPackage = pkg; 17764 mCurResumedUid = uid; 17765 if (mCurResumedPackage != null) { 17766 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17767 mCurResumedPackage, mCurResumedUid); 17768 } 17769 } 17770 return act; 17771 } 17772 17773 final boolean updateOomAdjLocked(ProcessRecord app) { 17774 final ActivityRecord TOP_ACT = resumedAppLocked(); 17775 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17776 final boolean wasCached = app.cached; 17777 17778 mAdjSeq++; 17779 17780 // This is the desired cached adjusment we want to tell it to use. 17781 // If our app is currently cached, we know it, and that is it. Otherwise, 17782 // we don't know it yet, and it needs to now be cached we will then 17783 // need to do a complete oom adj. 17784 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17785 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17786 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17787 SystemClock.uptimeMillis()); 17788 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17789 // Changed to/from cached state, so apps after it in the LRU 17790 // list may also be changed. 17791 updateOomAdjLocked(); 17792 } 17793 return success; 17794 } 17795 17796 final void updateOomAdjLocked() { 17797 final ActivityRecord TOP_ACT = resumedAppLocked(); 17798 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17799 final long now = SystemClock.uptimeMillis(); 17800 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17801 final int N = mLruProcesses.size(); 17802 17803 if (false) { 17804 RuntimeException e = new RuntimeException(); 17805 e.fillInStackTrace(); 17806 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17807 } 17808 17809 mAdjSeq++; 17810 mNewNumServiceProcs = 0; 17811 mNewNumAServiceProcs = 0; 17812 17813 final int emptyProcessLimit; 17814 final int cachedProcessLimit; 17815 if (mProcessLimit <= 0) { 17816 emptyProcessLimit = cachedProcessLimit = 0; 17817 } else if (mProcessLimit == 1) { 17818 emptyProcessLimit = 1; 17819 cachedProcessLimit = 0; 17820 } else { 17821 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17822 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17823 } 17824 17825 // Let's determine how many processes we have running vs. 17826 // how many slots we have for background processes; we may want 17827 // to put multiple processes in a slot of there are enough of 17828 // them. 17829 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17830 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17831 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17832 if (numEmptyProcs > cachedProcessLimit) { 17833 // If there are more empty processes than our limit on cached 17834 // processes, then use the cached process limit for the factor. 17835 // This ensures that the really old empty processes get pushed 17836 // down to the bottom, so if we are running low on memory we will 17837 // have a better chance at keeping around more cached processes 17838 // instead of a gazillion empty processes. 17839 numEmptyProcs = cachedProcessLimit; 17840 } 17841 int emptyFactor = numEmptyProcs/numSlots; 17842 if (emptyFactor < 1) emptyFactor = 1; 17843 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17844 if (cachedFactor < 1) cachedFactor = 1; 17845 int stepCached = 0; 17846 int stepEmpty = 0; 17847 int numCached = 0; 17848 int numEmpty = 0; 17849 int numTrimming = 0; 17850 17851 mNumNonCachedProcs = 0; 17852 mNumCachedHiddenProcs = 0; 17853 17854 // First update the OOM adjustment for each of the 17855 // application processes based on their current state. 17856 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17857 int nextCachedAdj = curCachedAdj+1; 17858 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17859 int nextEmptyAdj = curEmptyAdj+2; 17860 for (int i=N-1; i>=0; i--) { 17861 ProcessRecord app = mLruProcesses.get(i); 17862 if (!app.killedByAm && app.thread != null) { 17863 app.procStateChanged = false; 17864 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17865 17866 // If we haven't yet assigned the final cached adj 17867 // to the process, do that now. 17868 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17869 switch (app.curProcState) { 17870 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17871 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17872 // This process is a cached process holding activities... 17873 // assign it the next cached value for that type, and then 17874 // step that cached level. 17875 app.curRawAdj = curCachedAdj; 17876 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17877 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17878 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17879 + ")"); 17880 if (curCachedAdj != nextCachedAdj) { 17881 stepCached++; 17882 if (stepCached >= cachedFactor) { 17883 stepCached = 0; 17884 curCachedAdj = nextCachedAdj; 17885 nextCachedAdj += 2; 17886 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17887 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17888 } 17889 } 17890 } 17891 break; 17892 default: 17893 // For everything else, assign next empty cached process 17894 // level and bump that up. Note that this means that 17895 // long-running services that have dropped down to the 17896 // cached level will be treated as empty (since their process 17897 // state is still as a service), which is what we want. 17898 app.curRawAdj = curEmptyAdj; 17899 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17900 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17901 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17902 + ")"); 17903 if (curEmptyAdj != nextEmptyAdj) { 17904 stepEmpty++; 17905 if (stepEmpty >= emptyFactor) { 17906 stepEmpty = 0; 17907 curEmptyAdj = nextEmptyAdj; 17908 nextEmptyAdj += 2; 17909 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17910 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17911 } 17912 } 17913 } 17914 break; 17915 } 17916 } 17917 17918 applyOomAdjLocked(app, TOP_APP, true, now); 17919 17920 // Count the number of process types. 17921 switch (app.curProcState) { 17922 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17923 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17924 mNumCachedHiddenProcs++; 17925 numCached++; 17926 if (numCached > cachedProcessLimit) { 17927 app.kill("cached #" + numCached, true); 17928 } 17929 break; 17930 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17931 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17932 && app.lastActivityTime < oldTime) { 17933 app.kill("empty for " 17934 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17935 / 1000) + "s", true); 17936 } else { 17937 numEmpty++; 17938 if (numEmpty > emptyProcessLimit) { 17939 app.kill("empty #" + numEmpty, true); 17940 } 17941 } 17942 break; 17943 default: 17944 mNumNonCachedProcs++; 17945 break; 17946 } 17947 17948 if (app.isolated && app.services.size() <= 0) { 17949 // If this is an isolated process, and there are no 17950 // services running in it, then the process is no longer 17951 // needed. We agressively kill these because we can by 17952 // definition not re-use the same process again, and it is 17953 // good to avoid having whatever code was running in them 17954 // left sitting around after no longer needed. 17955 app.kill("isolated not needed", true); 17956 } 17957 17958 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17959 && !app.killedByAm) { 17960 numTrimming++; 17961 } 17962 } 17963 } 17964 17965 mNumServiceProcs = mNewNumServiceProcs; 17966 17967 // Now determine the memory trimming level of background processes. 17968 // Unfortunately we need to start at the back of the list to do this 17969 // properly. We only do this if the number of background apps we 17970 // are managing to keep around is less than half the maximum we desire; 17971 // if we are keeping a good number around, we'll let them use whatever 17972 // memory they want. 17973 final int numCachedAndEmpty = numCached + numEmpty; 17974 int memFactor; 17975 if (numCached <= ProcessList.TRIM_CACHED_APPS 17976 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17977 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17978 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17979 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17980 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17981 } else { 17982 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17983 } 17984 } else { 17985 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17986 } 17987 // We always allow the memory level to go up (better). We only allow it to go 17988 // down if we are in a state where that is allowed, *and* the total number of processes 17989 // has gone down since last time. 17990 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17991 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17992 + " last=" + mLastNumProcesses); 17993 if (memFactor > mLastMemoryLevel) { 17994 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17995 memFactor = mLastMemoryLevel; 17996 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17997 } 17998 } 17999 mLastMemoryLevel = memFactor; 18000 mLastNumProcesses = mLruProcesses.size(); 18001 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18002 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18003 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18004 if (mLowRamStartTime == 0) { 18005 mLowRamStartTime = now; 18006 } 18007 int step = 0; 18008 int fgTrimLevel; 18009 switch (memFactor) { 18010 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18011 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18012 break; 18013 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18014 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18015 break; 18016 default: 18017 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18018 break; 18019 } 18020 int factor = numTrimming/3; 18021 int minFactor = 2; 18022 if (mHomeProcess != null) minFactor++; 18023 if (mPreviousProcess != null) minFactor++; 18024 if (factor < minFactor) factor = minFactor; 18025 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18026 for (int i=N-1; i>=0; i--) { 18027 ProcessRecord app = mLruProcesses.get(i); 18028 if (allChanged || app.procStateChanged) { 18029 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18030 app.procStateChanged = false; 18031 } 18032 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18033 && !app.killedByAm) { 18034 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18035 try { 18036 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18037 "Trimming memory of " + app.processName 18038 + " to " + curLevel); 18039 app.thread.scheduleTrimMemory(curLevel); 18040 } catch (RemoteException e) { 18041 } 18042 if (false) { 18043 // For now we won't do this; our memory trimming seems 18044 // to be good enough at this point that destroying 18045 // activities causes more harm than good. 18046 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18047 && app != mHomeProcess && app != mPreviousProcess) { 18048 // Need to do this on its own message because the stack may not 18049 // be in a consistent state at this point. 18050 // For these apps we will also finish their activities 18051 // to help them free memory. 18052 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18053 } 18054 } 18055 } 18056 app.trimMemoryLevel = curLevel; 18057 step++; 18058 if (step >= factor) { 18059 step = 0; 18060 switch (curLevel) { 18061 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18062 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18063 break; 18064 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18065 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18066 break; 18067 } 18068 } 18069 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18070 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18071 && app.thread != null) { 18072 try { 18073 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18074 "Trimming memory of heavy-weight " + app.processName 18075 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18076 app.thread.scheduleTrimMemory( 18077 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18078 } catch (RemoteException e) { 18079 } 18080 } 18081 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18082 } else { 18083 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18084 || app.systemNoUi) && app.pendingUiClean) { 18085 // If this application is now in the background and it 18086 // had done UI, then give it the special trim level to 18087 // have it free UI resources. 18088 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18089 if (app.trimMemoryLevel < level && app.thread != null) { 18090 try { 18091 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18092 "Trimming memory of bg-ui " + app.processName 18093 + " to " + level); 18094 app.thread.scheduleTrimMemory(level); 18095 } catch (RemoteException e) { 18096 } 18097 } 18098 app.pendingUiClean = false; 18099 } 18100 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18101 try { 18102 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18103 "Trimming memory of fg " + app.processName 18104 + " to " + fgTrimLevel); 18105 app.thread.scheduleTrimMemory(fgTrimLevel); 18106 } catch (RemoteException e) { 18107 } 18108 } 18109 app.trimMemoryLevel = fgTrimLevel; 18110 } 18111 } 18112 } else { 18113 if (mLowRamStartTime != 0) { 18114 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18115 mLowRamStartTime = 0; 18116 } 18117 for (int i=N-1; i>=0; i--) { 18118 ProcessRecord app = mLruProcesses.get(i); 18119 if (allChanged || app.procStateChanged) { 18120 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18121 app.procStateChanged = false; 18122 } 18123 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18124 || app.systemNoUi) && app.pendingUiClean) { 18125 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18126 && app.thread != null) { 18127 try { 18128 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18129 "Trimming memory of ui hidden " + app.processName 18130 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18131 app.thread.scheduleTrimMemory( 18132 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18133 } catch (RemoteException e) { 18134 } 18135 } 18136 app.pendingUiClean = false; 18137 } 18138 app.trimMemoryLevel = 0; 18139 } 18140 } 18141 18142 if (mAlwaysFinishActivities) { 18143 // Need to do this on its own message because the stack may not 18144 // be in a consistent state at this point. 18145 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18146 } 18147 18148 if (allChanged) { 18149 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18150 } 18151 18152 if (mProcessStats.shouldWriteNowLocked(now)) { 18153 mHandler.post(new Runnable() { 18154 @Override public void run() { 18155 synchronized (ActivityManagerService.this) { 18156 mProcessStats.writeStateAsyncLocked(); 18157 } 18158 } 18159 }); 18160 } 18161 18162 if (DEBUG_OOM_ADJ) { 18163 if (false) { 18164 RuntimeException here = new RuntimeException("here"); 18165 here.fillInStackTrace(); 18166 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18167 } else { 18168 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18169 } 18170 } 18171 } 18172 18173 final void trimApplications() { 18174 synchronized (this) { 18175 int i; 18176 18177 // First remove any unused application processes whose package 18178 // has been removed. 18179 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18180 final ProcessRecord app = mRemovedProcesses.get(i); 18181 if (app.activities.size() == 0 18182 && app.curReceiver == null && app.services.size() == 0) { 18183 Slog.i( 18184 TAG, "Exiting empty application process " 18185 + app.processName + " (" 18186 + (app.thread != null ? app.thread.asBinder() : null) 18187 + ")\n"); 18188 if (app.pid > 0 && app.pid != MY_PID) { 18189 app.kill("empty", false); 18190 } else { 18191 try { 18192 app.thread.scheduleExit(); 18193 } catch (Exception e) { 18194 // Ignore exceptions. 18195 } 18196 } 18197 cleanUpApplicationRecordLocked(app, false, true, -1); 18198 mRemovedProcesses.remove(i); 18199 18200 if (app.persistent) { 18201 addAppLocked(app.info, false, null /* ABI override */); 18202 } 18203 } 18204 } 18205 18206 // Now update the oom adj for all processes. 18207 updateOomAdjLocked(); 18208 } 18209 } 18210 18211 /** This method sends the specified signal to each of the persistent apps */ 18212 public void signalPersistentProcesses(int sig) throws RemoteException { 18213 if (sig != Process.SIGNAL_USR1) { 18214 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18215 } 18216 18217 synchronized (this) { 18218 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18219 != PackageManager.PERMISSION_GRANTED) { 18220 throw new SecurityException("Requires permission " 18221 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18222 } 18223 18224 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18225 ProcessRecord r = mLruProcesses.get(i); 18226 if (r.thread != null && r.persistent) { 18227 Process.sendSignal(r.pid, sig); 18228 } 18229 } 18230 } 18231 } 18232 18233 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18234 if (proc == null || proc == mProfileProc) { 18235 proc = mProfileProc; 18236 profileType = mProfileType; 18237 clearProfilerLocked(); 18238 } 18239 if (proc == null) { 18240 return; 18241 } 18242 try { 18243 proc.thread.profilerControl(false, null, profileType); 18244 } catch (RemoteException e) { 18245 throw new IllegalStateException("Process disappeared"); 18246 } 18247 } 18248 18249 private void clearProfilerLocked() { 18250 if (mProfileFd != null) { 18251 try { 18252 mProfileFd.close(); 18253 } catch (IOException e) { 18254 } 18255 } 18256 mProfileApp = null; 18257 mProfileProc = null; 18258 mProfileFile = null; 18259 mProfileType = 0; 18260 mAutoStopProfiler = false; 18261 mSamplingInterval = 0; 18262 } 18263 18264 public boolean profileControl(String process, int userId, boolean start, 18265 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18266 18267 try { 18268 synchronized (this) { 18269 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18270 // its own permission. 18271 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18272 != PackageManager.PERMISSION_GRANTED) { 18273 throw new SecurityException("Requires permission " 18274 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18275 } 18276 18277 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18278 throw new IllegalArgumentException("null profile info or fd"); 18279 } 18280 18281 ProcessRecord proc = null; 18282 if (process != null) { 18283 proc = findProcessLocked(process, userId, "profileControl"); 18284 } 18285 18286 if (start && (proc == null || proc.thread == null)) { 18287 throw new IllegalArgumentException("Unknown process: " + process); 18288 } 18289 18290 if (start) { 18291 stopProfilerLocked(null, 0); 18292 setProfileApp(proc.info, proc.processName, profilerInfo); 18293 mProfileProc = proc; 18294 mProfileType = profileType; 18295 ParcelFileDescriptor fd = profilerInfo.profileFd; 18296 try { 18297 fd = fd.dup(); 18298 } catch (IOException e) { 18299 fd = null; 18300 } 18301 profilerInfo.profileFd = fd; 18302 proc.thread.profilerControl(start, profilerInfo, profileType); 18303 fd = null; 18304 mProfileFd = null; 18305 } else { 18306 stopProfilerLocked(proc, profileType); 18307 if (profilerInfo != null && profilerInfo.profileFd != null) { 18308 try { 18309 profilerInfo.profileFd.close(); 18310 } catch (IOException e) { 18311 } 18312 } 18313 } 18314 18315 return true; 18316 } 18317 } catch (RemoteException e) { 18318 throw new IllegalStateException("Process disappeared"); 18319 } finally { 18320 if (profilerInfo != null && profilerInfo.profileFd != null) { 18321 try { 18322 profilerInfo.profileFd.close(); 18323 } catch (IOException e) { 18324 } 18325 } 18326 } 18327 } 18328 18329 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18330 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18331 userId, true, ALLOW_FULL_ONLY, callName, null); 18332 ProcessRecord proc = null; 18333 try { 18334 int pid = Integer.parseInt(process); 18335 synchronized (mPidsSelfLocked) { 18336 proc = mPidsSelfLocked.get(pid); 18337 } 18338 } catch (NumberFormatException e) { 18339 } 18340 18341 if (proc == null) { 18342 ArrayMap<String, SparseArray<ProcessRecord>> all 18343 = mProcessNames.getMap(); 18344 SparseArray<ProcessRecord> procs = all.get(process); 18345 if (procs != null && procs.size() > 0) { 18346 proc = procs.valueAt(0); 18347 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18348 for (int i=1; i<procs.size(); i++) { 18349 ProcessRecord thisProc = procs.valueAt(i); 18350 if (thisProc.userId == userId) { 18351 proc = thisProc; 18352 break; 18353 } 18354 } 18355 } 18356 } 18357 } 18358 18359 return proc; 18360 } 18361 18362 public boolean dumpHeap(String process, int userId, boolean managed, 18363 String path, ParcelFileDescriptor fd) throws RemoteException { 18364 18365 try { 18366 synchronized (this) { 18367 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18368 // its own permission (same as profileControl). 18369 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18370 != PackageManager.PERMISSION_GRANTED) { 18371 throw new SecurityException("Requires permission " 18372 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18373 } 18374 18375 if (fd == null) { 18376 throw new IllegalArgumentException("null fd"); 18377 } 18378 18379 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18380 if (proc == null || proc.thread == null) { 18381 throw new IllegalArgumentException("Unknown process: " + process); 18382 } 18383 18384 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18385 if (!isDebuggable) { 18386 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18387 throw new SecurityException("Process not debuggable: " + proc); 18388 } 18389 } 18390 18391 proc.thread.dumpHeap(managed, path, fd); 18392 fd = null; 18393 return true; 18394 } 18395 } catch (RemoteException e) { 18396 throw new IllegalStateException("Process disappeared"); 18397 } finally { 18398 if (fd != null) { 18399 try { 18400 fd.close(); 18401 } catch (IOException e) { 18402 } 18403 } 18404 } 18405 } 18406 18407 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18408 public void monitor() { 18409 synchronized (this) { } 18410 } 18411 18412 void onCoreSettingsChange(Bundle settings) { 18413 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18414 ProcessRecord processRecord = mLruProcesses.get(i); 18415 try { 18416 if (processRecord.thread != null) { 18417 processRecord.thread.setCoreSettings(settings); 18418 } 18419 } catch (RemoteException re) { 18420 /* ignore */ 18421 } 18422 } 18423 } 18424 18425 // Multi-user methods 18426 18427 /** 18428 * Start user, if its not already running, but don't bring it to foreground. 18429 */ 18430 @Override 18431 public boolean startUserInBackground(final int userId) { 18432 return startUser(userId, /* foreground */ false); 18433 } 18434 18435 /** 18436 * Start user, if its not already running, and bring it to foreground. 18437 */ 18438 boolean startUserInForeground(final int userId, Dialog dlg) { 18439 boolean result = startUser(userId, /* foreground */ true); 18440 dlg.dismiss(); 18441 return result; 18442 } 18443 18444 /** 18445 * Refreshes the list of users related to the current user when either a 18446 * user switch happens or when a new related user is started in the 18447 * background. 18448 */ 18449 private void updateCurrentProfileIdsLocked() { 18450 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18451 mCurrentUserId, false /* enabledOnly */); 18452 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18453 for (int i = 0; i < currentProfileIds.length; i++) { 18454 currentProfileIds[i] = profiles.get(i).id; 18455 } 18456 mCurrentProfileIds = currentProfileIds; 18457 18458 synchronized (mUserProfileGroupIdsSelfLocked) { 18459 mUserProfileGroupIdsSelfLocked.clear(); 18460 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18461 for (int i = 0; i < users.size(); i++) { 18462 UserInfo user = users.get(i); 18463 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18464 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18465 } 18466 } 18467 } 18468 } 18469 18470 private Set getProfileIdsLocked(int userId) { 18471 Set userIds = new HashSet<Integer>(); 18472 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18473 userId, false /* enabledOnly */); 18474 for (UserInfo user : profiles) { 18475 userIds.add(Integer.valueOf(user.id)); 18476 } 18477 return userIds; 18478 } 18479 18480 @Override 18481 public boolean switchUser(final int userId) { 18482 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18483 String userName; 18484 synchronized (this) { 18485 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18486 if (userInfo == null) { 18487 Slog.w(TAG, "No user info for user #" + userId); 18488 return false; 18489 } 18490 if (userInfo.isManagedProfile()) { 18491 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18492 return false; 18493 } 18494 userName = userInfo.name; 18495 mTargetUserId = userId; 18496 } 18497 mHandler.removeMessages(START_USER_SWITCH_MSG); 18498 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18499 return true; 18500 } 18501 18502 private void showUserSwitchDialog(int userId, String userName) { 18503 // The dialog will show and then initiate the user switch by calling startUserInForeground 18504 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18505 true /* above system */); 18506 d.show(); 18507 } 18508 18509 private boolean startUser(final int userId, final boolean foreground) { 18510 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18511 != PackageManager.PERMISSION_GRANTED) { 18512 String msg = "Permission Denial: switchUser() from pid=" 18513 + Binder.getCallingPid() 18514 + ", uid=" + Binder.getCallingUid() 18515 + " requires " + INTERACT_ACROSS_USERS_FULL; 18516 Slog.w(TAG, msg); 18517 throw new SecurityException(msg); 18518 } 18519 18520 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18521 18522 final long ident = Binder.clearCallingIdentity(); 18523 try { 18524 synchronized (this) { 18525 final int oldUserId = mCurrentUserId; 18526 if (oldUserId == userId) { 18527 return true; 18528 } 18529 18530 mStackSupervisor.setLockTaskModeLocked(null, false); 18531 18532 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18533 if (userInfo == null) { 18534 Slog.w(TAG, "No user info for user #" + userId); 18535 return false; 18536 } 18537 if (foreground && userInfo.isManagedProfile()) { 18538 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18539 return false; 18540 } 18541 18542 if (foreground) { 18543 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18544 R.anim.screen_user_enter); 18545 } 18546 18547 boolean needStart = false; 18548 18549 // If the user we are switching to is not currently started, then 18550 // we need to start it now. 18551 if (mStartedUsers.get(userId) == null) { 18552 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18553 updateStartedUserArrayLocked(); 18554 needStart = true; 18555 } 18556 18557 final Integer userIdInt = Integer.valueOf(userId); 18558 mUserLru.remove(userIdInt); 18559 mUserLru.add(userIdInt); 18560 18561 if (foreground) { 18562 mCurrentUserId = userId; 18563 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18564 updateCurrentProfileIdsLocked(); 18565 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18566 // Once the internal notion of the active user has switched, we lock the device 18567 // with the option to show the user switcher on the keyguard. 18568 mWindowManager.lockNow(null); 18569 } else { 18570 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18571 updateCurrentProfileIdsLocked(); 18572 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18573 mUserLru.remove(currentUserIdInt); 18574 mUserLru.add(currentUserIdInt); 18575 } 18576 18577 final UserStartedState uss = mStartedUsers.get(userId); 18578 18579 // Make sure user is in the started state. If it is currently 18580 // stopping, we need to knock that off. 18581 if (uss.mState == UserStartedState.STATE_STOPPING) { 18582 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18583 // so we can just fairly silently bring the user back from 18584 // the almost-dead. 18585 uss.mState = UserStartedState.STATE_RUNNING; 18586 updateStartedUserArrayLocked(); 18587 needStart = true; 18588 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18589 // This means ACTION_SHUTDOWN has been sent, so we will 18590 // need to treat this as a new boot of the user. 18591 uss.mState = UserStartedState.STATE_BOOTING; 18592 updateStartedUserArrayLocked(); 18593 needStart = true; 18594 } 18595 18596 if (uss.mState == UserStartedState.STATE_BOOTING) { 18597 // Booting up a new user, need to tell system services about it. 18598 // Note that this is on the same handler as scheduling of broadcasts, 18599 // which is important because it needs to go first. 18600 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18601 } 18602 18603 if (foreground) { 18604 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18605 oldUserId)); 18606 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18607 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18608 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18609 oldUserId, userId, uss)); 18610 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18611 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18612 } 18613 18614 if (needStart) { 18615 // Send USER_STARTED broadcast 18616 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18617 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18618 | Intent.FLAG_RECEIVER_FOREGROUND); 18619 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18620 broadcastIntentLocked(null, null, intent, 18621 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18622 false, false, MY_PID, Process.SYSTEM_UID, userId); 18623 } 18624 18625 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18626 if (userId != UserHandle.USER_OWNER) { 18627 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18628 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18629 broadcastIntentLocked(null, null, intent, null, 18630 new IIntentReceiver.Stub() { 18631 public void performReceive(Intent intent, int resultCode, 18632 String data, Bundle extras, boolean ordered, 18633 boolean sticky, int sendingUser) { 18634 onUserInitialized(uss, foreground, oldUserId, userId); 18635 } 18636 }, 0, null, null, null, AppOpsManager.OP_NONE, 18637 true, false, MY_PID, Process.SYSTEM_UID, 18638 userId); 18639 uss.initializing = true; 18640 } else { 18641 getUserManagerLocked().makeInitialized(userInfo.id); 18642 } 18643 } 18644 18645 if (foreground) { 18646 if (!uss.initializing) { 18647 moveUserToForeground(uss, oldUserId, userId); 18648 } 18649 } else { 18650 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18651 } 18652 18653 if (needStart) { 18654 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18655 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18656 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18657 broadcastIntentLocked(null, null, intent, 18658 null, new IIntentReceiver.Stub() { 18659 @Override 18660 public void performReceive(Intent intent, int resultCode, String data, 18661 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18662 throws RemoteException { 18663 } 18664 }, 0, null, null, 18665 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18666 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18667 } 18668 } 18669 } finally { 18670 Binder.restoreCallingIdentity(ident); 18671 } 18672 18673 return true; 18674 } 18675 18676 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18677 long ident = Binder.clearCallingIdentity(); 18678 try { 18679 Intent intent; 18680 if (oldUserId >= 0) { 18681 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18682 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18683 int count = profiles.size(); 18684 for (int i = 0; i < count; i++) { 18685 int profileUserId = profiles.get(i).id; 18686 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18687 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18688 | Intent.FLAG_RECEIVER_FOREGROUND); 18689 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18690 broadcastIntentLocked(null, null, intent, 18691 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18692 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18693 } 18694 } 18695 if (newUserId >= 0) { 18696 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18697 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18698 int count = profiles.size(); 18699 for (int i = 0; i < count; i++) { 18700 int profileUserId = profiles.get(i).id; 18701 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18702 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18703 | Intent.FLAG_RECEIVER_FOREGROUND); 18704 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18705 broadcastIntentLocked(null, null, intent, 18706 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18707 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18708 } 18709 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18710 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18711 | Intent.FLAG_RECEIVER_FOREGROUND); 18712 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18713 broadcastIntentLocked(null, null, intent, 18714 null, null, 0, null, null, 18715 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18716 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18717 } 18718 } finally { 18719 Binder.restoreCallingIdentity(ident); 18720 } 18721 } 18722 18723 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18724 final int newUserId) { 18725 final int N = mUserSwitchObservers.beginBroadcast(); 18726 if (N > 0) { 18727 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18728 int mCount = 0; 18729 @Override 18730 public void sendResult(Bundle data) throws RemoteException { 18731 synchronized (ActivityManagerService.this) { 18732 if (mCurUserSwitchCallback == this) { 18733 mCount++; 18734 if (mCount == N) { 18735 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18736 } 18737 } 18738 } 18739 } 18740 }; 18741 synchronized (this) { 18742 uss.switching = true; 18743 mCurUserSwitchCallback = callback; 18744 } 18745 for (int i=0; i<N; i++) { 18746 try { 18747 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18748 newUserId, callback); 18749 } catch (RemoteException e) { 18750 } 18751 } 18752 } else { 18753 synchronized (this) { 18754 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18755 } 18756 } 18757 mUserSwitchObservers.finishBroadcast(); 18758 } 18759 18760 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18761 synchronized (this) { 18762 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18763 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18764 } 18765 } 18766 18767 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18768 mCurUserSwitchCallback = null; 18769 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18770 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18771 oldUserId, newUserId, uss)); 18772 } 18773 18774 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18775 synchronized (this) { 18776 if (foreground) { 18777 moveUserToForeground(uss, oldUserId, newUserId); 18778 } 18779 } 18780 18781 completeSwitchAndInitalize(uss, newUserId, true, false); 18782 } 18783 18784 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18785 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18786 if (homeInFront) { 18787 startHomeActivityLocked(newUserId); 18788 } else { 18789 mStackSupervisor.resumeTopActivitiesLocked(); 18790 } 18791 EventLogTags.writeAmSwitchUser(newUserId); 18792 getUserManagerLocked().userForeground(newUserId); 18793 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18794 } 18795 18796 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18797 completeSwitchAndInitalize(uss, newUserId, false, true); 18798 } 18799 18800 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18801 boolean clearInitializing, boolean clearSwitching) { 18802 boolean unfrozen = false; 18803 synchronized (this) { 18804 if (clearInitializing) { 18805 uss.initializing = false; 18806 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18807 } 18808 if (clearSwitching) { 18809 uss.switching = false; 18810 } 18811 if (!uss.switching && !uss.initializing) { 18812 mWindowManager.stopFreezingScreen(); 18813 unfrozen = true; 18814 } 18815 } 18816 if (unfrozen) { 18817 final int N = mUserSwitchObservers.beginBroadcast(); 18818 for (int i=0; i<N; i++) { 18819 try { 18820 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18821 } catch (RemoteException e) { 18822 } 18823 } 18824 mUserSwitchObservers.finishBroadcast(); 18825 } 18826 } 18827 18828 void scheduleStartProfilesLocked() { 18829 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18830 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18831 DateUtils.SECOND_IN_MILLIS); 18832 } 18833 } 18834 18835 void startProfilesLocked() { 18836 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18837 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18838 mCurrentUserId, false /* enabledOnly */); 18839 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18840 for (UserInfo user : profiles) { 18841 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18842 && user.id != mCurrentUserId) { 18843 toStart.add(user); 18844 } 18845 } 18846 final int n = toStart.size(); 18847 int i = 0; 18848 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18849 startUserInBackground(toStart.get(i).id); 18850 } 18851 if (i < n) { 18852 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18853 } 18854 } 18855 18856 void finishUserBoot(UserStartedState uss) { 18857 synchronized (this) { 18858 if (uss.mState == UserStartedState.STATE_BOOTING 18859 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18860 uss.mState = UserStartedState.STATE_RUNNING; 18861 final int userId = uss.mHandle.getIdentifier(); 18862 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18863 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18864 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18865 broadcastIntentLocked(null, null, intent, 18866 null, null, 0, null, null, 18867 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18868 true, false, MY_PID, Process.SYSTEM_UID, userId); 18869 } 18870 } 18871 } 18872 18873 void finishUserSwitch(UserStartedState uss) { 18874 synchronized (this) { 18875 finishUserBoot(uss); 18876 18877 startProfilesLocked(); 18878 18879 int num = mUserLru.size(); 18880 int i = 0; 18881 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18882 Integer oldUserId = mUserLru.get(i); 18883 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18884 if (oldUss == null) { 18885 // Shouldn't happen, but be sane if it does. 18886 mUserLru.remove(i); 18887 num--; 18888 continue; 18889 } 18890 if (oldUss.mState == UserStartedState.STATE_STOPPING 18891 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18892 // This user is already stopping, doesn't count. 18893 num--; 18894 i++; 18895 continue; 18896 } 18897 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18898 // Owner and current can't be stopped, but count as running. 18899 i++; 18900 continue; 18901 } 18902 // This is a user to be stopped. 18903 stopUserLocked(oldUserId, null); 18904 num--; 18905 i++; 18906 } 18907 } 18908 } 18909 18910 @Override 18911 public int stopUser(final int userId, final IStopUserCallback callback) { 18912 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18913 != PackageManager.PERMISSION_GRANTED) { 18914 String msg = "Permission Denial: switchUser() from pid=" 18915 + Binder.getCallingPid() 18916 + ", uid=" + Binder.getCallingUid() 18917 + " requires " + INTERACT_ACROSS_USERS_FULL; 18918 Slog.w(TAG, msg); 18919 throw new SecurityException(msg); 18920 } 18921 if (userId <= 0) { 18922 throw new IllegalArgumentException("Can't stop primary user " + userId); 18923 } 18924 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18925 synchronized (this) { 18926 return stopUserLocked(userId, callback); 18927 } 18928 } 18929 18930 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18931 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18932 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18933 return ActivityManager.USER_OP_IS_CURRENT; 18934 } 18935 18936 final UserStartedState uss = mStartedUsers.get(userId); 18937 if (uss == null) { 18938 // User is not started, nothing to do... but we do need to 18939 // callback if requested. 18940 if (callback != null) { 18941 mHandler.post(new Runnable() { 18942 @Override 18943 public void run() { 18944 try { 18945 callback.userStopped(userId); 18946 } catch (RemoteException e) { 18947 } 18948 } 18949 }); 18950 } 18951 return ActivityManager.USER_OP_SUCCESS; 18952 } 18953 18954 if (callback != null) { 18955 uss.mStopCallbacks.add(callback); 18956 } 18957 18958 if (uss.mState != UserStartedState.STATE_STOPPING 18959 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18960 uss.mState = UserStartedState.STATE_STOPPING; 18961 updateStartedUserArrayLocked(); 18962 18963 long ident = Binder.clearCallingIdentity(); 18964 try { 18965 // We are going to broadcast ACTION_USER_STOPPING and then 18966 // once that is done send a final ACTION_SHUTDOWN and then 18967 // stop the user. 18968 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18969 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18970 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18971 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18972 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18973 // This is the result receiver for the final shutdown broadcast. 18974 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18975 @Override 18976 public void performReceive(Intent intent, int resultCode, String data, 18977 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18978 finishUserStop(uss); 18979 } 18980 }; 18981 // This is the result receiver for the initial stopping broadcast. 18982 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18983 @Override 18984 public void performReceive(Intent intent, int resultCode, String data, 18985 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18986 // On to the next. 18987 synchronized (ActivityManagerService.this) { 18988 if (uss.mState != UserStartedState.STATE_STOPPING) { 18989 // Whoops, we are being started back up. Abort, abort! 18990 return; 18991 } 18992 uss.mState = UserStartedState.STATE_SHUTDOWN; 18993 } 18994 mBatteryStatsService.noteEvent( 18995 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18996 Integer.toString(userId), userId); 18997 mSystemServiceManager.stopUser(userId); 18998 broadcastIntentLocked(null, null, shutdownIntent, 18999 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19000 true, false, MY_PID, Process.SYSTEM_UID, userId); 19001 } 19002 }; 19003 // Kick things off. 19004 broadcastIntentLocked(null, null, stoppingIntent, 19005 null, stoppingReceiver, 0, null, null, 19006 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19007 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19008 } finally { 19009 Binder.restoreCallingIdentity(ident); 19010 } 19011 } 19012 19013 return ActivityManager.USER_OP_SUCCESS; 19014 } 19015 19016 void finishUserStop(UserStartedState uss) { 19017 final int userId = uss.mHandle.getIdentifier(); 19018 boolean stopped; 19019 ArrayList<IStopUserCallback> callbacks; 19020 synchronized (this) { 19021 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19022 if (mStartedUsers.get(userId) != uss) { 19023 stopped = false; 19024 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19025 stopped = false; 19026 } else { 19027 stopped = true; 19028 // User can no longer run. 19029 mStartedUsers.remove(userId); 19030 mUserLru.remove(Integer.valueOf(userId)); 19031 updateStartedUserArrayLocked(); 19032 19033 // Clean up all state and processes associated with the user. 19034 // Kill all the processes for the user. 19035 forceStopUserLocked(userId, "finish user"); 19036 } 19037 19038 // Explicitly remove the old information in mRecentTasks. 19039 removeRecentTasksForUserLocked(userId); 19040 } 19041 19042 for (int i=0; i<callbacks.size(); i++) { 19043 try { 19044 if (stopped) callbacks.get(i).userStopped(userId); 19045 else callbacks.get(i).userStopAborted(userId); 19046 } catch (RemoteException e) { 19047 } 19048 } 19049 19050 if (stopped) { 19051 mSystemServiceManager.cleanupUser(userId); 19052 synchronized (this) { 19053 mStackSupervisor.removeUserLocked(userId); 19054 } 19055 } 19056 } 19057 19058 @Override 19059 public UserInfo getCurrentUser() { 19060 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19061 != PackageManager.PERMISSION_GRANTED) && ( 19062 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19063 != PackageManager.PERMISSION_GRANTED)) { 19064 String msg = "Permission Denial: getCurrentUser() from pid=" 19065 + Binder.getCallingPid() 19066 + ", uid=" + Binder.getCallingUid() 19067 + " requires " + INTERACT_ACROSS_USERS; 19068 Slog.w(TAG, msg); 19069 throw new SecurityException(msg); 19070 } 19071 synchronized (this) { 19072 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19073 return getUserManagerLocked().getUserInfo(userId); 19074 } 19075 } 19076 19077 int getCurrentUserIdLocked() { 19078 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19079 } 19080 19081 @Override 19082 public boolean isUserRunning(int userId, boolean orStopped) { 19083 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19084 != PackageManager.PERMISSION_GRANTED) { 19085 String msg = "Permission Denial: isUserRunning() from pid=" 19086 + Binder.getCallingPid() 19087 + ", uid=" + Binder.getCallingUid() 19088 + " requires " + INTERACT_ACROSS_USERS; 19089 Slog.w(TAG, msg); 19090 throw new SecurityException(msg); 19091 } 19092 synchronized (this) { 19093 return isUserRunningLocked(userId, orStopped); 19094 } 19095 } 19096 19097 boolean isUserRunningLocked(int userId, boolean orStopped) { 19098 UserStartedState state = mStartedUsers.get(userId); 19099 if (state == null) { 19100 return false; 19101 } 19102 if (orStopped) { 19103 return true; 19104 } 19105 return state.mState != UserStartedState.STATE_STOPPING 19106 && state.mState != UserStartedState.STATE_SHUTDOWN; 19107 } 19108 19109 @Override 19110 public int[] getRunningUserIds() { 19111 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19112 != PackageManager.PERMISSION_GRANTED) { 19113 String msg = "Permission Denial: isUserRunning() from pid=" 19114 + Binder.getCallingPid() 19115 + ", uid=" + Binder.getCallingUid() 19116 + " requires " + INTERACT_ACROSS_USERS; 19117 Slog.w(TAG, msg); 19118 throw new SecurityException(msg); 19119 } 19120 synchronized (this) { 19121 return mStartedUserArray; 19122 } 19123 } 19124 19125 private void updateStartedUserArrayLocked() { 19126 int num = 0; 19127 for (int i=0; i<mStartedUsers.size(); i++) { 19128 UserStartedState uss = mStartedUsers.valueAt(i); 19129 // This list does not include stopping users. 19130 if (uss.mState != UserStartedState.STATE_STOPPING 19131 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19132 num++; 19133 } 19134 } 19135 mStartedUserArray = new int[num]; 19136 num = 0; 19137 for (int i=0; i<mStartedUsers.size(); i++) { 19138 UserStartedState uss = mStartedUsers.valueAt(i); 19139 if (uss.mState != UserStartedState.STATE_STOPPING 19140 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19141 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19142 num++; 19143 } 19144 } 19145 } 19146 19147 @Override 19148 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19149 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19150 != PackageManager.PERMISSION_GRANTED) { 19151 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19152 + Binder.getCallingPid() 19153 + ", uid=" + Binder.getCallingUid() 19154 + " requires " + INTERACT_ACROSS_USERS_FULL; 19155 Slog.w(TAG, msg); 19156 throw new SecurityException(msg); 19157 } 19158 19159 mUserSwitchObservers.register(observer); 19160 } 19161 19162 @Override 19163 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19164 mUserSwitchObservers.unregister(observer); 19165 } 19166 19167 private boolean userExists(int userId) { 19168 if (userId == 0) { 19169 return true; 19170 } 19171 UserManagerService ums = getUserManagerLocked(); 19172 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19173 } 19174 19175 int[] getUsersLocked() { 19176 UserManagerService ums = getUserManagerLocked(); 19177 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19178 } 19179 19180 UserManagerService getUserManagerLocked() { 19181 if (mUserManager == null) { 19182 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19183 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19184 } 19185 return mUserManager; 19186 } 19187 19188 private int applyUserId(int uid, int userId) { 19189 return UserHandle.getUid(userId, uid); 19190 } 19191 19192 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19193 if (info == null) return null; 19194 ApplicationInfo newInfo = new ApplicationInfo(info); 19195 newInfo.uid = applyUserId(info.uid, userId); 19196 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19197 + info.packageName; 19198 return newInfo; 19199 } 19200 19201 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19202 if (aInfo == null 19203 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19204 return aInfo; 19205 } 19206 19207 ActivityInfo info = new ActivityInfo(aInfo); 19208 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19209 return info; 19210 } 19211 19212 private final class LocalService extends ActivityManagerInternal { 19213 @Override 19214 public void goingToSleep() { 19215 ActivityManagerService.this.goingToSleep(); 19216 } 19217 19218 @Override 19219 public void wakingUp() { 19220 ActivityManagerService.this.wakingUp(); 19221 } 19222 19223 @Override 19224 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19225 String processName, String abiOverride, int uid, Runnable crashHandler) { 19226 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19227 processName, abiOverride, uid, crashHandler); 19228 } 19229 } 19230 19231 /** 19232 * An implementation of IAppTask, that allows an app to manage its own tasks via 19233 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19234 * only the process that calls getAppTasks() can call the AppTask methods. 19235 */ 19236 class AppTaskImpl extends IAppTask.Stub { 19237 private int mTaskId; 19238 private int mCallingUid; 19239 19240 public AppTaskImpl(int taskId, int callingUid) { 19241 mTaskId = taskId; 19242 mCallingUid = callingUid; 19243 } 19244 19245 private void checkCaller() { 19246 if (mCallingUid != Binder.getCallingUid()) { 19247 throw new SecurityException("Caller " + mCallingUid 19248 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19249 } 19250 } 19251 19252 @Override 19253 public void finishAndRemoveTask() { 19254 checkCaller(); 19255 19256 synchronized (ActivityManagerService.this) { 19257 long origId = Binder.clearCallingIdentity(); 19258 try { 19259 if (!removeTaskByIdLocked(mTaskId, false)) { 19260 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19261 } 19262 } finally { 19263 Binder.restoreCallingIdentity(origId); 19264 } 19265 } 19266 } 19267 19268 @Override 19269 public ActivityManager.RecentTaskInfo getTaskInfo() { 19270 checkCaller(); 19271 19272 synchronized (ActivityManagerService.this) { 19273 long origId = Binder.clearCallingIdentity(); 19274 try { 19275 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19276 if (tr == null) { 19277 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19278 } 19279 return createRecentTaskInfoFromTaskRecord(tr); 19280 } finally { 19281 Binder.restoreCallingIdentity(origId); 19282 } 19283 } 19284 } 19285 19286 @Override 19287 public void moveToFront() { 19288 checkCaller(); 19289 19290 final TaskRecord tr; 19291 synchronized (ActivityManagerService.this) { 19292 tr = recentTaskForIdLocked(mTaskId); 19293 if (tr == null) { 19294 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19295 } 19296 if (tr.getRootActivity() != null) { 19297 moveTaskToFrontLocked(tr.taskId, 0, null); 19298 return; 19299 } 19300 } 19301 19302 startActivityFromRecentsInner(tr.taskId, null); 19303 } 19304 19305 @Override 19306 public int startActivity(IBinder whoThread, String callingPackage, 19307 Intent intent, String resolvedType, Bundle options) { 19308 checkCaller(); 19309 19310 int callingUser = UserHandle.getCallingUserId(); 19311 TaskRecord tr; 19312 IApplicationThread appThread; 19313 synchronized (ActivityManagerService.this) { 19314 tr = recentTaskForIdLocked(mTaskId); 19315 if (tr == null) { 19316 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19317 } 19318 appThread = ApplicationThreadNative.asInterface(whoThread); 19319 if (appThread == null) { 19320 throw new IllegalArgumentException("Bad app thread " + appThread); 19321 } 19322 } 19323 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19324 resolvedType, null, null, null, null, 0, 0, null, null, 19325 null, options, callingUser, null, tr); 19326 } 19327 19328 @Override 19329 public void setExcludeFromRecents(boolean exclude) { 19330 checkCaller(); 19331 19332 synchronized (ActivityManagerService.this) { 19333 long origId = Binder.clearCallingIdentity(); 19334 try { 19335 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19336 if (tr == null) { 19337 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19338 } 19339 Intent intent = tr.getBaseIntent(); 19340 if (exclude) { 19341 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19342 } else { 19343 intent.setFlags(intent.getFlags() 19344 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19345 } 19346 } finally { 19347 Binder.restoreCallingIdentity(origId); 19348 } 19349 } 19350 } 19351 } 19352} 19353