ActivityManagerService.java revision 86677c9a511f4478bf94418208e600b1f40db733
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 IM_FEELING_LUCKY_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 1216 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1217 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1218 static final int FIRST_COMPAT_MODE_MSG = 300; 1219 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1220 1221 AlertDialog mUidAlert; 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 String title = "System UIDs Inconsistent"; 1451 String text = "UIDs on the system are inconsistent, you need to wipe your" 1452 + " data partition or your device will be unstable."; 1453 Log.e(TAG, title + ": " + text); 1454 if (mShowDialogs) { 1455 // XXX This is a temporary dialog, no need to localize. 1456 AlertDialog d = new BaseErrorDialog(mContext); 1457 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1458 d.setCancelable(false); 1459 d.setTitle(title); 1460 d.setMessage(text); 1461 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1462 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1463 mUidAlert = d; 1464 d.show(); 1465 } 1466 } break; 1467 case IM_FEELING_LUCKY_MSG: { 1468 if (mUidAlert != null) { 1469 mUidAlert.dismiss(); 1470 mUidAlert = null; 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 } 1731 } 1732 }; 1733 1734 static final int COLLECT_PSS_BG_MSG = 1; 1735 1736 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1737 @Override 1738 public void handleMessage(Message msg) { 1739 switch (msg.what) { 1740 case COLLECT_PSS_BG_MSG: { 1741 long start = SystemClock.uptimeMillis(); 1742 MemInfoReader memInfo = null; 1743 synchronized (ActivityManagerService.this) { 1744 if (mFullPssPending) { 1745 mFullPssPending = false; 1746 memInfo = new MemInfoReader(); 1747 } 1748 } 1749 if (memInfo != null) { 1750 updateCpuStatsNow(); 1751 long nativeTotalPss = 0; 1752 synchronized (mProcessCpuTracker) { 1753 final int N = mProcessCpuTracker.countStats(); 1754 for (int j=0; j<N; j++) { 1755 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1756 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1757 // This is definitely an application process; skip it. 1758 continue; 1759 } 1760 synchronized (mPidsSelfLocked) { 1761 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1762 // This is one of our own processes; skip it. 1763 continue; 1764 } 1765 } 1766 nativeTotalPss += Debug.getPss(st.pid, null); 1767 } 1768 } 1769 memInfo.readMemInfo(); 1770 synchronized (ActivityManagerService.this) { 1771 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1772 + (SystemClock.uptimeMillis()-start) + "ms"); 1773 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1774 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1775 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1776 } 1777 } 1778 1779 int i=0, num=0; 1780 long[] tmp = new long[1]; 1781 do { 1782 ProcessRecord proc; 1783 int procState; 1784 int pid; 1785 synchronized (ActivityManagerService.this) { 1786 if (i >= mPendingPssProcesses.size()) { 1787 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1788 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1789 mPendingPssProcesses.clear(); 1790 return; 1791 } 1792 proc = mPendingPssProcesses.get(i); 1793 procState = proc.pssProcState; 1794 if (proc.thread != null && procState == proc.setProcState) { 1795 pid = proc.pid; 1796 } else { 1797 proc = null; 1798 pid = 0; 1799 } 1800 i++; 1801 } 1802 if (proc != null) { 1803 long pss = Debug.getPss(pid, tmp); 1804 synchronized (ActivityManagerService.this) { 1805 if (proc.thread != null && proc.setProcState == procState 1806 && proc.pid == pid) { 1807 num++; 1808 proc.lastPssTime = SystemClock.uptimeMillis(); 1809 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1810 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1811 + ": " + pss + " lastPss=" + proc.lastPss 1812 + " state=" + ProcessList.makeProcStateString(procState)); 1813 if (proc.initialIdlePss == 0) { 1814 proc.initialIdlePss = pss; 1815 } 1816 proc.lastPss = pss; 1817 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1818 proc.lastCachedPss = pss; 1819 } 1820 } 1821 } 1822 } 1823 } while (true); 1824 } 1825 } 1826 } 1827 }; 1828 1829 /** 1830 * Monitor for package changes and update our internal state. 1831 */ 1832 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1833 @Override 1834 public void onPackageRemoved(String packageName, int uid) { 1835 // Remove all tasks with activities in the specified package from the list of recent tasks 1836 final int eventUserId = getChangingUserId(); 1837 synchronized (ActivityManagerService.this) { 1838 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1839 TaskRecord tr = mRecentTasks.get(i); 1840 if (tr.userId != eventUserId) continue; 1841 1842 ComponentName cn = tr.intent.getComponent(); 1843 if (cn != null && cn.getPackageName().equals(packageName)) { 1844 // If the package name matches, remove the task 1845 removeTaskByIdLocked(tr.taskId, true); 1846 } 1847 } 1848 } 1849 } 1850 1851 @Override 1852 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1853 onPackageModified(packageName); 1854 return true; 1855 } 1856 1857 @Override 1858 public void onPackageModified(String packageName) { 1859 final int eventUserId = getChangingUserId(); 1860 final IPackageManager pm = AppGlobals.getPackageManager(); 1861 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1862 new ArrayList<Pair<Intent, Integer>>(); 1863 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1864 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1865 // Copy the list of recent tasks so that we don't hold onto the lock on 1866 // ActivityManagerService for long periods while checking if components exist. 1867 synchronized (ActivityManagerService.this) { 1868 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1869 TaskRecord tr = mRecentTasks.get(i); 1870 if (tr.userId != eventUserId) continue; 1871 1872 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1873 } 1874 } 1875 // Check the recent tasks and filter out all tasks with components that no longer exist. 1876 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1877 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1878 ComponentName cn = p.first.getComponent(); 1879 if (cn != null && cn.getPackageName().equals(packageName)) { 1880 if (componentsKnownToExist.contains(cn)) { 1881 // If we know that the component still exists in the package, then skip 1882 continue; 1883 } 1884 try { 1885 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1886 if (info != null) { 1887 componentsKnownToExist.add(cn); 1888 } else { 1889 tasksToRemove.add(p.second); 1890 } 1891 } catch (RemoteException e) { 1892 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1893 } 1894 } 1895 } 1896 // Prune all the tasks with removed components from the list of recent tasks 1897 synchronized (ActivityManagerService.this) { 1898 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1899 removeTaskByIdLocked(tasksToRemove.get(i), false); 1900 } 1901 } 1902 } 1903 1904 @Override 1905 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1906 // Force stop the specified packages 1907 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1908 if (packages != null) { 1909 for (String pkg : packages) { 1910 synchronized (ActivityManagerService.this) { 1911 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1912 userId, "finished booting")) { 1913 return true; 1914 } 1915 } 1916 } 1917 } 1918 return false; 1919 } 1920 }; 1921 1922 public void setSystemProcess() { 1923 try { 1924 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1925 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1926 ServiceManager.addService("meminfo", new MemBinder(this)); 1927 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1928 ServiceManager.addService("dbinfo", new DbBinder(this)); 1929 if (MONITOR_CPU_USAGE) { 1930 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1931 } 1932 ServiceManager.addService("permission", new PermissionController(this)); 1933 1934 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1935 "android", STOCK_PM_FLAGS); 1936 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1937 1938 synchronized (this) { 1939 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1940 app.persistent = true; 1941 app.pid = MY_PID; 1942 app.maxAdj = ProcessList.SYSTEM_ADJ; 1943 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1944 mProcessNames.put(app.processName, app.uid, app); 1945 synchronized (mPidsSelfLocked) { 1946 mPidsSelfLocked.put(app.pid, app); 1947 } 1948 updateLruProcessLocked(app, false, null); 1949 updateOomAdjLocked(); 1950 } 1951 } catch (PackageManager.NameNotFoundException e) { 1952 throw new RuntimeException( 1953 "Unable to find android system package", e); 1954 } 1955 } 1956 1957 public void setWindowManager(WindowManagerService wm) { 1958 mWindowManager = wm; 1959 mStackSupervisor.setWindowManager(wm); 1960 } 1961 1962 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1963 mUsageStatsService = usageStatsManager; 1964 } 1965 1966 public void startObservingNativeCrashes() { 1967 final NativeCrashListener ncl = new NativeCrashListener(this); 1968 ncl.start(); 1969 } 1970 1971 public IAppOpsService getAppOpsService() { 1972 return mAppOpsService; 1973 } 1974 1975 static class MemBinder extends Binder { 1976 ActivityManagerService mActivityManagerService; 1977 MemBinder(ActivityManagerService activityManagerService) { 1978 mActivityManagerService = activityManagerService; 1979 } 1980 1981 @Override 1982 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1983 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1984 != PackageManager.PERMISSION_GRANTED) { 1985 pw.println("Permission Denial: can't dump meminfo from from pid=" 1986 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1987 + " without permission " + android.Manifest.permission.DUMP); 1988 return; 1989 } 1990 1991 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1992 } 1993 } 1994 1995 static class GraphicsBinder extends Binder { 1996 ActivityManagerService mActivityManagerService; 1997 GraphicsBinder(ActivityManagerService activityManagerService) { 1998 mActivityManagerService = activityManagerService; 1999 } 2000 2001 @Override 2002 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2003 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2004 != PackageManager.PERMISSION_GRANTED) { 2005 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2006 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2007 + " without permission " + android.Manifest.permission.DUMP); 2008 return; 2009 } 2010 2011 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2012 } 2013 } 2014 2015 static class DbBinder extends Binder { 2016 ActivityManagerService mActivityManagerService; 2017 DbBinder(ActivityManagerService activityManagerService) { 2018 mActivityManagerService = activityManagerService; 2019 } 2020 2021 @Override 2022 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2023 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2024 != PackageManager.PERMISSION_GRANTED) { 2025 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2026 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2027 + " without permission " + android.Manifest.permission.DUMP); 2028 return; 2029 } 2030 2031 mActivityManagerService.dumpDbInfo(fd, pw, args); 2032 } 2033 } 2034 2035 static class CpuBinder extends Binder { 2036 ActivityManagerService mActivityManagerService; 2037 CpuBinder(ActivityManagerService activityManagerService) { 2038 mActivityManagerService = activityManagerService; 2039 } 2040 2041 @Override 2042 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2043 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2044 != PackageManager.PERMISSION_GRANTED) { 2045 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2046 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2047 + " without permission " + android.Manifest.permission.DUMP); 2048 return; 2049 } 2050 2051 synchronized (mActivityManagerService.mProcessCpuTracker) { 2052 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2053 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2054 SystemClock.uptimeMillis())); 2055 } 2056 } 2057 } 2058 2059 public static final class Lifecycle extends SystemService { 2060 private final ActivityManagerService mService; 2061 2062 public Lifecycle(Context context) { 2063 super(context); 2064 mService = new ActivityManagerService(context); 2065 } 2066 2067 @Override 2068 public void onStart() { 2069 mService.start(); 2070 } 2071 2072 public ActivityManagerService getService() { 2073 return mService; 2074 } 2075 } 2076 2077 // Note: This method is invoked on the main thread but may need to attach various 2078 // handlers to other threads. So take care to be explicit about the looper. 2079 public ActivityManagerService(Context systemContext) { 2080 mContext = systemContext; 2081 mFactoryTest = FactoryTest.getMode(); 2082 mSystemThread = ActivityThread.currentActivityThread(); 2083 2084 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2085 2086 mHandlerThread = new ServiceThread(TAG, 2087 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2088 mHandlerThread.start(); 2089 mHandler = new MainHandler(mHandlerThread.getLooper()); 2090 2091 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2092 "foreground", BROADCAST_FG_TIMEOUT, false); 2093 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2094 "background", BROADCAST_BG_TIMEOUT, true); 2095 mBroadcastQueues[0] = mFgBroadcastQueue; 2096 mBroadcastQueues[1] = mBgBroadcastQueue; 2097 2098 mServices = new ActiveServices(this); 2099 mProviderMap = new ProviderMap(this); 2100 2101 // TODO: Move creation of battery stats service outside of activity manager service. 2102 File dataDir = Environment.getDataDirectory(); 2103 File systemDir = new File(dataDir, "system"); 2104 systemDir.mkdirs(); 2105 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2106 mBatteryStatsService.getActiveStatistics().readLocked(); 2107 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2108 mOnBattery = DEBUG_POWER ? true 2109 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2110 mBatteryStatsService.getActiveStatistics().setCallback(this); 2111 2112 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2113 2114 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2115 2116 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2117 2118 // User 0 is the first and only user that runs at boot. 2119 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2120 mUserLru.add(Integer.valueOf(0)); 2121 updateStartedUserArrayLocked(); 2122 2123 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2124 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2125 2126 mConfiguration.setToDefaults(); 2127 mConfiguration.setLocale(Locale.getDefault()); 2128 2129 mConfigurationSeq = mConfiguration.seq = 1; 2130 mProcessCpuTracker.init(); 2131 2132 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2133 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2134 mStackSupervisor = new ActivityStackSupervisor(this); 2135 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2136 2137 mProcessCpuThread = new Thread("CpuTracker") { 2138 @Override 2139 public void run() { 2140 while (true) { 2141 try { 2142 try { 2143 synchronized(this) { 2144 final long now = SystemClock.uptimeMillis(); 2145 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2146 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2147 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2148 // + ", write delay=" + nextWriteDelay); 2149 if (nextWriteDelay < nextCpuDelay) { 2150 nextCpuDelay = nextWriteDelay; 2151 } 2152 if (nextCpuDelay > 0) { 2153 mProcessCpuMutexFree.set(true); 2154 this.wait(nextCpuDelay); 2155 } 2156 } 2157 } catch (InterruptedException e) { 2158 } 2159 updateCpuStatsNow(); 2160 } catch (Exception e) { 2161 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2162 } 2163 } 2164 } 2165 }; 2166 2167 Watchdog.getInstance().addMonitor(this); 2168 Watchdog.getInstance().addThread(mHandler); 2169 } 2170 2171 public void setSystemServiceManager(SystemServiceManager mgr) { 2172 mSystemServiceManager = mgr; 2173 } 2174 2175 public void setInstaller(Installer installer) { 2176 mInstaller = installer; 2177 } 2178 2179 private void start() { 2180 Process.removeAllProcessGroups(); 2181 mProcessCpuThread.start(); 2182 2183 mBatteryStatsService.publish(mContext); 2184 mAppOpsService.publish(mContext); 2185 Slog.d("AppOps", "AppOpsService published"); 2186 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2187 } 2188 2189 public void initPowerManagement() { 2190 mStackSupervisor.initPowerManagement(); 2191 mBatteryStatsService.initPowerManagement(); 2192 } 2193 2194 @Override 2195 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2196 throws RemoteException { 2197 if (code == SYSPROPS_TRANSACTION) { 2198 // We need to tell all apps about the system property change. 2199 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2200 synchronized(this) { 2201 final int NP = mProcessNames.getMap().size(); 2202 for (int ip=0; ip<NP; ip++) { 2203 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2204 final int NA = apps.size(); 2205 for (int ia=0; ia<NA; ia++) { 2206 ProcessRecord app = apps.valueAt(ia); 2207 if (app.thread != null) { 2208 procs.add(app.thread.asBinder()); 2209 } 2210 } 2211 } 2212 } 2213 2214 int N = procs.size(); 2215 for (int i=0; i<N; i++) { 2216 Parcel data2 = Parcel.obtain(); 2217 try { 2218 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2219 } catch (RemoteException e) { 2220 } 2221 data2.recycle(); 2222 } 2223 } 2224 try { 2225 return super.onTransact(code, data, reply, flags); 2226 } catch (RuntimeException e) { 2227 // The activity manager only throws security exceptions, so let's 2228 // log all others. 2229 if (!(e instanceof SecurityException)) { 2230 Slog.wtf(TAG, "Activity Manager Crash", e); 2231 } 2232 throw e; 2233 } 2234 } 2235 2236 void updateCpuStats() { 2237 final long now = SystemClock.uptimeMillis(); 2238 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2239 return; 2240 } 2241 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2242 synchronized (mProcessCpuThread) { 2243 mProcessCpuThread.notify(); 2244 } 2245 } 2246 } 2247 2248 void updateCpuStatsNow() { 2249 synchronized (mProcessCpuTracker) { 2250 mProcessCpuMutexFree.set(false); 2251 final long now = SystemClock.uptimeMillis(); 2252 boolean haveNewCpuStats = false; 2253 2254 if (MONITOR_CPU_USAGE && 2255 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2256 mLastCpuTime.set(now); 2257 haveNewCpuStats = true; 2258 mProcessCpuTracker.update(); 2259 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2260 //Slog.i(TAG, "Total CPU usage: " 2261 // + mProcessCpu.getTotalCpuPercent() + "%"); 2262 2263 // Slog the cpu usage if the property is set. 2264 if ("true".equals(SystemProperties.get("events.cpu"))) { 2265 int user = mProcessCpuTracker.getLastUserTime(); 2266 int system = mProcessCpuTracker.getLastSystemTime(); 2267 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2268 int irq = mProcessCpuTracker.getLastIrqTime(); 2269 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2270 int idle = mProcessCpuTracker.getLastIdleTime(); 2271 2272 int total = user + system + iowait + irq + softIrq + idle; 2273 if (total == 0) total = 1; 2274 2275 EventLog.writeEvent(EventLogTags.CPU, 2276 ((user+system+iowait+irq+softIrq) * 100) / total, 2277 (user * 100) / total, 2278 (system * 100) / total, 2279 (iowait * 100) / total, 2280 (irq * 100) / total, 2281 (softIrq * 100) / total); 2282 } 2283 } 2284 2285 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2286 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2287 synchronized(bstats) { 2288 synchronized(mPidsSelfLocked) { 2289 if (haveNewCpuStats) { 2290 if (mOnBattery) { 2291 int perc = bstats.startAddingCpuLocked(); 2292 int totalUTime = 0; 2293 int totalSTime = 0; 2294 final int N = mProcessCpuTracker.countStats(); 2295 for (int i=0; i<N; i++) { 2296 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2297 if (!st.working) { 2298 continue; 2299 } 2300 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2301 int otherUTime = (st.rel_utime*perc)/100; 2302 int otherSTime = (st.rel_stime*perc)/100; 2303 totalUTime += otherUTime; 2304 totalSTime += otherSTime; 2305 if (pr != null) { 2306 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2307 if (ps == null || !ps.isActive()) { 2308 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2309 pr.info.uid, pr.processName); 2310 } 2311 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2312 st.rel_stime-otherSTime); 2313 ps.addSpeedStepTimes(cpuSpeedTimes); 2314 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2315 } else { 2316 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2317 if (ps == null || !ps.isActive()) { 2318 st.batteryStats = ps = bstats.getProcessStatsLocked( 2319 bstats.mapUid(st.uid), st.name); 2320 } 2321 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2322 st.rel_stime-otherSTime); 2323 ps.addSpeedStepTimes(cpuSpeedTimes); 2324 } 2325 } 2326 bstats.finishAddingCpuLocked(perc, totalUTime, 2327 totalSTime, cpuSpeedTimes); 2328 } 2329 } 2330 } 2331 2332 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2333 mLastWriteTime = now; 2334 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2335 } 2336 } 2337 } 2338 } 2339 2340 @Override 2341 public void batteryNeedsCpuUpdate() { 2342 updateCpuStatsNow(); 2343 } 2344 2345 @Override 2346 public void batteryPowerChanged(boolean onBattery) { 2347 // When plugging in, update the CPU stats first before changing 2348 // the plug state. 2349 updateCpuStatsNow(); 2350 synchronized (this) { 2351 synchronized(mPidsSelfLocked) { 2352 mOnBattery = DEBUG_POWER ? true : onBattery; 2353 } 2354 } 2355 } 2356 2357 /** 2358 * Initialize the application bind args. These are passed to each 2359 * process when the bindApplication() IPC is sent to the process. They're 2360 * lazily setup to make sure the services are running when they're asked for. 2361 */ 2362 private HashMap<String, IBinder> getCommonServicesLocked() { 2363 if (mAppBindArgs == null) { 2364 mAppBindArgs = new HashMap<String, IBinder>(); 2365 2366 // Setup the application init args 2367 mAppBindArgs.put("package", ServiceManager.getService("package")); 2368 mAppBindArgs.put("window", ServiceManager.getService("window")); 2369 mAppBindArgs.put(Context.ALARM_SERVICE, 2370 ServiceManager.getService(Context.ALARM_SERVICE)); 2371 } 2372 return mAppBindArgs; 2373 } 2374 2375 final void setFocusedActivityLocked(ActivityRecord r) { 2376 if (mFocusedActivity != r) { 2377 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2378 mFocusedActivity = r; 2379 if (r.task != null && r.task.voiceInteractor != null) { 2380 startRunningVoiceLocked(); 2381 } else { 2382 finishRunningVoiceLocked(); 2383 } 2384 mStackSupervisor.setFocusedStack(r); 2385 if (r != null) { 2386 mWindowManager.setFocusedApp(r.appToken, true); 2387 } 2388 applyUpdateLockStateLocked(r); 2389 } 2390 } 2391 2392 final void clearFocusedActivity(ActivityRecord r) { 2393 if (mFocusedActivity == r) { 2394 mFocusedActivity = null; 2395 } 2396 } 2397 2398 @Override 2399 public void setFocusedStack(int stackId) { 2400 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2401 synchronized (ActivityManagerService.this) { 2402 ActivityStack stack = mStackSupervisor.getStack(stackId); 2403 if (stack != null) { 2404 ActivityRecord r = stack.topRunningActivityLocked(null); 2405 if (r != null) { 2406 setFocusedActivityLocked(r); 2407 } 2408 } 2409 } 2410 } 2411 2412 @Override 2413 public void notifyActivityDrawn(IBinder token) { 2414 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2415 synchronized (this) { 2416 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2417 if (r != null) { 2418 r.task.stack.notifyActivityDrawnLocked(r); 2419 } 2420 } 2421 } 2422 2423 final void applyUpdateLockStateLocked(ActivityRecord r) { 2424 // Modifications to the UpdateLock state are done on our handler, outside 2425 // the activity manager's locks. The new state is determined based on the 2426 // state *now* of the relevant activity record. The object is passed to 2427 // the handler solely for logging detail, not to be consulted/modified. 2428 final boolean nextState = r != null && r.immersive; 2429 mHandler.sendMessage( 2430 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2431 } 2432 2433 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2434 Message msg = Message.obtain(); 2435 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2436 msg.obj = r.task.askedCompatMode ? null : r; 2437 mHandler.sendMessage(msg); 2438 } 2439 2440 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2441 String what, Object obj, ProcessRecord srcApp) { 2442 app.lastActivityTime = now; 2443 2444 if (app.activities.size() > 0) { 2445 // Don't want to touch dependent processes that are hosting activities. 2446 return index; 2447 } 2448 2449 int lrui = mLruProcesses.lastIndexOf(app); 2450 if (lrui < 0) { 2451 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2452 + what + " " + obj + " from " + srcApp); 2453 return index; 2454 } 2455 2456 if (lrui >= index) { 2457 // Don't want to cause this to move dependent processes *back* in the 2458 // list as if they were less frequently used. 2459 return index; 2460 } 2461 2462 if (lrui >= mLruProcessActivityStart) { 2463 // Don't want to touch dependent processes that are hosting activities. 2464 return index; 2465 } 2466 2467 mLruProcesses.remove(lrui); 2468 if (index > 0) { 2469 index--; 2470 } 2471 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2472 + " in LRU list: " + app); 2473 mLruProcesses.add(index, app); 2474 return index; 2475 } 2476 2477 final void removeLruProcessLocked(ProcessRecord app) { 2478 int lrui = mLruProcesses.lastIndexOf(app); 2479 if (lrui >= 0) { 2480 if (!app.killed) { 2481 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2482 Process.killProcessQuiet(app.pid); 2483 Process.killProcessGroup(app.info.uid, app.pid); 2484 } 2485 if (lrui <= mLruProcessActivityStart) { 2486 mLruProcessActivityStart--; 2487 } 2488 if (lrui <= mLruProcessServiceStart) { 2489 mLruProcessServiceStart--; 2490 } 2491 mLruProcesses.remove(lrui); 2492 } 2493 } 2494 2495 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2496 ProcessRecord client) { 2497 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2498 || app.treatLikeActivity; 2499 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2500 if (!activityChange && hasActivity) { 2501 // The process has activities, so we are only allowing activity-based adjustments 2502 // to move it. It should be kept in the front of the list with other 2503 // processes that have activities, and we don't want those to change their 2504 // order except due to activity operations. 2505 return; 2506 } 2507 2508 mLruSeq++; 2509 final long now = SystemClock.uptimeMillis(); 2510 app.lastActivityTime = now; 2511 2512 // First a quick reject: if the app is already at the position we will 2513 // put it, then there is nothing to do. 2514 if (hasActivity) { 2515 final int N = mLruProcesses.size(); 2516 if (N > 0 && mLruProcesses.get(N-1) == app) { 2517 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2518 return; 2519 } 2520 } else { 2521 if (mLruProcessServiceStart > 0 2522 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2523 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2524 return; 2525 } 2526 } 2527 2528 int lrui = mLruProcesses.lastIndexOf(app); 2529 2530 if (app.persistent && lrui >= 0) { 2531 // We don't care about the position of persistent processes, as long as 2532 // they are in the list. 2533 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2534 return; 2535 } 2536 2537 /* In progress: compute new position first, so we can avoid doing work 2538 if the process is not actually going to move. Not yet working. 2539 int addIndex; 2540 int nextIndex; 2541 boolean inActivity = false, inService = false; 2542 if (hasActivity) { 2543 // Process has activities, put it at the very tipsy-top. 2544 addIndex = mLruProcesses.size(); 2545 nextIndex = mLruProcessServiceStart; 2546 inActivity = true; 2547 } else if (hasService) { 2548 // Process has services, put it at the top of the service list. 2549 addIndex = mLruProcessActivityStart; 2550 nextIndex = mLruProcessServiceStart; 2551 inActivity = true; 2552 inService = true; 2553 } else { 2554 // Process not otherwise of interest, it goes to the top of the non-service area. 2555 addIndex = mLruProcessServiceStart; 2556 if (client != null) { 2557 int clientIndex = mLruProcesses.lastIndexOf(client); 2558 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2559 + app); 2560 if (clientIndex >= 0 && addIndex > clientIndex) { 2561 addIndex = clientIndex; 2562 } 2563 } 2564 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2565 } 2566 2567 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2568 + mLruProcessActivityStart + "): " + app); 2569 */ 2570 2571 if (lrui >= 0) { 2572 if (lrui < mLruProcessActivityStart) { 2573 mLruProcessActivityStart--; 2574 } 2575 if (lrui < mLruProcessServiceStart) { 2576 mLruProcessServiceStart--; 2577 } 2578 /* 2579 if (addIndex > lrui) { 2580 addIndex--; 2581 } 2582 if (nextIndex > lrui) { 2583 nextIndex--; 2584 } 2585 */ 2586 mLruProcesses.remove(lrui); 2587 } 2588 2589 /* 2590 mLruProcesses.add(addIndex, app); 2591 if (inActivity) { 2592 mLruProcessActivityStart++; 2593 } 2594 if (inService) { 2595 mLruProcessActivityStart++; 2596 } 2597 */ 2598 2599 int nextIndex; 2600 if (hasActivity) { 2601 final int N = mLruProcesses.size(); 2602 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2603 // Process doesn't have activities, but has clients with 2604 // activities... move it up, but one below the top (the top 2605 // should always have a real activity). 2606 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2607 mLruProcesses.add(N-1, app); 2608 // To keep it from spamming the LRU list (by making a bunch of clients), 2609 // we will push down any other entries owned by the app. 2610 final int uid = app.info.uid; 2611 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2612 ProcessRecord subProc = mLruProcesses.get(i); 2613 if (subProc.info.uid == uid) { 2614 // We want to push this one down the list. If the process after 2615 // it is for the same uid, however, don't do so, because we don't 2616 // want them internally to be re-ordered. 2617 if (mLruProcesses.get(i-1).info.uid != uid) { 2618 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2619 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2620 ProcessRecord tmp = mLruProcesses.get(i); 2621 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2622 mLruProcesses.set(i-1, tmp); 2623 i--; 2624 } 2625 } else { 2626 // A gap, we can stop here. 2627 break; 2628 } 2629 } 2630 } else { 2631 // Process has activities, put it at the very tipsy-top. 2632 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2633 mLruProcesses.add(app); 2634 } 2635 nextIndex = mLruProcessServiceStart; 2636 } else if (hasService) { 2637 // Process has services, put it at the top of the service list. 2638 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2639 mLruProcesses.add(mLruProcessActivityStart, app); 2640 nextIndex = mLruProcessServiceStart; 2641 mLruProcessActivityStart++; 2642 } else { 2643 // Process not otherwise of interest, it goes to the top of the non-service area. 2644 int index = mLruProcessServiceStart; 2645 if (client != null) { 2646 // If there is a client, don't allow the process to be moved up higher 2647 // in the list than that client. 2648 int clientIndex = mLruProcesses.lastIndexOf(client); 2649 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2650 + " when updating " + app); 2651 if (clientIndex <= lrui) { 2652 // Don't allow the client index restriction to push it down farther in the 2653 // list than it already is. 2654 clientIndex = lrui; 2655 } 2656 if (clientIndex >= 0 && index > clientIndex) { 2657 index = clientIndex; 2658 } 2659 } 2660 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2661 mLruProcesses.add(index, app); 2662 nextIndex = index-1; 2663 mLruProcessActivityStart++; 2664 mLruProcessServiceStart++; 2665 } 2666 2667 // If the app is currently using a content provider or service, 2668 // bump those processes as well. 2669 for (int j=app.connections.size()-1; j>=0; j--) { 2670 ConnectionRecord cr = app.connections.valueAt(j); 2671 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2672 && cr.binding.service.app != null 2673 && cr.binding.service.app.lruSeq != mLruSeq 2674 && !cr.binding.service.app.persistent) { 2675 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2676 "service connection", cr, app); 2677 } 2678 } 2679 for (int j=app.conProviders.size()-1; j>=0; j--) { 2680 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2681 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2682 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2683 "provider reference", cpr, app); 2684 } 2685 } 2686 } 2687 2688 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2689 if (uid == Process.SYSTEM_UID) { 2690 // The system gets to run in any process. If there are multiple 2691 // processes with the same uid, just pick the first (this 2692 // should never happen). 2693 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2694 if (procs == null) return null; 2695 final int N = procs.size(); 2696 for (int i = 0; i < N; i++) { 2697 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2698 } 2699 } 2700 ProcessRecord proc = mProcessNames.get(processName, uid); 2701 if (false && proc != null && !keepIfLarge 2702 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2703 && proc.lastCachedPss >= 4000) { 2704 // Turn this condition on to cause killing to happen regularly, for testing. 2705 if (proc.baseProcessTracker != null) { 2706 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2707 } 2708 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2709 } else if (proc != null && !keepIfLarge 2710 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2711 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2712 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2713 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2714 if (proc.baseProcessTracker != null) { 2715 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2716 } 2717 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2718 } 2719 } 2720 return proc; 2721 } 2722 2723 void ensurePackageDexOpt(String packageName) { 2724 IPackageManager pm = AppGlobals.getPackageManager(); 2725 try { 2726 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2727 mDidDexOpt = true; 2728 } 2729 } catch (RemoteException e) { 2730 } 2731 } 2732 2733 boolean isNextTransitionForward() { 2734 int transit = mWindowManager.getPendingAppTransition(); 2735 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2736 || transit == AppTransition.TRANSIT_TASK_OPEN 2737 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2738 } 2739 2740 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2741 String processName, String abiOverride, int uid, Runnable crashHandler) { 2742 synchronized(this) { 2743 ApplicationInfo info = new ApplicationInfo(); 2744 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2745 // For isolated processes, the former contains the parent's uid and the latter the 2746 // actual uid of the isolated process. 2747 // In the special case introduced by this method (which is, starting an isolated 2748 // process directly from the SystemServer without an actual parent app process) the 2749 // closest thing to a parent's uid is SYSTEM_UID. 2750 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2751 // the |isolated| logic in the ProcessRecord constructor. 2752 info.uid = Process.SYSTEM_UID; 2753 info.processName = processName; 2754 info.className = entryPoint; 2755 info.packageName = "android"; 2756 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2757 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2758 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2759 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2760 crashHandler); 2761 return proc != null ? proc.pid : 0; 2762 } 2763 } 2764 2765 final ProcessRecord startProcessLocked(String processName, 2766 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2767 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2768 boolean isolated, boolean keepIfLarge) { 2769 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2770 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2771 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2772 null /* crashHandler */); 2773 } 2774 2775 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2776 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2777 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2778 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2779 long startTime = SystemClock.elapsedRealtime(); 2780 ProcessRecord app; 2781 if (!isolated) { 2782 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2783 checkTime(startTime, "startProcess: after getProcessRecord"); 2784 } else { 2785 // If this is an isolated process, it can't re-use an existing process. 2786 app = null; 2787 } 2788 // We don't have to do anything more if: 2789 // (1) There is an existing application record; and 2790 // (2) The caller doesn't think it is dead, OR there is no thread 2791 // object attached to it so we know it couldn't have crashed; and 2792 // (3) There is a pid assigned to it, so it is either starting or 2793 // already running. 2794 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2795 + " app=" + app + " knownToBeDead=" + knownToBeDead 2796 + " thread=" + (app != null ? app.thread : null) 2797 + " pid=" + (app != null ? app.pid : -1)); 2798 if (app != null && app.pid > 0) { 2799 if (!knownToBeDead || app.thread == null) { 2800 // We already have the app running, or are waiting for it to 2801 // come up (we have a pid but not yet its thread), so keep it. 2802 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2803 // If this is a new package in the process, add the package to the list 2804 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2805 checkTime(startTime, "startProcess: done, added package to proc"); 2806 return app; 2807 } 2808 2809 // An application record is attached to a previous process, 2810 // clean it up now. 2811 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2812 checkTime(startTime, "startProcess: bad proc running, killing"); 2813 Process.killProcessGroup(app.info.uid, app.pid); 2814 handleAppDiedLocked(app, true, true); 2815 checkTime(startTime, "startProcess: done killing old proc"); 2816 } 2817 2818 String hostingNameStr = hostingName != null 2819 ? hostingName.flattenToShortString() : null; 2820 2821 if (!isolated) { 2822 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2823 // If we are in the background, then check to see if this process 2824 // is bad. If so, we will just silently fail. 2825 if (mBadProcesses.get(info.processName, info.uid) != null) { 2826 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2827 + "/" + info.processName); 2828 return null; 2829 } 2830 } else { 2831 // When the user is explicitly starting a process, then clear its 2832 // crash count so that we won't make it bad until they see at 2833 // least one crash dialog again, and make the process good again 2834 // if it had been bad. 2835 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2836 + "/" + info.processName); 2837 mProcessCrashTimes.remove(info.processName, info.uid); 2838 if (mBadProcesses.get(info.processName, info.uid) != null) { 2839 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2840 UserHandle.getUserId(info.uid), info.uid, 2841 info.processName); 2842 mBadProcesses.remove(info.processName, info.uid); 2843 if (app != null) { 2844 app.bad = false; 2845 } 2846 } 2847 } 2848 } 2849 2850 if (app == null) { 2851 checkTime(startTime, "startProcess: creating new process record"); 2852 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2853 app.crashHandler = crashHandler; 2854 if (app == null) { 2855 Slog.w(TAG, "Failed making new process record for " 2856 + processName + "/" + info.uid + " isolated=" + isolated); 2857 return null; 2858 } 2859 mProcessNames.put(processName, app.uid, app); 2860 if (isolated) { 2861 mIsolatedProcesses.put(app.uid, app); 2862 } 2863 checkTime(startTime, "startProcess: done creating new process record"); 2864 } else { 2865 // If this is a new package in the process, add the package to the list 2866 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2867 checkTime(startTime, "startProcess: added package to existing proc"); 2868 } 2869 2870 // If the system is not ready yet, then hold off on starting this 2871 // process until it is. 2872 if (!mProcessesReady 2873 && !isAllowedWhileBooting(info) 2874 && !allowWhileBooting) { 2875 if (!mProcessesOnHold.contains(app)) { 2876 mProcessesOnHold.add(app); 2877 } 2878 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2879 checkTime(startTime, "startProcess: returning with proc on hold"); 2880 return app; 2881 } 2882 2883 checkTime(startTime, "startProcess: stepping in to startProcess"); 2884 startProcessLocked( 2885 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2886 checkTime(startTime, "startProcess: done starting proc!"); 2887 return (app.pid != 0) ? app : null; 2888 } 2889 2890 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2891 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2892 } 2893 2894 private final void startProcessLocked(ProcessRecord app, 2895 String hostingType, String hostingNameStr) { 2896 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2897 null /* entryPoint */, null /* entryPointArgs */); 2898 } 2899 2900 private final void startProcessLocked(ProcessRecord app, String hostingType, 2901 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2902 long startTime = SystemClock.elapsedRealtime(); 2903 if (app.pid > 0 && app.pid != MY_PID) { 2904 checkTime(startTime, "startProcess: removing from pids map"); 2905 synchronized (mPidsSelfLocked) { 2906 mPidsSelfLocked.remove(app.pid); 2907 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2908 } 2909 checkTime(startTime, "startProcess: done removing from pids map"); 2910 app.setPid(0); 2911 } 2912 2913 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2914 "startProcessLocked removing on hold: " + app); 2915 mProcessesOnHold.remove(app); 2916 2917 checkTime(startTime, "startProcess: starting to update cpu stats"); 2918 updateCpuStats(); 2919 checkTime(startTime, "startProcess: done updating cpu stats"); 2920 2921 try { 2922 int uid = app.uid; 2923 2924 int[] gids = null; 2925 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2926 if (!app.isolated) { 2927 int[] permGids = null; 2928 try { 2929 checkTime(startTime, "startProcess: getting gids from package manager"); 2930 final PackageManager pm = mContext.getPackageManager(); 2931 permGids = pm.getPackageGids(app.info.packageName); 2932 2933 if (Environment.isExternalStorageEmulated()) { 2934 checkTime(startTime, "startProcess: checking external storage perm"); 2935 if (pm.checkPermission( 2936 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2937 app.info.packageName) == PERMISSION_GRANTED) { 2938 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2939 } else { 2940 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2941 } 2942 } 2943 } catch (PackageManager.NameNotFoundException e) { 2944 Slog.w(TAG, "Unable to retrieve gids", e); 2945 } 2946 2947 /* 2948 * Add shared application and profile GIDs so applications can share some 2949 * resources like shared libraries and access user-wide resources 2950 */ 2951 if (permGids == null) { 2952 gids = new int[2]; 2953 } else { 2954 gids = new int[permGids.length + 2]; 2955 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2956 } 2957 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2958 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2959 } 2960 checkTime(startTime, "startProcess: building args"); 2961 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2962 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2963 && mTopComponent != null 2964 && app.processName.equals(mTopComponent.getPackageName())) { 2965 uid = 0; 2966 } 2967 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2968 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2969 uid = 0; 2970 } 2971 } 2972 int debugFlags = 0; 2973 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2974 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2975 // Also turn on CheckJNI for debuggable apps. It's quite 2976 // awkward to turn on otherwise. 2977 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2978 } 2979 // Run the app in safe mode if its manifest requests so or the 2980 // system is booted in safe mode. 2981 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2982 mSafeMode == true) { 2983 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2984 } 2985 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2986 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2987 } 2988 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2989 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2990 } 2991 if ("1".equals(SystemProperties.get("debug.assert"))) { 2992 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2993 } 2994 2995 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2996 if (requiredAbi == null) { 2997 requiredAbi = Build.SUPPORTED_ABIS[0]; 2998 } 2999 3000 String instructionSet = null; 3001 if (app.info.primaryCpuAbi != null) { 3002 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3003 } 3004 3005 // Start the process. It will either succeed and return a result containing 3006 // the PID of the new process, or else throw a RuntimeException. 3007 boolean isActivityProcess = (entryPoint == null); 3008 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3009 checkTime(startTime, "startProcess: asking zygote to start proc"); 3010 Process.ProcessStartResult startResult = Process.start(entryPoint, 3011 app.processName, uid, uid, gids, debugFlags, mountExternal, 3012 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3013 app.info.dataDir, entryPointArgs); 3014 checkTime(startTime, "startProcess: returned from zygote!"); 3015 3016 if (app.isolated) { 3017 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3018 } 3019 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3020 checkTime(startTime, "startProcess: done updating battery stats"); 3021 3022 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3023 UserHandle.getUserId(uid), startResult.pid, uid, 3024 app.processName, hostingType, 3025 hostingNameStr != null ? hostingNameStr : ""); 3026 3027 if (app.persistent) { 3028 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3029 } 3030 3031 checkTime(startTime, "startProcess: building log message"); 3032 StringBuilder buf = mStringBuilder; 3033 buf.setLength(0); 3034 buf.append("Start proc "); 3035 buf.append(app.processName); 3036 if (!isActivityProcess) { 3037 buf.append(" ["); 3038 buf.append(entryPoint); 3039 buf.append("]"); 3040 } 3041 buf.append(" for "); 3042 buf.append(hostingType); 3043 if (hostingNameStr != null) { 3044 buf.append(" "); 3045 buf.append(hostingNameStr); 3046 } 3047 buf.append(": pid="); 3048 buf.append(startResult.pid); 3049 buf.append(" uid="); 3050 buf.append(uid); 3051 buf.append(" gids={"); 3052 if (gids != null) { 3053 for (int gi=0; gi<gids.length; gi++) { 3054 if (gi != 0) buf.append(", "); 3055 buf.append(gids[gi]); 3056 3057 } 3058 } 3059 buf.append("}"); 3060 if (requiredAbi != null) { 3061 buf.append(" abi="); 3062 buf.append(requiredAbi); 3063 } 3064 Slog.i(TAG, buf.toString()); 3065 app.setPid(startResult.pid); 3066 app.usingWrapper = startResult.usingWrapper; 3067 app.removed = false; 3068 app.killed = false; 3069 app.killedByAm = false; 3070 checkTime(startTime, "startProcess: starting to update pids map"); 3071 synchronized (mPidsSelfLocked) { 3072 this.mPidsSelfLocked.put(startResult.pid, app); 3073 if (isActivityProcess) { 3074 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3075 msg.obj = app; 3076 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3077 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3078 } 3079 } 3080 checkTime(startTime, "startProcess: done updating pids map"); 3081 } catch (RuntimeException e) { 3082 // XXX do better error recovery. 3083 app.setPid(0); 3084 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3085 if (app.isolated) { 3086 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3087 } 3088 Slog.e(TAG, "Failure starting process " + app.processName, e); 3089 } 3090 } 3091 3092 void updateUsageStats(ActivityRecord component, boolean resumed) { 3093 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3094 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3095 if (resumed) { 3096 if (mUsageStatsService != null) { 3097 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3098 UsageEvents.Event.MOVE_TO_FOREGROUND); 3099 } 3100 synchronized (stats) { 3101 stats.noteActivityResumedLocked(component.app.uid); 3102 } 3103 } else { 3104 if (mUsageStatsService != null) { 3105 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3106 UsageEvents.Event.MOVE_TO_BACKGROUND); 3107 } 3108 synchronized (stats) { 3109 stats.noteActivityPausedLocked(component.app.uid); 3110 } 3111 } 3112 } 3113 3114 Intent getHomeIntent() { 3115 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3116 intent.setComponent(mTopComponent); 3117 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3118 intent.addCategory(Intent.CATEGORY_HOME); 3119 } 3120 return intent; 3121 } 3122 3123 boolean startHomeActivityLocked(int userId) { 3124 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3125 && mTopAction == null) { 3126 // We are running in factory test mode, but unable to find 3127 // the factory test app, so just sit around displaying the 3128 // error message and don't try to start anything. 3129 return false; 3130 } 3131 Intent intent = getHomeIntent(); 3132 ActivityInfo aInfo = 3133 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3134 if (aInfo != null) { 3135 intent.setComponent(new ComponentName( 3136 aInfo.applicationInfo.packageName, aInfo.name)); 3137 // Don't do this if the home app is currently being 3138 // instrumented. 3139 aInfo = new ActivityInfo(aInfo); 3140 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3141 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3142 aInfo.applicationInfo.uid, true); 3143 if (app == null || app.instrumentationClass == null) { 3144 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3145 mStackSupervisor.startHomeActivity(intent, aInfo); 3146 } 3147 } 3148 3149 return true; 3150 } 3151 3152 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3153 ActivityInfo ai = null; 3154 ComponentName comp = intent.getComponent(); 3155 try { 3156 if (comp != null) { 3157 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3158 } else { 3159 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3160 intent, 3161 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3162 flags, userId); 3163 3164 if (info != null) { 3165 ai = info.activityInfo; 3166 } 3167 } 3168 } catch (RemoteException e) { 3169 // ignore 3170 } 3171 3172 return ai; 3173 } 3174 3175 /** 3176 * Starts the "new version setup screen" if appropriate. 3177 */ 3178 void startSetupActivityLocked() { 3179 // Only do this once per boot. 3180 if (mCheckedForSetup) { 3181 return; 3182 } 3183 3184 // We will show this screen if the current one is a different 3185 // version than the last one shown, and we are not running in 3186 // low-level factory test mode. 3187 final ContentResolver resolver = mContext.getContentResolver(); 3188 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3189 Settings.Global.getInt(resolver, 3190 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3191 mCheckedForSetup = true; 3192 3193 // See if we should be showing the platform update setup UI. 3194 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3195 List<ResolveInfo> ris = mContext.getPackageManager() 3196 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3197 3198 // We don't allow third party apps to replace this. 3199 ResolveInfo ri = null; 3200 for (int i=0; ris != null && i<ris.size(); i++) { 3201 if ((ris.get(i).activityInfo.applicationInfo.flags 3202 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3203 ri = ris.get(i); 3204 break; 3205 } 3206 } 3207 3208 if (ri != null) { 3209 String vers = ri.activityInfo.metaData != null 3210 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3211 : null; 3212 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3213 vers = ri.activityInfo.applicationInfo.metaData.getString( 3214 Intent.METADATA_SETUP_VERSION); 3215 } 3216 String lastVers = Settings.Secure.getString( 3217 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3218 if (vers != null && !vers.equals(lastVers)) { 3219 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3220 intent.setComponent(new ComponentName( 3221 ri.activityInfo.packageName, ri.activityInfo.name)); 3222 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3223 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3224 null); 3225 } 3226 } 3227 } 3228 } 3229 3230 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3231 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3232 } 3233 3234 void enforceNotIsolatedCaller(String caller) { 3235 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3236 throw new SecurityException("Isolated process not allowed to call " + caller); 3237 } 3238 } 3239 3240 void enforceShellRestriction(String restriction, int userHandle) { 3241 if (Binder.getCallingUid() == Process.SHELL_UID) { 3242 if (userHandle < 0 3243 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3244 throw new SecurityException("Shell does not have permission to access user " 3245 + userHandle); 3246 } 3247 } 3248 } 3249 3250 @Override 3251 public int getFrontActivityScreenCompatMode() { 3252 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3253 synchronized (this) { 3254 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3255 } 3256 } 3257 3258 @Override 3259 public void setFrontActivityScreenCompatMode(int mode) { 3260 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3261 "setFrontActivityScreenCompatMode"); 3262 synchronized (this) { 3263 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3264 } 3265 } 3266 3267 @Override 3268 public int getPackageScreenCompatMode(String packageName) { 3269 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3270 synchronized (this) { 3271 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3272 } 3273 } 3274 3275 @Override 3276 public void setPackageScreenCompatMode(String packageName, int mode) { 3277 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3278 "setPackageScreenCompatMode"); 3279 synchronized (this) { 3280 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3281 } 3282 } 3283 3284 @Override 3285 public boolean getPackageAskScreenCompat(String packageName) { 3286 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3287 synchronized (this) { 3288 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3289 } 3290 } 3291 3292 @Override 3293 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3294 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3295 "setPackageAskScreenCompat"); 3296 synchronized (this) { 3297 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3298 } 3299 } 3300 3301 private void dispatchProcessesChanged() { 3302 int N; 3303 synchronized (this) { 3304 N = mPendingProcessChanges.size(); 3305 if (mActiveProcessChanges.length < N) { 3306 mActiveProcessChanges = new ProcessChangeItem[N]; 3307 } 3308 mPendingProcessChanges.toArray(mActiveProcessChanges); 3309 mAvailProcessChanges.addAll(mPendingProcessChanges); 3310 mPendingProcessChanges.clear(); 3311 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3312 } 3313 3314 int i = mProcessObservers.beginBroadcast(); 3315 while (i > 0) { 3316 i--; 3317 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3318 if (observer != null) { 3319 try { 3320 for (int j=0; j<N; j++) { 3321 ProcessChangeItem item = mActiveProcessChanges[j]; 3322 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3324 + item.pid + " uid=" + item.uid + ": " 3325 + item.foregroundActivities); 3326 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3327 item.foregroundActivities); 3328 } 3329 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3330 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3331 + item.pid + " uid=" + item.uid + ": " + item.processState); 3332 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3333 } 3334 } 3335 } catch (RemoteException e) { 3336 } 3337 } 3338 } 3339 mProcessObservers.finishBroadcast(); 3340 } 3341 3342 private void dispatchProcessDied(int pid, int uid) { 3343 int i = mProcessObservers.beginBroadcast(); 3344 while (i > 0) { 3345 i--; 3346 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3347 if (observer != null) { 3348 try { 3349 observer.onProcessDied(pid, uid); 3350 } catch (RemoteException e) { 3351 } 3352 } 3353 } 3354 mProcessObservers.finishBroadcast(); 3355 } 3356 3357 @Override 3358 public final int startActivity(IApplicationThread caller, String callingPackage, 3359 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3360 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3361 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3362 resultWho, requestCode, startFlags, profilerInfo, options, 3363 UserHandle.getCallingUserId()); 3364 } 3365 3366 @Override 3367 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3368 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3369 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3370 enforceNotIsolatedCaller("startActivity"); 3371 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3372 false, ALLOW_FULL_ONLY, "startActivity", null); 3373 // TODO: Switch to user app stacks here. 3374 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3375 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3376 profilerInfo, null, null, options, userId, null, null); 3377 } 3378 3379 @Override 3380 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3381 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3382 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3383 3384 // This is very dangerous -- it allows you to perform a start activity (including 3385 // permission grants) as any app that may launch one of your own activities. So 3386 // we will only allow this to be done from activities that are part of the core framework, 3387 // and then only when they are running as the system. 3388 final ActivityRecord sourceRecord; 3389 final int targetUid; 3390 final String targetPackage; 3391 synchronized (this) { 3392 if (resultTo == null) { 3393 throw new SecurityException("Must be called from an activity"); 3394 } 3395 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3396 if (sourceRecord == null) { 3397 throw new SecurityException("Called with bad activity token: " + resultTo); 3398 } 3399 if (!sourceRecord.info.packageName.equals("android")) { 3400 throw new SecurityException( 3401 "Must be called from an activity that is declared in the android package"); 3402 } 3403 if (sourceRecord.app == null) { 3404 throw new SecurityException("Called without a process attached to activity"); 3405 } 3406 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3407 // This is still okay, as long as this activity is running under the 3408 // uid of the original calling activity. 3409 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3410 throw new SecurityException( 3411 "Calling activity in uid " + sourceRecord.app.uid 3412 + " must be system uid or original calling uid " 3413 + sourceRecord.launchedFromUid); 3414 } 3415 } 3416 targetUid = sourceRecord.launchedFromUid; 3417 targetPackage = sourceRecord.launchedFromPackage; 3418 } 3419 3420 if (userId == UserHandle.USER_NULL) { 3421 userId = UserHandle.getUserId(sourceRecord.app.uid); 3422 } 3423 3424 // TODO: Switch to user app stacks here. 3425 try { 3426 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3427 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3428 null, null, options, userId, null, null); 3429 return ret; 3430 } catch (SecurityException e) { 3431 // XXX need to figure out how to propagate to original app. 3432 // A SecurityException here is generally actually a fault of the original 3433 // calling activity (such as a fairly granting permissions), so propagate it 3434 // back to them. 3435 /* 3436 StringBuilder msg = new StringBuilder(); 3437 msg.append("While launching"); 3438 msg.append(intent.toString()); 3439 msg.append(": "); 3440 msg.append(e.getMessage()); 3441 */ 3442 throw e; 3443 } 3444 } 3445 3446 @Override 3447 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3448 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3449 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3450 enforceNotIsolatedCaller("startActivityAndWait"); 3451 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3452 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3453 WaitResult res = new WaitResult(); 3454 // TODO: Switch to user app stacks here. 3455 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3456 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3457 options, userId, null, null); 3458 return res; 3459 } 3460 3461 @Override 3462 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3463 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3464 int startFlags, Configuration config, Bundle options, int userId) { 3465 enforceNotIsolatedCaller("startActivityWithConfig"); 3466 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3467 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3468 // TODO: Switch to user app stacks here. 3469 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3470 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3471 null, null, config, options, userId, null, null); 3472 return ret; 3473 } 3474 3475 @Override 3476 public int startActivityIntentSender(IApplicationThread caller, 3477 IntentSender intent, Intent fillInIntent, String resolvedType, 3478 IBinder resultTo, String resultWho, int requestCode, 3479 int flagsMask, int flagsValues, Bundle options) { 3480 enforceNotIsolatedCaller("startActivityIntentSender"); 3481 // Refuse possible leaked file descriptors 3482 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3483 throw new IllegalArgumentException("File descriptors passed in Intent"); 3484 } 3485 3486 IIntentSender sender = intent.getTarget(); 3487 if (!(sender instanceof PendingIntentRecord)) { 3488 throw new IllegalArgumentException("Bad PendingIntent object"); 3489 } 3490 3491 PendingIntentRecord pir = (PendingIntentRecord)sender; 3492 3493 synchronized (this) { 3494 // If this is coming from the currently resumed activity, it is 3495 // effectively saying that app switches are allowed at this point. 3496 final ActivityStack stack = getFocusedStack(); 3497 if (stack.mResumedActivity != null && 3498 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3499 mAppSwitchesAllowedTime = 0; 3500 } 3501 } 3502 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3503 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3504 return ret; 3505 } 3506 3507 @Override 3508 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3509 Intent intent, String resolvedType, IVoiceInteractionSession session, 3510 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3511 Bundle options, int userId) { 3512 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3513 != PackageManager.PERMISSION_GRANTED) { 3514 String msg = "Permission Denial: startVoiceActivity() from pid=" 3515 + Binder.getCallingPid() 3516 + ", uid=" + Binder.getCallingUid() 3517 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3518 Slog.w(TAG, msg); 3519 throw new SecurityException(msg); 3520 } 3521 if (session == null || interactor == null) { 3522 throw new NullPointerException("null session or interactor"); 3523 } 3524 userId = handleIncomingUser(callingPid, callingUid, userId, 3525 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3526 // TODO: Switch to user app stacks here. 3527 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3528 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3529 null, options, userId, null, null); 3530 } 3531 3532 @Override 3533 public boolean startNextMatchingActivity(IBinder callingActivity, 3534 Intent intent, Bundle options) { 3535 // Refuse possible leaked file descriptors 3536 if (intent != null && intent.hasFileDescriptors() == true) { 3537 throw new IllegalArgumentException("File descriptors passed in Intent"); 3538 } 3539 3540 synchronized (this) { 3541 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3542 if (r == null) { 3543 ActivityOptions.abort(options); 3544 return false; 3545 } 3546 if (r.app == null || r.app.thread == null) { 3547 // The caller is not running... d'oh! 3548 ActivityOptions.abort(options); 3549 return false; 3550 } 3551 intent = new Intent(intent); 3552 // The caller is not allowed to change the data. 3553 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3554 // And we are resetting to find the next component... 3555 intent.setComponent(null); 3556 3557 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3558 3559 ActivityInfo aInfo = null; 3560 try { 3561 List<ResolveInfo> resolves = 3562 AppGlobals.getPackageManager().queryIntentActivities( 3563 intent, r.resolvedType, 3564 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3565 UserHandle.getCallingUserId()); 3566 3567 // Look for the original activity in the list... 3568 final int N = resolves != null ? resolves.size() : 0; 3569 for (int i=0; i<N; i++) { 3570 ResolveInfo rInfo = resolves.get(i); 3571 if (rInfo.activityInfo.packageName.equals(r.packageName) 3572 && rInfo.activityInfo.name.equals(r.info.name)) { 3573 // We found the current one... the next matching is 3574 // after it. 3575 i++; 3576 if (i<N) { 3577 aInfo = resolves.get(i).activityInfo; 3578 } 3579 if (debug) { 3580 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3581 + "/" + r.info.name); 3582 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3583 + "/" + aInfo.name); 3584 } 3585 break; 3586 } 3587 } 3588 } catch (RemoteException e) { 3589 } 3590 3591 if (aInfo == null) { 3592 // Nobody who is next! 3593 ActivityOptions.abort(options); 3594 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3595 return false; 3596 } 3597 3598 intent.setComponent(new ComponentName( 3599 aInfo.applicationInfo.packageName, aInfo.name)); 3600 intent.setFlags(intent.getFlags()&~( 3601 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3602 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3603 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3604 Intent.FLAG_ACTIVITY_NEW_TASK)); 3605 3606 // Okay now we need to start the new activity, replacing the 3607 // currently running activity. This is a little tricky because 3608 // we want to start the new one as if the current one is finished, 3609 // but not finish the current one first so that there is no flicker. 3610 // And thus... 3611 final boolean wasFinishing = r.finishing; 3612 r.finishing = true; 3613 3614 // Propagate reply information over to the new activity. 3615 final ActivityRecord resultTo = r.resultTo; 3616 final String resultWho = r.resultWho; 3617 final int requestCode = r.requestCode; 3618 r.resultTo = null; 3619 if (resultTo != null) { 3620 resultTo.removeResultsLocked(r, resultWho, requestCode); 3621 } 3622 3623 final long origId = Binder.clearCallingIdentity(); 3624 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3625 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3626 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3627 -1, r.launchedFromUid, 0, options, false, null, null, null); 3628 Binder.restoreCallingIdentity(origId); 3629 3630 r.finishing = wasFinishing; 3631 if (res != ActivityManager.START_SUCCESS) { 3632 return false; 3633 } 3634 return true; 3635 } 3636 } 3637 3638 @Override 3639 public final int startActivityFromRecents(int taskId, Bundle options) { 3640 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3641 String msg = "Permission Denial: startActivityFromRecents called without " + 3642 START_TASKS_FROM_RECENTS; 3643 Slog.w(TAG, msg); 3644 throw new SecurityException(msg); 3645 } 3646 return startActivityFromRecentsInner(taskId, options); 3647 } 3648 3649 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3650 final TaskRecord task; 3651 final int callingUid; 3652 final String callingPackage; 3653 final Intent intent; 3654 final int userId; 3655 synchronized (this) { 3656 task = recentTaskForIdLocked(taskId); 3657 if (task == null) { 3658 throw new IllegalArgumentException("Task " + taskId + " not found."); 3659 } 3660 callingUid = task.mCallingUid; 3661 callingPackage = task.mCallingPackage; 3662 intent = task.intent; 3663 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3664 userId = task.userId; 3665 } 3666 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3667 options, userId, null, task); 3668 } 3669 3670 final int startActivityInPackage(int uid, String callingPackage, 3671 Intent intent, String resolvedType, IBinder resultTo, 3672 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3673 IActivityContainer container, TaskRecord inTask) { 3674 3675 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3676 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3677 3678 // TODO: Switch to user app stacks here. 3679 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3680 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3681 null, null, null, options, userId, container, inTask); 3682 return ret; 3683 } 3684 3685 @Override 3686 public final int startActivities(IApplicationThread caller, String callingPackage, 3687 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3688 int userId) { 3689 enforceNotIsolatedCaller("startActivities"); 3690 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3691 false, ALLOW_FULL_ONLY, "startActivity", null); 3692 // TODO: Switch to user app stacks here. 3693 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3694 resolvedTypes, resultTo, options, userId); 3695 return ret; 3696 } 3697 3698 final int startActivitiesInPackage(int uid, String callingPackage, 3699 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3700 Bundle options, int userId) { 3701 3702 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3703 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3704 // TODO: Switch to user app stacks here. 3705 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3706 resultTo, options, userId); 3707 return ret; 3708 } 3709 3710 //explicitly remove thd old information in mRecentTasks when removing existing user. 3711 private void removeRecentTasksForUserLocked(int userId) { 3712 if(userId <= 0) { 3713 Slog.i(TAG, "Can't remove recent task on user " + userId); 3714 return; 3715 } 3716 3717 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3718 TaskRecord tr = mRecentTasks.get(i); 3719 if (tr.userId == userId) { 3720 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3721 + " when finishing user" + userId); 3722 mRecentTasks.remove(i); 3723 tr.removedFromRecents(mTaskPersister); 3724 } 3725 } 3726 3727 // Remove tasks from persistent storage. 3728 mTaskPersister.wakeup(null, true); 3729 } 3730 3731 // Sort by taskId 3732 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3733 @Override 3734 public int compare(TaskRecord lhs, TaskRecord rhs) { 3735 return rhs.taskId - lhs.taskId; 3736 } 3737 }; 3738 3739 // Extract the affiliates of the chain containing mRecentTasks[start]. 3740 private int processNextAffiliateChain(int start) { 3741 final TaskRecord startTask = mRecentTasks.get(start); 3742 final int affiliateId = startTask.mAffiliatedTaskId; 3743 3744 // Quick identification of isolated tasks. I.e. those not launched behind. 3745 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3746 startTask.mNextAffiliate == null) { 3747 // There is still a slim chance that there are other tasks that point to this task 3748 // and that the chain is so messed up that this task no longer points to them but 3749 // the gain of this optimization outweighs the risk. 3750 startTask.inRecents = true; 3751 return start + 1; 3752 } 3753 3754 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3755 mTmpRecents.clear(); 3756 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3757 final TaskRecord task = mRecentTasks.get(i); 3758 if (task.mAffiliatedTaskId == affiliateId) { 3759 mRecentTasks.remove(i); 3760 mTmpRecents.add(task); 3761 } 3762 } 3763 3764 // Sort them all by taskId. That is the order they were create in and that order will 3765 // always be correct. 3766 Collections.sort(mTmpRecents, mTaskRecordComparator); 3767 3768 // Go through and fix up the linked list. 3769 // The first one is the end of the chain and has no next. 3770 final TaskRecord first = mTmpRecents.get(0); 3771 first.inRecents = true; 3772 if (first.mNextAffiliate != null) { 3773 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3774 first.setNextAffiliate(null); 3775 mTaskPersister.wakeup(first, false); 3776 } 3777 // Everything in the middle is doubly linked from next to prev. 3778 final int tmpSize = mTmpRecents.size(); 3779 for (int i = 0; i < tmpSize - 1; ++i) { 3780 final TaskRecord next = mTmpRecents.get(i); 3781 final TaskRecord prev = mTmpRecents.get(i + 1); 3782 if (next.mPrevAffiliate != prev) { 3783 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3784 " setting prev=" + prev); 3785 next.setPrevAffiliate(prev); 3786 mTaskPersister.wakeup(next, false); 3787 } 3788 if (prev.mNextAffiliate != next) { 3789 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3790 " setting next=" + next); 3791 prev.setNextAffiliate(next); 3792 mTaskPersister.wakeup(prev, false); 3793 } 3794 prev.inRecents = true; 3795 } 3796 // The last one is the beginning of the list and has no prev. 3797 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3798 if (last.mPrevAffiliate != null) { 3799 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3800 last.setPrevAffiliate(null); 3801 mTaskPersister.wakeup(last, false); 3802 } 3803 3804 // Insert the group back into mRecentTasks at start. 3805 mRecentTasks.addAll(start, mTmpRecents); 3806 3807 // Let the caller know where we left off. 3808 return start + tmpSize; 3809 } 3810 3811 /** 3812 * Update the recent tasks lists: make sure tasks should still be here (their 3813 * applications / activities still exist), update their availability, fixup ordering 3814 * of affiliations. 3815 */ 3816 void cleanupRecentTasksLocked(int userId) { 3817 if (mRecentTasks == null) { 3818 // Happens when called from the packagemanager broadcast before boot. 3819 return; 3820 } 3821 3822 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3823 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3824 final IPackageManager pm = AppGlobals.getPackageManager(); 3825 final ActivityInfo dummyAct = new ActivityInfo(); 3826 final ApplicationInfo dummyApp = new ApplicationInfo(); 3827 3828 int N = mRecentTasks.size(); 3829 3830 int[] users = userId == UserHandle.USER_ALL 3831 ? getUsersLocked() : new int[] { userId }; 3832 for (int user : users) { 3833 for (int i = 0; i < N; i++) { 3834 TaskRecord task = mRecentTasks.get(i); 3835 if (task.userId != user) { 3836 // Only look at tasks for the user ID of interest. 3837 continue; 3838 } 3839 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3840 // This situation is broken, and we should just get rid of it now. 3841 mRecentTasks.remove(i); 3842 task.removedFromRecents(mTaskPersister); 3843 i--; 3844 N--; 3845 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3846 continue; 3847 } 3848 // Check whether this activity is currently available. 3849 if (task.realActivity != null) { 3850 ActivityInfo ai = availActCache.get(task.realActivity); 3851 if (ai == null) { 3852 try { 3853 ai = pm.getActivityInfo(task.realActivity, 3854 PackageManager.GET_UNINSTALLED_PACKAGES 3855 | PackageManager.GET_DISABLED_COMPONENTS, user); 3856 } catch (RemoteException e) { 3857 // Will never happen. 3858 continue; 3859 } 3860 if (ai == null) { 3861 ai = dummyAct; 3862 } 3863 availActCache.put(task.realActivity, ai); 3864 } 3865 if (ai == dummyAct) { 3866 // This could be either because the activity no longer exists, or the 3867 // app is temporarily gone. For the former we want to remove the recents 3868 // entry; for the latter we want to mark it as unavailable. 3869 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3870 if (app == null) { 3871 try { 3872 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3873 PackageManager.GET_UNINSTALLED_PACKAGES 3874 | PackageManager.GET_DISABLED_COMPONENTS, user); 3875 } catch (RemoteException e) { 3876 // Will never happen. 3877 continue; 3878 } 3879 if (app == null) { 3880 app = dummyApp; 3881 } 3882 availAppCache.put(task.realActivity.getPackageName(), app); 3883 } 3884 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3885 // Doesn't exist any more! Good-bye. 3886 mRecentTasks.remove(i); 3887 task.removedFromRecents(mTaskPersister); 3888 i--; 3889 N--; 3890 Slog.w(TAG, "Removing no longer valid recent: " + task); 3891 continue; 3892 } else { 3893 // Otherwise just not available for now. 3894 if (task.isAvailable) { 3895 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3896 + task); 3897 } 3898 task.isAvailable = false; 3899 } 3900 } else { 3901 if (!ai.enabled || !ai.applicationInfo.enabled 3902 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3903 if (task.isAvailable) { 3904 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3905 + task + " (enabled=" + ai.enabled + "/" 3906 + ai.applicationInfo.enabled + " flags=" 3907 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3908 } 3909 task.isAvailable = false; 3910 } else { 3911 if (!task.isAvailable) { 3912 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3913 + task); 3914 } 3915 task.isAvailable = true; 3916 } 3917 } 3918 } 3919 } 3920 } 3921 3922 // Verify the affiliate chain for each task. 3923 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3924 } 3925 3926 mTmpRecents.clear(); 3927 // mRecentTasks is now in sorted, affiliated order. 3928 } 3929 3930 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3931 int N = mRecentTasks.size(); 3932 TaskRecord top = task; 3933 int topIndex = taskIndex; 3934 while (top.mNextAffiliate != null && topIndex > 0) { 3935 top = top.mNextAffiliate; 3936 topIndex--; 3937 } 3938 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3939 + topIndex + " from intial " + taskIndex); 3940 // Find the end of the chain, doing a sanity check along the way. 3941 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3942 int endIndex = topIndex; 3943 TaskRecord prev = top; 3944 while (endIndex < N) { 3945 TaskRecord cur = mRecentTasks.get(endIndex); 3946 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3947 + endIndex + " " + cur); 3948 if (cur == top) { 3949 // Verify start of the chain. 3950 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3951 Slog.wtf(TAG, "Bad chain @" + endIndex 3952 + ": first task has next affiliate: " + prev); 3953 sane = false; 3954 break; 3955 } 3956 } else { 3957 // Verify middle of the chain's next points back to the one before. 3958 if (cur.mNextAffiliate != prev 3959 || cur.mNextAffiliateTaskId != prev.taskId) { 3960 Slog.wtf(TAG, "Bad chain @" + endIndex 3961 + ": middle task " + cur + " @" + endIndex 3962 + " has bad next affiliate " 3963 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3964 + ", expected " + prev); 3965 sane = false; 3966 break; 3967 } 3968 } 3969 if (cur.mPrevAffiliateTaskId == -1) { 3970 // Chain ends here. 3971 if (cur.mPrevAffiliate != null) { 3972 Slog.wtf(TAG, "Bad chain @" + endIndex 3973 + ": last task " + cur + " has previous affiliate " 3974 + cur.mPrevAffiliate); 3975 sane = false; 3976 } 3977 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3978 break; 3979 } else { 3980 // Verify middle of the chain's prev points to a valid item. 3981 if (cur.mPrevAffiliate == null) { 3982 Slog.wtf(TAG, "Bad chain @" + endIndex 3983 + ": task " + cur + " has previous affiliate " 3984 + cur.mPrevAffiliate + " but should be id " 3985 + cur.mPrevAffiliate); 3986 sane = false; 3987 break; 3988 } 3989 } 3990 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3991 Slog.wtf(TAG, "Bad chain @" + endIndex 3992 + ": task " + cur + " has affiliated id " 3993 + cur.mAffiliatedTaskId + " but should be " 3994 + task.mAffiliatedTaskId); 3995 sane = false; 3996 break; 3997 } 3998 prev = cur; 3999 endIndex++; 4000 if (endIndex >= N) { 4001 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4002 + ": last task " + prev); 4003 sane = false; 4004 break; 4005 } 4006 } 4007 if (sane) { 4008 if (endIndex < taskIndex) { 4009 Slog.wtf(TAG, "Bad chain @" + endIndex 4010 + ": did not extend to task " + task + " @" + taskIndex); 4011 sane = false; 4012 } 4013 } 4014 if (sane) { 4015 // All looks good, we can just move all of the affiliated tasks 4016 // to the top. 4017 for (int i=topIndex; i<=endIndex; i++) { 4018 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4019 + " from " + i + " to " + (i-topIndex)); 4020 TaskRecord cur = mRecentTasks.remove(i); 4021 mRecentTasks.add(i-topIndex, cur); 4022 } 4023 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4024 + " to " + endIndex); 4025 return true; 4026 } 4027 4028 // Whoops, couldn't do it. 4029 return false; 4030 } 4031 4032 final void addRecentTaskLocked(TaskRecord task) { 4033 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4034 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4035 4036 int N = mRecentTasks.size(); 4037 // Quick case: check if the top-most recent task is the same. 4038 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4039 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4040 return; 4041 } 4042 // Another quick case: check if this is part of a set of affiliated 4043 // tasks that are at the top. 4044 if (isAffiliated && N > 0 && task.inRecents 4045 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4047 + " at top when adding " + task); 4048 return; 4049 } 4050 // Another quick case: never add voice sessions. 4051 if (task.voiceSession != null) { 4052 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4053 return; 4054 } 4055 4056 boolean needAffiliationFix = false; 4057 4058 // Slightly less quick case: the task is already in recents, so all we need 4059 // to do is move it. 4060 if (task.inRecents) { 4061 int taskIndex = mRecentTasks.indexOf(task); 4062 if (taskIndex >= 0) { 4063 if (!isAffiliated) { 4064 // Simple case: this is not an affiliated task, so we just move it to the front. 4065 mRecentTasks.remove(taskIndex); 4066 mRecentTasks.add(0, task); 4067 notifyTaskPersisterLocked(task, false); 4068 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4069 + " from " + taskIndex); 4070 return; 4071 } else { 4072 // More complicated: need to keep all affiliated tasks together. 4073 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4074 // All went well. 4075 return; 4076 } 4077 4078 // Uh oh... something bad in the affiliation chain, try to rebuild 4079 // everything and then go through our general path of adding a new task. 4080 needAffiliationFix = true; 4081 } 4082 } else { 4083 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4084 needAffiliationFix = true; 4085 } 4086 } 4087 4088 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4089 trimRecentsForTask(task, true); 4090 4091 N = mRecentTasks.size(); 4092 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4093 final TaskRecord tr = mRecentTasks.remove(N - 1); 4094 tr.removedFromRecents(mTaskPersister); 4095 N--; 4096 } 4097 task.inRecents = true; 4098 if (!isAffiliated || needAffiliationFix) { 4099 // If this is a simple non-affiliated task, or we had some failure trying to 4100 // handle it as part of an affilated task, then just place it at the top. 4101 mRecentTasks.add(0, task); 4102 } else if (isAffiliated) { 4103 // If this is a new affiliated task, then move all of the affiliated tasks 4104 // to the front and insert this new one. 4105 TaskRecord other = task.mNextAffiliate; 4106 if (other == null) { 4107 other = task.mPrevAffiliate; 4108 } 4109 if (other != null) { 4110 int otherIndex = mRecentTasks.indexOf(other); 4111 if (otherIndex >= 0) { 4112 // Insert new task at appropriate location. 4113 int taskIndex; 4114 if (other == task.mNextAffiliate) { 4115 // We found the index of our next affiliation, which is who is 4116 // before us in the list, so add after that point. 4117 taskIndex = otherIndex+1; 4118 } else { 4119 // We found the index of our previous affiliation, which is who is 4120 // after us in the list, so add at their position. 4121 taskIndex = otherIndex; 4122 } 4123 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4124 + taskIndex + ": " + task); 4125 mRecentTasks.add(taskIndex, task); 4126 4127 // Now move everything to the front. 4128 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4129 // All went well. 4130 return; 4131 } 4132 4133 // Uh oh... something bad in the affiliation chain, try to rebuild 4134 // everything and then go through our general path of adding a new task. 4135 needAffiliationFix = true; 4136 } else { 4137 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4138 + other); 4139 needAffiliationFix = true; 4140 } 4141 } else { 4142 if (DEBUG_RECENTS) Slog.d(TAG, 4143 "addRecent: adding affiliated task without next/prev:" + task); 4144 needAffiliationFix = true; 4145 } 4146 } 4147 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4148 4149 if (needAffiliationFix) { 4150 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4151 cleanupRecentTasksLocked(task.userId); 4152 } 4153 } 4154 4155 /** 4156 * If needed, remove oldest existing entries in recents that are for the same kind 4157 * of task as the given one. 4158 */ 4159 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4160 int N = mRecentTasks.size(); 4161 final Intent intent = task.intent; 4162 final boolean document = intent != null && intent.isDocument(); 4163 4164 int maxRecents = task.maxRecents - 1; 4165 for (int i=0; i<N; i++) { 4166 final TaskRecord tr = mRecentTasks.get(i); 4167 if (task != tr) { 4168 if (task.userId != tr.userId) { 4169 continue; 4170 } 4171 if (i > MAX_RECENT_BITMAPS) { 4172 tr.freeLastThumbnail(); 4173 } 4174 final Intent trIntent = tr.intent; 4175 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4176 (intent == null || !intent.filterEquals(trIntent))) { 4177 continue; 4178 } 4179 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4180 if (document && trIsDocument) { 4181 // These are the same document activity (not necessarily the same doc). 4182 if (maxRecents > 0) { 4183 --maxRecents; 4184 continue; 4185 } 4186 // Hit the maximum number of documents for this task. Fall through 4187 // and remove this document from recents. 4188 } else if (document || trIsDocument) { 4189 // Only one of these is a document. Not the droid we're looking for. 4190 continue; 4191 } 4192 } 4193 4194 if (!doTrim) { 4195 // If the caller is not actually asking for a trim, just tell them we reached 4196 // a point where the trim would happen. 4197 return i; 4198 } 4199 4200 // Either task and tr are the same or, their affinities match or their intents match 4201 // and neither of them is a document, or they are documents using the same activity 4202 // and their maxRecents has been reached. 4203 tr.disposeThumbnail(); 4204 mRecentTasks.remove(i); 4205 if (task != tr) { 4206 tr.removedFromRecents(mTaskPersister); 4207 } 4208 i--; 4209 N--; 4210 if (task.intent == null) { 4211 // If the new recent task we are adding is not fully 4212 // specified, then replace it with the existing recent task. 4213 task = tr; 4214 } 4215 notifyTaskPersisterLocked(tr, false); 4216 } 4217 4218 return -1; 4219 } 4220 4221 @Override 4222 public void reportActivityFullyDrawn(IBinder token) { 4223 synchronized (this) { 4224 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4225 if (r == null) { 4226 return; 4227 } 4228 r.reportFullyDrawnLocked(); 4229 } 4230 } 4231 4232 @Override 4233 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4234 synchronized (this) { 4235 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4236 if (r == null) { 4237 return; 4238 } 4239 final long origId = Binder.clearCallingIdentity(); 4240 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4241 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4242 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4243 if (config != null) { 4244 r.frozenBeforeDestroy = true; 4245 if (!updateConfigurationLocked(config, r, false, false)) { 4246 mStackSupervisor.resumeTopActivitiesLocked(); 4247 } 4248 } 4249 Binder.restoreCallingIdentity(origId); 4250 } 4251 } 4252 4253 @Override 4254 public int getRequestedOrientation(IBinder token) { 4255 synchronized (this) { 4256 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4257 if (r == null) { 4258 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4259 } 4260 return mWindowManager.getAppOrientation(r.appToken); 4261 } 4262 } 4263 4264 /** 4265 * This is the internal entry point for handling Activity.finish(). 4266 * 4267 * @param token The Binder token referencing the Activity we want to finish. 4268 * @param resultCode Result code, if any, from this Activity. 4269 * @param resultData Result data (Intent), if any, from this Activity. 4270 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4271 * the root Activity in the task. 4272 * 4273 * @return Returns true if the activity successfully finished, or false if it is still running. 4274 */ 4275 @Override 4276 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4277 boolean finishTask) { 4278 // Refuse possible leaked file descriptors 4279 if (resultData != null && resultData.hasFileDescriptors() == true) { 4280 throw new IllegalArgumentException("File descriptors passed in Intent"); 4281 } 4282 4283 synchronized(this) { 4284 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4285 if (r == null) { 4286 return true; 4287 } 4288 // Keep track of the root activity of the task before we finish it 4289 TaskRecord tr = r.task; 4290 ActivityRecord rootR = tr.getRootActivity(); 4291 if (rootR == null) { 4292 Slog.w(TAG, "Finishing task with all activities already finished"); 4293 } 4294 // Do not allow task to finish in Lock Task mode. 4295 if (tr == mStackSupervisor.mLockTaskModeTask) { 4296 if (rootR == r) { 4297 Slog.i(TAG, "Not finishing task in lock task mode"); 4298 mStackSupervisor.showLockTaskToast(); 4299 return false; 4300 } 4301 } 4302 if (mController != null) { 4303 // Find the first activity that is not finishing. 4304 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4305 if (next != null) { 4306 // ask watcher if this is allowed 4307 boolean resumeOK = true; 4308 try { 4309 resumeOK = mController.activityResuming(next.packageName); 4310 } catch (RemoteException e) { 4311 mController = null; 4312 Watchdog.getInstance().setActivityController(null); 4313 } 4314 4315 if (!resumeOK) { 4316 Slog.i(TAG, "Not finishing activity because controller resumed"); 4317 return false; 4318 } 4319 } 4320 } 4321 final long origId = Binder.clearCallingIdentity(); 4322 try { 4323 boolean res; 4324 if (finishTask && r == rootR) { 4325 // If requested, remove the task that is associated to this activity only if it 4326 // was the root activity in the task. The result code and data is ignored 4327 // because we don't support returning them across task boundaries. 4328 res = removeTaskByIdLocked(tr.taskId, false); 4329 if (!res) { 4330 Slog.i(TAG, "Removing task failed to finish activity"); 4331 } 4332 } else { 4333 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4334 resultData, "app-request", true); 4335 if (!res) { 4336 Slog.i(TAG, "Failed to finish by app-request"); 4337 } 4338 } 4339 return res; 4340 } finally { 4341 Binder.restoreCallingIdentity(origId); 4342 } 4343 } 4344 } 4345 4346 @Override 4347 public final void finishHeavyWeightApp() { 4348 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4349 != PackageManager.PERMISSION_GRANTED) { 4350 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4351 + Binder.getCallingPid() 4352 + ", uid=" + Binder.getCallingUid() 4353 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4354 Slog.w(TAG, msg); 4355 throw new SecurityException(msg); 4356 } 4357 4358 synchronized(this) { 4359 if (mHeavyWeightProcess == null) { 4360 return; 4361 } 4362 4363 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4364 mHeavyWeightProcess.activities); 4365 for (int i=0; i<activities.size(); i++) { 4366 ActivityRecord r = activities.get(i); 4367 if (!r.finishing) { 4368 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4369 null, "finish-heavy", true); 4370 } 4371 } 4372 4373 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4374 mHeavyWeightProcess.userId, 0)); 4375 mHeavyWeightProcess = null; 4376 } 4377 } 4378 4379 @Override 4380 public void crashApplication(int uid, int initialPid, String packageName, 4381 String message) { 4382 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4383 != PackageManager.PERMISSION_GRANTED) { 4384 String msg = "Permission Denial: crashApplication() from pid=" 4385 + Binder.getCallingPid() 4386 + ", uid=" + Binder.getCallingUid() 4387 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4388 Slog.w(TAG, msg); 4389 throw new SecurityException(msg); 4390 } 4391 4392 synchronized(this) { 4393 ProcessRecord proc = null; 4394 4395 // Figure out which process to kill. We don't trust that initialPid 4396 // still has any relation to current pids, so must scan through the 4397 // list. 4398 synchronized (mPidsSelfLocked) { 4399 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4400 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4401 if (p.uid != uid) { 4402 continue; 4403 } 4404 if (p.pid == initialPid) { 4405 proc = p; 4406 break; 4407 } 4408 if (p.pkgList.containsKey(packageName)) { 4409 proc = p; 4410 } 4411 } 4412 } 4413 4414 if (proc == null) { 4415 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4416 + " initialPid=" + initialPid 4417 + " packageName=" + packageName); 4418 return; 4419 } 4420 4421 if (proc.thread != null) { 4422 if (proc.pid == Process.myPid()) { 4423 Log.w(TAG, "crashApplication: trying to crash self!"); 4424 return; 4425 } 4426 long ident = Binder.clearCallingIdentity(); 4427 try { 4428 proc.thread.scheduleCrash(message); 4429 } catch (RemoteException e) { 4430 } 4431 Binder.restoreCallingIdentity(ident); 4432 } 4433 } 4434 } 4435 4436 @Override 4437 public final void finishSubActivity(IBinder token, String resultWho, 4438 int requestCode) { 4439 synchronized(this) { 4440 final long origId = Binder.clearCallingIdentity(); 4441 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4442 if (r != null) { 4443 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4444 } 4445 Binder.restoreCallingIdentity(origId); 4446 } 4447 } 4448 4449 @Override 4450 public boolean finishActivityAffinity(IBinder token) { 4451 synchronized(this) { 4452 final long origId = Binder.clearCallingIdentity(); 4453 try { 4454 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4455 4456 ActivityRecord rootR = r.task.getRootActivity(); 4457 // Do not allow task to finish in Lock Task mode. 4458 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4459 if (rootR == r) { 4460 mStackSupervisor.showLockTaskToast(); 4461 return false; 4462 } 4463 } 4464 boolean res = false; 4465 if (r != null) { 4466 res = r.task.stack.finishActivityAffinityLocked(r); 4467 } 4468 return res; 4469 } finally { 4470 Binder.restoreCallingIdentity(origId); 4471 } 4472 } 4473 } 4474 4475 @Override 4476 public void finishVoiceTask(IVoiceInteractionSession session) { 4477 synchronized(this) { 4478 final long origId = Binder.clearCallingIdentity(); 4479 try { 4480 mStackSupervisor.finishVoiceTask(session); 4481 } finally { 4482 Binder.restoreCallingIdentity(origId); 4483 } 4484 } 4485 4486 } 4487 4488 @Override 4489 public boolean releaseActivityInstance(IBinder token) { 4490 synchronized(this) { 4491 final long origId = Binder.clearCallingIdentity(); 4492 try { 4493 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4494 if (r.task == null || r.task.stack == null) { 4495 return false; 4496 } 4497 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4498 } finally { 4499 Binder.restoreCallingIdentity(origId); 4500 } 4501 } 4502 } 4503 4504 @Override 4505 public void releaseSomeActivities(IApplicationThread appInt) { 4506 synchronized(this) { 4507 final long origId = Binder.clearCallingIdentity(); 4508 try { 4509 ProcessRecord app = getRecordForAppLocked(appInt); 4510 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4511 } finally { 4512 Binder.restoreCallingIdentity(origId); 4513 } 4514 } 4515 } 4516 4517 @Override 4518 public boolean willActivityBeVisible(IBinder token) { 4519 synchronized(this) { 4520 ActivityStack stack = ActivityRecord.getStackLocked(token); 4521 if (stack != null) { 4522 return stack.willActivityBeVisibleLocked(token); 4523 } 4524 return false; 4525 } 4526 } 4527 4528 @Override 4529 public void overridePendingTransition(IBinder token, String packageName, 4530 int enterAnim, int exitAnim) { 4531 synchronized(this) { 4532 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4533 if (self == null) { 4534 return; 4535 } 4536 4537 final long origId = Binder.clearCallingIdentity(); 4538 4539 if (self.state == ActivityState.RESUMED 4540 || self.state == ActivityState.PAUSING) { 4541 mWindowManager.overridePendingAppTransition(packageName, 4542 enterAnim, exitAnim, null); 4543 } 4544 4545 Binder.restoreCallingIdentity(origId); 4546 } 4547 } 4548 4549 /** 4550 * Main function for removing an existing process from the activity manager 4551 * as a result of that process going away. Clears out all connections 4552 * to the process. 4553 */ 4554 private final void handleAppDiedLocked(ProcessRecord app, 4555 boolean restarting, boolean allowRestart) { 4556 int pid = app.pid; 4557 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4558 if (!kept && !restarting) { 4559 removeLruProcessLocked(app); 4560 if (pid > 0) { 4561 ProcessList.remove(pid); 4562 } 4563 } 4564 4565 if (mProfileProc == app) { 4566 clearProfilerLocked(); 4567 } 4568 4569 // Remove this application's activities from active lists. 4570 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4571 4572 app.activities.clear(); 4573 4574 if (app.instrumentationClass != null) { 4575 Slog.w(TAG, "Crash of app " + app.processName 4576 + " running instrumentation " + app.instrumentationClass); 4577 Bundle info = new Bundle(); 4578 info.putString("shortMsg", "Process crashed."); 4579 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4580 } 4581 4582 if (!restarting) { 4583 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4584 // If there was nothing to resume, and we are not already 4585 // restarting this process, but there is a visible activity that 4586 // is hosted by the process... then make sure all visible 4587 // activities are running, taking care of restarting this 4588 // process. 4589 if (hasVisibleActivities) { 4590 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4591 } 4592 } 4593 } 4594 } 4595 4596 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4597 IBinder threadBinder = thread.asBinder(); 4598 // Find the application record. 4599 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4600 ProcessRecord rec = mLruProcesses.get(i); 4601 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4602 return i; 4603 } 4604 } 4605 return -1; 4606 } 4607 4608 final ProcessRecord getRecordForAppLocked( 4609 IApplicationThread thread) { 4610 if (thread == null) { 4611 return null; 4612 } 4613 4614 int appIndex = getLRURecordIndexForAppLocked(thread); 4615 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4616 } 4617 4618 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4619 // If there are no longer any background processes running, 4620 // and the app that died was not running instrumentation, 4621 // then tell everyone we are now low on memory. 4622 boolean haveBg = false; 4623 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4624 ProcessRecord rec = mLruProcesses.get(i); 4625 if (rec.thread != null 4626 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4627 haveBg = true; 4628 break; 4629 } 4630 } 4631 4632 if (!haveBg) { 4633 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4634 if (doReport) { 4635 long now = SystemClock.uptimeMillis(); 4636 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4637 doReport = false; 4638 } else { 4639 mLastMemUsageReportTime = now; 4640 } 4641 } 4642 final ArrayList<ProcessMemInfo> memInfos 4643 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4644 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4645 long now = SystemClock.uptimeMillis(); 4646 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4647 ProcessRecord rec = mLruProcesses.get(i); 4648 if (rec == dyingProc || rec.thread == null) { 4649 continue; 4650 } 4651 if (doReport) { 4652 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4653 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4654 } 4655 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4656 // The low memory report is overriding any current 4657 // state for a GC request. Make sure to do 4658 // heavy/important/visible/foreground processes first. 4659 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4660 rec.lastRequestedGc = 0; 4661 } else { 4662 rec.lastRequestedGc = rec.lastLowMemory; 4663 } 4664 rec.reportLowMemory = true; 4665 rec.lastLowMemory = now; 4666 mProcessesToGc.remove(rec); 4667 addProcessToGcListLocked(rec); 4668 } 4669 } 4670 if (doReport) { 4671 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4672 mHandler.sendMessage(msg); 4673 } 4674 scheduleAppGcsLocked(); 4675 } 4676 } 4677 4678 final void appDiedLocked(ProcessRecord app) { 4679 appDiedLocked(app, app.pid, app.thread); 4680 } 4681 4682 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4683 // First check if this ProcessRecord is actually active for the pid. 4684 synchronized (mPidsSelfLocked) { 4685 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4686 if (curProc != app) { 4687 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4688 return; 4689 } 4690 } 4691 4692 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4693 synchronized (stats) { 4694 stats.noteProcessDiedLocked(app.info.uid, pid); 4695 } 4696 4697 Process.killProcessQuiet(pid); 4698 Process.killProcessGroup(app.info.uid, pid); 4699 app.killed = true; 4700 4701 // Clean up already done if the process has been re-started. 4702 if (app.pid == pid && app.thread != null && 4703 app.thread.asBinder() == thread.asBinder()) { 4704 boolean doLowMem = app.instrumentationClass == null; 4705 boolean doOomAdj = doLowMem; 4706 if (!app.killedByAm) { 4707 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4708 + ") has died"); 4709 mAllowLowerMemLevel = true; 4710 } else { 4711 // Note that we always want to do oom adj to update our state with the 4712 // new number of procs. 4713 mAllowLowerMemLevel = false; 4714 doLowMem = false; 4715 } 4716 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4717 if (DEBUG_CLEANUP) Slog.v( 4718 TAG, "Dying app: " + app + ", pid: " + pid 4719 + ", thread: " + thread.asBinder()); 4720 handleAppDiedLocked(app, false, true); 4721 4722 if (doOomAdj) { 4723 updateOomAdjLocked(); 4724 } 4725 if (doLowMem) { 4726 doLowMemReportIfNeededLocked(app); 4727 } 4728 } else if (app.pid != pid) { 4729 // A new process has already been started. 4730 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4731 + ") has died and restarted (pid " + app.pid + ")."); 4732 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4733 } else if (DEBUG_PROCESSES) { 4734 Slog.d(TAG, "Received spurious death notification for thread " 4735 + thread.asBinder()); 4736 } 4737 } 4738 4739 /** 4740 * If a stack trace dump file is configured, dump process stack traces. 4741 * @param clearTraces causes the dump file to be erased prior to the new 4742 * traces being written, if true; when false, the new traces will be 4743 * appended to any existing file content. 4744 * @param firstPids of dalvik VM processes to dump stack traces for first 4745 * @param lastPids of dalvik VM processes to dump stack traces for last 4746 * @param nativeProcs optional list of native process names to dump stack crawls 4747 * @return file containing stack traces, or null if no dump file is configured 4748 */ 4749 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4750 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4751 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4752 if (tracesPath == null || tracesPath.length() == 0) { 4753 return null; 4754 } 4755 4756 File tracesFile = new File(tracesPath); 4757 try { 4758 File tracesDir = tracesFile.getParentFile(); 4759 if (!tracesDir.exists()) { 4760 tracesDir.mkdirs(); 4761 if (!SELinux.restorecon(tracesDir)) { 4762 return null; 4763 } 4764 } 4765 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4766 4767 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4768 tracesFile.createNewFile(); 4769 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4770 } catch (IOException e) { 4771 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4772 return null; 4773 } 4774 4775 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4776 return tracesFile; 4777 } 4778 4779 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4780 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4781 // Use a FileObserver to detect when traces finish writing. 4782 // The order of traces is considered important to maintain for legibility. 4783 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4784 @Override 4785 public synchronized void onEvent(int event, String path) { notify(); } 4786 }; 4787 4788 try { 4789 observer.startWatching(); 4790 4791 // First collect all of the stacks of the most important pids. 4792 if (firstPids != null) { 4793 try { 4794 int num = firstPids.size(); 4795 for (int i = 0; i < num; i++) { 4796 synchronized (observer) { 4797 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4798 observer.wait(200); // Wait for write-close, give up after 200msec 4799 } 4800 } 4801 } catch (InterruptedException e) { 4802 Slog.wtf(TAG, e); 4803 } 4804 } 4805 4806 // Next collect the stacks of the native pids 4807 if (nativeProcs != null) { 4808 int[] pids = Process.getPidsForCommands(nativeProcs); 4809 if (pids != null) { 4810 for (int pid : pids) { 4811 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4812 } 4813 } 4814 } 4815 4816 // Lastly, measure CPU usage. 4817 if (processCpuTracker != null) { 4818 processCpuTracker.init(); 4819 System.gc(); 4820 processCpuTracker.update(); 4821 try { 4822 synchronized (processCpuTracker) { 4823 processCpuTracker.wait(500); // measure over 1/2 second. 4824 } 4825 } catch (InterruptedException e) { 4826 } 4827 processCpuTracker.update(); 4828 4829 // We'll take the stack crawls of just the top apps using CPU. 4830 final int N = processCpuTracker.countWorkingStats(); 4831 int numProcs = 0; 4832 for (int i=0; i<N && numProcs<5; i++) { 4833 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4834 if (lastPids.indexOfKey(stats.pid) >= 0) { 4835 numProcs++; 4836 try { 4837 synchronized (observer) { 4838 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4839 observer.wait(200); // Wait for write-close, give up after 200msec 4840 } 4841 } catch (InterruptedException e) { 4842 Slog.wtf(TAG, e); 4843 } 4844 4845 } 4846 } 4847 } 4848 } finally { 4849 observer.stopWatching(); 4850 } 4851 } 4852 4853 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4854 if (true || IS_USER_BUILD) { 4855 return; 4856 } 4857 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4858 if (tracesPath == null || tracesPath.length() == 0) { 4859 return; 4860 } 4861 4862 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4863 StrictMode.allowThreadDiskWrites(); 4864 try { 4865 final File tracesFile = new File(tracesPath); 4866 final File tracesDir = tracesFile.getParentFile(); 4867 final File tracesTmp = new File(tracesDir, "__tmp__"); 4868 try { 4869 if (!tracesDir.exists()) { 4870 tracesDir.mkdirs(); 4871 if (!SELinux.restorecon(tracesDir.getPath())) { 4872 return; 4873 } 4874 } 4875 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4876 4877 if (tracesFile.exists()) { 4878 tracesTmp.delete(); 4879 tracesFile.renameTo(tracesTmp); 4880 } 4881 StringBuilder sb = new StringBuilder(); 4882 Time tobj = new Time(); 4883 tobj.set(System.currentTimeMillis()); 4884 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4885 sb.append(": "); 4886 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4887 sb.append(" since "); 4888 sb.append(msg); 4889 FileOutputStream fos = new FileOutputStream(tracesFile); 4890 fos.write(sb.toString().getBytes()); 4891 if (app == null) { 4892 fos.write("\n*** No application process!".getBytes()); 4893 } 4894 fos.close(); 4895 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4896 } catch (IOException e) { 4897 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4898 return; 4899 } 4900 4901 if (app != null) { 4902 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4903 firstPids.add(app.pid); 4904 dumpStackTraces(tracesPath, firstPids, null, null, null); 4905 } 4906 4907 File lastTracesFile = null; 4908 File curTracesFile = null; 4909 for (int i=9; i>=0; i--) { 4910 String name = String.format(Locale.US, "slow%02d.txt", i); 4911 curTracesFile = new File(tracesDir, name); 4912 if (curTracesFile.exists()) { 4913 if (lastTracesFile != null) { 4914 curTracesFile.renameTo(lastTracesFile); 4915 } else { 4916 curTracesFile.delete(); 4917 } 4918 } 4919 lastTracesFile = curTracesFile; 4920 } 4921 tracesFile.renameTo(curTracesFile); 4922 if (tracesTmp.exists()) { 4923 tracesTmp.renameTo(tracesFile); 4924 } 4925 } finally { 4926 StrictMode.setThreadPolicy(oldPolicy); 4927 } 4928 } 4929 4930 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4931 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4932 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4933 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4934 4935 if (mController != null) { 4936 try { 4937 // 0 == continue, -1 = kill process immediately 4938 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4939 if (res < 0 && app.pid != MY_PID) { 4940 app.kill("anr", true); 4941 } 4942 } catch (RemoteException e) { 4943 mController = null; 4944 Watchdog.getInstance().setActivityController(null); 4945 } 4946 } 4947 4948 long anrTime = SystemClock.uptimeMillis(); 4949 if (MONITOR_CPU_USAGE) { 4950 updateCpuStatsNow(); 4951 } 4952 4953 synchronized (this) { 4954 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4955 if (mShuttingDown) { 4956 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4957 return; 4958 } else if (app.notResponding) { 4959 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4960 return; 4961 } else if (app.crashing) { 4962 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4963 return; 4964 } 4965 4966 // In case we come through here for the same app before completing 4967 // this one, mark as anring now so we will bail out. 4968 app.notResponding = true; 4969 4970 // Log the ANR to the event log. 4971 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4972 app.processName, app.info.flags, annotation); 4973 4974 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4975 firstPids.add(app.pid); 4976 4977 int parentPid = app.pid; 4978 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4979 if (parentPid != app.pid) firstPids.add(parentPid); 4980 4981 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4982 4983 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4984 ProcessRecord r = mLruProcesses.get(i); 4985 if (r != null && r.thread != null) { 4986 int pid = r.pid; 4987 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4988 if (r.persistent) { 4989 firstPids.add(pid); 4990 } else { 4991 lastPids.put(pid, Boolean.TRUE); 4992 } 4993 } 4994 } 4995 } 4996 } 4997 4998 // Log the ANR to the main log. 4999 StringBuilder info = new StringBuilder(); 5000 info.setLength(0); 5001 info.append("ANR in ").append(app.processName); 5002 if (activity != null && activity.shortComponentName != null) { 5003 info.append(" (").append(activity.shortComponentName).append(")"); 5004 } 5005 info.append("\n"); 5006 info.append("PID: ").append(app.pid).append("\n"); 5007 if (annotation != null) { 5008 info.append("Reason: ").append(annotation).append("\n"); 5009 } 5010 if (parent != null && parent != activity) { 5011 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5012 } 5013 5014 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5015 5016 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5017 NATIVE_STACKS_OF_INTEREST); 5018 5019 String cpuInfo = null; 5020 if (MONITOR_CPU_USAGE) { 5021 updateCpuStatsNow(); 5022 synchronized (mProcessCpuTracker) { 5023 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5024 } 5025 info.append(processCpuTracker.printCurrentLoad()); 5026 info.append(cpuInfo); 5027 } 5028 5029 info.append(processCpuTracker.printCurrentState(anrTime)); 5030 5031 Slog.e(TAG, info.toString()); 5032 if (tracesFile == null) { 5033 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5034 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5035 } 5036 5037 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5038 cpuInfo, tracesFile, null); 5039 5040 if (mController != null) { 5041 try { 5042 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5043 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5044 if (res != 0) { 5045 if (res < 0 && app.pid != MY_PID) { 5046 app.kill("anr", true); 5047 } else { 5048 synchronized (this) { 5049 mServices.scheduleServiceTimeoutLocked(app); 5050 } 5051 } 5052 return; 5053 } 5054 } catch (RemoteException e) { 5055 mController = null; 5056 Watchdog.getInstance().setActivityController(null); 5057 } 5058 } 5059 5060 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5061 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5062 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5063 5064 synchronized (this) { 5065 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5066 app.kill("bg anr", true); 5067 return; 5068 } 5069 5070 // Set the app's notResponding state, and look up the errorReportReceiver 5071 makeAppNotRespondingLocked(app, 5072 activity != null ? activity.shortComponentName : null, 5073 annotation != null ? "ANR " + annotation : "ANR", 5074 info.toString()); 5075 5076 // Bring up the infamous App Not Responding dialog 5077 Message msg = Message.obtain(); 5078 HashMap<String, Object> map = new HashMap<String, Object>(); 5079 msg.what = SHOW_NOT_RESPONDING_MSG; 5080 msg.obj = map; 5081 msg.arg1 = aboveSystem ? 1 : 0; 5082 map.put("app", app); 5083 if (activity != null) { 5084 map.put("activity", activity); 5085 } 5086 5087 mHandler.sendMessage(msg); 5088 } 5089 } 5090 5091 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5092 if (!mLaunchWarningShown) { 5093 mLaunchWarningShown = true; 5094 mHandler.post(new Runnable() { 5095 @Override 5096 public void run() { 5097 synchronized (ActivityManagerService.this) { 5098 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5099 d.show(); 5100 mHandler.postDelayed(new Runnable() { 5101 @Override 5102 public void run() { 5103 synchronized (ActivityManagerService.this) { 5104 d.dismiss(); 5105 mLaunchWarningShown = false; 5106 } 5107 } 5108 }, 4000); 5109 } 5110 } 5111 }); 5112 } 5113 } 5114 5115 @Override 5116 public boolean clearApplicationUserData(final String packageName, 5117 final IPackageDataObserver observer, int userId) { 5118 enforceNotIsolatedCaller("clearApplicationUserData"); 5119 int uid = Binder.getCallingUid(); 5120 int pid = Binder.getCallingPid(); 5121 userId = handleIncomingUser(pid, uid, 5122 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5123 long callingId = Binder.clearCallingIdentity(); 5124 try { 5125 IPackageManager pm = AppGlobals.getPackageManager(); 5126 int pkgUid = -1; 5127 synchronized(this) { 5128 try { 5129 pkgUid = pm.getPackageUid(packageName, userId); 5130 } catch (RemoteException e) { 5131 } 5132 if (pkgUid == -1) { 5133 Slog.w(TAG, "Invalid packageName: " + packageName); 5134 if (observer != null) { 5135 try { 5136 observer.onRemoveCompleted(packageName, false); 5137 } catch (RemoteException e) { 5138 Slog.i(TAG, "Observer no longer exists."); 5139 } 5140 } 5141 return false; 5142 } 5143 if (uid == pkgUid || checkComponentPermission( 5144 android.Manifest.permission.CLEAR_APP_USER_DATA, 5145 pid, uid, -1, true) 5146 == PackageManager.PERMISSION_GRANTED) { 5147 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5148 } else { 5149 throw new SecurityException("PID " + pid + " does not have permission " 5150 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5151 + " of package " + packageName); 5152 } 5153 5154 // Remove all tasks match the cleared application package and user 5155 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5156 final TaskRecord tr = mRecentTasks.get(i); 5157 final String taskPackageName = 5158 tr.getBaseIntent().getComponent().getPackageName(); 5159 if (tr.userId != userId) continue; 5160 if (!taskPackageName.equals(packageName)) continue; 5161 removeTaskByIdLocked(tr.taskId, false); 5162 } 5163 } 5164 5165 try { 5166 // Clear application user data 5167 pm.clearApplicationUserData(packageName, observer, userId); 5168 5169 synchronized(this) { 5170 // Remove all permissions granted from/to this package 5171 removeUriPermissionsForPackageLocked(packageName, userId, true); 5172 } 5173 5174 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5175 Uri.fromParts("package", packageName, null)); 5176 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5177 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5178 null, null, 0, null, null, null, false, false, userId); 5179 } catch (RemoteException e) { 5180 } 5181 } finally { 5182 Binder.restoreCallingIdentity(callingId); 5183 } 5184 return true; 5185 } 5186 5187 @Override 5188 public void killBackgroundProcesses(final String packageName, int userId) { 5189 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5190 != PackageManager.PERMISSION_GRANTED && 5191 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5192 != PackageManager.PERMISSION_GRANTED) { 5193 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5194 + Binder.getCallingPid() 5195 + ", uid=" + Binder.getCallingUid() 5196 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5197 Slog.w(TAG, msg); 5198 throw new SecurityException(msg); 5199 } 5200 5201 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5202 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5203 long callingId = Binder.clearCallingIdentity(); 5204 try { 5205 IPackageManager pm = AppGlobals.getPackageManager(); 5206 synchronized(this) { 5207 int appId = -1; 5208 try { 5209 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5210 } catch (RemoteException e) { 5211 } 5212 if (appId == -1) { 5213 Slog.w(TAG, "Invalid packageName: " + packageName); 5214 return; 5215 } 5216 killPackageProcessesLocked(packageName, appId, userId, 5217 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5218 } 5219 } finally { 5220 Binder.restoreCallingIdentity(callingId); 5221 } 5222 } 5223 5224 @Override 5225 public void killAllBackgroundProcesses() { 5226 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5227 != PackageManager.PERMISSION_GRANTED) { 5228 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5229 + Binder.getCallingPid() 5230 + ", uid=" + Binder.getCallingUid() 5231 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5232 Slog.w(TAG, msg); 5233 throw new SecurityException(msg); 5234 } 5235 5236 long callingId = Binder.clearCallingIdentity(); 5237 try { 5238 synchronized(this) { 5239 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5240 final int NP = mProcessNames.getMap().size(); 5241 for (int ip=0; ip<NP; ip++) { 5242 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5243 final int NA = apps.size(); 5244 for (int ia=0; ia<NA; ia++) { 5245 ProcessRecord app = apps.valueAt(ia); 5246 if (app.persistent) { 5247 // we don't kill persistent processes 5248 continue; 5249 } 5250 if (app.removed) { 5251 procs.add(app); 5252 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5253 app.removed = true; 5254 procs.add(app); 5255 } 5256 } 5257 } 5258 5259 int N = procs.size(); 5260 for (int i=0; i<N; i++) { 5261 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5262 } 5263 mAllowLowerMemLevel = true; 5264 updateOomAdjLocked(); 5265 doLowMemReportIfNeededLocked(null); 5266 } 5267 } finally { 5268 Binder.restoreCallingIdentity(callingId); 5269 } 5270 } 5271 5272 @Override 5273 public void forceStopPackage(final String packageName, int userId) { 5274 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5275 != PackageManager.PERMISSION_GRANTED) { 5276 String msg = "Permission Denial: forceStopPackage() from pid=" 5277 + Binder.getCallingPid() 5278 + ", uid=" + Binder.getCallingUid() 5279 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5280 Slog.w(TAG, msg); 5281 throw new SecurityException(msg); 5282 } 5283 final int callingPid = Binder.getCallingPid(); 5284 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5285 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5286 long callingId = Binder.clearCallingIdentity(); 5287 try { 5288 IPackageManager pm = AppGlobals.getPackageManager(); 5289 synchronized(this) { 5290 int[] users = userId == UserHandle.USER_ALL 5291 ? getUsersLocked() : new int[] { userId }; 5292 for (int user : users) { 5293 int pkgUid = -1; 5294 try { 5295 pkgUid = pm.getPackageUid(packageName, user); 5296 } catch (RemoteException e) { 5297 } 5298 if (pkgUid == -1) { 5299 Slog.w(TAG, "Invalid packageName: " + packageName); 5300 continue; 5301 } 5302 try { 5303 pm.setPackageStoppedState(packageName, true, user); 5304 } catch (RemoteException e) { 5305 } catch (IllegalArgumentException e) { 5306 Slog.w(TAG, "Failed trying to unstop package " 5307 + packageName + ": " + e); 5308 } 5309 if (isUserRunningLocked(user, false)) { 5310 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5311 } 5312 } 5313 } 5314 } finally { 5315 Binder.restoreCallingIdentity(callingId); 5316 } 5317 } 5318 5319 @Override 5320 public void addPackageDependency(String packageName) { 5321 synchronized (this) { 5322 int callingPid = Binder.getCallingPid(); 5323 if (callingPid == Process.myPid()) { 5324 // Yeah, um, no. 5325 Slog.w(TAG, "Can't addPackageDependency on system process"); 5326 return; 5327 } 5328 ProcessRecord proc; 5329 synchronized (mPidsSelfLocked) { 5330 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5331 } 5332 if (proc != null) { 5333 if (proc.pkgDeps == null) { 5334 proc.pkgDeps = new ArraySet<String>(1); 5335 } 5336 proc.pkgDeps.add(packageName); 5337 } 5338 } 5339 } 5340 5341 /* 5342 * The pkg name and app id have to be specified. 5343 */ 5344 @Override 5345 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5346 if (pkg == null) { 5347 return; 5348 } 5349 // Make sure the uid is valid. 5350 if (appid < 0) { 5351 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5352 return; 5353 } 5354 int callerUid = Binder.getCallingUid(); 5355 // Only the system server can kill an application 5356 if (callerUid == Process.SYSTEM_UID) { 5357 // Post an aysnc message to kill the application 5358 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5359 msg.arg1 = appid; 5360 msg.arg2 = 0; 5361 Bundle bundle = new Bundle(); 5362 bundle.putString("pkg", pkg); 5363 bundle.putString("reason", reason); 5364 msg.obj = bundle; 5365 mHandler.sendMessage(msg); 5366 } else { 5367 throw new SecurityException(callerUid + " cannot kill pkg: " + 5368 pkg); 5369 } 5370 } 5371 5372 @Override 5373 public void closeSystemDialogs(String reason) { 5374 enforceNotIsolatedCaller("closeSystemDialogs"); 5375 5376 final int pid = Binder.getCallingPid(); 5377 final int uid = Binder.getCallingUid(); 5378 final long origId = Binder.clearCallingIdentity(); 5379 try { 5380 synchronized (this) { 5381 // Only allow this from foreground processes, so that background 5382 // applications can't abuse it to prevent system UI from being shown. 5383 if (uid >= Process.FIRST_APPLICATION_UID) { 5384 ProcessRecord proc; 5385 synchronized (mPidsSelfLocked) { 5386 proc = mPidsSelfLocked.get(pid); 5387 } 5388 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5389 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5390 + " from background process " + proc); 5391 return; 5392 } 5393 } 5394 closeSystemDialogsLocked(reason); 5395 } 5396 } finally { 5397 Binder.restoreCallingIdentity(origId); 5398 } 5399 } 5400 5401 void closeSystemDialogsLocked(String reason) { 5402 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5403 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5404 | Intent.FLAG_RECEIVER_FOREGROUND); 5405 if (reason != null) { 5406 intent.putExtra("reason", reason); 5407 } 5408 mWindowManager.closeSystemDialogs(reason); 5409 5410 mStackSupervisor.closeSystemDialogsLocked(); 5411 5412 broadcastIntentLocked(null, null, intent, null, 5413 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5414 Process.SYSTEM_UID, UserHandle.USER_ALL); 5415 } 5416 5417 @Override 5418 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5419 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5420 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5421 for (int i=pids.length-1; i>=0; i--) { 5422 ProcessRecord proc; 5423 int oomAdj; 5424 synchronized (this) { 5425 synchronized (mPidsSelfLocked) { 5426 proc = mPidsSelfLocked.get(pids[i]); 5427 oomAdj = proc != null ? proc.setAdj : 0; 5428 } 5429 } 5430 infos[i] = new Debug.MemoryInfo(); 5431 Debug.getMemoryInfo(pids[i], infos[i]); 5432 if (proc != null) { 5433 synchronized (this) { 5434 if (proc.thread != null && proc.setAdj == oomAdj) { 5435 // Record this for posterity if the process has been stable. 5436 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5437 infos[i].getTotalUss(), false, proc.pkgList); 5438 } 5439 } 5440 } 5441 } 5442 return infos; 5443 } 5444 5445 @Override 5446 public long[] getProcessPss(int[] pids) { 5447 enforceNotIsolatedCaller("getProcessPss"); 5448 long[] pss = new long[pids.length]; 5449 for (int i=pids.length-1; i>=0; i--) { 5450 ProcessRecord proc; 5451 int oomAdj; 5452 synchronized (this) { 5453 synchronized (mPidsSelfLocked) { 5454 proc = mPidsSelfLocked.get(pids[i]); 5455 oomAdj = proc != null ? proc.setAdj : 0; 5456 } 5457 } 5458 long[] tmpUss = new long[1]; 5459 pss[i] = Debug.getPss(pids[i], tmpUss); 5460 if (proc != null) { 5461 synchronized (this) { 5462 if (proc.thread != null && proc.setAdj == oomAdj) { 5463 // Record this for posterity if the process has been stable. 5464 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5465 } 5466 } 5467 } 5468 } 5469 return pss; 5470 } 5471 5472 @Override 5473 public void killApplicationProcess(String processName, int uid) { 5474 if (processName == null) { 5475 return; 5476 } 5477 5478 int callerUid = Binder.getCallingUid(); 5479 // Only the system server can kill an application 5480 if (callerUid == Process.SYSTEM_UID) { 5481 synchronized (this) { 5482 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5483 if (app != null && app.thread != null) { 5484 try { 5485 app.thread.scheduleSuicide(); 5486 } catch (RemoteException e) { 5487 // If the other end already died, then our work here is done. 5488 } 5489 } else { 5490 Slog.w(TAG, "Process/uid not found attempting kill of " 5491 + processName + " / " + uid); 5492 } 5493 } 5494 } else { 5495 throw new SecurityException(callerUid + " cannot kill app process: " + 5496 processName); 5497 } 5498 } 5499 5500 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5501 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5502 false, true, false, false, UserHandle.getUserId(uid), reason); 5503 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5504 Uri.fromParts("package", packageName, null)); 5505 if (!mProcessesReady) { 5506 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5507 | Intent.FLAG_RECEIVER_FOREGROUND); 5508 } 5509 intent.putExtra(Intent.EXTRA_UID, uid); 5510 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5511 broadcastIntentLocked(null, null, intent, 5512 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5513 false, false, 5514 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5515 } 5516 5517 private void forceStopUserLocked(int userId, String reason) { 5518 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5519 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5520 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5521 | Intent.FLAG_RECEIVER_FOREGROUND); 5522 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5523 broadcastIntentLocked(null, null, intent, 5524 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5525 false, false, 5526 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5527 } 5528 5529 private final boolean killPackageProcessesLocked(String packageName, int appId, 5530 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5531 boolean doit, boolean evenPersistent, String reason) { 5532 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5533 5534 // Remove all processes this package may have touched: all with the 5535 // same UID (except for the system or root user), and all whose name 5536 // matches the package name. 5537 final int NP = mProcessNames.getMap().size(); 5538 for (int ip=0; ip<NP; ip++) { 5539 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5540 final int NA = apps.size(); 5541 for (int ia=0; ia<NA; ia++) { 5542 ProcessRecord app = apps.valueAt(ia); 5543 if (app.persistent && !evenPersistent) { 5544 // we don't kill persistent processes 5545 continue; 5546 } 5547 if (app.removed) { 5548 if (doit) { 5549 procs.add(app); 5550 } 5551 continue; 5552 } 5553 5554 // Skip process if it doesn't meet our oom adj requirement. 5555 if (app.setAdj < minOomAdj) { 5556 continue; 5557 } 5558 5559 // If no package is specified, we call all processes under the 5560 // give user id. 5561 if (packageName == null) { 5562 if (app.userId != userId) { 5563 continue; 5564 } 5565 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5566 continue; 5567 } 5568 // Package has been specified, we want to hit all processes 5569 // that match it. We need to qualify this by the processes 5570 // that are running under the specified app and user ID. 5571 } else { 5572 final boolean isDep = app.pkgDeps != null 5573 && app.pkgDeps.contains(packageName); 5574 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5575 continue; 5576 } 5577 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5578 continue; 5579 } 5580 if (!app.pkgList.containsKey(packageName) && !isDep) { 5581 continue; 5582 } 5583 } 5584 5585 // Process has passed all conditions, kill it! 5586 if (!doit) { 5587 return true; 5588 } 5589 app.removed = true; 5590 procs.add(app); 5591 } 5592 } 5593 5594 int N = procs.size(); 5595 for (int i=0; i<N; i++) { 5596 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5597 } 5598 updateOomAdjLocked(); 5599 return N > 0; 5600 } 5601 5602 private final boolean forceStopPackageLocked(String name, int appId, 5603 boolean callerWillRestart, boolean purgeCache, boolean doit, 5604 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5605 int i; 5606 int N; 5607 5608 if (userId == UserHandle.USER_ALL && name == null) { 5609 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5610 } 5611 5612 if (appId < 0 && name != null) { 5613 try { 5614 appId = UserHandle.getAppId( 5615 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5616 } catch (RemoteException e) { 5617 } 5618 } 5619 5620 if (doit) { 5621 if (name != null) { 5622 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5623 + " user=" + userId + ": " + reason); 5624 } else { 5625 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5626 } 5627 5628 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5629 for (int ip=pmap.size()-1; ip>=0; ip--) { 5630 SparseArray<Long> ba = pmap.valueAt(ip); 5631 for (i=ba.size()-1; i>=0; i--) { 5632 boolean remove = false; 5633 final int entUid = ba.keyAt(i); 5634 if (name != null) { 5635 if (userId == UserHandle.USER_ALL) { 5636 if (UserHandle.getAppId(entUid) == appId) { 5637 remove = true; 5638 } 5639 } else { 5640 if (entUid == UserHandle.getUid(userId, appId)) { 5641 remove = true; 5642 } 5643 } 5644 } else if (UserHandle.getUserId(entUid) == userId) { 5645 remove = true; 5646 } 5647 if (remove) { 5648 ba.removeAt(i); 5649 } 5650 } 5651 if (ba.size() == 0) { 5652 pmap.removeAt(ip); 5653 } 5654 } 5655 } 5656 5657 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5658 -100, callerWillRestart, true, doit, evenPersistent, 5659 name == null ? ("stop user " + userId) : ("stop " + name)); 5660 5661 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5662 if (!doit) { 5663 return true; 5664 } 5665 didSomething = true; 5666 } 5667 5668 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5669 if (!doit) { 5670 return true; 5671 } 5672 didSomething = true; 5673 } 5674 5675 if (name == null) { 5676 // Remove all sticky broadcasts from this user. 5677 mStickyBroadcasts.remove(userId); 5678 } 5679 5680 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5681 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5682 userId, providers)) { 5683 if (!doit) { 5684 return true; 5685 } 5686 didSomething = true; 5687 } 5688 N = providers.size(); 5689 for (i=0; i<N; i++) { 5690 removeDyingProviderLocked(null, providers.get(i), true); 5691 } 5692 5693 // Remove transient permissions granted from/to this package/user 5694 removeUriPermissionsForPackageLocked(name, userId, false); 5695 5696 if (name == null || uninstalling) { 5697 // Remove pending intents. For now we only do this when force 5698 // stopping users, because we have some problems when doing this 5699 // for packages -- app widgets are not currently cleaned up for 5700 // such packages, so they can be left with bad pending intents. 5701 if (mIntentSenderRecords.size() > 0) { 5702 Iterator<WeakReference<PendingIntentRecord>> it 5703 = mIntentSenderRecords.values().iterator(); 5704 while (it.hasNext()) { 5705 WeakReference<PendingIntentRecord> wpir = it.next(); 5706 if (wpir == null) { 5707 it.remove(); 5708 continue; 5709 } 5710 PendingIntentRecord pir = wpir.get(); 5711 if (pir == null) { 5712 it.remove(); 5713 continue; 5714 } 5715 if (name == null) { 5716 // Stopping user, remove all objects for the user. 5717 if (pir.key.userId != userId) { 5718 // Not the same user, skip it. 5719 continue; 5720 } 5721 } else { 5722 if (UserHandle.getAppId(pir.uid) != appId) { 5723 // Different app id, skip it. 5724 continue; 5725 } 5726 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5727 // Different user, skip it. 5728 continue; 5729 } 5730 if (!pir.key.packageName.equals(name)) { 5731 // Different package, skip it. 5732 continue; 5733 } 5734 } 5735 if (!doit) { 5736 return true; 5737 } 5738 didSomething = true; 5739 it.remove(); 5740 pir.canceled = true; 5741 if (pir.key.activity != null) { 5742 pir.key.activity.pendingResults.remove(pir.ref); 5743 } 5744 } 5745 } 5746 } 5747 5748 if (doit) { 5749 if (purgeCache && name != null) { 5750 AttributeCache ac = AttributeCache.instance(); 5751 if (ac != null) { 5752 ac.removePackage(name); 5753 } 5754 } 5755 if (mBooted) { 5756 mStackSupervisor.resumeTopActivitiesLocked(); 5757 mStackSupervisor.scheduleIdleLocked(); 5758 } 5759 } 5760 5761 return didSomething; 5762 } 5763 5764 private final boolean removeProcessLocked(ProcessRecord app, 5765 boolean callerWillRestart, boolean allowRestart, String reason) { 5766 final String name = app.processName; 5767 final int uid = app.uid; 5768 if (DEBUG_PROCESSES) Slog.d( 5769 TAG, "Force removing proc " + app.toShortString() + " (" + name 5770 + "/" + uid + ")"); 5771 5772 mProcessNames.remove(name, uid); 5773 mIsolatedProcesses.remove(app.uid); 5774 if (mHeavyWeightProcess == app) { 5775 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5776 mHeavyWeightProcess.userId, 0)); 5777 mHeavyWeightProcess = null; 5778 } 5779 boolean needRestart = false; 5780 if (app.pid > 0 && app.pid != MY_PID) { 5781 int pid = app.pid; 5782 synchronized (mPidsSelfLocked) { 5783 mPidsSelfLocked.remove(pid); 5784 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5785 } 5786 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5787 if (app.isolated) { 5788 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5789 } 5790 app.kill(reason, true); 5791 handleAppDiedLocked(app, true, allowRestart); 5792 removeLruProcessLocked(app); 5793 5794 if (app.persistent && !app.isolated) { 5795 if (!callerWillRestart) { 5796 addAppLocked(app.info, false, null /* ABI override */); 5797 } else { 5798 needRestart = true; 5799 } 5800 } 5801 } else { 5802 mRemovedProcesses.add(app); 5803 } 5804 5805 return needRestart; 5806 } 5807 5808 private final void processStartTimedOutLocked(ProcessRecord app) { 5809 final int pid = app.pid; 5810 boolean gone = false; 5811 synchronized (mPidsSelfLocked) { 5812 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5813 if (knownApp != null && knownApp.thread == null) { 5814 mPidsSelfLocked.remove(pid); 5815 gone = true; 5816 } 5817 } 5818 5819 if (gone) { 5820 Slog.w(TAG, "Process " + app + " failed to attach"); 5821 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5822 pid, app.uid, app.processName); 5823 mProcessNames.remove(app.processName, app.uid); 5824 mIsolatedProcesses.remove(app.uid); 5825 if (mHeavyWeightProcess == app) { 5826 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5827 mHeavyWeightProcess.userId, 0)); 5828 mHeavyWeightProcess = null; 5829 } 5830 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5831 if (app.isolated) { 5832 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5833 } 5834 // Take care of any launching providers waiting for this process. 5835 checkAppInLaunchingProvidersLocked(app, true); 5836 // Take care of any services that are waiting for the process. 5837 mServices.processStartTimedOutLocked(app); 5838 app.kill("start timeout", true); 5839 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5840 Slog.w(TAG, "Unattached app died before backup, skipping"); 5841 try { 5842 IBackupManager bm = IBackupManager.Stub.asInterface( 5843 ServiceManager.getService(Context.BACKUP_SERVICE)); 5844 bm.agentDisconnected(app.info.packageName); 5845 } catch (RemoteException e) { 5846 // Can't happen; the backup manager is local 5847 } 5848 } 5849 if (isPendingBroadcastProcessLocked(pid)) { 5850 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5851 skipPendingBroadcastLocked(pid); 5852 } 5853 } else { 5854 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5855 } 5856 } 5857 5858 private final boolean attachApplicationLocked(IApplicationThread thread, 5859 int pid) { 5860 5861 // Find the application record that is being attached... either via 5862 // the pid if we are running in multiple processes, or just pull the 5863 // next app record if we are emulating process with anonymous threads. 5864 ProcessRecord app; 5865 if (pid != MY_PID && pid >= 0) { 5866 synchronized (mPidsSelfLocked) { 5867 app = mPidsSelfLocked.get(pid); 5868 } 5869 } else { 5870 app = null; 5871 } 5872 5873 if (app == null) { 5874 Slog.w(TAG, "No pending application record for pid " + pid 5875 + " (IApplicationThread " + thread + "); dropping process"); 5876 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5877 if (pid > 0 && pid != MY_PID) { 5878 Process.killProcessQuiet(pid); 5879 //TODO: Process.killProcessGroup(app.info.uid, pid); 5880 } else { 5881 try { 5882 thread.scheduleExit(); 5883 } catch (Exception e) { 5884 // Ignore exceptions. 5885 } 5886 } 5887 return false; 5888 } 5889 5890 // If this application record is still attached to a previous 5891 // process, clean it up now. 5892 if (app.thread != null) { 5893 handleAppDiedLocked(app, true, true); 5894 } 5895 5896 // Tell the process all about itself. 5897 5898 if (localLOGV) Slog.v( 5899 TAG, "Binding process pid " + pid + " to record " + app); 5900 5901 final String processName = app.processName; 5902 try { 5903 AppDeathRecipient adr = new AppDeathRecipient( 5904 app, pid, thread); 5905 thread.asBinder().linkToDeath(adr, 0); 5906 app.deathRecipient = adr; 5907 } catch (RemoteException e) { 5908 app.resetPackageList(mProcessStats); 5909 startProcessLocked(app, "link fail", processName); 5910 return false; 5911 } 5912 5913 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5914 5915 app.makeActive(thread, mProcessStats); 5916 app.curAdj = app.setAdj = -100; 5917 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5918 app.forcingToForeground = null; 5919 updateProcessForegroundLocked(app, false, false); 5920 app.hasShownUi = false; 5921 app.debugging = false; 5922 app.cached = false; 5923 5924 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5925 5926 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5927 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5928 5929 if (!normalMode) { 5930 Slog.i(TAG, "Launching preboot mode app: " + app); 5931 } 5932 5933 if (localLOGV) Slog.v( 5934 TAG, "New app record " + app 5935 + " thread=" + thread.asBinder() + " pid=" + pid); 5936 try { 5937 int testMode = IApplicationThread.DEBUG_OFF; 5938 if (mDebugApp != null && mDebugApp.equals(processName)) { 5939 testMode = mWaitForDebugger 5940 ? IApplicationThread.DEBUG_WAIT 5941 : IApplicationThread.DEBUG_ON; 5942 app.debugging = true; 5943 if (mDebugTransient) { 5944 mDebugApp = mOrigDebugApp; 5945 mWaitForDebugger = mOrigWaitForDebugger; 5946 } 5947 } 5948 String profileFile = app.instrumentationProfileFile; 5949 ParcelFileDescriptor profileFd = null; 5950 int samplingInterval = 0; 5951 boolean profileAutoStop = false; 5952 if (mProfileApp != null && mProfileApp.equals(processName)) { 5953 mProfileProc = app; 5954 profileFile = mProfileFile; 5955 profileFd = mProfileFd; 5956 samplingInterval = mSamplingInterval; 5957 profileAutoStop = mAutoStopProfiler; 5958 } 5959 boolean enableOpenGlTrace = false; 5960 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5961 enableOpenGlTrace = true; 5962 mOpenGlTraceApp = null; 5963 } 5964 5965 // If the app is being launched for restore or full backup, set it up specially 5966 boolean isRestrictedBackupMode = false; 5967 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5968 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5969 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5970 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5971 } 5972 5973 ensurePackageDexOpt(app.instrumentationInfo != null 5974 ? app.instrumentationInfo.packageName 5975 : app.info.packageName); 5976 if (app.instrumentationClass != null) { 5977 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5978 } 5979 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5980 + processName + " with config " + mConfiguration); 5981 ApplicationInfo appInfo = app.instrumentationInfo != null 5982 ? app.instrumentationInfo : app.info; 5983 app.compat = compatibilityInfoForPackageLocked(appInfo); 5984 if (profileFd != null) { 5985 profileFd = profileFd.dup(); 5986 } 5987 ProfilerInfo profilerInfo = profileFile == null ? null 5988 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5989 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5990 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5991 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5992 isRestrictedBackupMode || !normalMode, app.persistent, 5993 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5994 mCoreSettingsObserver.getCoreSettingsLocked()); 5995 updateLruProcessLocked(app, false, null); 5996 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5997 } catch (Exception e) { 5998 // todo: Yikes! What should we do? For now we will try to 5999 // start another process, but that could easily get us in 6000 // an infinite loop of restarting processes... 6001 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6002 6003 app.resetPackageList(mProcessStats); 6004 app.unlinkDeathRecipient(); 6005 startProcessLocked(app, "bind fail", processName); 6006 return false; 6007 } 6008 6009 // Remove this record from the list of starting applications. 6010 mPersistentStartingProcesses.remove(app); 6011 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6012 "Attach application locked removing on hold: " + app); 6013 mProcessesOnHold.remove(app); 6014 6015 boolean badApp = false; 6016 boolean didSomething = false; 6017 6018 // See if the top visible activity is waiting to run in this process... 6019 if (normalMode) { 6020 try { 6021 if (mStackSupervisor.attachApplicationLocked(app)) { 6022 didSomething = true; 6023 } 6024 } catch (Exception e) { 6025 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6026 badApp = true; 6027 } 6028 } 6029 6030 // Find any services that should be running in this process... 6031 if (!badApp) { 6032 try { 6033 didSomething |= mServices.attachApplicationLocked(app, processName); 6034 } catch (Exception e) { 6035 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6036 badApp = true; 6037 } 6038 } 6039 6040 // Check if a next-broadcast receiver is in this process... 6041 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6042 try { 6043 didSomething |= sendPendingBroadcastsLocked(app); 6044 } catch (Exception e) { 6045 // If the app died trying to launch the receiver we declare it 'bad' 6046 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6047 badApp = true; 6048 } 6049 } 6050 6051 // Check whether the next backup agent is in this process... 6052 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6053 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6054 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6055 try { 6056 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6057 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6058 mBackupTarget.backupMode); 6059 } catch (Exception e) { 6060 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6061 badApp = true; 6062 } 6063 } 6064 6065 if (badApp) { 6066 app.kill("error during init", true); 6067 handleAppDiedLocked(app, false, true); 6068 return false; 6069 } 6070 6071 if (!didSomething) { 6072 updateOomAdjLocked(); 6073 } 6074 6075 return true; 6076 } 6077 6078 @Override 6079 public final void attachApplication(IApplicationThread thread) { 6080 synchronized (this) { 6081 int callingPid = Binder.getCallingPid(); 6082 final long origId = Binder.clearCallingIdentity(); 6083 attachApplicationLocked(thread, callingPid); 6084 Binder.restoreCallingIdentity(origId); 6085 } 6086 } 6087 6088 @Override 6089 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6090 final long origId = Binder.clearCallingIdentity(); 6091 synchronized (this) { 6092 ActivityStack stack = ActivityRecord.getStackLocked(token); 6093 if (stack != null) { 6094 ActivityRecord r = 6095 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6096 if (stopProfiling) { 6097 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6098 try { 6099 mProfileFd.close(); 6100 } catch (IOException e) { 6101 } 6102 clearProfilerLocked(); 6103 } 6104 } 6105 } 6106 } 6107 Binder.restoreCallingIdentity(origId); 6108 } 6109 6110 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6111 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6112 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6113 } 6114 6115 void enableScreenAfterBoot() { 6116 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6117 SystemClock.uptimeMillis()); 6118 mWindowManager.enableScreenAfterBoot(); 6119 6120 synchronized (this) { 6121 updateEventDispatchingLocked(); 6122 } 6123 } 6124 6125 @Override 6126 public void showBootMessage(final CharSequence msg, final boolean always) { 6127 enforceNotIsolatedCaller("showBootMessage"); 6128 mWindowManager.showBootMessage(msg, always); 6129 } 6130 6131 @Override 6132 public void keyguardWaitingForActivityDrawn() { 6133 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6134 final long token = Binder.clearCallingIdentity(); 6135 try { 6136 synchronized (this) { 6137 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6138 mWindowManager.keyguardWaitingForActivityDrawn(); 6139 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6140 mLockScreenShown = LOCK_SCREEN_LEAVING; 6141 } 6142 } 6143 } finally { 6144 Binder.restoreCallingIdentity(token); 6145 } 6146 } 6147 6148 final void finishBooting() { 6149 synchronized (this) { 6150 if (!mBootAnimationComplete) { 6151 mCallFinishBooting = true; 6152 return; 6153 } 6154 mCallFinishBooting = false; 6155 } 6156 6157 ArraySet<String> completedIsas = new ArraySet<String>(); 6158 for (String abi : Build.SUPPORTED_ABIS) { 6159 Process.establishZygoteConnectionForAbi(abi); 6160 final String instructionSet = VMRuntime.getInstructionSet(abi); 6161 if (!completedIsas.contains(instructionSet)) { 6162 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6163 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6164 } 6165 completedIsas.add(instructionSet); 6166 } 6167 } 6168 6169 // Register receivers to handle package update events 6170 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6171 6172 // Let system services know. 6173 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6174 6175 synchronized (this) { 6176 // Ensure that any processes we had put on hold are now started 6177 // up. 6178 final int NP = mProcessesOnHold.size(); 6179 if (NP > 0) { 6180 ArrayList<ProcessRecord> procs = 6181 new ArrayList<ProcessRecord>(mProcessesOnHold); 6182 for (int ip=0; ip<NP; ip++) { 6183 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6184 + procs.get(ip)); 6185 startProcessLocked(procs.get(ip), "on-hold", null); 6186 } 6187 } 6188 6189 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6190 // Start looking for apps that are abusing wake locks. 6191 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6192 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6193 // Tell anyone interested that we are done booting! 6194 SystemProperties.set("sys.boot_completed", "1"); 6195 6196 // And trigger dev.bootcomplete if we are not showing encryption progress 6197 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6198 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6199 SystemProperties.set("dev.bootcomplete", "1"); 6200 } 6201 for (int i=0; i<mStartedUsers.size(); i++) { 6202 UserStartedState uss = mStartedUsers.valueAt(i); 6203 if (uss.mState == UserStartedState.STATE_BOOTING) { 6204 uss.mState = UserStartedState.STATE_RUNNING; 6205 final int userId = mStartedUsers.keyAt(i); 6206 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6207 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6208 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6209 broadcastIntentLocked(null, null, intent, null, 6210 new IIntentReceiver.Stub() { 6211 @Override 6212 public void performReceive(Intent intent, int resultCode, 6213 String data, Bundle extras, boolean ordered, 6214 boolean sticky, int sendingUser) { 6215 synchronized (ActivityManagerService.this) { 6216 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6217 true, false); 6218 } 6219 } 6220 }, 6221 0, null, null, 6222 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6223 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6224 userId); 6225 } 6226 } 6227 scheduleStartProfilesLocked(); 6228 } 6229 } 6230 } 6231 6232 @Override 6233 public void bootAnimationComplete() { 6234 final boolean callFinishBooting; 6235 synchronized (this) { 6236 callFinishBooting = mCallFinishBooting; 6237 mBootAnimationComplete = true; 6238 } 6239 if (callFinishBooting) { 6240 finishBooting(); 6241 } 6242 } 6243 6244 final void ensureBootCompleted() { 6245 boolean booting; 6246 boolean enableScreen; 6247 synchronized (this) { 6248 booting = mBooting; 6249 mBooting = false; 6250 enableScreen = !mBooted; 6251 mBooted = true; 6252 } 6253 6254 if (booting) { 6255 finishBooting(); 6256 } 6257 6258 if (enableScreen) { 6259 enableScreenAfterBoot(); 6260 } 6261 } 6262 6263 @Override 6264 public final void activityResumed(IBinder token) { 6265 final long origId = Binder.clearCallingIdentity(); 6266 synchronized(this) { 6267 ActivityStack stack = ActivityRecord.getStackLocked(token); 6268 if (stack != null) { 6269 ActivityRecord.activityResumedLocked(token); 6270 } 6271 } 6272 Binder.restoreCallingIdentity(origId); 6273 } 6274 6275 @Override 6276 public final void activityPaused(IBinder token) { 6277 final long origId = Binder.clearCallingIdentity(); 6278 synchronized(this) { 6279 ActivityStack stack = ActivityRecord.getStackLocked(token); 6280 if (stack != null) { 6281 stack.activityPausedLocked(token, false); 6282 } 6283 } 6284 Binder.restoreCallingIdentity(origId); 6285 } 6286 6287 @Override 6288 public final void activityStopped(IBinder token, Bundle icicle, 6289 PersistableBundle persistentState, CharSequence description) { 6290 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6291 6292 // Refuse possible leaked file descriptors 6293 if (icicle != null && icicle.hasFileDescriptors()) { 6294 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6295 } 6296 6297 final long origId = Binder.clearCallingIdentity(); 6298 6299 synchronized (this) { 6300 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6301 if (r != null) { 6302 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6303 } 6304 } 6305 6306 trimApplications(); 6307 6308 Binder.restoreCallingIdentity(origId); 6309 } 6310 6311 @Override 6312 public final void activityDestroyed(IBinder token) { 6313 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6314 synchronized (this) { 6315 ActivityStack stack = ActivityRecord.getStackLocked(token); 6316 if (stack != null) { 6317 stack.activityDestroyedLocked(token); 6318 } 6319 } 6320 } 6321 6322 @Override 6323 public final void backgroundResourcesReleased(IBinder token) { 6324 final long origId = Binder.clearCallingIdentity(); 6325 try { 6326 synchronized (this) { 6327 ActivityStack stack = ActivityRecord.getStackLocked(token); 6328 if (stack != null) { 6329 stack.backgroundResourcesReleased(token); 6330 } 6331 } 6332 } finally { 6333 Binder.restoreCallingIdentity(origId); 6334 } 6335 } 6336 6337 @Override 6338 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6339 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6340 } 6341 6342 @Override 6343 public final void notifyEnterAnimationComplete(IBinder token) { 6344 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6345 } 6346 6347 @Override 6348 public String getCallingPackage(IBinder token) { 6349 synchronized (this) { 6350 ActivityRecord r = getCallingRecordLocked(token); 6351 return r != null ? r.info.packageName : null; 6352 } 6353 } 6354 6355 @Override 6356 public ComponentName getCallingActivity(IBinder token) { 6357 synchronized (this) { 6358 ActivityRecord r = getCallingRecordLocked(token); 6359 return r != null ? r.intent.getComponent() : null; 6360 } 6361 } 6362 6363 private ActivityRecord getCallingRecordLocked(IBinder token) { 6364 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6365 if (r == null) { 6366 return null; 6367 } 6368 return r.resultTo; 6369 } 6370 6371 @Override 6372 public ComponentName getActivityClassForToken(IBinder token) { 6373 synchronized(this) { 6374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6375 if (r == null) { 6376 return null; 6377 } 6378 return r.intent.getComponent(); 6379 } 6380 } 6381 6382 @Override 6383 public String getPackageForToken(IBinder token) { 6384 synchronized(this) { 6385 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6386 if (r == null) { 6387 return null; 6388 } 6389 return r.packageName; 6390 } 6391 } 6392 6393 @Override 6394 public IIntentSender getIntentSender(int type, 6395 String packageName, IBinder token, String resultWho, 6396 int requestCode, Intent[] intents, String[] resolvedTypes, 6397 int flags, Bundle options, int userId) { 6398 enforceNotIsolatedCaller("getIntentSender"); 6399 // Refuse possible leaked file descriptors 6400 if (intents != null) { 6401 if (intents.length < 1) { 6402 throw new IllegalArgumentException("Intents array length must be >= 1"); 6403 } 6404 for (int i=0; i<intents.length; i++) { 6405 Intent intent = intents[i]; 6406 if (intent != null) { 6407 if (intent.hasFileDescriptors()) { 6408 throw new IllegalArgumentException("File descriptors passed in Intent"); 6409 } 6410 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6411 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6412 throw new IllegalArgumentException( 6413 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6414 } 6415 intents[i] = new Intent(intent); 6416 } 6417 } 6418 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6419 throw new IllegalArgumentException( 6420 "Intent array length does not match resolvedTypes length"); 6421 } 6422 } 6423 if (options != null) { 6424 if (options.hasFileDescriptors()) { 6425 throw new IllegalArgumentException("File descriptors passed in options"); 6426 } 6427 } 6428 6429 synchronized(this) { 6430 int callingUid = Binder.getCallingUid(); 6431 int origUserId = userId; 6432 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6433 type == ActivityManager.INTENT_SENDER_BROADCAST, 6434 ALLOW_NON_FULL, "getIntentSender", null); 6435 if (origUserId == UserHandle.USER_CURRENT) { 6436 // We don't want to evaluate this until the pending intent is 6437 // actually executed. However, we do want to always do the 6438 // security checking for it above. 6439 userId = UserHandle.USER_CURRENT; 6440 } 6441 try { 6442 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6443 int uid = AppGlobals.getPackageManager() 6444 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6445 if (!UserHandle.isSameApp(callingUid, uid)) { 6446 String msg = "Permission Denial: getIntentSender() from pid=" 6447 + Binder.getCallingPid() 6448 + ", uid=" + Binder.getCallingUid() 6449 + ", (need uid=" + uid + ")" 6450 + " is not allowed to send as package " + packageName; 6451 Slog.w(TAG, msg); 6452 throw new SecurityException(msg); 6453 } 6454 } 6455 6456 return getIntentSenderLocked(type, packageName, callingUid, userId, 6457 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6458 6459 } catch (RemoteException e) { 6460 throw new SecurityException(e); 6461 } 6462 } 6463 } 6464 6465 IIntentSender getIntentSenderLocked(int type, String packageName, 6466 int callingUid, int userId, IBinder token, String resultWho, 6467 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6468 Bundle options) { 6469 if (DEBUG_MU) 6470 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6471 ActivityRecord activity = null; 6472 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6473 activity = ActivityRecord.isInStackLocked(token); 6474 if (activity == null) { 6475 return null; 6476 } 6477 if (activity.finishing) { 6478 return null; 6479 } 6480 } 6481 6482 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6483 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6484 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6485 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6486 |PendingIntent.FLAG_UPDATE_CURRENT); 6487 6488 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6489 type, packageName, activity, resultWho, 6490 requestCode, intents, resolvedTypes, flags, options, userId); 6491 WeakReference<PendingIntentRecord> ref; 6492 ref = mIntentSenderRecords.get(key); 6493 PendingIntentRecord rec = ref != null ? ref.get() : null; 6494 if (rec != null) { 6495 if (!cancelCurrent) { 6496 if (updateCurrent) { 6497 if (rec.key.requestIntent != null) { 6498 rec.key.requestIntent.replaceExtras(intents != null ? 6499 intents[intents.length - 1] : null); 6500 } 6501 if (intents != null) { 6502 intents[intents.length-1] = rec.key.requestIntent; 6503 rec.key.allIntents = intents; 6504 rec.key.allResolvedTypes = resolvedTypes; 6505 } else { 6506 rec.key.allIntents = null; 6507 rec.key.allResolvedTypes = null; 6508 } 6509 } 6510 return rec; 6511 } 6512 rec.canceled = true; 6513 mIntentSenderRecords.remove(key); 6514 } 6515 if (noCreate) { 6516 return rec; 6517 } 6518 rec = new PendingIntentRecord(this, key, callingUid); 6519 mIntentSenderRecords.put(key, rec.ref); 6520 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6521 if (activity.pendingResults == null) { 6522 activity.pendingResults 6523 = new HashSet<WeakReference<PendingIntentRecord>>(); 6524 } 6525 activity.pendingResults.add(rec.ref); 6526 } 6527 return rec; 6528 } 6529 6530 @Override 6531 public void cancelIntentSender(IIntentSender sender) { 6532 if (!(sender instanceof PendingIntentRecord)) { 6533 return; 6534 } 6535 synchronized(this) { 6536 PendingIntentRecord rec = (PendingIntentRecord)sender; 6537 try { 6538 int uid = AppGlobals.getPackageManager() 6539 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6540 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6541 String msg = "Permission Denial: cancelIntentSender() from pid=" 6542 + Binder.getCallingPid() 6543 + ", uid=" + Binder.getCallingUid() 6544 + " is not allowed to cancel packges " 6545 + rec.key.packageName; 6546 Slog.w(TAG, msg); 6547 throw new SecurityException(msg); 6548 } 6549 } catch (RemoteException e) { 6550 throw new SecurityException(e); 6551 } 6552 cancelIntentSenderLocked(rec, true); 6553 } 6554 } 6555 6556 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6557 rec.canceled = true; 6558 mIntentSenderRecords.remove(rec.key); 6559 if (cleanActivity && rec.key.activity != null) { 6560 rec.key.activity.pendingResults.remove(rec.ref); 6561 } 6562 } 6563 6564 @Override 6565 public String getPackageForIntentSender(IIntentSender pendingResult) { 6566 if (!(pendingResult instanceof PendingIntentRecord)) { 6567 return null; 6568 } 6569 try { 6570 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6571 return res.key.packageName; 6572 } catch (ClassCastException e) { 6573 } 6574 return null; 6575 } 6576 6577 @Override 6578 public int getUidForIntentSender(IIntentSender sender) { 6579 if (sender instanceof PendingIntentRecord) { 6580 try { 6581 PendingIntentRecord res = (PendingIntentRecord)sender; 6582 return res.uid; 6583 } catch (ClassCastException e) { 6584 } 6585 } 6586 return -1; 6587 } 6588 6589 @Override 6590 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6591 if (!(pendingResult instanceof PendingIntentRecord)) { 6592 return false; 6593 } 6594 try { 6595 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6596 if (res.key.allIntents == null) { 6597 return false; 6598 } 6599 for (int i=0; i<res.key.allIntents.length; i++) { 6600 Intent intent = res.key.allIntents[i]; 6601 if (intent.getPackage() != null && intent.getComponent() != null) { 6602 return false; 6603 } 6604 } 6605 return true; 6606 } catch (ClassCastException e) { 6607 } 6608 return false; 6609 } 6610 6611 @Override 6612 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6613 if (!(pendingResult instanceof PendingIntentRecord)) { 6614 return false; 6615 } 6616 try { 6617 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6618 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6619 return true; 6620 } 6621 return false; 6622 } catch (ClassCastException e) { 6623 } 6624 return false; 6625 } 6626 6627 @Override 6628 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6629 if (!(pendingResult instanceof PendingIntentRecord)) { 6630 return null; 6631 } 6632 try { 6633 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6634 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6635 } catch (ClassCastException e) { 6636 } 6637 return null; 6638 } 6639 6640 @Override 6641 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6642 if (!(pendingResult instanceof PendingIntentRecord)) { 6643 return null; 6644 } 6645 try { 6646 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6647 Intent intent = res.key.requestIntent; 6648 if (intent != null) { 6649 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6650 || res.lastTagPrefix.equals(prefix))) { 6651 return res.lastTag; 6652 } 6653 res.lastTagPrefix = prefix; 6654 StringBuilder sb = new StringBuilder(128); 6655 if (prefix != null) { 6656 sb.append(prefix); 6657 } 6658 if (intent.getAction() != null) { 6659 sb.append(intent.getAction()); 6660 } else if (intent.getComponent() != null) { 6661 intent.getComponent().appendShortString(sb); 6662 } else { 6663 sb.append("?"); 6664 } 6665 return res.lastTag = sb.toString(); 6666 } 6667 } catch (ClassCastException e) { 6668 } 6669 return null; 6670 } 6671 6672 @Override 6673 public void setProcessLimit(int max) { 6674 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6675 "setProcessLimit()"); 6676 synchronized (this) { 6677 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6678 mProcessLimitOverride = max; 6679 } 6680 trimApplications(); 6681 } 6682 6683 @Override 6684 public int getProcessLimit() { 6685 synchronized (this) { 6686 return mProcessLimitOverride; 6687 } 6688 } 6689 6690 void foregroundTokenDied(ForegroundToken token) { 6691 synchronized (ActivityManagerService.this) { 6692 synchronized (mPidsSelfLocked) { 6693 ForegroundToken cur 6694 = mForegroundProcesses.get(token.pid); 6695 if (cur != token) { 6696 return; 6697 } 6698 mForegroundProcesses.remove(token.pid); 6699 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6700 if (pr == null) { 6701 return; 6702 } 6703 pr.forcingToForeground = null; 6704 updateProcessForegroundLocked(pr, false, false); 6705 } 6706 updateOomAdjLocked(); 6707 } 6708 } 6709 6710 @Override 6711 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6712 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6713 "setProcessForeground()"); 6714 synchronized(this) { 6715 boolean changed = false; 6716 6717 synchronized (mPidsSelfLocked) { 6718 ProcessRecord pr = mPidsSelfLocked.get(pid); 6719 if (pr == null && isForeground) { 6720 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6721 return; 6722 } 6723 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6724 if (oldToken != null) { 6725 oldToken.token.unlinkToDeath(oldToken, 0); 6726 mForegroundProcesses.remove(pid); 6727 if (pr != null) { 6728 pr.forcingToForeground = null; 6729 } 6730 changed = true; 6731 } 6732 if (isForeground && token != null) { 6733 ForegroundToken newToken = new ForegroundToken() { 6734 @Override 6735 public void binderDied() { 6736 foregroundTokenDied(this); 6737 } 6738 }; 6739 newToken.pid = pid; 6740 newToken.token = token; 6741 try { 6742 token.linkToDeath(newToken, 0); 6743 mForegroundProcesses.put(pid, newToken); 6744 pr.forcingToForeground = token; 6745 changed = true; 6746 } catch (RemoteException e) { 6747 // If the process died while doing this, we will later 6748 // do the cleanup with the process death link. 6749 } 6750 } 6751 } 6752 6753 if (changed) { 6754 updateOomAdjLocked(); 6755 } 6756 } 6757 } 6758 6759 // ========================================================= 6760 // PERMISSIONS 6761 // ========================================================= 6762 6763 static class PermissionController extends IPermissionController.Stub { 6764 ActivityManagerService mActivityManagerService; 6765 PermissionController(ActivityManagerService activityManagerService) { 6766 mActivityManagerService = activityManagerService; 6767 } 6768 6769 @Override 6770 public boolean checkPermission(String permission, int pid, int uid) { 6771 return mActivityManagerService.checkPermission(permission, pid, 6772 uid) == PackageManager.PERMISSION_GRANTED; 6773 } 6774 } 6775 6776 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6777 @Override 6778 public int checkComponentPermission(String permission, int pid, int uid, 6779 int owningUid, boolean exported) { 6780 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6781 owningUid, exported); 6782 } 6783 6784 @Override 6785 public Object getAMSLock() { 6786 return ActivityManagerService.this; 6787 } 6788 } 6789 6790 /** 6791 * This can be called with or without the global lock held. 6792 */ 6793 int checkComponentPermission(String permission, int pid, int uid, 6794 int owningUid, boolean exported) { 6795 // We might be performing an operation on behalf of an indirect binder 6796 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6797 // client identity accordingly before proceeding. 6798 Identity tlsIdentity = sCallerIdentity.get(); 6799 if (tlsIdentity != null) { 6800 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6801 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6802 uid = tlsIdentity.uid; 6803 pid = tlsIdentity.pid; 6804 } 6805 6806 if (pid == MY_PID) { 6807 return PackageManager.PERMISSION_GRANTED; 6808 } 6809 6810 return ActivityManager.checkComponentPermission(permission, uid, 6811 owningUid, exported); 6812 } 6813 6814 /** 6815 * As the only public entry point for permissions checking, this method 6816 * can enforce the semantic that requesting a check on a null global 6817 * permission is automatically denied. (Internally a null permission 6818 * string is used when calling {@link #checkComponentPermission} in cases 6819 * when only uid-based security is needed.) 6820 * 6821 * This can be called with or without the global lock held. 6822 */ 6823 @Override 6824 public int checkPermission(String permission, int pid, int uid) { 6825 if (permission == null) { 6826 return PackageManager.PERMISSION_DENIED; 6827 } 6828 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6829 } 6830 6831 /** 6832 * Binder IPC calls go through the public entry point. 6833 * This can be called with or without the global lock held. 6834 */ 6835 int checkCallingPermission(String permission) { 6836 return checkPermission(permission, 6837 Binder.getCallingPid(), 6838 UserHandle.getAppId(Binder.getCallingUid())); 6839 } 6840 6841 /** 6842 * This can be called with or without the global lock held. 6843 */ 6844 void enforceCallingPermission(String permission, String func) { 6845 if (checkCallingPermission(permission) 6846 == PackageManager.PERMISSION_GRANTED) { 6847 return; 6848 } 6849 6850 String msg = "Permission Denial: " + func + " from pid=" 6851 + Binder.getCallingPid() 6852 + ", uid=" + Binder.getCallingUid() 6853 + " requires " + permission; 6854 Slog.w(TAG, msg); 6855 throw new SecurityException(msg); 6856 } 6857 6858 /** 6859 * Determine if UID is holding permissions required to access {@link Uri} in 6860 * the given {@link ProviderInfo}. Final permission checking is always done 6861 * in {@link ContentProvider}. 6862 */ 6863 private final boolean checkHoldingPermissionsLocked( 6864 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6865 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6866 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6867 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6868 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6869 != PERMISSION_GRANTED) { 6870 return false; 6871 } 6872 } 6873 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6874 } 6875 6876 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6877 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6878 if (pi.applicationInfo.uid == uid) { 6879 return true; 6880 } else if (!pi.exported) { 6881 return false; 6882 } 6883 6884 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6885 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6886 try { 6887 // check if target holds top-level <provider> permissions 6888 if (!readMet && pi.readPermission != null && considerUidPermissions 6889 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6890 readMet = true; 6891 } 6892 if (!writeMet && pi.writePermission != null && considerUidPermissions 6893 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6894 writeMet = true; 6895 } 6896 6897 // track if unprotected read/write is allowed; any denied 6898 // <path-permission> below removes this ability 6899 boolean allowDefaultRead = pi.readPermission == null; 6900 boolean allowDefaultWrite = pi.writePermission == null; 6901 6902 // check if target holds any <path-permission> that match uri 6903 final PathPermission[] pps = pi.pathPermissions; 6904 if (pps != null) { 6905 final String path = grantUri.uri.getPath(); 6906 int i = pps.length; 6907 while (i > 0 && (!readMet || !writeMet)) { 6908 i--; 6909 PathPermission pp = pps[i]; 6910 if (pp.match(path)) { 6911 if (!readMet) { 6912 final String pprperm = pp.getReadPermission(); 6913 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6914 + pprperm + " for " + pp.getPath() 6915 + ": match=" + pp.match(path) 6916 + " check=" + pm.checkUidPermission(pprperm, uid)); 6917 if (pprperm != null) { 6918 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6919 == PERMISSION_GRANTED) { 6920 readMet = true; 6921 } else { 6922 allowDefaultRead = false; 6923 } 6924 } 6925 } 6926 if (!writeMet) { 6927 final String ppwperm = pp.getWritePermission(); 6928 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6929 + ppwperm + " for " + pp.getPath() 6930 + ": match=" + pp.match(path) 6931 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6932 if (ppwperm != null) { 6933 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6934 == PERMISSION_GRANTED) { 6935 writeMet = true; 6936 } else { 6937 allowDefaultWrite = false; 6938 } 6939 } 6940 } 6941 } 6942 } 6943 } 6944 6945 // grant unprotected <provider> read/write, if not blocked by 6946 // <path-permission> above 6947 if (allowDefaultRead) readMet = true; 6948 if (allowDefaultWrite) writeMet = true; 6949 6950 } catch (RemoteException e) { 6951 return false; 6952 } 6953 6954 return readMet && writeMet; 6955 } 6956 6957 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6958 ProviderInfo pi = null; 6959 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6960 if (cpr != null) { 6961 pi = cpr.info; 6962 } else { 6963 try { 6964 pi = AppGlobals.getPackageManager().resolveContentProvider( 6965 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6966 } catch (RemoteException ex) { 6967 } 6968 } 6969 return pi; 6970 } 6971 6972 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6973 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6974 if (targetUris != null) { 6975 return targetUris.get(grantUri); 6976 } 6977 return null; 6978 } 6979 6980 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6981 String targetPkg, int targetUid, GrantUri grantUri) { 6982 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6983 if (targetUris == null) { 6984 targetUris = Maps.newArrayMap(); 6985 mGrantedUriPermissions.put(targetUid, targetUris); 6986 } 6987 6988 UriPermission perm = targetUris.get(grantUri); 6989 if (perm == null) { 6990 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6991 targetUris.put(grantUri, perm); 6992 } 6993 6994 return perm; 6995 } 6996 6997 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6998 final int modeFlags) { 6999 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7000 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7001 : UriPermission.STRENGTH_OWNED; 7002 7003 // Root gets to do everything. 7004 if (uid == 0) { 7005 return true; 7006 } 7007 7008 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7009 if (perms == null) return false; 7010 7011 // First look for exact match 7012 final UriPermission exactPerm = perms.get(grantUri); 7013 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7014 return true; 7015 } 7016 7017 // No exact match, look for prefixes 7018 final int N = perms.size(); 7019 for (int i = 0; i < N; i++) { 7020 final UriPermission perm = perms.valueAt(i); 7021 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7022 && perm.getStrength(modeFlags) >= minStrength) { 7023 return true; 7024 } 7025 } 7026 7027 return false; 7028 } 7029 7030 /** 7031 * @param uri This uri must NOT contain an embedded userId. 7032 * @param userId The userId in which the uri is to be resolved. 7033 */ 7034 @Override 7035 public int checkUriPermission(Uri uri, int pid, int uid, 7036 final int modeFlags, int userId) { 7037 enforceNotIsolatedCaller("checkUriPermission"); 7038 7039 // Another redirected-binder-call permissions check as in 7040 // {@link checkComponentPermission}. 7041 Identity tlsIdentity = sCallerIdentity.get(); 7042 if (tlsIdentity != null) { 7043 uid = tlsIdentity.uid; 7044 pid = tlsIdentity.pid; 7045 } 7046 7047 // Our own process gets to do everything. 7048 if (pid == MY_PID) { 7049 return PackageManager.PERMISSION_GRANTED; 7050 } 7051 synchronized (this) { 7052 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7053 ? PackageManager.PERMISSION_GRANTED 7054 : PackageManager.PERMISSION_DENIED; 7055 } 7056 } 7057 7058 /** 7059 * Check if the targetPkg can be granted permission to access uri by 7060 * the callingUid using the given modeFlags. Throws a security exception 7061 * if callingUid is not allowed to do this. Returns the uid of the target 7062 * if the URI permission grant should be performed; returns -1 if it is not 7063 * needed (for example targetPkg already has permission to access the URI). 7064 * If you already know the uid of the target, you can supply it in 7065 * lastTargetUid else set that to -1. 7066 */ 7067 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7068 final int modeFlags, int lastTargetUid) { 7069 if (!Intent.isAccessUriMode(modeFlags)) { 7070 return -1; 7071 } 7072 7073 if (targetPkg != null) { 7074 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7075 "Checking grant " + targetPkg + " permission to " + grantUri); 7076 } 7077 7078 final IPackageManager pm = AppGlobals.getPackageManager(); 7079 7080 // If this is not a content: uri, we can't do anything with it. 7081 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7082 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7083 "Can't grant URI permission for non-content URI: " + grantUri); 7084 return -1; 7085 } 7086 7087 final String authority = grantUri.uri.getAuthority(); 7088 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7089 if (pi == null) { 7090 Slog.w(TAG, "No content provider found for permission check: " + 7091 grantUri.uri.toSafeString()); 7092 return -1; 7093 } 7094 7095 int targetUid = lastTargetUid; 7096 if (targetUid < 0 && targetPkg != null) { 7097 try { 7098 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7099 if (targetUid < 0) { 7100 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7101 "Can't grant URI permission no uid for: " + targetPkg); 7102 return -1; 7103 } 7104 } catch (RemoteException ex) { 7105 return -1; 7106 } 7107 } 7108 7109 if (targetUid >= 0) { 7110 // First... does the target actually need this permission? 7111 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7112 // No need to grant the target this permission. 7113 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7114 "Target " + targetPkg + " already has full permission to " + grantUri); 7115 return -1; 7116 } 7117 } else { 7118 // First... there is no target package, so can anyone access it? 7119 boolean allowed = pi.exported; 7120 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7121 if (pi.readPermission != null) { 7122 allowed = false; 7123 } 7124 } 7125 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7126 if (pi.writePermission != null) { 7127 allowed = false; 7128 } 7129 } 7130 if (allowed) { 7131 return -1; 7132 } 7133 } 7134 7135 /* There is a special cross user grant if: 7136 * - The target is on another user. 7137 * - Apps on the current user can access the uri without any uid permissions. 7138 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7139 * grant uri permissions. 7140 */ 7141 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7142 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7143 modeFlags, false /*without considering the uid permissions*/); 7144 7145 // Second... is the provider allowing granting of URI permissions? 7146 if (!specialCrossUserGrant) { 7147 if (!pi.grantUriPermissions) { 7148 throw new SecurityException("Provider " + pi.packageName 7149 + "/" + pi.name 7150 + " does not allow granting of Uri permissions (uri " 7151 + grantUri + ")"); 7152 } 7153 if (pi.uriPermissionPatterns != null) { 7154 final int N = pi.uriPermissionPatterns.length; 7155 boolean allowed = false; 7156 for (int i=0; i<N; i++) { 7157 if (pi.uriPermissionPatterns[i] != null 7158 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7159 allowed = true; 7160 break; 7161 } 7162 } 7163 if (!allowed) { 7164 throw new SecurityException("Provider " + pi.packageName 7165 + "/" + pi.name 7166 + " does not allow granting of permission to path of Uri " 7167 + grantUri); 7168 } 7169 } 7170 } 7171 7172 // Third... does the caller itself have permission to access 7173 // this uri? 7174 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7175 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7176 // Require they hold a strong enough Uri permission 7177 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7178 throw new SecurityException("Uid " + callingUid 7179 + " does not have permission to uri " + grantUri); 7180 } 7181 } 7182 } 7183 return targetUid; 7184 } 7185 7186 /** 7187 * @param uri This uri must NOT contain an embedded userId. 7188 * @param userId The userId in which the uri is to be resolved. 7189 */ 7190 @Override 7191 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7192 final int modeFlags, int userId) { 7193 enforceNotIsolatedCaller("checkGrantUriPermission"); 7194 synchronized(this) { 7195 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7196 new GrantUri(userId, uri, false), modeFlags, -1); 7197 } 7198 } 7199 7200 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7201 final int modeFlags, UriPermissionOwner owner) { 7202 if (!Intent.isAccessUriMode(modeFlags)) { 7203 return; 7204 } 7205 7206 // So here we are: the caller has the assumed permission 7207 // to the uri, and the target doesn't. Let's now give this to 7208 // the target. 7209 7210 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7211 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7212 7213 final String authority = grantUri.uri.getAuthority(); 7214 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7215 if (pi == null) { 7216 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7217 return; 7218 } 7219 7220 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7221 grantUri.prefix = true; 7222 } 7223 final UriPermission perm = findOrCreateUriPermissionLocked( 7224 pi.packageName, targetPkg, targetUid, grantUri); 7225 perm.grantModes(modeFlags, owner); 7226 } 7227 7228 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7229 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7230 if (targetPkg == null) { 7231 throw new NullPointerException("targetPkg"); 7232 } 7233 int targetUid; 7234 final IPackageManager pm = AppGlobals.getPackageManager(); 7235 try { 7236 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7237 } catch (RemoteException ex) { 7238 return; 7239 } 7240 7241 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7242 targetUid); 7243 if (targetUid < 0) { 7244 return; 7245 } 7246 7247 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7248 owner); 7249 } 7250 7251 static class NeededUriGrants extends ArrayList<GrantUri> { 7252 final String targetPkg; 7253 final int targetUid; 7254 final int flags; 7255 7256 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7257 this.targetPkg = targetPkg; 7258 this.targetUid = targetUid; 7259 this.flags = flags; 7260 } 7261 } 7262 7263 /** 7264 * Like checkGrantUriPermissionLocked, but takes an Intent. 7265 */ 7266 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7267 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7268 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7269 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7270 + " clip=" + (intent != null ? intent.getClipData() : null) 7271 + " from " + intent + "; flags=0x" 7272 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7273 7274 if (targetPkg == null) { 7275 throw new NullPointerException("targetPkg"); 7276 } 7277 7278 if (intent == null) { 7279 return null; 7280 } 7281 Uri data = intent.getData(); 7282 ClipData clip = intent.getClipData(); 7283 if (data == null && clip == null) { 7284 return null; 7285 } 7286 // Default userId for uris in the intent (if they don't specify it themselves) 7287 int contentUserHint = intent.getContentUserHint(); 7288 if (contentUserHint == UserHandle.USER_CURRENT) { 7289 contentUserHint = UserHandle.getUserId(callingUid); 7290 } 7291 final IPackageManager pm = AppGlobals.getPackageManager(); 7292 int targetUid; 7293 if (needed != null) { 7294 targetUid = needed.targetUid; 7295 } else { 7296 try { 7297 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7298 } catch (RemoteException ex) { 7299 return null; 7300 } 7301 if (targetUid < 0) { 7302 if (DEBUG_URI_PERMISSION) { 7303 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7304 + " on user " + targetUserId); 7305 } 7306 return null; 7307 } 7308 } 7309 if (data != null) { 7310 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7311 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7312 targetUid); 7313 if (targetUid > 0) { 7314 if (needed == null) { 7315 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7316 } 7317 needed.add(grantUri); 7318 } 7319 } 7320 if (clip != null) { 7321 for (int i=0; i<clip.getItemCount(); i++) { 7322 Uri uri = clip.getItemAt(i).getUri(); 7323 if (uri != null) { 7324 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7325 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7326 targetUid); 7327 if (targetUid > 0) { 7328 if (needed == null) { 7329 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7330 } 7331 needed.add(grantUri); 7332 } 7333 } else { 7334 Intent clipIntent = clip.getItemAt(i).getIntent(); 7335 if (clipIntent != null) { 7336 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7337 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7338 if (newNeeded != null) { 7339 needed = newNeeded; 7340 } 7341 } 7342 } 7343 } 7344 } 7345 7346 return needed; 7347 } 7348 7349 /** 7350 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7351 */ 7352 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7353 UriPermissionOwner owner) { 7354 if (needed != null) { 7355 for (int i=0; i<needed.size(); i++) { 7356 GrantUri grantUri = needed.get(i); 7357 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7358 grantUri, needed.flags, owner); 7359 } 7360 } 7361 } 7362 7363 void grantUriPermissionFromIntentLocked(int callingUid, 7364 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7365 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7366 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7367 if (needed == null) { 7368 return; 7369 } 7370 7371 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7372 } 7373 7374 /** 7375 * @param uri This uri must NOT contain an embedded userId. 7376 * @param userId The userId in which the uri is to be resolved. 7377 */ 7378 @Override 7379 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7380 final int modeFlags, int userId) { 7381 enforceNotIsolatedCaller("grantUriPermission"); 7382 GrantUri grantUri = new GrantUri(userId, uri, false); 7383 synchronized(this) { 7384 final ProcessRecord r = getRecordForAppLocked(caller); 7385 if (r == null) { 7386 throw new SecurityException("Unable to find app for caller " 7387 + caller 7388 + " when granting permission to uri " + grantUri); 7389 } 7390 if (targetPkg == null) { 7391 throw new IllegalArgumentException("null target"); 7392 } 7393 if (grantUri == null) { 7394 throw new IllegalArgumentException("null uri"); 7395 } 7396 7397 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7398 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7399 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7400 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7401 7402 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7403 UserHandle.getUserId(r.uid)); 7404 } 7405 } 7406 7407 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7408 if (perm.modeFlags == 0) { 7409 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7410 perm.targetUid); 7411 if (perms != null) { 7412 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7413 "Removing " + perm.targetUid + " permission to " + perm.uri); 7414 7415 perms.remove(perm.uri); 7416 if (perms.isEmpty()) { 7417 mGrantedUriPermissions.remove(perm.targetUid); 7418 } 7419 } 7420 } 7421 } 7422 7423 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7424 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7425 7426 final IPackageManager pm = AppGlobals.getPackageManager(); 7427 final String authority = grantUri.uri.getAuthority(); 7428 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7429 if (pi == null) { 7430 Slog.w(TAG, "No content provider found for permission revoke: " 7431 + grantUri.toSafeString()); 7432 return; 7433 } 7434 7435 // Does the caller have this permission on the URI? 7436 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7437 // If they don't have direct access to the URI, then revoke any 7438 // ownerless URI permissions that have been granted to them. 7439 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7440 if (perms != null) { 7441 boolean persistChanged = false; 7442 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7443 final UriPermission perm = it.next(); 7444 if (perm.uri.sourceUserId == grantUri.sourceUserId 7445 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7446 if (DEBUG_URI_PERMISSION) 7447 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7448 " permission to " + perm.uri); 7449 persistChanged |= perm.revokeModes( 7450 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7451 if (perm.modeFlags == 0) { 7452 it.remove(); 7453 } 7454 } 7455 } 7456 if (perms.isEmpty()) { 7457 mGrantedUriPermissions.remove(callingUid); 7458 } 7459 if (persistChanged) { 7460 schedulePersistUriGrants(); 7461 } 7462 } 7463 return; 7464 } 7465 7466 boolean persistChanged = false; 7467 7468 // Go through all of the permissions and remove any that match. 7469 int N = mGrantedUriPermissions.size(); 7470 for (int i = 0; i < N; i++) { 7471 final int targetUid = mGrantedUriPermissions.keyAt(i); 7472 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7473 7474 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7475 final UriPermission perm = it.next(); 7476 if (perm.uri.sourceUserId == grantUri.sourceUserId 7477 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7478 if (DEBUG_URI_PERMISSION) 7479 Slog.v(TAG, 7480 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7481 persistChanged |= perm.revokeModes( 7482 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7483 if (perm.modeFlags == 0) { 7484 it.remove(); 7485 } 7486 } 7487 } 7488 7489 if (perms.isEmpty()) { 7490 mGrantedUriPermissions.remove(targetUid); 7491 N--; 7492 i--; 7493 } 7494 } 7495 7496 if (persistChanged) { 7497 schedulePersistUriGrants(); 7498 } 7499 } 7500 7501 /** 7502 * @param uri This uri must NOT contain an embedded userId. 7503 * @param userId The userId in which the uri is to be resolved. 7504 */ 7505 @Override 7506 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7507 int userId) { 7508 enforceNotIsolatedCaller("revokeUriPermission"); 7509 synchronized(this) { 7510 final ProcessRecord r = getRecordForAppLocked(caller); 7511 if (r == null) { 7512 throw new SecurityException("Unable to find app for caller " 7513 + caller 7514 + " when revoking permission to uri " + uri); 7515 } 7516 if (uri == null) { 7517 Slog.w(TAG, "revokeUriPermission: null uri"); 7518 return; 7519 } 7520 7521 if (!Intent.isAccessUriMode(modeFlags)) { 7522 return; 7523 } 7524 7525 final IPackageManager pm = AppGlobals.getPackageManager(); 7526 final String authority = uri.getAuthority(); 7527 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7528 if (pi == null) { 7529 Slog.w(TAG, "No content provider found for permission revoke: " 7530 + uri.toSafeString()); 7531 return; 7532 } 7533 7534 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7535 } 7536 } 7537 7538 /** 7539 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7540 * given package. 7541 * 7542 * @param packageName Package name to match, or {@code null} to apply to all 7543 * packages. 7544 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7545 * to all users. 7546 * @param persistable If persistable grants should be removed. 7547 */ 7548 private void removeUriPermissionsForPackageLocked( 7549 String packageName, int userHandle, boolean persistable) { 7550 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7551 throw new IllegalArgumentException("Must narrow by either package or user"); 7552 } 7553 7554 boolean persistChanged = false; 7555 7556 int N = mGrantedUriPermissions.size(); 7557 for (int i = 0; i < N; i++) { 7558 final int targetUid = mGrantedUriPermissions.keyAt(i); 7559 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7560 7561 // Only inspect grants matching user 7562 if (userHandle == UserHandle.USER_ALL 7563 || userHandle == UserHandle.getUserId(targetUid)) { 7564 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7565 final UriPermission perm = it.next(); 7566 7567 // Only inspect grants matching package 7568 if (packageName == null || perm.sourcePkg.equals(packageName) 7569 || perm.targetPkg.equals(packageName)) { 7570 persistChanged |= perm.revokeModes(persistable 7571 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7572 7573 // Only remove when no modes remain; any persisted grants 7574 // will keep this alive. 7575 if (perm.modeFlags == 0) { 7576 it.remove(); 7577 } 7578 } 7579 } 7580 7581 if (perms.isEmpty()) { 7582 mGrantedUriPermissions.remove(targetUid); 7583 N--; 7584 i--; 7585 } 7586 } 7587 } 7588 7589 if (persistChanged) { 7590 schedulePersistUriGrants(); 7591 } 7592 } 7593 7594 @Override 7595 public IBinder newUriPermissionOwner(String name) { 7596 enforceNotIsolatedCaller("newUriPermissionOwner"); 7597 synchronized(this) { 7598 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7599 return owner.getExternalTokenLocked(); 7600 } 7601 } 7602 7603 /** 7604 * @param uri This uri must NOT contain an embedded userId. 7605 * @param sourceUserId The userId in which the uri is to be resolved. 7606 * @param targetUserId The userId of the app that receives the grant. 7607 */ 7608 @Override 7609 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7610 final int modeFlags, int sourceUserId, int targetUserId) { 7611 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7612 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7613 synchronized(this) { 7614 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7615 if (owner == null) { 7616 throw new IllegalArgumentException("Unknown owner: " + token); 7617 } 7618 if (fromUid != Binder.getCallingUid()) { 7619 if (Binder.getCallingUid() != Process.myUid()) { 7620 // Only system code can grant URI permissions on behalf 7621 // of other users. 7622 throw new SecurityException("nice try"); 7623 } 7624 } 7625 if (targetPkg == null) { 7626 throw new IllegalArgumentException("null target"); 7627 } 7628 if (uri == null) { 7629 throw new IllegalArgumentException("null uri"); 7630 } 7631 7632 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7633 modeFlags, owner, targetUserId); 7634 } 7635 } 7636 7637 /** 7638 * @param uri This uri must NOT contain an embedded userId. 7639 * @param userId The userId in which the uri is to be resolved. 7640 */ 7641 @Override 7642 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7643 synchronized(this) { 7644 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7645 if (owner == null) { 7646 throw new IllegalArgumentException("Unknown owner: " + token); 7647 } 7648 7649 if (uri == null) { 7650 owner.removeUriPermissionsLocked(mode); 7651 } else { 7652 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7653 } 7654 } 7655 } 7656 7657 private void schedulePersistUriGrants() { 7658 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7659 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7660 10 * DateUtils.SECOND_IN_MILLIS); 7661 } 7662 } 7663 7664 private void writeGrantedUriPermissions() { 7665 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7666 7667 // Snapshot permissions so we can persist without lock 7668 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7669 synchronized (this) { 7670 final int size = mGrantedUriPermissions.size(); 7671 for (int i = 0; i < size; i++) { 7672 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7673 for (UriPermission perm : perms.values()) { 7674 if (perm.persistedModeFlags != 0) { 7675 persist.add(perm.snapshot()); 7676 } 7677 } 7678 } 7679 } 7680 7681 FileOutputStream fos = null; 7682 try { 7683 fos = mGrantFile.startWrite(); 7684 7685 XmlSerializer out = new FastXmlSerializer(); 7686 out.setOutput(fos, "utf-8"); 7687 out.startDocument(null, true); 7688 out.startTag(null, TAG_URI_GRANTS); 7689 for (UriPermission.Snapshot perm : persist) { 7690 out.startTag(null, TAG_URI_GRANT); 7691 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7692 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7693 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7694 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7695 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7696 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7697 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7698 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7699 out.endTag(null, TAG_URI_GRANT); 7700 } 7701 out.endTag(null, TAG_URI_GRANTS); 7702 out.endDocument(); 7703 7704 mGrantFile.finishWrite(fos); 7705 } catch (IOException e) { 7706 if (fos != null) { 7707 mGrantFile.failWrite(fos); 7708 } 7709 } 7710 } 7711 7712 private void readGrantedUriPermissionsLocked() { 7713 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7714 7715 final long now = System.currentTimeMillis(); 7716 7717 FileInputStream fis = null; 7718 try { 7719 fis = mGrantFile.openRead(); 7720 final XmlPullParser in = Xml.newPullParser(); 7721 in.setInput(fis, null); 7722 7723 int type; 7724 while ((type = in.next()) != END_DOCUMENT) { 7725 final String tag = in.getName(); 7726 if (type == START_TAG) { 7727 if (TAG_URI_GRANT.equals(tag)) { 7728 final int sourceUserId; 7729 final int targetUserId; 7730 final int userHandle = readIntAttribute(in, 7731 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7732 if (userHandle != UserHandle.USER_NULL) { 7733 // For backwards compatibility. 7734 sourceUserId = userHandle; 7735 targetUserId = userHandle; 7736 } else { 7737 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7738 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7739 } 7740 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7741 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7742 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7743 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7744 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7745 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7746 7747 // Sanity check that provider still belongs to source package 7748 final ProviderInfo pi = getProviderInfoLocked( 7749 uri.getAuthority(), sourceUserId); 7750 if (pi != null && sourcePkg.equals(pi.packageName)) { 7751 int targetUid = -1; 7752 try { 7753 targetUid = AppGlobals.getPackageManager() 7754 .getPackageUid(targetPkg, targetUserId); 7755 } catch (RemoteException e) { 7756 } 7757 if (targetUid != -1) { 7758 final UriPermission perm = findOrCreateUriPermissionLocked( 7759 sourcePkg, targetPkg, targetUid, 7760 new GrantUri(sourceUserId, uri, prefix)); 7761 perm.initPersistedModes(modeFlags, createdTime); 7762 } 7763 } else { 7764 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7765 + " but instead found " + pi); 7766 } 7767 } 7768 } 7769 } 7770 } catch (FileNotFoundException e) { 7771 // Missing grants is okay 7772 } catch (IOException e) { 7773 Slog.wtf(TAG, "Failed reading Uri grants", e); 7774 } catch (XmlPullParserException e) { 7775 Slog.wtf(TAG, "Failed reading Uri grants", e); 7776 } finally { 7777 IoUtils.closeQuietly(fis); 7778 } 7779 } 7780 7781 /** 7782 * @param uri This uri must NOT contain an embedded userId. 7783 * @param userId The userId in which the uri is to be resolved. 7784 */ 7785 @Override 7786 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7787 enforceNotIsolatedCaller("takePersistableUriPermission"); 7788 7789 Preconditions.checkFlagsArgument(modeFlags, 7790 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7791 7792 synchronized (this) { 7793 final int callingUid = Binder.getCallingUid(); 7794 boolean persistChanged = false; 7795 GrantUri grantUri = new GrantUri(userId, uri, false); 7796 7797 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7798 new GrantUri(userId, uri, false)); 7799 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7800 new GrantUri(userId, uri, true)); 7801 7802 final boolean exactValid = (exactPerm != null) 7803 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7804 final boolean prefixValid = (prefixPerm != null) 7805 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7806 7807 if (!(exactValid || prefixValid)) { 7808 throw new SecurityException("No persistable permission grants found for UID " 7809 + callingUid + " and Uri " + grantUri.toSafeString()); 7810 } 7811 7812 if (exactValid) { 7813 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7814 } 7815 if (prefixValid) { 7816 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7817 } 7818 7819 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7820 7821 if (persistChanged) { 7822 schedulePersistUriGrants(); 7823 } 7824 } 7825 } 7826 7827 /** 7828 * @param uri This uri must NOT contain an embedded userId. 7829 * @param userId The userId in which the uri is to be resolved. 7830 */ 7831 @Override 7832 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7833 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7834 7835 Preconditions.checkFlagsArgument(modeFlags, 7836 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7837 7838 synchronized (this) { 7839 final int callingUid = Binder.getCallingUid(); 7840 boolean persistChanged = false; 7841 7842 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7843 new GrantUri(userId, uri, false)); 7844 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7845 new GrantUri(userId, uri, true)); 7846 if (exactPerm == null && prefixPerm == null) { 7847 throw new SecurityException("No permission grants found for UID " + callingUid 7848 + " and Uri " + uri.toSafeString()); 7849 } 7850 7851 if (exactPerm != null) { 7852 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7853 removeUriPermissionIfNeededLocked(exactPerm); 7854 } 7855 if (prefixPerm != null) { 7856 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7857 removeUriPermissionIfNeededLocked(prefixPerm); 7858 } 7859 7860 if (persistChanged) { 7861 schedulePersistUriGrants(); 7862 } 7863 } 7864 } 7865 7866 /** 7867 * Prune any older {@link UriPermission} for the given UID until outstanding 7868 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7869 * 7870 * @return if any mutations occured that require persisting. 7871 */ 7872 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7873 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7874 if (perms == null) return false; 7875 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7876 7877 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7878 for (UriPermission perm : perms.values()) { 7879 if (perm.persistedModeFlags != 0) { 7880 persisted.add(perm); 7881 } 7882 } 7883 7884 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7885 if (trimCount <= 0) return false; 7886 7887 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7888 for (int i = 0; i < trimCount; i++) { 7889 final UriPermission perm = persisted.get(i); 7890 7891 if (DEBUG_URI_PERMISSION) { 7892 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7893 } 7894 7895 perm.releasePersistableModes(~0); 7896 removeUriPermissionIfNeededLocked(perm); 7897 } 7898 7899 return true; 7900 } 7901 7902 @Override 7903 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7904 String packageName, boolean incoming) { 7905 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7906 Preconditions.checkNotNull(packageName, "packageName"); 7907 7908 final int callingUid = Binder.getCallingUid(); 7909 final IPackageManager pm = AppGlobals.getPackageManager(); 7910 try { 7911 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7912 if (packageUid != callingUid) { 7913 throw new SecurityException( 7914 "Package " + packageName + " does not belong to calling UID " + callingUid); 7915 } 7916 } catch (RemoteException e) { 7917 throw new SecurityException("Failed to verify package name ownership"); 7918 } 7919 7920 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7921 synchronized (this) { 7922 if (incoming) { 7923 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7924 callingUid); 7925 if (perms == null) { 7926 Slog.w(TAG, "No permission grants found for " + packageName); 7927 } else { 7928 for (UriPermission perm : perms.values()) { 7929 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7930 result.add(perm.buildPersistedPublicApiObject()); 7931 } 7932 } 7933 } 7934 } else { 7935 final int size = mGrantedUriPermissions.size(); 7936 for (int i = 0; i < size; i++) { 7937 final ArrayMap<GrantUri, UriPermission> perms = 7938 mGrantedUriPermissions.valueAt(i); 7939 for (UriPermission perm : perms.values()) { 7940 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7941 result.add(perm.buildPersistedPublicApiObject()); 7942 } 7943 } 7944 } 7945 } 7946 } 7947 return new ParceledListSlice<android.content.UriPermission>(result); 7948 } 7949 7950 @Override 7951 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7952 synchronized (this) { 7953 ProcessRecord app = 7954 who != null ? getRecordForAppLocked(who) : null; 7955 if (app == null) return; 7956 7957 Message msg = Message.obtain(); 7958 msg.what = WAIT_FOR_DEBUGGER_MSG; 7959 msg.obj = app; 7960 msg.arg1 = waiting ? 1 : 0; 7961 mHandler.sendMessage(msg); 7962 } 7963 } 7964 7965 @Override 7966 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7967 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7968 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7969 outInfo.availMem = Process.getFreeMemory(); 7970 outInfo.totalMem = Process.getTotalMemory(); 7971 outInfo.threshold = homeAppMem; 7972 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7973 outInfo.hiddenAppThreshold = cachedAppMem; 7974 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7975 ProcessList.SERVICE_ADJ); 7976 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7977 ProcessList.VISIBLE_APP_ADJ); 7978 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7979 ProcessList.FOREGROUND_APP_ADJ); 7980 } 7981 7982 // ========================================================= 7983 // TASK MANAGEMENT 7984 // ========================================================= 7985 7986 @Override 7987 public List<IAppTask> getAppTasks(String callingPackage) { 7988 int callingUid = Binder.getCallingUid(); 7989 long ident = Binder.clearCallingIdentity(); 7990 7991 synchronized(this) { 7992 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7993 try { 7994 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7995 7996 final int N = mRecentTasks.size(); 7997 for (int i = 0; i < N; i++) { 7998 TaskRecord tr = mRecentTasks.get(i); 7999 // Skip tasks that do not match the caller. We don't need to verify 8000 // callingPackage, because we are also limiting to callingUid and know 8001 // that will limit to the correct security sandbox. 8002 if (tr.effectiveUid != callingUid) { 8003 continue; 8004 } 8005 Intent intent = tr.getBaseIntent(); 8006 if (intent == null || 8007 !callingPackage.equals(intent.getComponent().getPackageName())) { 8008 continue; 8009 } 8010 ActivityManager.RecentTaskInfo taskInfo = 8011 createRecentTaskInfoFromTaskRecord(tr); 8012 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8013 list.add(taskImpl); 8014 } 8015 } finally { 8016 Binder.restoreCallingIdentity(ident); 8017 } 8018 return list; 8019 } 8020 } 8021 8022 @Override 8023 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8024 final int callingUid = Binder.getCallingUid(); 8025 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8026 8027 synchronized(this) { 8028 if (localLOGV) Slog.v( 8029 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8030 8031 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8032 callingUid); 8033 8034 // TODO: Improve with MRU list from all ActivityStacks. 8035 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8036 } 8037 8038 return list; 8039 } 8040 8041 TaskRecord getMostRecentTask() { 8042 return mRecentTasks.get(0); 8043 } 8044 8045 /** 8046 * Creates a new RecentTaskInfo from a TaskRecord. 8047 */ 8048 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8049 // Update the task description to reflect any changes in the task stack 8050 tr.updateTaskDescription(); 8051 8052 // Compose the recent task info 8053 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8054 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8055 rti.persistentId = tr.taskId; 8056 rti.baseIntent = new Intent(tr.getBaseIntent()); 8057 rti.origActivity = tr.origActivity; 8058 rti.description = tr.lastDescription; 8059 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8060 rti.userId = tr.userId; 8061 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8062 rti.firstActiveTime = tr.firstActiveTime; 8063 rti.lastActiveTime = tr.lastActiveTime; 8064 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8065 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8066 return rti; 8067 } 8068 8069 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8070 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8071 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8072 if (!allowed) { 8073 if (checkPermission(android.Manifest.permission.GET_TASKS, 8074 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8075 // Temporary compatibility: some existing apps on the system image may 8076 // still be requesting the old permission and not switched to the new 8077 // one; if so, we'll still allow them full access. This means we need 8078 // to see if they are holding the old permission and are a system app. 8079 try { 8080 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8081 allowed = true; 8082 Slog.w(TAG, caller + ": caller " + callingUid 8083 + " is using old GET_TASKS but privileged; allowing"); 8084 } 8085 } catch (RemoteException e) { 8086 } 8087 } 8088 } 8089 if (!allowed) { 8090 Slog.w(TAG, caller + ": caller " + callingUid 8091 + " does not hold GET_TASKS; limiting output"); 8092 } 8093 return allowed; 8094 } 8095 8096 @Override 8097 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8098 final int callingUid = Binder.getCallingUid(); 8099 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8100 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8101 8102 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8103 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8104 synchronized (this) { 8105 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8106 callingUid); 8107 final boolean detailed = checkCallingPermission( 8108 android.Manifest.permission.GET_DETAILED_TASKS) 8109 == PackageManager.PERMISSION_GRANTED; 8110 8111 final int N = mRecentTasks.size(); 8112 ArrayList<ActivityManager.RecentTaskInfo> res 8113 = new ArrayList<ActivityManager.RecentTaskInfo>( 8114 maxNum < N ? maxNum : N); 8115 8116 final Set<Integer> includedUsers; 8117 if (includeProfiles) { 8118 includedUsers = getProfileIdsLocked(userId); 8119 } else { 8120 includedUsers = new HashSet<Integer>(); 8121 } 8122 includedUsers.add(Integer.valueOf(userId)); 8123 8124 for (int i=0; i<N && maxNum > 0; i++) { 8125 TaskRecord tr = mRecentTasks.get(i); 8126 // Only add calling user or related users recent tasks 8127 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8128 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8129 continue; 8130 } 8131 8132 // Return the entry if desired by the caller. We always return 8133 // the first entry, because callers always expect this to be the 8134 // foreground app. We may filter others if the caller has 8135 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8136 // we should exclude the entry. 8137 8138 if (i == 0 8139 || withExcluded 8140 || (tr.intent == null) 8141 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8142 == 0)) { 8143 if (!allowed) { 8144 // If the caller doesn't have the GET_TASKS permission, then only 8145 // allow them to see a small subset of tasks -- their own and home. 8146 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8147 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8148 continue; 8149 } 8150 } 8151 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8152 if (tr.stack != null && tr.stack.isHomeStack()) { 8153 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8154 continue; 8155 } 8156 } 8157 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8158 // Don't include auto remove tasks that are finished or finishing. 8159 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8160 + tr); 8161 continue; 8162 } 8163 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8164 && !tr.isAvailable) { 8165 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8166 continue; 8167 } 8168 8169 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8170 if (!detailed) { 8171 rti.baseIntent.replaceExtras((Bundle)null); 8172 } 8173 8174 res.add(rti); 8175 maxNum--; 8176 } 8177 } 8178 return res; 8179 } 8180 } 8181 8182 private TaskRecord taskForIdLocked(int id) { 8183 final TaskRecord task = recentTaskForIdLocked(id); 8184 if (task != null) { 8185 return task; 8186 } 8187 8188 // Don't give up. Sometimes it just hasn't made it to recents yet. 8189 return mStackSupervisor.anyTaskForIdLocked(id); 8190 } 8191 8192 private TaskRecord recentTaskForIdLocked(int id) { 8193 final int N = mRecentTasks.size(); 8194 for (int i=0; i<N; i++) { 8195 TaskRecord tr = mRecentTasks.get(i); 8196 if (tr.taskId == id) { 8197 return tr; 8198 } 8199 } 8200 return null; 8201 } 8202 8203 @Override 8204 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8205 synchronized (this) { 8206 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8207 "getTaskThumbnail()"); 8208 TaskRecord tr = recentTaskForIdLocked(id); 8209 if (tr != null) { 8210 return tr.getTaskThumbnailLocked(); 8211 } 8212 } 8213 return null; 8214 } 8215 8216 @Override 8217 public int addAppTask(IBinder activityToken, Intent intent, 8218 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8219 final int callingUid = Binder.getCallingUid(); 8220 final long callingIdent = Binder.clearCallingIdentity(); 8221 8222 try { 8223 synchronized (this) { 8224 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8225 if (r == null) { 8226 throw new IllegalArgumentException("Activity does not exist; token=" 8227 + activityToken); 8228 } 8229 ComponentName comp = intent.getComponent(); 8230 if (comp == null) { 8231 throw new IllegalArgumentException("Intent " + intent 8232 + " must specify explicit component"); 8233 } 8234 if (thumbnail.getWidth() != mThumbnailWidth 8235 || thumbnail.getHeight() != mThumbnailHeight) { 8236 throw new IllegalArgumentException("Bad thumbnail size: got " 8237 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8238 + mThumbnailWidth + "x" + mThumbnailHeight); 8239 } 8240 if (intent.getSelector() != null) { 8241 intent.setSelector(null); 8242 } 8243 if (intent.getSourceBounds() != null) { 8244 intent.setSourceBounds(null); 8245 } 8246 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8247 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8248 // The caller has added this as an auto-remove task... that makes no 8249 // sense, so turn off auto-remove. 8250 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8251 } 8252 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8253 // Must be a new task. 8254 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8255 } 8256 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8257 mLastAddedTaskActivity = null; 8258 } 8259 ActivityInfo ainfo = mLastAddedTaskActivity; 8260 if (ainfo == null) { 8261 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8262 comp, 0, UserHandle.getUserId(callingUid)); 8263 if (ainfo.applicationInfo.uid != callingUid) { 8264 throw new SecurityException( 8265 "Can't add task for another application: target uid=" 8266 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8267 } 8268 } 8269 8270 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8271 intent, description); 8272 8273 int trimIdx = trimRecentsForTask(task, false); 8274 if (trimIdx >= 0) { 8275 // If this would have caused a trim, then we'll abort because that 8276 // means it would be added at the end of the list but then just removed. 8277 return -1; 8278 } 8279 8280 final int N = mRecentTasks.size(); 8281 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8282 final TaskRecord tr = mRecentTasks.remove(N - 1); 8283 tr.removedFromRecents(mTaskPersister); 8284 } 8285 8286 task.inRecents = true; 8287 mRecentTasks.add(task); 8288 r.task.stack.addTask(task, false, false); 8289 8290 task.setLastThumbnail(thumbnail); 8291 task.freeLastThumbnail(); 8292 8293 return task.taskId; 8294 } 8295 } finally { 8296 Binder.restoreCallingIdentity(callingIdent); 8297 } 8298 } 8299 8300 @Override 8301 public Point getAppTaskThumbnailSize() { 8302 synchronized (this) { 8303 return new Point(mThumbnailWidth, mThumbnailHeight); 8304 } 8305 } 8306 8307 @Override 8308 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8309 synchronized (this) { 8310 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8311 if (r != null) { 8312 r.setTaskDescription(td); 8313 r.task.updateTaskDescription(); 8314 } 8315 } 8316 } 8317 8318 @Override 8319 public Bitmap getTaskDescriptionIcon(String filename) { 8320 if (!FileUtils.isValidExtFilename(filename) 8321 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8322 throw new IllegalArgumentException("Bad filename: " + filename); 8323 } 8324 return mTaskPersister.getTaskDescriptionIcon(filename); 8325 } 8326 8327 @Override 8328 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8329 throws RemoteException { 8330 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8331 opts.getCustomInPlaceResId() == 0) { 8332 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8333 "with valid animation"); 8334 } 8335 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8336 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8337 opts.getCustomInPlaceResId()); 8338 mWindowManager.executeAppTransition(); 8339 } 8340 8341 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8342 mRecentTasks.remove(tr); 8343 tr.removedFromRecents(mTaskPersister); 8344 ComponentName component = tr.getBaseIntent().getComponent(); 8345 if (component == null) { 8346 Slog.w(TAG, "No component for base intent of task: " + tr); 8347 return; 8348 } 8349 8350 if (!killProcess) { 8351 return; 8352 } 8353 8354 // Determine if the process(es) for this task should be killed. 8355 final String pkg = component.getPackageName(); 8356 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8357 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8358 for (int i = 0; i < pmap.size(); i++) { 8359 8360 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8361 for (int j = 0; j < uids.size(); j++) { 8362 ProcessRecord proc = uids.valueAt(j); 8363 if (proc.userId != tr.userId) { 8364 // Don't kill process for a different user. 8365 continue; 8366 } 8367 if (proc == mHomeProcess) { 8368 // Don't kill the home process along with tasks from the same package. 8369 continue; 8370 } 8371 if (!proc.pkgList.containsKey(pkg)) { 8372 // Don't kill process that is not associated with this task. 8373 continue; 8374 } 8375 8376 for (int k = 0; k < proc.activities.size(); k++) { 8377 TaskRecord otherTask = proc.activities.get(k).task; 8378 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8379 // Don't kill process(es) that has an activity in a different task that is 8380 // also in recents. 8381 return; 8382 } 8383 } 8384 8385 // Add process to kill list. 8386 procsToKill.add(proc); 8387 } 8388 } 8389 8390 // Find any running services associated with this app and stop if needed. 8391 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8392 8393 // Kill the running processes. 8394 for (int i = 0; i < procsToKill.size(); i++) { 8395 ProcessRecord pr = procsToKill.get(i); 8396 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8397 pr.kill("remove task", true); 8398 } else { 8399 pr.waitingToKill = "remove task"; 8400 } 8401 } 8402 } 8403 8404 /** 8405 * Removes the task with the specified task id. 8406 * 8407 * @param taskId Identifier of the task to be removed. 8408 * @param killProcess Kill any process associated with the task if possible. 8409 * @return Returns true if the given task was found and removed. 8410 */ 8411 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8412 TaskRecord tr = taskForIdLocked(taskId); 8413 if (tr != null) { 8414 tr.removeTaskActivitiesLocked(); 8415 cleanUpRemovedTaskLocked(tr, killProcess); 8416 if (tr.isPersistable) { 8417 notifyTaskPersisterLocked(null, true); 8418 } 8419 return true; 8420 } 8421 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8422 return false; 8423 } 8424 8425 @Override 8426 public boolean removeTask(int taskId) { 8427 synchronized (this) { 8428 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8429 "removeTask()"); 8430 long ident = Binder.clearCallingIdentity(); 8431 try { 8432 return removeTaskByIdLocked(taskId, true); 8433 } finally { 8434 Binder.restoreCallingIdentity(ident); 8435 } 8436 } 8437 } 8438 8439 /** 8440 * TODO: Add mController hook 8441 */ 8442 @Override 8443 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8444 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8445 "moveTaskToFront()"); 8446 8447 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8448 synchronized(this) { 8449 moveTaskToFrontLocked(taskId, flags, options); 8450 } 8451 } 8452 8453 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8454 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8455 Binder.getCallingUid(), -1, -1, "Task to front")) { 8456 ActivityOptions.abort(options); 8457 return; 8458 } 8459 final long origId = Binder.clearCallingIdentity(); 8460 try { 8461 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8462 if (task == null) { 8463 Slog.d(TAG, "Could not find task for id: "+ taskId); 8464 return; 8465 } 8466 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8467 mStackSupervisor.showLockTaskToast(); 8468 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8469 return; 8470 } 8471 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8472 if (prev != null && prev.isRecentsActivity()) { 8473 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8474 } 8475 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8476 } finally { 8477 Binder.restoreCallingIdentity(origId); 8478 } 8479 ActivityOptions.abort(options); 8480 } 8481 8482 @Override 8483 public void moveTaskToBack(int taskId) { 8484 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8485 "moveTaskToBack()"); 8486 8487 synchronized(this) { 8488 TaskRecord tr = taskForIdLocked(taskId); 8489 if (tr != null) { 8490 if (tr == mStackSupervisor.mLockTaskModeTask) { 8491 mStackSupervisor.showLockTaskToast(); 8492 return; 8493 } 8494 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8495 ActivityStack stack = tr.stack; 8496 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8497 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8498 Binder.getCallingUid(), -1, -1, "Task to back")) { 8499 return; 8500 } 8501 } 8502 final long origId = Binder.clearCallingIdentity(); 8503 try { 8504 stack.moveTaskToBackLocked(taskId, null); 8505 } finally { 8506 Binder.restoreCallingIdentity(origId); 8507 } 8508 } 8509 } 8510 } 8511 8512 /** 8513 * Moves an activity, and all of the other activities within the same task, to the bottom 8514 * of the history stack. The activity's order within the task is unchanged. 8515 * 8516 * @param token A reference to the activity we wish to move 8517 * @param nonRoot If false then this only works if the activity is the root 8518 * of a task; if true it will work for any activity in a task. 8519 * @return Returns true if the move completed, false if not. 8520 */ 8521 @Override 8522 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8523 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8524 synchronized(this) { 8525 final long origId = Binder.clearCallingIdentity(); 8526 try { 8527 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8528 if (taskId >= 0) { 8529 if ((mStackSupervisor.mLockTaskModeTask != null) 8530 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8531 mStackSupervisor.showLockTaskToast(); 8532 return false; 8533 } 8534 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8535 } 8536 } finally { 8537 Binder.restoreCallingIdentity(origId); 8538 } 8539 } 8540 return false; 8541 } 8542 8543 @Override 8544 public void moveTaskBackwards(int task) { 8545 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8546 "moveTaskBackwards()"); 8547 8548 synchronized(this) { 8549 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8550 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8551 return; 8552 } 8553 final long origId = Binder.clearCallingIdentity(); 8554 moveTaskBackwardsLocked(task); 8555 Binder.restoreCallingIdentity(origId); 8556 } 8557 } 8558 8559 private final void moveTaskBackwardsLocked(int task) { 8560 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8561 } 8562 8563 @Override 8564 public IBinder getHomeActivityToken() throws RemoteException { 8565 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8566 "getHomeActivityToken()"); 8567 synchronized (this) { 8568 return mStackSupervisor.getHomeActivityToken(); 8569 } 8570 } 8571 8572 @Override 8573 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8574 IActivityContainerCallback callback) throws RemoteException { 8575 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8576 "createActivityContainer()"); 8577 synchronized (this) { 8578 if (parentActivityToken == null) { 8579 throw new IllegalArgumentException("parent token must not be null"); 8580 } 8581 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8582 if (r == null) { 8583 return null; 8584 } 8585 if (callback == null) { 8586 throw new IllegalArgumentException("callback must not be null"); 8587 } 8588 return mStackSupervisor.createActivityContainer(r, callback); 8589 } 8590 } 8591 8592 @Override 8593 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8594 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8595 "deleteActivityContainer()"); 8596 synchronized (this) { 8597 mStackSupervisor.deleteActivityContainer(container); 8598 } 8599 } 8600 8601 @Override 8602 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8603 throws RemoteException { 8604 synchronized (this) { 8605 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8606 if (stack != null) { 8607 return stack.mActivityContainer; 8608 } 8609 return null; 8610 } 8611 } 8612 8613 @Override 8614 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8615 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8616 "moveTaskToStack()"); 8617 if (stackId == HOME_STACK_ID) { 8618 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8619 new RuntimeException("here").fillInStackTrace()); 8620 } 8621 synchronized (this) { 8622 long ident = Binder.clearCallingIdentity(); 8623 try { 8624 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8625 + stackId + " toTop=" + toTop); 8626 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8627 } finally { 8628 Binder.restoreCallingIdentity(ident); 8629 } 8630 } 8631 } 8632 8633 @Override 8634 public void resizeStack(int stackBoxId, Rect bounds) { 8635 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8636 "resizeStackBox()"); 8637 long ident = Binder.clearCallingIdentity(); 8638 try { 8639 mWindowManager.resizeStack(stackBoxId, bounds); 8640 } finally { 8641 Binder.restoreCallingIdentity(ident); 8642 } 8643 } 8644 8645 @Override 8646 public List<StackInfo> getAllStackInfos() { 8647 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8648 "getAllStackInfos()"); 8649 long ident = Binder.clearCallingIdentity(); 8650 try { 8651 synchronized (this) { 8652 return mStackSupervisor.getAllStackInfosLocked(); 8653 } 8654 } finally { 8655 Binder.restoreCallingIdentity(ident); 8656 } 8657 } 8658 8659 @Override 8660 public StackInfo getStackInfo(int stackId) { 8661 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8662 "getStackInfo()"); 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 synchronized (this) { 8666 return mStackSupervisor.getStackInfoLocked(stackId); 8667 } 8668 } finally { 8669 Binder.restoreCallingIdentity(ident); 8670 } 8671 } 8672 8673 @Override 8674 public boolean isInHomeStack(int taskId) { 8675 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8676 "getStackInfo()"); 8677 long ident = Binder.clearCallingIdentity(); 8678 try { 8679 synchronized (this) { 8680 TaskRecord tr = taskForIdLocked(taskId); 8681 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8682 } 8683 } finally { 8684 Binder.restoreCallingIdentity(ident); 8685 } 8686 } 8687 8688 @Override 8689 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8690 synchronized(this) { 8691 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8692 } 8693 } 8694 8695 private boolean isLockTaskAuthorized(String pkg) { 8696 final DevicePolicyManager dpm = (DevicePolicyManager) 8697 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8698 try { 8699 int uid = mContext.getPackageManager().getPackageUid(pkg, 8700 Binder.getCallingUserHandle().getIdentifier()); 8701 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8702 } catch (NameNotFoundException e) { 8703 return false; 8704 } 8705 } 8706 8707 void startLockTaskMode(TaskRecord task) { 8708 final String pkg; 8709 synchronized (this) { 8710 pkg = task.intent.getComponent().getPackageName(); 8711 } 8712 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8713 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8714 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8715 StatusBarManagerInternal.class); 8716 if (statusBarManager != null) { 8717 statusBarManager.showScreenPinningRequest(); 8718 } 8719 return; 8720 } 8721 long ident = Binder.clearCallingIdentity(); 8722 try { 8723 synchronized (this) { 8724 // Since we lost lock on task, make sure it is still there. 8725 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8726 if (task != null) { 8727 if (!isSystemInitiated 8728 && ((mStackSupervisor.getFocusedStack() == null) 8729 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8730 throw new IllegalArgumentException("Invalid task, not in foreground"); 8731 } 8732 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8733 } 8734 } 8735 } finally { 8736 Binder.restoreCallingIdentity(ident); 8737 } 8738 } 8739 8740 @Override 8741 public void startLockTaskMode(int taskId) { 8742 final TaskRecord task; 8743 long ident = Binder.clearCallingIdentity(); 8744 try { 8745 synchronized (this) { 8746 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8747 } 8748 } finally { 8749 Binder.restoreCallingIdentity(ident); 8750 } 8751 if (task != null) { 8752 startLockTaskMode(task); 8753 } 8754 } 8755 8756 @Override 8757 public void startLockTaskMode(IBinder token) { 8758 final TaskRecord task; 8759 long ident = Binder.clearCallingIdentity(); 8760 try { 8761 synchronized (this) { 8762 final ActivityRecord r = ActivityRecord.forToken(token); 8763 if (r == null) { 8764 return; 8765 } 8766 task = r.task; 8767 } 8768 } finally { 8769 Binder.restoreCallingIdentity(ident); 8770 } 8771 if (task != null) { 8772 startLockTaskMode(task); 8773 } 8774 } 8775 8776 @Override 8777 public void startLockTaskModeOnCurrent() throws RemoteException { 8778 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8779 "startLockTaskModeOnCurrent"); 8780 long ident = Binder.clearCallingIdentity(); 8781 try { 8782 ActivityRecord r = null; 8783 synchronized (this) { 8784 r = mStackSupervisor.topRunningActivityLocked(); 8785 } 8786 startLockTaskMode(r.task); 8787 } finally { 8788 Binder.restoreCallingIdentity(ident); 8789 } 8790 } 8791 8792 @Override 8793 public void stopLockTaskMode() { 8794 // Verify that the user matches the package of the intent for the TaskRecord 8795 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8796 // and stopLockTaskMode. 8797 final int callingUid = Binder.getCallingUid(); 8798 if (callingUid != Process.SYSTEM_UID) { 8799 try { 8800 String pkg = 8801 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8802 int uid = mContext.getPackageManager().getPackageUid(pkg, 8803 Binder.getCallingUserHandle().getIdentifier()); 8804 if (uid != callingUid) { 8805 throw new SecurityException("Invalid uid, expected " + uid); 8806 } 8807 } catch (NameNotFoundException e) { 8808 Log.d(TAG, "stopLockTaskMode " + e); 8809 return; 8810 } 8811 } 8812 long ident = Binder.clearCallingIdentity(); 8813 try { 8814 Log.d(TAG, "stopLockTaskMode"); 8815 // Stop lock task 8816 synchronized (this) { 8817 mStackSupervisor.setLockTaskModeLocked(null, false); 8818 } 8819 } finally { 8820 Binder.restoreCallingIdentity(ident); 8821 } 8822 } 8823 8824 @Override 8825 public void stopLockTaskModeOnCurrent() throws RemoteException { 8826 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8827 "stopLockTaskModeOnCurrent"); 8828 long ident = Binder.clearCallingIdentity(); 8829 try { 8830 stopLockTaskMode(); 8831 } finally { 8832 Binder.restoreCallingIdentity(ident); 8833 } 8834 } 8835 8836 @Override 8837 public boolean isInLockTaskMode() { 8838 synchronized (this) { 8839 return mStackSupervisor.isInLockTaskMode(); 8840 } 8841 } 8842 8843 // ========================================================= 8844 // CONTENT PROVIDERS 8845 // ========================================================= 8846 8847 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8848 List<ProviderInfo> providers = null; 8849 try { 8850 providers = AppGlobals.getPackageManager(). 8851 queryContentProviders(app.processName, app.uid, 8852 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8853 } catch (RemoteException ex) { 8854 } 8855 if (DEBUG_MU) 8856 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8857 int userId = app.userId; 8858 if (providers != null) { 8859 int N = providers.size(); 8860 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8861 for (int i=0; i<N; i++) { 8862 ProviderInfo cpi = 8863 (ProviderInfo)providers.get(i); 8864 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8865 cpi.name, cpi.flags); 8866 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8867 // This is a singleton provider, but a user besides the 8868 // default user is asking to initialize a process it runs 8869 // in... well, no, it doesn't actually run in this process, 8870 // it runs in the process of the default user. Get rid of it. 8871 providers.remove(i); 8872 N--; 8873 i--; 8874 continue; 8875 } 8876 8877 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8878 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8879 if (cpr == null) { 8880 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8881 mProviderMap.putProviderByClass(comp, cpr); 8882 } 8883 if (DEBUG_MU) 8884 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8885 app.pubProviders.put(cpi.name, cpr); 8886 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8887 // Don't add this if it is a platform component that is marked 8888 // to run in multiple processes, because this is actually 8889 // part of the framework so doesn't make sense to track as a 8890 // separate apk in the process. 8891 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8892 mProcessStats); 8893 } 8894 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8895 } 8896 } 8897 return providers; 8898 } 8899 8900 /** 8901 * Check if {@link ProcessRecord} has a possible chance at accessing the 8902 * given {@link ProviderInfo}. Final permission checking is always done 8903 * in {@link ContentProvider}. 8904 */ 8905 private final String checkContentProviderPermissionLocked( 8906 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8907 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8908 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8909 boolean checkedGrants = false; 8910 if (checkUser) { 8911 // Looking for cross-user grants before enforcing the typical cross-users permissions 8912 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8913 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8914 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8915 return null; 8916 } 8917 checkedGrants = true; 8918 } 8919 userId = handleIncomingUser(callingPid, callingUid, userId, 8920 false, ALLOW_NON_FULL, 8921 "checkContentProviderPermissionLocked " + cpi.authority, null); 8922 if (userId != tmpTargetUserId) { 8923 // When we actually went to determine the final targer user ID, this ended 8924 // up different than our initial check for the authority. This is because 8925 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8926 // SELF. So we need to re-check the grants again. 8927 checkedGrants = false; 8928 } 8929 } 8930 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8931 cpi.applicationInfo.uid, cpi.exported) 8932 == PackageManager.PERMISSION_GRANTED) { 8933 return null; 8934 } 8935 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8936 cpi.applicationInfo.uid, cpi.exported) 8937 == PackageManager.PERMISSION_GRANTED) { 8938 return null; 8939 } 8940 8941 PathPermission[] pps = cpi.pathPermissions; 8942 if (pps != null) { 8943 int i = pps.length; 8944 while (i > 0) { 8945 i--; 8946 PathPermission pp = pps[i]; 8947 String pprperm = pp.getReadPermission(); 8948 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8949 cpi.applicationInfo.uid, cpi.exported) 8950 == PackageManager.PERMISSION_GRANTED) { 8951 return null; 8952 } 8953 String ppwperm = pp.getWritePermission(); 8954 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8955 cpi.applicationInfo.uid, cpi.exported) 8956 == PackageManager.PERMISSION_GRANTED) { 8957 return null; 8958 } 8959 } 8960 } 8961 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8962 return null; 8963 } 8964 8965 String msg; 8966 if (!cpi.exported) { 8967 msg = "Permission Denial: opening provider " + cpi.name 8968 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8969 + ", uid=" + callingUid + ") that is not exported from uid " 8970 + cpi.applicationInfo.uid; 8971 } else { 8972 msg = "Permission Denial: opening provider " + cpi.name 8973 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8974 + ", uid=" + callingUid + ") requires " 8975 + cpi.readPermission + " or " + cpi.writePermission; 8976 } 8977 Slog.w(TAG, msg); 8978 return msg; 8979 } 8980 8981 /** 8982 * Returns if the ContentProvider has granted a uri to callingUid 8983 */ 8984 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8985 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8986 if (perms != null) { 8987 for (int i=perms.size()-1; i>=0; i--) { 8988 GrantUri grantUri = perms.keyAt(i); 8989 if (grantUri.sourceUserId == userId || !checkUser) { 8990 if (matchesProvider(grantUri.uri, cpi)) { 8991 return true; 8992 } 8993 } 8994 } 8995 } 8996 return false; 8997 } 8998 8999 /** 9000 * Returns true if the uri authority is one of the authorities specified in the provider. 9001 */ 9002 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9003 String uriAuth = uri.getAuthority(); 9004 String cpiAuth = cpi.authority; 9005 if (cpiAuth.indexOf(';') == -1) { 9006 return cpiAuth.equals(uriAuth); 9007 } 9008 String[] cpiAuths = cpiAuth.split(";"); 9009 int length = cpiAuths.length; 9010 for (int i = 0; i < length; i++) { 9011 if (cpiAuths[i].equals(uriAuth)) return true; 9012 } 9013 return false; 9014 } 9015 9016 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9017 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9018 if (r != null) { 9019 for (int i=0; i<r.conProviders.size(); i++) { 9020 ContentProviderConnection conn = r.conProviders.get(i); 9021 if (conn.provider == cpr) { 9022 if (DEBUG_PROVIDER) Slog.v(TAG, 9023 "Adding provider requested by " 9024 + r.processName + " from process " 9025 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9026 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9027 if (stable) { 9028 conn.stableCount++; 9029 conn.numStableIncs++; 9030 } else { 9031 conn.unstableCount++; 9032 conn.numUnstableIncs++; 9033 } 9034 return conn; 9035 } 9036 } 9037 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9038 if (stable) { 9039 conn.stableCount = 1; 9040 conn.numStableIncs = 1; 9041 } else { 9042 conn.unstableCount = 1; 9043 conn.numUnstableIncs = 1; 9044 } 9045 cpr.connections.add(conn); 9046 r.conProviders.add(conn); 9047 return conn; 9048 } 9049 cpr.addExternalProcessHandleLocked(externalProcessToken); 9050 return null; 9051 } 9052 9053 boolean decProviderCountLocked(ContentProviderConnection conn, 9054 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9055 if (conn != null) { 9056 cpr = conn.provider; 9057 if (DEBUG_PROVIDER) Slog.v(TAG, 9058 "Removing provider requested by " 9059 + conn.client.processName + " from process " 9060 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9061 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9062 if (stable) { 9063 conn.stableCount--; 9064 } else { 9065 conn.unstableCount--; 9066 } 9067 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9068 cpr.connections.remove(conn); 9069 conn.client.conProviders.remove(conn); 9070 return true; 9071 } 9072 return false; 9073 } 9074 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9075 return false; 9076 } 9077 9078 private void checkTime(long startTime, String where) { 9079 long now = SystemClock.elapsedRealtime(); 9080 if ((now-startTime) > 1000) { 9081 // If we are taking more than a second, log about it. 9082 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9083 } 9084 } 9085 9086 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9087 String name, IBinder token, boolean stable, int userId) { 9088 ContentProviderRecord cpr; 9089 ContentProviderConnection conn = null; 9090 ProviderInfo cpi = null; 9091 9092 synchronized(this) { 9093 long startTime = SystemClock.elapsedRealtime(); 9094 9095 ProcessRecord r = null; 9096 if (caller != null) { 9097 r = getRecordForAppLocked(caller); 9098 if (r == null) { 9099 throw new SecurityException( 9100 "Unable to find app for caller " + caller 9101 + " (pid=" + Binder.getCallingPid() 9102 + ") when getting content provider " + name); 9103 } 9104 } 9105 9106 boolean checkCrossUser = true; 9107 9108 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9109 9110 // First check if this content provider has been published... 9111 cpr = mProviderMap.getProviderByName(name, userId); 9112 // If that didn't work, check if it exists for user 0 and then 9113 // verify that it's a singleton provider before using it. 9114 if (cpr == null && userId != UserHandle.USER_OWNER) { 9115 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9116 if (cpr != null) { 9117 cpi = cpr.info; 9118 if (isSingleton(cpi.processName, cpi.applicationInfo, 9119 cpi.name, cpi.flags) 9120 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9121 userId = UserHandle.USER_OWNER; 9122 checkCrossUser = false; 9123 } else { 9124 cpr = null; 9125 cpi = null; 9126 } 9127 } 9128 } 9129 9130 boolean providerRunning = cpr != null; 9131 if (providerRunning) { 9132 cpi = cpr.info; 9133 String msg; 9134 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9135 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9136 != null) { 9137 throw new SecurityException(msg); 9138 } 9139 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9140 9141 if (r != null && cpr.canRunHere(r)) { 9142 // This provider has been published or is in the process 9143 // of being published... but it is also allowed to run 9144 // in the caller's process, so don't make a connection 9145 // and just let the caller instantiate its own instance. 9146 ContentProviderHolder holder = cpr.newHolder(null); 9147 // don't give caller the provider object, it needs 9148 // to make its own. 9149 holder.provider = null; 9150 return holder; 9151 } 9152 9153 final long origId = Binder.clearCallingIdentity(); 9154 9155 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9156 9157 // In this case the provider instance already exists, so we can 9158 // return it right away. 9159 conn = incProviderCountLocked(r, cpr, token, stable); 9160 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9161 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9162 // If this is a perceptible app accessing the provider, 9163 // make sure to count it as being accessed and thus 9164 // back up on the LRU list. This is good because 9165 // content providers are often expensive to start. 9166 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9167 updateLruProcessLocked(cpr.proc, false, null); 9168 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9169 } 9170 } 9171 9172 if (cpr.proc != null) { 9173 if (false) { 9174 if (cpr.name.flattenToShortString().equals( 9175 "com.android.providers.calendar/.CalendarProvider2")) { 9176 Slog.v(TAG, "****************** KILLING " 9177 + cpr.name.flattenToShortString()); 9178 Process.killProcess(cpr.proc.pid); 9179 } 9180 } 9181 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9182 boolean success = updateOomAdjLocked(cpr.proc); 9183 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9184 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9185 // NOTE: there is still a race here where a signal could be 9186 // pending on the process even though we managed to update its 9187 // adj level. Not sure what to do about this, but at least 9188 // the race is now smaller. 9189 if (!success) { 9190 // Uh oh... it looks like the provider's process 9191 // has been killed on us. We need to wait for a new 9192 // process to be started, and make sure its death 9193 // doesn't kill our process. 9194 Slog.i(TAG, 9195 "Existing provider " + cpr.name.flattenToShortString() 9196 + " is crashing; detaching " + r); 9197 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9198 checkTime(startTime, "getContentProviderImpl: before appDied"); 9199 appDiedLocked(cpr.proc); 9200 checkTime(startTime, "getContentProviderImpl: after appDied"); 9201 if (!lastRef) { 9202 // This wasn't the last ref our process had on 9203 // the provider... we have now been killed, bail. 9204 return null; 9205 } 9206 providerRunning = false; 9207 conn = null; 9208 } 9209 } 9210 9211 Binder.restoreCallingIdentity(origId); 9212 } 9213 9214 boolean singleton; 9215 if (!providerRunning) { 9216 try { 9217 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9218 cpi = AppGlobals.getPackageManager(). 9219 resolveContentProvider(name, 9220 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9221 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9222 } catch (RemoteException ex) { 9223 } 9224 if (cpi == null) { 9225 return null; 9226 } 9227 // If the provider is a singleton AND 9228 // (it's a call within the same user || the provider is a 9229 // privileged app) 9230 // Then allow connecting to the singleton provider 9231 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9232 cpi.name, cpi.flags) 9233 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9234 if (singleton) { 9235 userId = UserHandle.USER_OWNER; 9236 } 9237 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9238 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9239 9240 String msg; 9241 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9242 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9243 != null) { 9244 throw new SecurityException(msg); 9245 } 9246 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9247 9248 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9249 && !cpi.processName.equals("system")) { 9250 // If this content provider does not run in the system 9251 // process, and the system is not yet ready to run other 9252 // processes, then fail fast instead of hanging. 9253 throw new IllegalArgumentException( 9254 "Attempt to launch content provider before system ready"); 9255 } 9256 9257 // Make sure that the user who owns this provider is started. If not, 9258 // we don't want to allow it to run. 9259 if (mStartedUsers.get(userId) == null) { 9260 Slog.w(TAG, "Unable to launch app " 9261 + cpi.applicationInfo.packageName + "/" 9262 + cpi.applicationInfo.uid + " for provider " 9263 + name + ": user " + userId + " is stopped"); 9264 return null; 9265 } 9266 9267 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9268 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9269 cpr = mProviderMap.getProviderByClass(comp, userId); 9270 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9271 final boolean firstClass = cpr == null; 9272 if (firstClass) { 9273 final long ident = Binder.clearCallingIdentity(); 9274 try { 9275 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9276 ApplicationInfo ai = 9277 AppGlobals.getPackageManager(). 9278 getApplicationInfo( 9279 cpi.applicationInfo.packageName, 9280 STOCK_PM_FLAGS, userId); 9281 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9282 if (ai == null) { 9283 Slog.w(TAG, "No package info for content provider " 9284 + cpi.name); 9285 return null; 9286 } 9287 ai = getAppInfoForUser(ai, userId); 9288 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9289 } catch (RemoteException ex) { 9290 // pm is in same process, this will never happen. 9291 } finally { 9292 Binder.restoreCallingIdentity(ident); 9293 } 9294 } 9295 9296 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9297 9298 if (r != null && cpr.canRunHere(r)) { 9299 // If this is a multiprocess provider, then just return its 9300 // info and allow the caller to instantiate it. Only do 9301 // this if the provider is the same user as the caller's 9302 // process, or can run as root (so can be in any process). 9303 return cpr.newHolder(null); 9304 } 9305 9306 if (DEBUG_PROVIDER) { 9307 RuntimeException e = new RuntimeException("here"); 9308 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9309 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9310 } 9311 9312 // This is single process, and our app is now connecting to it. 9313 // See if we are already in the process of launching this 9314 // provider. 9315 final int N = mLaunchingProviders.size(); 9316 int i; 9317 for (i=0; i<N; i++) { 9318 if (mLaunchingProviders.get(i) == cpr) { 9319 break; 9320 } 9321 } 9322 9323 // If the provider is not already being launched, then get it 9324 // started. 9325 if (i >= N) { 9326 final long origId = Binder.clearCallingIdentity(); 9327 9328 try { 9329 // Content provider is now in use, its package can't be stopped. 9330 try { 9331 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9332 AppGlobals.getPackageManager().setPackageStoppedState( 9333 cpr.appInfo.packageName, false, userId); 9334 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9335 } catch (RemoteException e) { 9336 } catch (IllegalArgumentException e) { 9337 Slog.w(TAG, "Failed trying to unstop package " 9338 + cpr.appInfo.packageName + ": " + e); 9339 } 9340 9341 // Use existing process if already started 9342 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9343 ProcessRecord proc = getProcessRecordLocked( 9344 cpi.processName, cpr.appInfo.uid, false); 9345 if (proc != null && proc.thread != null) { 9346 if (DEBUG_PROVIDER) { 9347 Slog.d(TAG, "Installing in existing process " + proc); 9348 } 9349 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9350 proc.pubProviders.put(cpi.name, cpr); 9351 try { 9352 proc.thread.scheduleInstallProvider(cpi); 9353 } catch (RemoteException e) { 9354 } 9355 } else { 9356 checkTime(startTime, "getContentProviderImpl: before start process"); 9357 proc = startProcessLocked(cpi.processName, 9358 cpr.appInfo, false, 0, "content provider", 9359 new ComponentName(cpi.applicationInfo.packageName, 9360 cpi.name), false, false, false); 9361 checkTime(startTime, "getContentProviderImpl: after start process"); 9362 if (proc == null) { 9363 Slog.w(TAG, "Unable to launch app " 9364 + cpi.applicationInfo.packageName + "/" 9365 + cpi.applicationInfo.uid + " for provider " 9366 + name + ": process is bad"); 9367 return null; 9368 } 9369 } 9370 cpr.launchingApp = proc; 9371 mLaunchingProviders.add(cpr); 9372 } finally { 9373 Binder.restoreCallingIdentity(origId); 9374 } 9375 } 9376 9377 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9378 9379 // Make sure the provider is published (the same provider class 9380 // may be published under multiple names). 9381 if (firstClass) { 9382 mProviderMap.putProviderByClass(comp, cpr); 9383 } 9384 9385 mProviderMap.putProviderByName(name, cpr); 9386 conn = incProviderCountLocked(r, cpr, token, stable); 9387 if (conn != null) { 9388 conn.waiting = true; 9389 } 9390 } 9391 checkTime(startTime, "getContentProviderImpl: done!"); 9392 } 9393 9394 // Wait for the provider to be published... 9395 synchronized (cpr) { 9396 while (cpr.provider == null) { 9397 if (cpr.launchingApp == null) { 9398 Slog.w(TAG, "Unable to launch app " 9399 + cpi.applicationInfo.packageName + "/" 9400 + cpi.applicationInfo.uid + " for provider " 9401 + name + ": launching app became null"); 9402 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9403 UserHandle.getUserId(cpi.applicationInfo.uid), 9404 cpi.applicationInfo.packageName, 9405 cpi.applicationInfo.uid, name); 9406 return null; 9407 } 9408 try { 9409 if (DEBUG_MU) { 9410 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9411 + cpr.launchingApp); 9412 } 9413 if (conn != null) { 9414 conn.waiting = true; 9415 } 9416 cpr.wait(); 9417 } catch (InterruptedException ex) { 9418 } finally { 9419 if (conn != null) { 9420 conn.waiting = false; 9421 } 9422 } 9423 } 9424 } 9425 return cpr != null ? cpr.newHolder(conn) : null; 9426 } 9427 9428 @Override 9429 public final ContentProviderHolder getContentProvider( 9430 IApplicationThread caller, String name, int userId, boolean stable) { 9431 enforceNotIsolatedCaller("getContentProvider"); 9432 if (caller == null) { 9433 String msg = "null IApplicationThread when getting content provider " 9434 + name; 9435 Slog.w(TAG, msg); 9436 throw new SecurityException(msg); 9437 } 9438 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9439 // with cross-user grant. 9440 return getContentProviderImpl(caller, name, null, stable, userId); 9441 } 9442 9443 public ContentProviderHolder getContentProviderExternal( 9444 String name, int userId, IBinder token) { 9445 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9446 "Do not have permission in call getContentProviderExternal()"); 9447 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9448 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9449 return getContentProviderExternalUnchecked(name, token, userId); 9450 } 9451 9452 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9453 IBinder token, int userId) { 9454 return getContentProviderImpl(null, name, token, true, userId); 9455 } 9456 9457 /** 9458 * Drop a content provider from a ProcessRecord's bookkeeping 9459 */ 9460 public void removeContentProvider(IBinder connection, boolean stable) { 9461 enforceNotIsolatedCaller("removeContentProvider"); 9462 long ident = Binder.clearCallingIdentity(); 9463 try { 9464 synchronized (this) { 9465 ContentProviderConnection conn; 9466 try { 9467 conn = (ContentProviderConnection)connection; 9468 } catch (ClassCastException e) { 9469 String msg ="removeContentProvider: " + connection 9470 + " not a ContentProviderConnection"; 9471 Slog.w(TAG, msg); 9472 throw new IllegalArgumentException(msg); 9473 } 9474 if (conn == null) { 9475 throw new NullPointerException("connection is null"); 9476 } 9477 if (decProviderCountLocked(conn, null, null, stable)) { 9478 updateOomAdjLocked(); 9479 } 9480 } 9481 } finally { 9482 Binder.restoreCallingIdentity(ident); 9483 } 9484 } 9485 9486 public void removeContentProviderExternal(String name, IBinder token) { 9487 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9488 "Do not have permission in call removeContentProviderExternal()"); 9489 int userId = UserHandle.getCallingUserId(); 9490 long ident = Binder.clearCallingIdentity(); 9491 try { 9492 removeContentProviderExternalUnchecked(name, token, userId); 9493 } finally { 9494 Binder.restoreCallingIdentity(ident); 9495 } 9496 } 9497 9498 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9499 synchronized (this) { 9500 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9501 if(cpr == null) { 9502 //remove from mProvidersByClass 9503 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9504 return; 9505 } 9506 9507 //update content provider record entry info 9508 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9509 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9510 if (localCpr.hasExternalProcessHandles()) { 9511 if (localCpr.removeExternalProcessHandleLocked(token)) { 9512 updateOomAdjLocked(); 9513 } else { 9514 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9515 + " with no external reference for token: " 9516 + token + "."); 9517 } 9518 } else { 9519 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9520 + " with no external references."); 9521 } 9522 } 9523 } 9524 9525 public final void publishContentProviders(IApplicationThread caller, 9526 List<ContentProviderHolder> providers) { 9527 if (providers == null) { 9528 return; 9529 } 9530 9531 enforceNotIsolatedCaller("publishContentProviders"); 9532 synchronized (this) { 9533 final ProcessRecord r = getRecordForAppLocked(caller); 9534 if (DEBUG_MU) 9535 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9536 if (r == null) { 9537 throw new SecurityException( 9538 "Unable to find app for caller " + caller 9539 + " (pid=" + Binder.getCallingPid() 9540 + ") when publishing content providers"); 9541 } 9542 9543 final long origId = Binder.clearCallingIdentity(); 9544 9545 final int N = providers.size(); 9546 for (int i=0; i<N; i++) { 9547 ContentProviderHolder src = providers.get(i); 9548 if (src == null || src.info == null || src.provider == null) { 9549 continue; 9550 } 9551 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9552 if (DEBUG_MU) 9553 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9554 if (dst != null) { 9555 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9556 mProviderMap.putProviderByClass(comp, dst); 9557 String names[] = dst.info.authority.split(";"); 9558 for (int j = 0; j < names.length; j++) { 9559 mProviderMap.putProviderByName(names[j], dst); 9560 } 9561 9562 int NL = mLaunchingProviders.size(); 9563 int j; 9564 for (j=0; j<NL; j++) { 9565 if (mLaunchingProviders.get(j) == dst) { 9566 mLaunchingProviders.remove(j); 9567 j--; 9568 NL--; 9569 } 9570 } 9571 synchronized (dst) { 9572 dst.provider = src.provider; 9573 dst.proc = r; 9574 dst.notifyAll(); 9575 } 9576 updateOomAdjLocked(r); 9577 } 9578 } 9579 9580 Binder.restoreCallingIdentity(origId); 9581 } 9582 } 9583 9584 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9585 ContentProviderConnection conn; 9586 try { 9587 conn = (ContentProviderConnection)connection; 9588 } catch (ClassCastException e) { 9589 String msg ="refContentProvider: " + connection 9590 + " not a ContentProviderConnection"; 9591 Slog.w(TAG, msg); 9592 throw new IllegalArgumentException(msg); 9593 } 9594 if (conn == null) { 9595 throw new NullPointerException("connection is null"); 9596 } 9597 9598 synchronized (this) { 9599 if (stable > 0) { 9600 conn.numStableIncs += stable; 9601 } 9602 stable = conn.stableCount + stable; 9603 if (stable < 0) { 9604 throw new IllegalStateException("stableCount < 0: " + stable); 9605 } 9606 9607 if (unstable > 0) { 9608 conn.numUnstableIncs += unstable; 9609 } 9610 unstable = conn.unstableCount + unstable; 9611 if (unstable < 0) { 9612 throw new IllegalStateException("unstableCount < 0: " + unstable); 9613 } 9614 9615 if ((stable+unstable) <= 0) { 9616 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9617 + stable + " unstable=" + unstable); 9618 } 9619 conn.stableCount = stable; 9620 conn.unstableCount = unstable; 9621 return !conn.dead; 9622 } 9623 } 9624 9625 public void unstableProviderDied(IBinder connection) { 9626 ContentProviderConnection conn; 9627 try { 9628 conn = (ContentProviderConnection)connection; 9629 } catch (ClassCastException e) { 9630 String msg ="refContentProvider: " + connection 9631 + " not a ContentProviderConnection"; 9632 Slog.w(TAG, msg); 9633 throw new IllegalArgumentException(msg); 9634 } 9635 if (conn == null) { 9636 throw new NullPointerException("connection is null"); 9637 } 9638 9639 // Safely retrieve the content provider associated with the connection. 9640 IContentProvider provider; 9641 synchronized (this) { 9642 provider = conn.provider.provider; 9643 } 9644 9645 if (provider == null) { 9646 // Um, yeah, we're way ahead of you. 9647 return; 9648 } 9649 9650 // Make sure the caller is being honest with us. 9651 if (provider.asBinder().pingBinder()) { 9652 // Er, no, still looks good to us. 9653 synchronized (this) { 9654 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9655 + " says " + conn + " died, but we don't agree"); 9656 return; 9657 } 9658 } 9659 9660 // Well look at that! It's dead! 9661 synchronized (this) { 9662 if (conn.provider.provider != provider) { 9663 // But something changed... good enough. 9664 return; 9665 } 9666 9667 ProcessRecord proc = conn.provider.proc; 9668 if (proc == null || proc.thread == null) { 9669 // Seems like the process is already cleaned up. 9670 return; 9671 } 9672 9673 // As far as we're concerned, this is just like receiving a 9674 // death notification... just a bit prematurely. 9675 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9676 + ") early provider death"); 9677 final long ident = Binder.clearCallingIdentity(); 9678 try { 9679 appDiedLocked(proc); 9680 } finally { 9681 Binder.restoreCallingIdentity(ident); 9682 } 9683 } 9684 } 9685 9686 @Override 9687 public void appNotRespondingViaProvider(IBinder connection) { 9688 enforceCallingPermission( 9689 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9690 9691 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9692 if (conn == null) { 9693 Slog.w(TAG, "ContentProviderConnection is null"); 9694 return; 9695 } 9696 9697 final ProcessRecord host = conn.provider.proc; 9698 if (host == null) { 9699 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9700 return; 9701 } 9702 9703 final long token = Binder.clearCallingIdentity(); 9704 try { 9705 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9706 } finally { 9707 Binder.restoreCallingIdentity(token); 9708 } 9709 } 9710 9711 public final void installSystemProviders() { 9712 List<ProviderInfo> providers; 9713 synchronized (this) { 9714 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9715 providers = generateApplicationProvidersLocked(app); 9716 if (providers != null) { 9717 for (int i=providers.size()-1; i>=0; i--) { 9718 ProviderInfo pi = (ProviderInfo)providers.get(i); 9719 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9720 Slog.w(TAG, "Not installing system proc provider " + pi.name 9721 + ": not system .apk"); 9722 providers.remove(i); 9723 } 9724 } 9725 } 9726 } 9727 if (providers != null) { 9728 mSystemThread.installSystemProviders(providers); 9729 } 9730 9731 mCoreSettingsObserver = new CoreSettingsObserver(this); 9732 9733 //mUsageStatsService.monitorPackages(); 9734 } 9735 9736 /** 9737 * Allows apps to retrieve the MIME type of a URI. 9738 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9739 * users, then it does not need permission to access the ContentProvider. 9740 * Either, it needs cross-user uri grants. 9741 * 9742 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9743 * 9744 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9745 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9746 */ 9747 public String getProviderMimeType(Uri uri, int userId) { 9748 enforceNotIsolatedCaller("getProviderMimeType"); 9749 final String name = uri.getAuthority(); 9750 int callingUid = Binder.getCallingUid(); 9751 int callingPid = Binder.getCallingPid(); 9752 long ident = 0; 9753 boolean clearedIdentity = false; 9754 userId = unsafeConvertIncomingUser(userId); 9755 if (canClearIdentity(callingPid, callingUid, userId)) { 9756 clearedIdentity = true; 9757 ident = Binder.clearCallingIdentity(); 9758 } 9759 ContentProviderHolder holder = null; 9760 try { 9761 holder = getContentProviderExternalUnchecked(name, null, userId); 9762 if (holder != null) { 9763 return holder.provider.getType(uri); 9764 } 9765 } catch (RemoteException e) { 9766 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9767 return null; 9768 } finally { 9769 // We need to clear the identity to call removeContentProviderExternalUnchecked 9770 if (!clearedIdentity) { 9771 ident = Binder.clearCallingIdentity(); 9772 } 9773 try { 9774 if (holder != null) { 9775 removeContentProviderExternalUnchecked(name, null, userId); 9776 } 9777 } finally { 9778 Binder.restoreCallingIdentity(ident); 9779 } 9780 } 9781 9782 return null; 9783 } 9784 9785 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9786 if (UserHandle.getUserId(callingUid) == userId) { 9787 return true; 9788 } 9789 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9790 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9791 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9792 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9793 return true; 9794 } 9795 return false; 9796 } 9797 9798 // ========================================================= 9799 // GLOBAL MANAGEMENT 9800 // ========================================================= 9801 9802 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9803 boolean isolated, int isolatedUid) { 9804 String proc = customProcess != null ? customProcess : info.processName; 9805 BatteryStatsImpl.Uid.Proc ps = null; 9806 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9807 int uid = info.uid; 9808 if (isolated) { 9809 if (isolatedUid == 0) { 9810 int userId = UserHandle.getUserId(uid); 9811 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9812 while (true) { 9813 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9814 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9815 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9816 } 9817 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9818 mNextIsolatedProcessUid++; 9819 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9820 // No process for this uid, use it. 9821 break; 9822 } 9823 stepsLeft--; 9824 if (stepsLeft <= 0) { 9825 return null; 9826 } 9827 } 9828 } else { 9829 // Special case for startIsolatedProcess (internal only), where 9830 // the uid of the isolated process is specified by the caller. 9831 uid = isolatedUid; 9832 } 9833 } 9834 return new ProcessRecord(stats, info, proc, uid); 9835 } 9836 9837 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9838 String abiOverride) { 9839 ProcessRecord app; 9840 if (!isolated) { 9841 app = getProcessRecordLocked(info.processName, info.uid, true); 9842 } else { 9843 app = null; 9844 } 9845 9846 if (app == null) { 9847 app = newProcessRecordLocked(info, null, isolated, 0); 9848 mProcessNames.put(info.processName, app.uid, app); 9849 if (isolated) { 9850 mIsolatedProcesses.put(app.uid, app); 9851 } 9852 updateLruProcessLocked(app, false, null); 9853 updateOomAdjLocked(); 9854 } 9855 9856 // This package really, really can not be stopped. 9857 try { 9858 AppGlobals.getPackageManager().setPackageStoppedState( 9859 info.packageName, false, UserHandle.getUserId(app.uid)); 9860 } catch (RemoteException e) { 9861 } catch (IllegalArgumentException e) { 9862 Slog.w(TAG, "Failed trying to unstop package " 9863 + info.packageName + ": " + e); 9864 } 9865 9866 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9867 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9868 app.persistent = true; 9869 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9870 } 9871 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9872 mPersistentStartingProcesses.add(app); 9873 startProcessLocked(app, "added application", app.processName, abiOverride, 9874 null /* entryPoint */, null /* entryPointArgs */); 9875 } 9876 9877 return app; 9878 } 9879 9880 public void unhandledBack() { 9881 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9882 "unhandledBack()"); 9883 9884 synchronized(this) { 9885 final long origId = Binder.clearCallingIdentity(); 9886 try { 9887 getFocusedStack().unhandledBackLocked(); 9888 } finally { 9889 Binder.restoreCallingIdentity(origId); 9890 } 9891 } 9892 } 9893 9894 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9895 enforceNotIsolatedCaller("openContentUri"); 9896 final int userId = UserHandle.getCallingUserId(); 9897 String name = uri.getAuthority(); 9898 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9899 ParcelFileDescriptor pfd = null; 9900 if (cph != null) { 9901 // We record the binder invoker's uid in thread-local storage before 9902 // going to the content provider to open the file. Later, in the code 9903 // that handles all permissions checks, we look for this uid and use 9904 // that rather than the Activity Manager's own uid. The effect is that 9905 // we do the check against the caller's permissions even though it looks 9906 // to the content provider like the Activity Manager itself is making 9907 // the request. 9908 sCallerIdentity.set(new Identity( 9909 Binder.getCallingPid(), Binder.getCallingUid())); 9910 try { 9911 pfd = cph.provider.openFile(null, uri, "r", null); 9912 } catch (FileNotFoundException e) { 9913 // do nothing; pfd will be returned null 9914 } finally { 9915 // Ensure that whatever happens, we clean up the identity state 9916 sCallerIdentity.remove(); 9917 } 9918 9919 // We've got the fd now, so we're done with the provider. 9920 removeContentProviderExternalUnchecked(name, null, userId); 9921 } else { 9922 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9923 } 9924 return pfd; 9925 } 9926 9927 // Actually is sleeping or shutting down or whatever else in the future 9928 // is an inactive state. 9929 public boolean isSleepingOrShuttingDown() { 9930 return isSleeping() || mShuttingDown; 9931 } 9932 9933 public boolean isSleeping() { 9934 return mSleeping; 9935 } 9936 9937 void goingToSleep() { 9938 synchronized(this) { 9939 mWentToSleep = true; 9940 goToSleepIfNeededLocked(); 9941 } 9942 } 9943 9944 void finishRunningVoiceLocked() { 9945 if (mRunningVoice) { 9946 mRunningVoice = false; 9947 goToSleepIfNeededLocked(); 9948 } 9949 } 9950 9951 void goToSleepIfNeededLocked() { 9952 if (mWentToSleep && !mRunningVoice) { 9953 if (!mSleeping) { 9954 mSleeping = true; 9955 mStackSupervisor.goingToSleepLocked(); 9956 9957 // Initialize the wake times of all processes. 9958 checkExcessivePowerUsageLocked(false); 9959 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9960 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9961 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9962 } 9963 } 9964 } 9965 9966 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9967 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9968 // Never persist the home stack. 9969 return; 9970 } 9971 mTaskPersister.wakeup(task, flush); 9972 } 9973 9974 @Override 9975 public boolean shutdown(int timeout) { 9976 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9977 != PackageManager.PERMISSION_GRANTED) { 9978 throw new SecurityException("Requires permission " 9979 + android.Manifest.permission.SHUTDOWN); 9980 } 9981 9982 boolean timedout = false; 9983 9984 synchronized(this) { 9985 mShuttingDown = true; 9986 updateEventDispatchingLocked(); 9987 timedout = mStackSupervisor.shutdownLocked(timeout); 9988 } 9989 9990 mAppOpsService.shutdown(); 9991 if (mUsageStatsService != null) { 9992 mUsageStatsService.prepareShutdown(); 9993 } 9994 mBatteryStatsService.shutdown(); 9995 synchronized (this) { 9996 mProcessStats.shutdownLocked(); 9997 } 9998 notifyTaskPersisterLocked(null, true); 9999 10000 return timedout; 10001 } 10002 10003 public final void activitySlept(IBinder token) { 10004 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10005 10006 final long origId = Binder.clearCallingIdentity(); 10007 10008 synchronized (this) { 10009 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10010 if (r != null) { 10011 mStackSupervisor.activitySleptLocked(r); 10012 } 10013 } 10014 10015 Binder.restoreCallingIdentity(origId); 10016 } 10017 10018 private String lockScreenShownToString() { 10019 switch (mLockScreenShown) { 10020 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10021 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10022 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10023 default: return "Unknown=" + mLockScreenShown; 10024 } 10025 } 10026 10027 void logLockScreen(String msg) { 10028 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10029 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10030 mWentToSleep + " mSleeping=" + mSleeping); 10031 } 10032 10033 void comeOutOfSleepIfNeededLocked() { 10034 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10035 if (mSleeping) { 10036 mSleeping = false; 10037 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10038 } 10039 } 10040 } 10041 10042 void wakingUp() { 10043 synchronized(this) { 10044 mWentToSleep = false; 10045 comeOutOfSleepIfNeededLocked(); 10046 } 10047 } 10048 10049 void startRunningVoiceLocked() { 10050 if (!mRunningVoice) { 10051 mRunningVoice = true; 10052 comeOutOfSleepIfNeededLocked(); 10053 } 10054 } 10055 10056 private void updateEventDispatchingLocked() { 10057 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10058 } 10059 10060 public void setLockScreenShown(boolean shown) { 10061 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10062 != PackageManager.PERMISSION_GRANTED) { 10063 throw new SecurityException("Requires permission " 10064 + android.Manifest.permission.DEVICE_POWER); 10065 } 10066 10067 synchronized(this) { 10068 long ident = Binder.clearCallingIdentity(); 10069 try { 10070 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10071 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10072 comeOutOfSleepIfNeededLocked(); 10073 } finally { 10074 Binder.restoreCallingIdentity(ident); 10075 } 10076 } 10077 } 10078 10079 @Override 10080 public void stopAppSwitches() { 10081 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10082 != PackageManager.PERMISSION_GRANTED) { 10083 throw new SecurityException("Requires permission " 10084 + android.Manifest.permission.STOP_APP_SWITCHES); 10085 } 10086 10087 synchronized(this) { 10088 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10089 + APP_SWITCH_DELAY_TIME; 10090 mDidAppSwitch = false; 10091 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10092 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10093 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10094 } 10095 } 10096 10097 public void resumeAppSwitches() { 10098 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10099 != PackageManager.PERMISSION_GRANTED) { 10100 throw new SecurityException("Requires permission " 10101 + android.Manifest.permission.STOP_APP_SWITCHES); 10102 } 10103 10104 synchronized(this) { 10105 // Note that we don't execute any pending app switches... we will 10106 // let those wait until either the timeout, or the next start 10107 // activity request. 10108 mAppSwitchesAllowedTime = 0; 10109 } 10110 } 10111 10112 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10113 int callingPid, int callingUid, String name) { 10114 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10115 return true; 10116 } 10117 10118 int perm = checkComponentPermission( 10119 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10120 sourceUid, -1, true); 10121 if (perm == PackageManager.PERMISSION_GRANTED) { 10122 return true; 10123 } 10124 10125 // If the actual IPC caller is different from the logical source, then 10126 // also see if they are allowed to control app switches. 10127 if (callingUid != -1 && callingUid != sourceUid) { 10128 perm = checkComponentPermission( 10129 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10130 callingUid, -1, true); 10131 if (perm == PackageManager.PERMISSION_GRANTED) { 10132 return true; 10133 } 10134 } 10135 10136 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10137 return false; 10138 } 10139 10140 public void setDebugApp(String packageName, boolean waitForDebugger, 10141 boolean persistent) { 10142 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10143 "setDebugApp()"); 10144 10145 long ident = Binder.clearCallingIdentity(); 10146 try { 10147 // Note that this is not really thread safe if there are multiple 10148 // callers into it at the same time, but that's not a situation we 10149 // care about. 10150 if (persistent) { 10151 final ContentResolver resolver = mContext.getContentResolver(); 10152 Settings.Global.putString( 10153 resolver, Settings.Global.DEBUG_APP, 10154 packageName); 10155 Settings.Global.putInt( 10156 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10157 waitForDebugger ? 1 : 0); 10158 } 10159 10160 synchronized (this) { 10161 if (!persistent) { 10162 mOrigDebugApp = mDebugApp; 10163 mOrigWaitForDebugger = mWaitForDebugger; 10164 } 10165 mDebugApp = packageName; 10166 mWaitForDebugger = waitForDebugger; 10167 mDebugTransient = !persistent; 10168 if (packageName != null) { 10169 forceStopPackageLocked(packageName, -1, false, false, true, true, 10170 false, UserHandle.USER_ALL, "set debug app"); 10171 } 10172 } 10173 } finally { 10174 Binder.restoreCallingIdentity(ident); 10175 } 10176 } 10177 10178 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10179 synchronized (this) { 10180 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10181 if (!isDebuggable) { 10182 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10183 throw new SecurityException("Process not debuggable: " + app.packageName); 10184 } 10185 } 10186 10187 mOpenGlTraceApp = processName; 10188 } 10189 } 10190 10191 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10192 synchronized (this) { 10193 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10194 if (!isDebuggable) { 10195 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10196 throw new SecurityException("Process not debuggable: " + app.packageName); 10197 } 10198 } 10199 mProfileApp = processName; 10200 mProfileFile = profilerInfo.profileFile; 10201 if (mProfileFd != null) { 10202 try { 10203 mProfileFd.close(); 10204 } catch (IOException e) { 10205 } 10206 mProfileFd = null; 10207 } 10208 mProfileFd = profilerInfo.profileFd; 10209 mSamplingInterval = profilerInfo.samplingInterval; 10210 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10211 mProfileType = 0; 10212 } 10213 } 10214 10215 @Override 10216 public void setAlwaysFinish(boolean enabled) { 10217 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10218 "setAlwaysFinish()"); 10219 10220 Settings.Global.putInt( 10221 mContext.getContentResolver(), 10222 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10223 10224 synchronized (this) { 10225 mAlwaysFinishActivities = enabled; 10226 } 10227 } 10228 10229 @Override 10230 public void setActivityController(IActivityController controller) { 10231 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10232 "setActivityController()"); 10233 synchronized (this) { 10234 mController = controller; 10235 Watchdog.getInstance().setActivityController(controller); 10236 } 10237 } 10238 10239 @Override 10240 public void setUserIsMonkey(boolean userIsMonkey) { 10241 synchronized (this) { 10242 synchronized (mPidsSelfLocked) { 10243 final int callingPid = Binder.getCallingPid(); 10244 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10245 if (precessRecord == null) { 10246 throw new SecurityException("Unknown process: " + callingPid); 10247 } 10248 if (precessRecord.instrumentationUiAutomationConnection == null) { 10249 throw new SecurityException("Only an instrumentation process " 10250 + "with a UiAutomation can call setUserIsMonkey"); 10251 } 10252 } 10253 mUserIsMonkey = userIsMonkey; 10254 } 10255 } 10256 10257 @Override 10258 public boolean isUserAMonkey() { 10259 synchronized (this) { 10260 // If there is a controller also implies the user is a monkey. 10261 return (mUserIsMonkey || mController != null); 10262 } 10263 } 10264 10265 public void requestBugReport() { 10266 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10267 SystemProperties.set("ctl.start", "bugreport"); 10268 } 10269 10270 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10271 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10272 } 10273 10274 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10275 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10276 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10277 } 10278 return KEY_DISPATCHING_TIMEOUT; 10279 } 10280 10281 @Override 10282 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10283 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10284 != PackageManager.PERMISSION_GRANTED) { 10285 throw new SecurityException("Requires permission " 10286 + android.Manifest.permission.FILTER_EVENTS); 10287 } 10288 ProcessRecord proc; 10289 long timeout; 10290 synchronized (this) { 10291 synchronized (mPidsSelfLocked) { 10292 proc = mPidsSelfLocked.get(pid); 10293 } 10294 timeout = getInputDispatchingTimeoutLocked(proc); 10295 } 10296 10297 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10298 return -1; 10299 } 10300 10301 return timeout; 10302 } 10303 10304 /** 10305 * Handle input dispatching timeouts. 10306 * Returns whether input dispatching should be aborted or not. 10307 */ 10308 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10309 final ActivityRecord activity, final ActivityRecord parent, 10310 final boolean aboveSystem, String reason) { 10311 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10312 != PackageManager.PERMISSION_GRANTED) { 10313 throw new SecurityException("Requires permission " 10314 + android.Manifest.permission.FILTER_EVENTS); 10315 } 10316 10317 final String annotation; 10318 if (reason == null) { 10319 annotation = "Input dispatching timed out"; 10320 } else { 10321 annotation = "Input dispatching timed out (" + reason + ")"; 10322 } 10323 10324 if (proc != null) { 10325 synchronized (this) { 10326 if (proc.debugging) { 10327 return false; 10328 } 10329 10330 if (mDidDexOpt) { 10331 // Give more time since we were dexopting. 10332 mDidDexOpt = false; 10333 return false; 10334 } 10335 10336 if (proc.instrumentationClass != null) { 10337 Bundle info = new Bundle(); 10338 info.putString("shortMsg", "keyDispatchingTimedOut"); 10339 info.putString("longMsg", annotation); 10340 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10341 return true; 10342 } 10343 } 10344 mHandler.post(new Runnable() { 10345 @Override 10346 public void run() { 10347 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10348 } 10349 }); 10350 } 10351 10352 return true; 10353 } 10354 10355 public Bundle getAssistContextExtras(int requestType) { 10356 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10357 UserHandle.getCallingUserId()); 10358 if (pae == null) { 10359 return null; 10360 } 10361 synchronized (pae) { 10362 while (!pae.haveResult) { 10363 try { 10364 pae.wait(); 10365 } catch (InterruptedException e) { 10366 } 10367 } 10368 if (pae.result != null) { 10369 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10370 } 10371 } 10372 synchronized (this) { 10373 mPendingAssistExtras.remove(pae); 10374 mHandler.removeCallbacks(pae); 10375 } 10376 return pae.extras; 10377 } 10378 10379 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10380 int userHandle) { 10381 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10382 "getAssistContextExtras()"); 10383 PendingAssistExtras pae; 10384 Bundle extras = new Bundle(); 10385 synchronized (this) { 10386 ActivityRecord activity = getFocusedStack().mResumedActivity; 10387 if (activity == null) { 10388 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10389 return null; 10390 } 10391 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10392 if (activity.app == null || activity.app.thread == null) { 10393 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10394 return null; 10395 } 10396 if (activity.app.pid == Binder.getCallingPid()) { 10397 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10398 return null; 10399 } 10400 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10401 try { 10402 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10403 requestType); 10404 mPendingAssistExtras.add(pae); 10405 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10406 } catch (RemoteException e) { 10407 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10408 return null; 10409 } 10410 return pae; 10411 } 10412 } 10413 10414 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10415 PendingAssistExtras pae = (PendingAssistExtras)token; 10416 synchronized (pae) { 10417 pae.result = extras; 10418 pae.haveResult = true; 10419 pae.notifyAll(); 10420 if (pae.intent == null) { 10421 // Caller is just waiting for the result. 10422 return; 10423 } 10424 } 10425 10426 // We are now ready to launch the assist activity. 10427 synchronized (this) { 10428 boolean exists = mPendingAssistExtras.remove(pae); 10429 mHandler.removeCallbacks(pae); 10430 if (!exists) { 10431 // Timed out. 10432 return; 10433 } 10434 } 10435 pae.intent.replaceExtras(extras); 10436 if (pae.hint != null) { 10437 pae.intent.putExtra(pae.hint, true); 10438 } 10439 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10440 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10441 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10442 closeSystemDialogs("assist"); 10443 try { 10444 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10445 } catch (ActivityNotFoundException e) { 10446 Slog.w(TAG, "No activity to handle assist action.", e); 10447 } 10448 } 10449 10450 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10451 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10452 } 10453 10454 public void registerProcessObserver(IProcessObserver observer) { 10455 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10456 "registerProcessObserver()"); 10457 synchronized (this) { 10458 mProcessObservers.register(observer); 10459 } 10460 } 10461 10462 @Override 10463 public void unregisterProcessObserver(IProcessObserver observer) { 10464 synchronized (this) { 10465 mProcessObservers.unregister(observer); 10466 } 10467 } 10468 10469 @Override 10470 public boolean convertFromTranslucent(IBinder token) { 10471 final long origId = Binder.clearCallingIdentity(); 10472 try { 10473 synchronized (this) { 10474 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10475 if (r == null) { 10476 return false; 10477 } 10478 final boolean translucentChanged = r.changeWindowTranslucency(true); 10479 if (translucentChanged) { 10480 r.task.stack.releaseBackgroundResources(); 10481 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10482 } 10483 mWindowManager.setAppFullscreen(token, true); 10484 return translucentChanged; 10485 } 10486 } finally { 10487 Binder.restoreCallingIdentity(origId); 10488 } 10489 } 10490 10491 @Override 10492 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10493 final long origId = Binder.clearCallingIdentity(); 10494 try { 10495 synchronized (this) { 10496 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10497 if (r == null) { 10498 return false; 10499 } 10500 int index = r.task.mActivities.lastIndexOf(r); 10501 if (index > 0) { 10502 ActivityRecord under = r.task.mActivities.get(index - 1); 10503 under.returningOptions = options; 10504 } 10505 final boolean translucentChanged = r.changeWindowTranslucency(false); 10506 if (translucentChanged) { 10507 r.task.stack.convertToTranslucent(r); 10508 } 10509 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10510 mWindowManager.setAppFullscreen(token, false); 10511 return translucentChanged; 10512 } 10513 } finally { 10514 Binder.restoreCallingIdentity(origId); 10515 } 10516 } 10517 10518 @Override 10519 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10520 final long origId = Binder.clearCallingIdentity(); 10521 try { 10522 synchronized (this) { 10523 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10524 if (r != null) { 10525 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10526 } 10527 } 10528 return false; 10529 } finally { 10530 Binder.restoreCallingIdentity(origId); 10531 } 10532 } 10533 10534 @Override 10535 public boolean isBackgroundVisibleBehind(IBinder token) { 10536 final long origId = Binder.clearCallingIdentity(); 10537 try { 10538 synchronized (this) { 10539 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10540 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10541 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10542 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10543 return visible; 10544 } 10545 } finally { 10546 Binder.restoreCallingIdentity(origId); 10547 } 10548 } 10549 10550 @Override 10551 public ActivityOptions getActivityOptions(IBinder token) { 10552 final long origId = Binder.clearCallingIdentity(); 10553 try { 10554 synchronized (this) { 10555 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10556 if (r != null) { 10557 final ActivityOptions activityOptions = r.pendingOptions; 10558 r.pendingOptions = null; 10559 return activityOptions; 10560 } 10561 return null; 10562 } 10563 } finally { 10564 Binder.restoreCallingIdentity(origId); 10565 } 10566 } 10567 10568 @Override 10569 public void setImmersive(IBinder token, boolean immersive) { 10570 synchronized(this) { 10571 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10572 if (r == null) { 10573 throw new IllegalArgumentException(); 10574 } 10575 r.immersive = immersive; 10576 10577 // update associated state if we're frontmost 10578 if (r == mFocusedActivity) { 10579 if (DEBUG_IMMERSIVE) { 10580 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10581 } 10582 applyUpdateLockStateLocked(r); 10583 } 10584 } 10585 } 10586 10587 @Override 10588 public boolean isImmersive(IBinder token) { 10589 synchronized (this) { 10590 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10591 if (r == null) { 10592 throw new IllegalArgumentException(); 10593 } 10594 return r.immersive; 10595 } 10596 } 10597 10598 public boolean isTopActivityImmersive() { 10599 enforceNotIsolatedCaller("startActivity"); 10600 synchronized (this) { 10601 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10602 return (r != null) ? r.immersive : false; 10603 } 10604 } 10605 10606 @Override 10607 public boolean isTopOfTask(IBinder token) { 10608 synchronized (this) { 10609 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10610 if (r == null) { 10611 throw new IllegalArgumentException(); 10612 } 10613 return r.task.getTopActivity() == r; 10614 } 10615 } 10616 10617 public final void enterSafeMode() { 10618 synchronized(this) { 10619 // It only makes sense to do this before the system is ready 10620 // and started launching other packages. 10621 if (!mSystemReady) { 10622 try { 10623 AppGlobals.getPackageManager().enterSafeMode(); 10624 } catch (RemoteException e) { 10625 } 10626 } 10627 10628 mSafeMode = true; 10629 } 10630 } 10631 10632 public final void showSafeModeOverlay() { 10633 View v = LayoutInflater.from(mContext).inflate( 10634 com.android.internal.R.layout.safe_mode, null); 10635 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10636 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10637 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10638 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10639 lp.gravity = Gravity.BOTTOM | Gravity.START; 10640 lp.format = v.getBackground().getOpacity(); 10641 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10642 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10643 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10644 ((WindowManager)mContext.getSystemService( 10645 Context.WINDOW_SERVICE)).addView(v, lp); 10646 } 10647 10648 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10649 if (!(sender instanceof PendingIntentRecord)) { 10650 return; 10651 } 10652 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10653 synchronized (stats) { 10654 if (mBatteryStatsService.isOnBattery()) { 10655 mBatteryStatsService.enforceCallingPermission(); 10656 PendingIntentRecord rec = (PendingIntentRecord)sender; 10657 int MY_UID = Binder.getCallingUid(); 10658 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10659 BatteryStatsImpl.Uid.Pkg pkg = 10660 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10661 sourcePkg != null ? sourcePkg : rec.key.packageName); 10662 pkg.incWakeupsLocked(); 10663 } 10664 } 10665 } 10666 10667 public boolean killPids(int[] pids, String pReason, boolean secure) { 10668 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10669 throw new SecurityException("killPids only available to the system"); 10670 } 10671 String reason = (pReason == null) ? "Unknown" : pReason; 10672 // XXX Note: don't acquire main activity lock here, because the window 10673 // manager calls in with its locks held. 10674 10675 boolean killed = false; 10676 synchronized (mPidsSelfLocked) { 10677 int[] types = new int[pids.length]; 10678 int worstType = 0; 10679 for (int i=0; i<pids.length; i++) { 10680 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10681 if (proc != null) { 10682 int type = proc.setAdj; 10683 types[i] = type; 10684 if (type > worstType) { 10685 worstType = type; 10686 } 10687 } 10688 } 10689 10690 // If the worst oom_adj is somewhere in the cached proc LRU range, 10691 // then constrain it so we will kill all cached procs. 10692 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10693 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10694 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10695 } 10696 10697 // If this is not a secure call, don't let it kill processes that 10698 // are important. 10699 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10700 worstType = ProcessList.SERVICE_ADJ; 10701 } 10702 10703 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10704 for (int i=0; i<pids.length; i++) { 10705 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10706 if (proc == null) { 10707 continue; 10708 } 10709 int adj = proc.setAdj; 10710 if (adj >= worstType && !proc.killedByAm) { 10711 proc.kill(reason, true); 10712 killed = true; 10713 } 10714 } 10715 } 10716 return killed; 10717 } 10718 10719 @Override 10720 public void killUid(int uid, String reason) { 10721 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10722 throw new SecurityException("killUid only available to the system"); 10723 } 10724 synchronized (this) { 10725 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10726 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10727 reason != null ? reason : "kill uid"); 10728 } 10729 } 10730 10731 @Override 10732 public boolean killProcessesBelowForeground(String reason) { 10733 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10734 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10735 } 10736 10737 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10738 } 10739 10740 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10741 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10742 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10743 } 10744 10745 boolean killed = false; 10746 synchronized (mPidsSelfLocked) { 10747 final int size = mPidsSelfLocked.size(); 10748 for (int i = 0; i < size; i++) { 10749 final int pid = mPidsSelfLocked.keyAt(i); 10750 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10751 if (proc == null) continue; 10752 10753 final int adj = proc.setAdj; 10754 if (adj > belowAdj && !proc.killedByAm) { 10755 proc.kill(reason, true); 10756 killed = true; 10757 } 10758 } 10759 } 10760 return killed; 10761 } 10762 10763 @Override 10764 public void hang(final IBinder who, boolean allowRestart) { 10765 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10766 != PackageManager.PERMISSION_GRANTED) { 10767 throw new SecurityException("Requires permission " 10768 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10769 } 10770 10771 final IBinder.DeathRecipient death = new DeathRecipient() { 10772 @Override 10773 public void binderDied() { 10774 synchronized (this) { 10775 notifyAll(); 10776 } 10777 } 10778 }; 10779 10780 try { 10781 who.linkToDeath(death, 0); 10782 } catch (RemoteException e) { 10783 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10784 return; 10785 } 10786 10787 synchronized (this) { 10788 Watchdog.getInstance().setAllowRestart(allowRestart); 10789 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10790 synchronized (death) { 10791 while (who.isBinderAlive()) { 10792 try { 10793 death.wait(); 10794 } catch (InterruptedException e) { 10795 } 10796 } 10797 } 10798 Watchdog.getInstance().setAllowRestart(true); 10799 } 10800 } 10801 10802 @Override 10803 public void restart() { 10804 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10805 != PackageManager.PERMISSION_GRANTED) { 10806 throw new SecurityException("Requires permission " 10807 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10808 } 10809 10810 Log.i(TAG, "Sending shutdown broadcast..."); 10811 10812 BroadcastReceiver br = new BroadcastReceiver() { 10813 @Override public void onReceive(Context context, Intent intent) { 10814 // Now the broadcast is done, finish up the low-level shutdown. 10815 Log.i(TAG, "Shutting down activity manager..."); 10816 shutdown(10000); 10817 Log.i(TAG, "Shutdown complete, restarting!"); 10818 Process.killProcess(Process.myPid()); 10819 System.exit(10); 10820 } 10821 }; 10822 10823 // First send the high-level shut down broadcast. 10824 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10825 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10826 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10827 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10828 mContext.sendOrderedBroadcastAsUser(intent, 10829 UserHandle.ALL, null, br, mHandler, 0, null, null); 10830 */ 10831 br.onReceive(mContext, intent); 10832 } 10833 10834 private long getLowRamTimeSinceIdle(long now) { 10835 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10836 } 10837 10838 @Override 10839 public void performIdleMaintenance() { 10840 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10841 != PackageManager.PERMISSION_GRANTED) { 10842 throw new SecurityException("Requires permission " 10843 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10844 } 10845 10846 synchronized (this) { 10847 final long now = SystemClock.uptimeMillis(); 10848 final long timeSinceLastIdle = now - mLastIdleTime; 10849 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10850 mLastIdleTime = now; 10851 mLowRamTimeSinceLastIdle = 0; 10852 if (mLowRamStartTime != 0) { 10853 mLowRamStartTime = now; 10854 } 10855 10856 StringBuilder sb = new StringBuilder(128); 10857 sb.append("Idle maintenance over "); 10858 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10859 sb.append(" low RAM for "); 10860 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10861 Slog.i(TAG, sb.toString()); 10862 10863 // If at least 1/3 of our time since the last idle period has been spent 10864 // with RAM low, then we want to kill processes. 10865 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10866 10867 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10868 ProcessRecord proc = mLruProcesses.get(i); 10869 if (proc.notCachedSinceIdle) { 10870 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10871 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10872 if (doKilling && proc.initialIdlePss != 0 10873 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10874 proc.kill("idle maint (pss " + proc.lastPss 10875 + " from " + proc.initialIdlePss + ")", true); 10876 } 10877 } 10878 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10879 proc.notCachedSinceIdle = true; 10880 proc.initialIdlePss = 0; 10881 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10882 isSleeping(), now); 10883 } 10884 } 10885 10886 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10887 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10888 } 10889 } 10890 10891 private void retrieveSettings() { 10892 final ContentResolver resolver = mContext.getContentResolver(); 10893 String debugApp = Settings.Global.getString( 10894 resolver, Settings.Global.DEBUG_APP); 10895 boolean waitForDebugger = Settings.Global.getInt( 10896 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10897 boolean alwaysFinishActivities = Settings.Global.getInt( 10898 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10899 boolean forceRtl = Settings.Global.getInt( 10900 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10901 // Transfer any global setting for forcing RTL layout, into a System Property 10902 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10903 10904 Configuration configuration = new Configuration(); 10905 Settings.System.getConfiguration(resolver, configuration); 10906 if (forceRtl) { 10907 // This will take care of setting the correct layout direction flags 10908 configuration.setLayoutDirection(configuration.locale); 10909 } 10910 10911 synchronized (this) { 10912 mDebugApp = mOrigDebugApp = debugApp; 10913 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10914 mAlwaysFinishActivities = alwaysFinishActivities; 10915 // This happens before any activities are started, so we can 10916 // change mConfiguration in-place. 10917 updateConfigurationLocked(configuration, null, false, true); 10918 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10919 } 10920 } 10921 10922 /** Loads resources after the current configuration has been set. */ 10923 private void loadResourcesOnSystemReady() { 10924 final Resources res = mContext.getResources(); 10925 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10926 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10927 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10928 } 10929 10930 public boolean testIsSystemReady() { 10931 // no need to synchronize(this) just to read & return the value 10932 return mSystemReady; 10933 } 10934 10935 private static File getCalledPreBootReceiversFile() { 10936 File dataDir = Environment.getDataDirectory(); 10937 File systemDir = new File(dataDir, "system"); 10938 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10939 return fname; 10940 } 10941 10942 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10943 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10944 File file = getCalledPreBootReceiversFile(); 10945 FileInputStream fis = null; 10946 try { 10947 fis = new FileInputStream(file); 10948 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10949 int fvers = dis.readInt(); 10950 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10951 String vers = dis.readUTF(); 10952 String codename = dis.readUTF(); 10953 String build = dis.readUTF(); 10954 if (android.os.Build.VERSION.RELEASE.equals(vers) 10955 && android.os.Build.VERSION.CODENAME.equals(codename) 10956 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10957 int num = dis.readInt(); 10958 while (num > 0) { 10959 num--; 10960 String pkg = dis.readUTF(); 10961 String cls = dis.readUTF(); 10962 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10963 } 10964 } 10965 } 10966 } catch (FileNotFoundException e) { 10967 } catch (IOException e) { 10968 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10969 } finally { 10970 if (fis != null) { 10971 try { 10972 fis.close(); 10973 } catch (IOException e) { 10974 } 10975 } 10976 } 10977 return lastDoneReceivers; 10978 } 10979 10980 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10981 File file = getCalledPreBootReceiversFile(); 10982 FileOutputStream fos = null; 10983 DataOutputStream dos = null; 10984 try { 10985 fos = new FileOutputStream(file); 10986 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10987 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10988 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10989 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10990 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10991 dos.writeInt(list.size()); 10992 for (int i=0; i<list.size(); i++) { 10993 dos.writeUTF(list.get(i).getPackageName()); 10994 dos.writeUTF(list.get(i).getClassName()); 10995 } 10996 } catch (IOException e) { 10997 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10998 file.delete(); 10999 } finally { 11000 FileUtils.sync(fos); 11001 if (dos != null) { 11002 try { 11003 dos.close(); 11004 } catch (IOException e) { 11005 // TODO Auto-generated catch block 11006 e.printStackTrace(); 11007 } 11008 } 11009 } 11010 } 11011 11012 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11013 ArrayList<ComponentName> doneReceivers, int userId) { 11014 boolean waitingUpdate = false; 11015 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11016 List<ResolveInfo> ris = null; 11017 try { 11018 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11019 intent, null, 0, userId); 11020 } catch (RemoteException e) { 11021 } 11022 if (ris != null) { 11023 for (int i=ris.size()-1; i>=0; i--) { 11024 if ((ris.get(i).activityInfo.applicationInfo.flags 11025 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11026 ris.remove(i); 11027 } 11028 } 11029 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11030 11031 // For User 0, load the version number. When delivering to a new user, deliver 11032 // to all receivers. 11033 if (userId == UserHandle.USER_OWNER) { 11034 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11035 for (int i=0; i<ris.size(); i++) { 11036 ActivityInfo ai = ris.get(i).activityInfo; 11037 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11038 if (lastDoneReceivers.contains(comp)) { 11039 // We already did the pre boot receiver for this app with the current 11040 // platform version, so don't do it again... 11041 ris.remove(i); 11042 i--; 11043 // ...however, do keep it as one that has been done, so we don't 11044 // forget about it when rewriting the file of last done receivers. 11045 doneReceivers.add(comp); 11046 } 11047 } 11048 } 11049 11050 // If primary user, send broadcast to all available users, else just to userId 11051 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11052 : new int[] { userId }; 11053 for (int i = 0; i < ris.size(); i++) { 11054 ActivityInfo ai = ris.get(i).activityInfo; 11055 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11056 doneReceivers.add(comp); 11057 intent.setComponent(comp); 11058 for (int j=0; j<users.length; j++) { 11059 IIntentReceiver finisher = null; 11060 // On last receiver and user, set up a completion callback 11061 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11062 finisher = new IIntentReceiver.Stub() { 11063 public void performReceive(Intent intent, int resultCode, 11064 String data, Bundle extras, boolean ordered, 11065 boolean sticky, int sendingUser) { 11066 // The raw IIntentReceiver interface is called 11067 // with the AM lock held, so redispatch to 11068 // execute our code without the lock. 11069 mHandler.post(onFinishCallback); 11070 } 11071 }; 11072 } 11073 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11074 + " for user " + users[j]); 11075 broadcastIntentLocked(null, null, intent, null, finisher, 11076 0, null, null, null, AppOpsManager.OP_NONE, 11077 true, false, MY_PID, Process.SYSTEM_UID, 11078 users[j]); 11079 if (finisher != null) { 11080 waitingUpdate = true; 11081 } 11082 } 11083 } 11084 } 11085 11086 return waitingUpdate; 11087 } 11088 11089 public void systemReady(final Runnable goingCallback) { 11090 synchronized(this) { 11091 if (mSystemReady) { 11092 // If we're done calling all the receivers, run the next "boot phase" passed in 11093 // by the SystemServer 11094 if (goingCallback != null) { 11095 goingCallback.run(); 11096 } 11097 return; 11098 } 11099 11100 // Make sure we have the current profile info, since it is needed for 11101 // security checks. 11102 updateCurrentProfileIdsLocked(); 11103 11104 if (mRecentTasks == null) { 11105 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11106 if (!mRecentTasks.isEmpty()) { 11107 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11108 } 11109 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11110 mTaskPersister.startPersisting(); 11111 } 11112 11113 // Check to see if there are any update receivers to run. 11114 if (!mDidUpdate) { 11115 if (mWaitingUpdate) { 11116 return; 11117 } 11118 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11119 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11120 public void run() { 11121 synchronized (ActivityManagerService.this) { 11122 mDidUpdate = true; 11123 } 11124 writeLastDonePreBootReceivers(doneReceivers); 11125 showBootMessage(mContext.getText( 11126 R.string.android_upgrading_complete), 11127 false); 11128 systemReady(goingCallback); 11129 } 11130 }, doneReceivers, UserHandle.USER_OWNER); 11131 11132 if (mWaitingUpdate) { 11133 return; 11134 } 11135 mDidUpdate = true; 11136 } 11137 11138 mAppOpsService.systemReady(); 11139 mSystemReady = true; 11140 } 11141 11142 ArrayList<ProcessRecord> procsToKill = null; 11143 synchronized(mPidsSelfLocked) { 11144 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11145 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11146 if (!isAllowedWhileBooting(proc.info)){ 11147 if (procsToKill == null) { 11148 procsToKill = new ArrayList<ProcessRecord>(); 11149 } 11150 procsToKill.add(proc); 11151 } 11152 } 11153 } 11154 11155 synchronized(this) { 11156 if (procsToKill != null) { 11157 for (int i=procsToKill.size()-1; i>=0; i--) { 11158 ProcessRecord proc = procsToKill.get(i); 11159 Slog.i(TAG, "Removing system update proc: " + proc); 11160 removeProcessLocked(proc, true, false, "system update done"); 11161 } 11162 } 11163 11164 // Now that we have cleaned up any update processes, we 11165 // are ready to start launching real processes and know that 11166 // we won't trample on them any more. 11167 mProcessesReady = true; 11168 } 11169 11170 Slog.i(TAG, "System now ready"); 11171 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11172 SystemClock.uptimeMillis()); 11173 11174 synchronized(this) { 11175 // Make sure we have no pre-ready processes sitting around. 11176 11177 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11178 ResolveInfo ri = mContext.getPackageManager() 11179 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11180 STOCK_PM_FLAGS); 11181 CharSequence errorMsg = null; 11182 if (ri != null) { 11183 ActivityInfo ai = ri.activityInfo; 11184 ApplicationInfo app = ai.applicationInfo; 11185 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11186 mTopAction = Intent.ACTION_FACTORY_TEST; 11187 mTopData = null; 11188 mTopComponent = new ComponentName(app.packageName, 11189 ai.name); 11190 } else { 11191 errorMsg = mContext.getResources().getText( 11192 com.android.internal.R.string.factorytest_not_system); 11193 } 11194 } else { 11195 errorMsg = mContext.getResources().getText( 11196 com.android.internal.R.string.factorytest_no_action); 11197 } 11198 if (errorMsg != null) { 11199 mTopAction = null; 11200 mTopData = null; 11201 mTopComponent = null; 11202 Message msg = Message.obtain(); 11203 msg.what = SHOW_FACTORY_ERROR_MSG; 11204 msg.getData().putCharSequence("msg", errorMsg); 11205 mHandler.sendMessage(msg); 11206 } 11207 } 11208 } 11209 11210 retrieveSettings(); 11211 loadResourcesOnSystemReady(); 11212 11213 synchronized (this) { 11214 readGrantedUriPermissionsLocked(); 11215 } 11216 11217 if (goingCallback != null) goingCallback.run(); 11218 11219 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11220 Integer.toString(mCurrentUserId), mCurrentUserId); 11221 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11222 Integer.toString(mCurrentUserId), mCurrentUserId); 11223 mSystemServiceManager.startUser(mCurrentUserId); 11224 11225 synchronized (this) { 11226 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11227 try { 11228 List apps = AppGlobals.getPackageManager(). 11229 getPersistentApplications(STOCK_PM_FLAGS); 11230 if (apps != null) { 11231 int N = apps.size(); 11232 int i; 11233 for (i=0; i<N; i++) { 11234 ApplicationInfo info 11235 = (ApplicationInfo)apps.get(i); 11236 if (info != null && 11237 !info.packageName.equals("android")) { 11238 addAppLocked(info, false, null /* ABI override */); 11239 } 11240 } 11241 } 11242 } catch (RemoteException ex) { 11243 // pm is in same process, this will never happen. 11244 } 11245 } 11246 11247 // Start up initial activity. 11248 mBooting = true; 11249 startHomeActivityLocked(mCurrentUserId); 11250 11251 try { 11252 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11253 Message msg = Message.obtain(); 11254 msg.what = SHOW_UID_ERROR_MSG; 11255 mHandler.sendMessage(msg); 11256 } 11257 } catch (RemoteException e) { 11258 } 11259 11260 long ident = Binder.clearCallingIdentity(); 11261 try { 11262 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11263 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11264 | Intent.FLAG_RECEIVER_FOREGROUND); 11265 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11266 broadcastIntentLocked(null, null, intent, 11267 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11268 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11269 intent = new Intent(Intent.ACTION_USER_STARTING); 11270 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11271 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11272 broadcastIntentLocked(null, null, intent, 11273 null, new IIntentReceiver.Stub() { 11274 @Override 11275 public void performReceive(Intent intent, int resultCode, String data, 11276 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11277 throws RemoteException { 11278 } 11279 }, 0, null, null, 11280 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11281 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11282 } catch (Throwable t) { 11283 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11284 } finally { 11285 Binder.restoreCallingIdentity(ident); 11286 } 11287 mStackSupervisor.resumeTopActivitiesLocked(); 11288 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11289 } 11290 } 11291 11292 private boolean makeAppCrashingLocked(ProcessRecord app, 11293 String shortMsg, String longMsg, String stackTrace) { 11294 app.crashing = true; 11295 app.crashingReport = generateProcessError(app, 11296 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11297 startAppProblemLocked(app); 11298 app.stopFreezingAllLocked(); 11299 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11300 } 11301 11302 private void makeAppNotRespondingLocked(ProcessRecord app, 11303 String activity, String shortMsg, String longMsg) { 11304 app.notResponding = true; 11305 app.notRespondingReport = generateProcessError(app, 11306 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11307 activity, shortMsg, longMsg, null); 11308 startAppProblemLocked(app); 11309 app.stopFreezingAllLocked(); 11310 } 11311 11312 /** 11313 * Generate a process error record, suitable for attachment to a ProcessRecord. 11314 * 11315 * @param app The ProcessRecord in which the error occurred. 11316 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11317 * ActivityManager.AppErrorStateInfo 11318 * @param activity The activity associated with the crash, if known. 11319 * @param shortMsg Short message describing the crash. 11320 * @param longMsg Long message describing the crash. 11321 * @param stackTrace Full crash stack trace, may be null. 11322 * 11323 * @return Returns a fully-formed AppErrorStateInfo record. 11324 */ 11325 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11326 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11327 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11328 11329 report.condition = condition; 11330 report.processName = app.processName; 11331 report.pid = app.pid; 11332 report.uid = app.info.uid; 11333 report.tag = activity; 11334 report.shortMsg = shortMsg; 11335 report.longMsg = longMsg; 11336 report.stackTrace = stackTrace; 11337 11338 return report; 11339 } 11340 11341 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11342 synchronized (this) { 11343 app.crashing = false; 11344 app.crashingReport = null; 11345 app.notResponding = false; 11346 app.notRespondingReport = null; 11347 if (app.anrDialog == fromDialog) { 11348 app.anrDialog = null; 11349 } 11350 if (app.waitDialog == fromDialog) { 11351 app.waitDialog = null; 11352 } 11353 if (app.pid > 0 && app.pid != MY_PID) { 11354 handleAppCrashLocked(app, null, null, null); 11355 app.kill("user request after error", true); 11356 } 11357 } 11358 } 11359 11360 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11361 String stackTrace) { 11362 long now = SystemClock.uptimeMillis(); 11363 11364 Long crashTime; 11365 if (!app.isolated) { 11366 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11367 } else { 11368 crashTime = null; 11369 } 11370 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11371 // This process loses! 11372 Slog.w(TAG, "Process " + app.info.processName 11373 + " has crashed too many times: killing!"); 11374 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11375 app.userId, app.info.processName, app.uid); 11376 mStackSupervisor.handleAppCrashLocked(app); 11377 if (!app.persistent) { 11378 // We don't want to start this process again until the user 11379 // explicitly does so... but for persistent process, we really 11380 // need to keep it running. If a persistent process is actually 11381 // repeatedly crashing, then badness for everyone. 11382 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11383 app.info.processName); 11384 if (!app.isolated) { 11385 // XXX We don't have a way to mark isolated processes 11386 // as bad, since they don't have a peristent identity. 11387 mBadProcesses.put(app.info.processName, app.uid, 11388 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11389 mProcessCrashTimes.remove(app.info.processName, app.uid); 11390 } 11391 app.bad = true; 11392 app.removed = true; 11393 // Don't let services in this process be restarted and potentially 11394 // annoy the user repeatedly. Unless it is persistent, since those 11395 // processes run critical code. 11396 removeProcessLocked(app, false, false, "crash"); 11397 mStackSupervisor.resumeTopActivitiesLocked(); 11398 return false; 11399 } 11400 mStackSupervisor.resumeTopActivitiesLocked(); 11401 } else { 11402 mStackSupervisor.finishTopRunningActivityLocked(app); 11403 } 11404 11405 // Bump up the crash count of any services currently running in the proc. 11406 for (int i=app.services.size()-1; i>=0; i--) { 11407 // Any services running in the application need to be placed 11408 // back in the pending list. 11409 ServiceRecord sr = app.services.valueAt(i); 11410 sr.crashCount++; 11411 } 11412 11413 // If the crashing process is what we consider to be the "home process" and it has been 11414 // replaced by a third-party app, clear the package preferred activities from packages 11415 // with a home activity running in the process to prevent a repeatedly crashing app 11416 // from blocking the user to manually clear the list. 11417 final ArrayList<ActivityRecord> activities = app.activities; 11418 if (app == mHomeProcess && activities.size() > 0 11419 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11420 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11421 final ActivityRecord r = activities.get(activityNdx); 11422 if (r.isHomeActivity()) { 11423 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11424 try { 11425 ActivityThread.getPackageManager() 11426 .clearPackagePreferredActivities(r.packageName); 11427 } catch (RemoteException c) { 11428 // pm is in same process, this will never happen. 11429 } 11430 } 11431 } 11432 } 11433 11434 if (!app.isolated) { 11435 // XXX Can't keep track of crash times for isolated processes, 11436 // because they don't have a perisistent identity. 11437 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11438 } 11439 11440 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11441 return true; 11442 } 11443 11444 void startAppProblemLocked(ProcessRecord app) { 11445 // If this app is not running under the current user, then we 11446 // can't give it a report button because that would require 11447 // launching the report UI under a different user. 11448 app.errorReportReceiver = null; 11449 11450 for (int userId : mCurrentProfileIds) { 11451 if (app.userId == userId) { 11452 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11453 mContext, app.info.packageName, app.info.flags); 11454 } 11455 } 11456 skipCurrentReceiverLocked(app); 11457 } 11458 11459 void skipCurrentReceiverLocked(ProcessRecord app) { 11460 for (BroadcastQueue queue : mBroadcastQueues) { 11461 queue.skipCurrentReceiverLocked(app); 11462 } 11463 } 11464 11465 /** 11466 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11467 * The application process will exit immediately after this call returns. 11468 * @param app object of the crashing app, null for the system server 11469 * @param crashInfo describing the exception 11470 */ 11471 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11472 ProcessRecord r = findAppProcess(app, "Crash"); 11473 final String processName = app == null ? "system_server" 11474 : (r == null ? "unknown" : r.processName); 11475 11476 handleApplicationCrashInner("crash", r, processName, crashInfo); 11477 } 11478 11479 /* Native crash reporting uses this inner version because it needs to be somewhat 11480 * decoupled from the AM-managed cleanup lifecycle 11481 */ 11482 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11483 ApplicationErrorReport.CrashInfo crashInfo) { 11484 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11485 UserHandle.getUserId(Binder.getCallingUid()), processName, 11486 r == null ? -1 : r.info.flags, 11487 crashInfo.exceptionClassName, 11488 crashInfo.exceptionMessage, 11489 crashInfo.throwFileName, 11490 crashInfo.throwLineNumber); 11491 11492 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11493 11494 crashApplication(r, crashInfo); 11495 } 11496 11497 public void handleApplicationStrictModeViolation( 11498 IBinder app, 11499 int violationMask, 11500 StrictMode.ViolationInfo info) { 11501 ProcessRecord r = findAppProcess(app, "StrictMode"); 11502 if (r == null) { 11503 return; 11504 } 11505 11506 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11507 Integer stackFingerprint = info.hashCode(); 11508 boolean logIt = true; 11509 synchronized (mAlreadyLoggedViolatedStacks) { 11510 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11511 logIt = false; 11512 // TODO: sub-sample into EventLog for these, with 11513 // the info.durationMillis? Then we'd get 11514 // the relative pain numbers, without logging all 11515 // the stack traces repeatedly. We'd want to do 11516 // likewise in the client code, which also does 11517 // dup suppression, before the Binder call. 11518 } else { 11519 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11520 mAlreadyLoggedViolatedStacks.clear(); 11521 } 11522 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11523 } 11524 } 11525 if (logIt) { 11526 logStrictModeViolationToDropBox(r, info); 11527 } 11528 } 11529 11530 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11531 AppErrorResult result = new AppErrorResult(); 11532 synchronized (this) { 11533 final long origId = Binder.clearCallingIdentity(); 11534 11535 Message msg = Message.obtain(); 11536 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11537 HashMap<String, Object> data = new HashMap<String, Object>(); 11538 data.put("result", result); 11539 data.put("app", r); 11540 data.put("violationMask", violationMask); 11541 data.put("info", info); 11542 msg.obj = data; 11543 mHandler.sendMessage(msg); 11544 11545 Binder.restoreCallingIdentity(origId); 11546 } 11547 int res = result.get(); 11548 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11549 } 11550 } 11551 11552 // Depending on the policy in effect, there could be a bunch of 11553 // these in quick succession so we try to batch these together to 11554 // minimize disk writes, number of dropbox entries, and maximize 11555 // compression, by having more fewer, larger records. 11556 private void logStrictModeViolationToDropBox( 11557 ProcessRecord process, 11558 StrictMode.ViolationInfo info) { 11559 if (info == null) { 11560 return; 11561 } 11562 final boolean isSystemApp = process == null || 11563 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11564 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11565 final String processName = process == null ? "unknown" : process.processName; 11566 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11567 final DropBoxManager dbox = (DropBoxManager) 11568 mContext.getSystemService(Context.DROPBOX_SERVICE); 11569 11570 // Exit early if the dropbox isn't configured to accept this report type. 11571 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11572 11573 boolean bufferWasEmpty; 11574 boolean needsFlush; 11575 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11576 synchronized (sb) { 11577 bufferWasEmpty = sb.length() == 0; 11578 appendDropBoxProcessHeaders(process, processName, sb); 11579 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11580 sb.append("System-App: ").append(isSystemApp).append("\n"); 11581 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11582 if (info.violationNumThisLoop != 0) { 11583 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11584 } 11585 if (info.numAnimationsRunning != 0) { 11586 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11587 } 11588 if (info.broadcastIntentAction != null) { 11589 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11590 } 11591 if (info.durationMillis != -1) { 11592 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11593 } 11594 if (info.numInstances != -1) { 11595 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11596 } 11597 if (info.tags != null) { 11598 for (String tag : info.tags) { 11599 sb.append("Span-Tag: ").append(tag).append("\n"); 11600 } 11601 } 11602 sb.append("\n"); 11603 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11604 sb.append(info.crashInfo.stackTrace); 11605 } 11606 sb.append("\n"); 11607 11608 // Only buffer up to ~64k. Various logging bits truncate 11609 // things at 128k. 11610 needsFlush = (sb.length() > 64 * 1024); 11611 } 11612 11613 // Flush immediately if the buffer's grown too large, or this 11614 // is a non-system app. Non-system apps are isolated with a 11615 // different tag & policy and not batched. 11616 // 11617 // Batching is useful during internal testing with 11618 // StrictMode settings turned up high. Without batching, 11619 // thousands of separate files could be created on boot. 11620 if (!isSystemApp || needsFlush) { 11621 new Thread("Error dump: " + dropboxTag) { 11622 @Override 11623 public void run() { 11624 String report; 11625 synchronized (sb) { 11626 report = sb.toString(); 11627 sb.delete(0, sb.length()); 11628 sb.trimToSize(); 11629 } 11630 if (report.length() != 0) { 11631 dbox.addText(dropboxTag, report); 11632 } 11633 } 11634 }.start(); 11635 return; 11636 } 11637 11638 // System app batching: 11639 if (!bufferWasEmpty) { 11640 // An existing dropbox-writing thread is outstanding, so 11641 // we don't need to start it up. The existing thread will 11642 // catch the buffer appends we just did. 11643 return; 11644 } 11645 11646 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11647 // (After this point, we shouldn't access AMS internal data structures.) 11648 new Thread("Error dump: " + dropboxTag) { 11649 @Override 11650 public void run() { 11651 // 5 second sleep to let stacks arrive and be batched together 11652 try { 11653 Thread.sleep(5000); // 5 seconds 11654 } catch (InterruptedException e) {} 11655 11656 String errorReport; 11657 synchronized (mStrictModeBuffer) { 11658 errorReport = mStrictModeBuffer.toString(); 11659 if (errorReport.length() == 0) { 11660 return; 11661 } 11662 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11663 mStrictModeBuffer.trimToSize(); 11664 } 11665 dbox.addText(dropboxTag, errorReport); 11666 } 11667 }.start(); 11668 } 11669 11670 /** 11671 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11672 * @param app object of the crashing app, null for the system server 11673 * @param tag reported by the caller 11674 * @param system whether this wtf is coming from the system 11675 * @param crashInfo describing the context of the error 11676 * @return true if the process should exit immediately (WTF is fatal) 11677 */ 11678 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11679 final ApplicationErrorReport.CrashInfo crashInfo) { 11680 final int callingUid = Binder.getCallingUid(); 11681 final int callingPid = Binder.getCallingPid(); 11682 11683 if (system) { 11684 // If this is coming from the system, we could very well have low-level 11685 // system locks held, so we want to do this all asynchronously. And we 11686 // never want this to become fatal, so there is that too. 11687 mHandler.post(new Runnable() { 11688 @Override public void run() { 11689 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11690 } 11691 }); 11692 return false; 11693 } 11694 11695 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11696 crashInfo); 11697 11698 if (r != null && r.pid != Process.myPid() && 11699 Settings.Global.getInt(mContext.getContentResolver(), 11700 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11701 crashApplication(r, crashInfo); 11702 return true; 11703 } else { 11704 return false; 11705 } 11706 } 11707 11708 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11709 final ApplicationErrorReport.CrashInfo crashInfo) { 11710 final ProcessRecord r = findAppProcess(app, "WTF"); 11711 final String processName = app == null ? "system_server" 11712 : (r == null ? "unknown" : r.processName); 11713 11714 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11715 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11716 11717 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11718 11719 return r; 11720 } 11721 11722 /** 11723 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11724 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11725 */ 11726 private ProcessRecord findAppProcess(IBinder app, String reason) { 11727 if (app == null) { 11728 return null; 11729 } 11730 11731 synchronized (this) { 11732 final int NP = mProcessNames.getMap().size(); 11733 for (int ip=0; ip<NP; ip++) { 11734 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11735 final int NA = apps.size(); 11736 for (int ia=0; ia<NA; ia++) { 11737 ProcessRecord p = apps.valueAt(ia); 11738 if (p.thread != null && p.thread.asBinder() == app) { 11739 return p; 11740 } 11741 } 11742 } 11743 11744 Slog.w(TAG, "Can't find mystery application for " + reason 11745 + " from pid=" + Binder.getCallingPid() 11746 + " uid=" + Binder.getCallingUid() + ": " + app); 11747 return null; 11748 } 11749 } 11750 11751 /** 11752 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11753 * to append various headers to the dropbox log text. 11754 */ 11755 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11756 StringBuilder sb) { 11757 // Watchdog thread ends up invoking this function (with 11758 // a null ProcessRecord) to add the stack file to dropbox. 11759 // Do not acquire a lock on this (am) in such cases, as it 11760 // could cause a potential deadlock, if and when watchdog 11761 // is invoked due to unavailability of lock on am and it 11762 // would prevent watchdog from killing system_server. 11763 if (process == null) { 11764 sb.append("Process: ").append(processName).append("\n"); 11765 return; 11766 } 11767 // Note: ProcessRecord 'process' is guarded by the service 11768 // instance. (notably process.pkgList, which could otherwise change 11769 // concurrently during execution of this method) 11770 synchronized (this) { 11771 sb.append("Process: ").append(processName).append("\n"); 11772 int flags = process.info.flags; 11773 IPackageManager pm = AppGlobals.getPackageManager(); 11774 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11775 for (int ip=0; ip<process.pkgList.size(); ip++) { 11776 String pkg = process.pkgList.keyAt(ip); 11777 sb.append("Package: ").append(pkg); 11778 try { 11779 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11780 if (pi != null) { 11781 sb.append(" v").append(pi.versionCode); 11782 if (pi.versionName != null) { 11783 sb.append(" (").append(pi.versionName).append(")"); 11784 } 11785 } 11786 } catch (RemoteException e) { 11787 Slog.e(TAG, "Error getting package info: " + pkg, e); 11788 } 11789 sb.append("\n"); 11790 } 11791 } 11792 } 11793 11794 private static String processClass(ProcessRecord process) { 11795 if (process == null || process.pid == MY_PID) { 11796 return "system_server"; 11797 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11798 return "system_app"; 11799 } else { 11800 return "data_app"; 11801 } 11802 } 11803 11804 /** 11805 * Write a description of an error (crash, WTF, ANR) to the drop box. 11806 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11807 * @param process which caused the error, null means the system server 11808 * @param activity which triggered the error, null if unknown 11809 * @param parent activity related to the error, null if unknown 11810 * @param subject line related to the error, null if absent 11811 * @param report in long form describing the error, null if absent 11812 * @param logFile to include in the report, null if none 11813 * @param crashInfo giving an application stack trace, null if absent 11814 */ 11815 public void addErrorToDropBox(String eventType, 11816 ProcessRecord process, String processName, ActivityRecord activity, 11817 ActivityRecord parent, String subject, 11818 final String report, final File logFile, 11819 final ApplicationErrorReport.CrashInfo crashInfo) { 11820 // NOTE -- this must never acquire the ActivityManagerService lock, 11821 // otherwise the watchdog may be prevented from resetting the system. 11822 11823 final String dropboxTag = processClass(process) + "_" + eventType; 11824 final DropBoxManager dbox = (DropBoxManager) 11825 mContext.getSystemService(Context.DROPBOX_SERVICE); 11826 11827 // Exit early if the dropbox isn't configured to accept this report type. 11828 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11829 11830 final StringBuilder sb = new StringBuilder(1024); 11831 appendDropBoxProcessHeaders(process, processName, sb); 11832 if (activity != null) { 11833 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11834 } 11835 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11836 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11837 } 11838 if (parent != null && parent != activity) { 11839 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11840 } 11841 if (subject != null) { 11842 sb.append("Subject: ").append(subject).append("\n"); 11843 } 11844 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11845 if (Debug.isDebuggerConnected()) { 11846 sb.append("Debugger: Connected\n"); 11847 } 11848 sb.append("\n"); 11849 11850 // Do the rest in a worker thread to avoid blocking the caller on I/O 11851 // (After this point, we shouldn't access AMS internal data structures.) 11852 Thread worker = new Thread("Error dump: " + dropboxTag) { 11853 @Override 11854 public void run() { 11855 if (report != null) { 11856 sb.append(report); 11857 } 11858 if (logFile != null) { 11859 try { 11860 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11861 "\n\n[[TRUNCATED]]")); 11862 } catch (IOException e) { 11863 Slog.e(TAG, "Error reading " + logFile, e); 11864 } 11865 } 11866 if (crashInfo != null && crashInfo.stackTrace != null) { 11867 sb.append(crashInfo.stackTrace); 11868 } 11869 11870 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11871 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11872 if (lines > 0) { 11873 sb.append("\n"); 11874 11875 // Merge several logcat streams, and take the last N lines 11876 InputStreamReader input = null; 11877 try { 11878 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11879 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11880 "-b", "crash", 11881 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11882 11883 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11884 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11885 input = new InputStreamReader(logcat.getInputStream()); 11886 11887 int num; 11888 char[] buf = new char[8192]; 11889 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11890 } catch (IOException e) { 11891 Slog.e(TAG, "Error running logcat", e); 11892 } finally { 11893 if (input != null) try { input.close(); } catch (IOException e) {} 11894 } 11895 } 11896 11897 dbox.addText(dropboxTag, sb.toString()); 11898 } 11899 }; 11900 11901 if (process == null) { 11902 // If process is null, we are being called from some internal code 11903 // and may be about to die -- run this synchronously. 11904 worker.run(); 11905 } else { 11906 worker.start(); 11907 } 11908 } 11909 11910 /** 11911 * Bring up the "unexpected error" dialog box for a crashing app. 11912 * Deal with edge cases (intercepts from instrumented applications, 11913 * ActivityController, error intent receivers, that sort of thing). 11914 * @param r the application crashing 11915 * @param crashInfo describing the failure 11916 */ 11917 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11918 long timeMillis = System.currentTimeMillis(); 11919 String shortMsg = crashInfo.exceptionClassName; 11920 String longMsg = crashInfo.exceptionMessage; 11921 String stackTrace = crashInfo.stackTrace; 11922 if (shortMsg != null && longMsg != null) { 11923 longMsg = shortMsg + ": " + longMsg; 11924 } else if (shortMsg != null) { 11925 longMsg = shortMsg; 11926 } 11927 11928 AppErrorResult result = new AppErrorResult(); 11929 synchronized (this) { 11930 if (mController != null) { 11931 try { 11932 String name = r != null ? r.processName : null; 11933 int pid = r != null ? r.pid : Binder.getCallingPid(); 11934 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11935 if (!mController.appCrashed(name, pid, 11936 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11937 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11938 && "Native crash".equals(crashInfo.exceptionClassName)) { 11939 Slog.w(TAG, "Skip killing native crashed app " + name 11940 + "(" + pid + ") during testing"); 11941 } else { 11942 Slog.w(TAG, "Force-killing crashed app " + name 11943 + " at watcher's request"); 11944 if (r != null) { 11945 r.kill("crash", true); 11946 } else { 11947 // Huh. 11948 Process.killProcess(pid); 11949 Process.killProcessGroup(uid, pid); 11950 } 11951 } 11952 return; 11953 } 11954 } catch (RemoteException e) { 11955 mController = null; 11956 Watchdog.getInstance().setActivityController(null); 11957 } 11958 } 11959 11960 final long origId = Binder.clearCallingIdentity(); 11961 11962 // If this process is running instrumentation, finish it. 11963 if (r != null && r.instrumentationClass != null) { 11964 Slog.w(TAG, "Error in app " + r.processName 11965 + " running instrumentation " + r.instrumentationClass + ":"); 11966 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11967 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11968 Bundle info = new Bundle(); 11969 info.putString("shortMsg", shortMsg); 11970 info.putString("longMsg", longMsg); 11971 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11972 Binder.restoreCallingIdentity(origId); 11973 return; 11974 } 11975 11976 // If we can't identify the process or it's already exceeded its crash quota, 11977 // quit right away without showing a crash dialog. 11978 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11979 Binder.restoreCallingIdentity(origId); 11980 return; 11981 } 11982 11983 Message msg = Message.obtain(); 11984 msg.what = SHOW_ERROR_MSG; 11985 HashMap data = new HashMap(); 11986 data.put("result", result); 11987 data.put("app", r); 11988 msg.obj = data; 11989 mHandler.sendMessage(msg); 11990 11991 Binder.restoreCallingIdentity(origId); 11992 } 11993 11994 int res = result.get(); 11995 11996 Intent appErrorIntent = null; 11997 synchronized (this) { 11998 if (r != null && !r.isolated) { 11999 // XXX Can't keep track of crash time for isolated processes, 12000 // since they don't have a persistent identity. 12001 mProcessCrashTimes.put(r.info.processName, r.uid, 12002 SystemClock.uptimeMillis()); 12003 } 12004 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12005 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12006 } 12007 } 12008 12009 if (appErrorIntent != null) { 12010 try { 12011 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12012 } catch (ActivityNotFoundException e) { 12013 Slog.w(TAG, "bug report receiver dissappeared", e); 12014 } 12015 } 12016 } 12017 12018 Intent createAppErrorIntentLocked(ProcessRecord r, 12019 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12020 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12021 if (report == null) { 12022 return null; 12023 } 12024 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12025 result.setComponent(r.errorReportReceiver); 12026 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12027 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12028 return result; 12029 } 12030 12031 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12032 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12033 if (r.errorReportReceiver == null) { 12034 return null; 12035 } 12036 12037 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12038 return null; 12039 } 12040 12041 ApplicationErrorReport report = new ApplicationErrorReport(); 12042 report.packageName = r.info.packageName; 12043 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12044 report.processName = r.processName; 12045 report.time = timeMillis; 12046 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12047 12048 if (r.crashing || r.forceCrashReport) { 12049 report.type = ApplicationErrorReport.TYPE_CRASH; 12050 report.crashInfo = crashInfo; 12051 } else if (r.notResponding) { 12052 report.type = ApplicationErrorReport.TYPE_ANR; 12053 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12054 12055 report.anrInfo.activity = r.notRespondingReport.tag; 12056 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12057 report.anrInfo.info = r.notRespondingReport.longMsg; 12058 } 12059 12060 return report; 12061 } 12062 12063 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12064 enforceNotIsolatedCaller("getProcessesInErrorState"); 12065 // assume our apps are happy - lazy create the list 12066 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12067 12068 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12069 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12070 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12071 12072 synchronized (this) { 12073 12074 // iterate across all processes 12075 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12076 ProcessRecord app = mLruProcesses.get(i); 12077 if (!allUsers && app.userId != userId) { 12078 continue; 12079 } 12080 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12081 // This one's in trouble, so we'll generate a report for it 12082 // crashes are higher priority (in case there's a crash *and* an anr) 12083 ActivityManager.ProcessErrorStateInfo report = null; 12084 if (app.crashing) { 12085 report = app.crashingReport; 12086 } else if (app.notResponding) { 12087 report = app.notRespondingReport; 12088 } 12089 12090 if (report != null) { 12091 if (errList == null) { 12092 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12093 } 12094 errList.add(report); 12095 } else { 12096 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12097 " crashing = " + app.crashing + 12098 " notResponding = " + app.notResponding); 12099 } 12100 } 12101 } 12102 } 12103 12104 return errList; 12105 } 12106 12107 static int procStateToImportance(int procState, int memAdj, 12108 ActivityManager.RunningAppProcessInfo currApp) { 12109 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12110 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12111 currApp.lru = memAdj; 12112 } else { 12113 currApp.lru = 0; 12114 } 12115 return imp; 12116 } 12117 12118 private void fillInProcMemInfo(ProcessRecord app, 12119 ActivityManager.RunningAppProcessInfo outInfo) { 12120 outInfo.pid = app.pid; 12121 outInfo.uid = app.info.uid; 12122 if (mHeavyWeightProcess == app) { 12123 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12124 } 12125 if (app.persistent) { 12126 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12127 } 12128 if (app.activities.size() > 0) { 12129 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12130 } 12131 outInfo.lastTrimLevel = app.trimMemoryLevel; 12132 int adj = app.curAdj; 12133 int procState = app.curProcState; 12134 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12135 outInfo.importanceReasonCode = app.adjTypeCode; 12136 outInfo.processState = app.curProcState; 12137 } 12138 12139 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12140 enforceNotIsolatedCaller("getRunningAppProcesses"); 12141 // Lazy instantiation of list 12142 List<ActivityManager.RunningAppProcessInfo> runList = null; 12143 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12144 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12145 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12146 synchronized (this) { 12147 // Iterate across all processes 12148 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12149 ProcessRecord app = mLruProcesses.get(i); 12150 if (!allUsers && app.userId != userId) { 12151 continue; 12152 } 12153 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12154 // Generate process state info for running application 12155 ActivityManager.RunningAppProcessInfo currApp = 12156 new ActivityManager.RunningAppProcessInfo(app.processName, 12157 app.pid, app.getPackageList()); 12158 fillInProcMemInfo(app, currApp); 12159 if (app.adjSource instanceof ProcessRecord) { 12160 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12161 currApp.importanceReasonImportance = 12162 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12163 app.adjSourceProcState); 12164 } else if (app.adjSource instanceof ActivityRecord) { 12165 ActivityRecord r = (ActivityRecord)app.adjSource; 12166 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12167 } 12168 if (app.adjTarget instanceof ComponentName) { 12169 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12170 } 12171 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12172 // + " lru=" + currApp.lru); 12173 if (runList == null) { 12174 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12175 } 12176 runList.add(currApp); 12177 } 12178 } 12179 } 12180 return runList; 12181 } 12182 12183 public List<ApplicationInfo> getRunningExternalApplications() { 12184 enforceNotIsolatedCaller("getRunningExternalApplications"); 12185 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12186 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12187 if (runningApps != null && runningApps.size() > 0) { 12188 Set<String> extList = new HashSet<String>(); 12189 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12190 if (app.pkgList != null) { 12191 for (String pkg : app.pkgList) { 12192 extList.add(pkg); 12193 } 12194 } 12195 } 12196 IPackageManager pm = AppGlobals.getPackageManager(); 12197 for (String pkg : extList) { 12198 try { 12199 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12200 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12201 retList.add(info); 12202 } 12203 } catch (RemoteException e) { 12204 } 12205 } 12206 } 12207 return retList; 12208 } 12209 12210 @Override 12211 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12212 enforceNotIsolatedCaller("getMyMemoryState"); 12213 synchronized (this) { 12214 ProcessRecord proc; 12215 synchronized (mPidsSelfLocked) { 12216 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12217 } 12218 fillInProcMemInfo(proc, outInfo); 12219 } 12220 } 12221 12222 @Override 12223 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12224 if (checkCallingPermission(android.Manifest.permission.DUMP) 12225 != PackageManager.PERMISSION_GRANTED) { 12226 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12227 + Binder.getCallingPid() 12228 + ", uid=" + Binder.getCallingUid() 12229 + " without permission " 12230 + android.Manifest.permission.DUMP); 12231 return; 12232 } 12233 12234 boolean dumpAll = false; 12235 boolean dumpClient = false; 12236 String dumpPackage = null; 12237 12238 int opti = 0; 12239 while (opti < args.length) { 12240 String opt = args[opti]; 12241 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12242 break; 12243 } 12244 opti++; 12245 if ("-a".equals(opt)) { 12246 dumpAll = true; 12247 } else if ("-c".equals(opt)) { 12248 dumpClient = true; 12249 } else if ("-h".equals(opt)) { 12250 pw.println("Activity manager dump options:"); 12251 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12252 pw.println(" cmd may be one of:"); 12253 pw.println(" a[ctivities]: activity stack state"); 12254 pw.println(" r[recents]: recent activities state"); 12255 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12256 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12257 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12258 pw.println(" o[om]: out of memory management"); 12259 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12260 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12261 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12262 pw.println(" service [COMP_SPEC]: service client-side state"); 12263 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12264 pw.println(" all: dump all activities"); 12265 pw.println(" top: dump the top activity"); 12266 pw.println(" write: write all pending state to storage"); 12267 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12268 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12269 pw.println(" a partial substring in a component name, a"); 12270 pw.println(" hex object identifier."); 12271 pw.println(" -a: include all available server state."); 12272 pw.println(" -c: include client state."); 12273 return; 12274 } else { 12275 pw.println("Unknown argument: " + opt + "; use -h for help"); 12276 } 12277 } 12278 12279 long origId = Binder.clearCallingIdentity(); 12280 boolean more = false; 12281 // Is the caller requesting to dump a particular piece of data? 12282 if (opti < args.length) { 12283 String cmd = args[opti]; 12284 opti++; 12285 if ("activities".equals(cmd) || "a".equals(cmd)) { 12286 synchronized (this) { 12287 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12288 } 12289 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12290 synchronized (this) { 12291 dumpRecentsLocked(fd, pw, args, opti, true, null); 12292 } 12293 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12294 String[] newArgs; 12295 String name; 12296 if (opti >= args.length) { 12297 name = null; 12298 newArgs = EMPTY_STRING_ARRAY; 12299 } else { 12300 name = args[opti]; 12301 opti++; 12302 newArgs = new String[args.length - opti]; 12303 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12304 args.length - opti); 12305 } 12306 synchronized (this) { 12307 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12308 } 12309 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12310 String[] newArgs; 12311 String name; 12312 if (opti >= args.length) { 12313 name = null; 12314 newArgs = EMPTY_STRING_ARRAY; 12315 } else { 12316 name = args[opti]; 12317 opti++; 12318 newArgs = new String[args.length - opti]; 12319 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12320 args.length - opti); 12321 } 12322 synchronized (this) { 12323 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12324 } 12325 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12326 String[] newArgs; 12327 String name; 12328 if (opti >= args.length) { 12329 name = null; 12330 newArgs = EMPTY_STRING_ARRAY; 12331 } else { 12332 name = args[opti]; 12333 opti++; 12334 newArgs = new String[args.length - opti]; 12335 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12336 args.length - opti); 12337 } 12338 synchronized (this) { 12339 dumpProcessesLocked(fd, pw, args, opti, true, name); 12340 } 12341 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12342 synchronized (this) { 12343 dumpOomLocked(fd, pw, args, opti, true); 12344 } 12345 } else if ("provider".equals(cmd)) { 12346 String[] newArgs; 12347 String name; 12348 if (opti >= args.length) { 12349 name = null; 12350 newArgs = EMPTY_STRING_ARRAY; 12351 } else { 12352 name = args[opti]; 12353 opti++; 12354 newArgs = new String[args.length - opti]; 12355 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12356 } 12357 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12358 pw.println("No providers match: " + name); 12359 pw.println("Use -h for help."); 12360 } 12361 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12362 synchronized (this) { 12363 dumpProvidersLocked(fd, pw, args, opti, true, null); 12364 } 12365 } else if ("service".equals(cmd)) { 12366 String[] newArgs; 12367 String name; 12368 if (opti >= args.length) { 12369 name = null; 12370 newArgs = EMPTY_STRING_ARRAY; 12371 } else { 12372 name = args[opti]; 12373 opti++; 12374 newArgs = new String[args.length - opti]; 12375 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12376 args.length - opti); 12377 } 12378 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12379 pw.println("No services match: " + name); 12380 pw.println("Use -h for help."); 12381 } 12382 } else if ("package".equals(cmd)) { 12383 String[] newArgs; 12384 if (opti >= args.length) { 12385 pw.println("package: no package name specified"); 12386 pw.println("Use -h for help."); 12387 } else { 12388 dumpPackage = args[opti]; 12389 opti++; 12390 newArgs = new String[args.length - opti]; 12391 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12392 args.length - opti); 12393 args = newArgs; 12394 opti = 0; 12395 more = true; 12396 } 12397 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12398 synchronized (this) { 12399 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12400 } 12401 } else if ("write".equals(cmd)) { 12402 mTaskPersister.flush(); 12403 pw.println("All tasks persisted."); 12404 return; 12405 } else { 12406 // Dumping a single activity? 12407 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12408 pw.println("Bad activity command, or no activities match: " + cmd); 12409 pw.println("Use -h for help."); 12410 } 12411 } 12412 if (!more) { 12413 Binder.restoreCallingIdentity(origId); 12414 return; 12415 } 12416 } 12417 12418 // No piece of data specified, dump everything. 12419 synchronized (this) { 12420 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12421 pw.println(); 12422 if (dumpAll) { 12423 pw.println("-------------------------------------------------------------------------------"); 12424 } 12425 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12426 pw.println(); 12427 if (dumpAll) { 12428 pw.println("-------------------------------------------------------------------------------"); 12429 } 12430 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12431 pw.println(); 12432 if (dumpAll) { 12433 pw.println("-------------------------------------------------------------------------------"); 12434 } 12435 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12436 pw.println(); 12437 if (dumpAll) { 12438 pw.println("-------------------------------------------------------------------------------"); 12439 } 12440 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12441 pw.println(); 12442 if (dumpAll) { 12443 pw.println("-------------------------------------------------------------------------------"); 12444 } 12445 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12446 pw.println(); 12447 if (dumpAll) { 12448 pw.println("-------------------------------------------------------------------------------"); 12449 } 12450 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12451 } 12452 Binder.restoreCallingIdentity(origId); 12453 } 12454 12455 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12456 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12457 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12458 12459 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12460 dumpPackage); 12461 boolean needSep = printedAnything; 12462 12463 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12464 dumpPackage, needSep, " mFocusedActivity: "); 12465 if (printed) { 12466 printedAnything = true; 12467 needSep = false; 12468 } 12469 12470 if (dumpPackage == null) { 12471 if (needSep) { 12472 pw.println(); 12473 } 12474 needSep = true; 12475 printedAnything = true; 12476 mStackSupervisor.dump(pw, " "); 12477 } 12478 12479 if (!printedAnything) { 12480 pw.println(" (nothing)"); 12481 } 12482 } 12483 12484 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12485 int opti, boolean dumpAll, String dumpPackage) { 12486 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12487 12488 boolean printedAnything = false; 12489 12490 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12491 boolean printedHeader = false; 12492 12493 final int N = mRecentTasks.size(); 12494 for (int i=0; i<N; i++) { 12495 TaskRecord tr = mRecentTasks.get(i); 12496 if (dumpPackage != null) { 12497 if (tr.realActivity == null || 12498 !dumpPackage.equals(tr.realActivity)) { 12499 continue; 12500 } 12501 } 12502 if (!printedHeader) { 12503 pw.println(" Recent tasks:"); 12504 printedHeader = true; 12505 printedAnything = true; 12506 } 12507 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12508 pw.println(tr); 12509 if (dumpAll) { 12510 mRecentTasks.get(i).dump(pw, " "); 12511 } 12512 } 12513 } 12514 12515 if (!printedAnything) { 12516 pw.println(" (nothing)"); 12517 } 12518 } 12519 12520 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12521 int opti, boolean dumpAll, String dumpPackage) { 12522 boolean needSep = false; 12523 boolean printedAnything = false; 12524 int numPers = 0; 12525 12526 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12527 12528 if (dumpAll) { 12529 final int NP = mProcessNames.getMap().size(); 12530 for (int ip=0; ip<NP; ip++) { 12531 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12532 final int NA = procs.size(); 12533 for (int ia=0; ia<NA; ia++) { 12534 ProcessRecord r = procs.valueAt(ia); 12535 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12536 continue; 12537 } 12538 if (!needSep) { 12539 pw.println(" All known processes:"); 12540 needSep = true; 12541 printedAnything = true; 12542 } 12543 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12544 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12545 pw.print(" "); pw.println(r); 12546 r.dump(pw, " "); 12547 if (r.persistent) { 12548 numPers++; 12549 } 12550 } 12551 } 12552 } 12553 12554 if (mIsolatedProcesses.size() > 0) { 12555 boolean printed = false; 12556 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12557 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12558 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12559 continue; 12560 } 12561 if (!printed) { 12562 if (needSep) { 12563 pw.println(); 12564 } 12565 pw.println(" Isolated process list (sorted by uid):"); 12566 printedAnything = true; 12567 printed = true; 12568 needSep = true; 12569 } 12570 pw.println(String.format("%sIsolated #%2d: %s", 12571 " ", i, r.toString())); 12572 } 12573 } 12574 12575 if (mLruProcesses.size() > 0) { 12576 if (needSep) { 12577 pw.println(); 12578 } 12579 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12580 pw.print(" total, non-act at "); 12581 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12582 pw.print(", non-svc at "); 12583 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12584 pw.println("):"); 12585 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12586 needSep = true; 12587 printedAnything = true; 12588 } 12589 12590 if (dumpAll || dumpPackage != null) { 12591 synchronized (mPidsSelfLocked) { 12592 boolean printed = false; 12593 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12594 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12595 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12596 continue; 12597 } 12598 if (!printed) { 12599 if (needSep) pw.println(); 12600 needSep = true; 12601 pw.println(" PID mappings:"); 12602 printed = true; 12603 printedAnything = true; 12604 } 12605 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12606 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12607 } 12608 } 12609 } 12610 12611 if (mForegroundProcesses.size() > 0) { 12612 synchronized (mPidsSelfLocked) { 12613 boolean printed = false; 12614 for (int i=0; i<mForegroundProcesses.size(); i++) { 12615 ProcessRecord r = mPidsSelfLocked.get( 12616 mForegroundProcesses.valueAt(i).pid); 12617 if (dumpPackage != null && (r == null 12618 || !r.pkgList.containsKey(dumpPackage))) { 12619 continue; 12620 } 12621 if (!printed) { 12622 if (needSep) pw.println(); 12623 needSep = true; 12624 pw.println(" Foreground Processes:"); 12625 printed = true; 12626 printedAnything = true; 12627 } 12628 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12629 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12630 } 12631 } 12632 } 12633 12634 if (mPersistentStartingProcesses.size() > 0) { 12635 if (needSep) pw.println(); 12636 needSep = true; 12637 printedAnything = true; 12638 pw.println(" Persisent processes that are starting:"); 12639 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12640 "Starting Norm", "Restarting PERS", dumpPackage); 12641 } 12642 12643 if (mRemovedProcesses.size() > 0) { 12644 if (needSep) pw.println(); 12645 needSep = true; 12646 printedAnything = true; 12647 pw.println(" Processes that are being removed:"); 12648 dumpProcessList(pw, this, mRemovedProcesses, " ", 12649 "Removed Norm", "Removed PERS", dumpPackage); 12650 } 12651 12652 if (mProcessesOnHold.size() > 0) { 12653 if (needSep) pw.println(); 12654 needSep = true; 12655 printedAnything = true; 12656 pw.println(" Processes that are on old until the system is ready:"); 12657 dumpProcessList(pw, this, mProcessesOnHold, " ", 12658 "OnHold Norm", "OnHold PERS", dumpPackage); 12659 } 12660 12661 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12662 12663 if (mProcessCrashTimes.getMap().size() > 0) { 12664 boolean printed = false; 12665 long now = SystemClock.uptimeMillis(); 12666 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12667 final int NP = pmap.size(); 12668 for (int ip=0; ip<NP; ip++) { 12669 String pname = pmap.keyAt(ip); 12670 SparseArray<Long> uids = pmap.valueAt(ip); 12671 final int N = uids.size(); 12672 for (int i=0; i<N; i++) { 12673 int puid = uids.keyAt(i); 12674 ProcessRecord r = mProcessNames.get(pname, puid); 12675 if (dumpPackage != null && (r == null 12676 || !r.pkgList.containsKey(dumpPackage))) { 12677 continue; 12678 } 12679 if (!printed) { 12680 if (needSep) pw.println(); 12681 needSep = true; 12682 pw.println(" Time since processes crashed:"); 12683 printed = true; 12684 printedAnything = true; 12685 } 12686 pw.print(" Process "); pw.print(pname); 12687 pw.print(" uid "); pw.print(puid); 12688 pw.print(": last crashed "); 12689 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12690 pw.println(" ago"); 12691 } 12692 } 12693 } 12694 12695 if (mBadProcesses.getMap().size() > 0) { 12696 boolean printed = false; 12697 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12698 final int NP = pmap.size(); 12699 for (int ip=0; ip<NP; ip++) { 12700 String pname = pmap.keyAt(ip); 12701 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12702 final int N = uids.size(); 12703 for (int i=0; i<N; i++) { 12704 int puid = uids.keyAt(i); 12705 ProcessRecord r = mProcessNames.get(pname, puid); 12706 if (dumpPackage != null && (r == null 12707 || !r.pkgList.containsKey(dumpPackage))) { 12708 continue; 12709 } 12710 if (!printed) { 12711 if (needSep) pw.println(); 12712 needSep = true; 12713 pw.println(" Bad processes:"); 12714 printedAnything = true; 12715 } 12716 BadProcessInfo info = uids.valueAt(i); 12717 pw.print(" Bad process "); pw.print(pname); 12718 pw.print(" uid "); pw.print(puid); 12719 pw.print(": crashed at time "); pw.println(info.time); 12720 if (info.shortMsg != null) { 12721 pw.print(" Short msg: "); pw.println(info.shortMsg); 12722 } 12723 if (info.longMsg != null) { 12724 pw.print(" Long msg: "); pw.println(info.longMsg); 12725 } 12726 if (info.stack != null) { 12727 pw.println(" Stack:"); 12728 int lastPos = 0; 12729 for (int pos=0; pos<info.stack.length(); pos++) { 12730 if (info.stack.charAt(pos) == '\n') { 12731 pw.print(" "); 12732 pw.write(info.stack, lastPos, pos-lastPos); 12733 pw.println(); 12734 lastPos = pos+1; 12735 } 12736 } 12737 if (lastPos < info.stack.length()) { 12738 pw.print(" "); 12739 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12740 pw.println(); 12741 } 12742 } 12743 } 12744 } 12745 } 12746 12747 if (dumpPackage == null) { 12748 pw.println(); 12749 needSep = false; 12750 pw.println(" mStartedUsers:"); 12751 for (int i=0; i<mStartedUsers.size(); i++) { 12752 UserStartedState uss = mStartedUsers.valueAt(i); 12753 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12754 pw.print(": "); uss.dump("", pw); 12755 } 12756 pw.print(" mStartedUserArray: ["); 12757 for (int i=0; i<mStartedUserArray.length; i++) { 12758 if (i > 0) pw.print(", "); 12759 pw.print(mStartedUserArray[i]); 12760 } 12761 pw.println("]"); 12762 pw.print(" mUserLru: ["); 12763 for (int i=0; i<mUserLru.size(); i++) { 12764 if (i > 0) pw.print(", "); 12765 pw.print(mUserLru.get(i)); 12766 } 12767 pw.println("]"); 12768 if (dumpAll) { 12769 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12770 } 12771 synchronized (mUserProfileGroupIdsSelfLocked) { 12772 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12773 pw.println(" mUserProfileGroupIds:"); 12774 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12775 pw.print(" User #"); 12776 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12777 pw.print(" -> profile #"); 12778 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12779 } 12780 } 12781 } 12782 } 12783 if (mHomeProcess != null && (dumpPackage == null 12784 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12785 if (needSep) { 12786 pw.println(); 12787 needSep = false; 12788 } 12789 pw.println(" mHomeProcess: " + mHomeProcess); 12790 } 12791 if (mPreviousProcess != null && (dumpPackage == null 12792 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12793 if (needSep) { 12794 pw.println(); 12795 needSep = false; 12796 } 12797 pw.println(" mPreviousProcess: " + mPreviousProcess); 12798 } 12799 if (dumpAll) { 12800 StringBuilder sb = new StringBuilder(128); 12801 sb.append(" mPreviousProcessVisibleTime: "); 12802 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12803 pw.println(sb); 12804 } 12805 if (mHeavyWeightProcess != null && (dumpPackage == null 12806 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12807 if (needSep) { 12808 pw.println(); 12809 needSep = false; 12810 } 12811 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12812 } 12813 if (dumpPackage == null) { 12814 pw.println(" mConfiguration: " + mConfiguration); 12815 } 12816 if (dumpAll) { 12817 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12818 if (mCompatModePackages.getPackages().size() > 0) { 12819 boolean printed = false; 12820 for (Map.Entry<String, Integer> entry 12821 : mCompatModePackages.getPackages().entrySet()) { 12822 String pkg = entry.getKey(); 12823 int mode = entry.getValue(); 12824 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12825 continue; 12826 } 12827 if (!printed) { 12828 pw.println(" mScreenCompatPackages:"); 12829 printed = true; 12830 } 12831 pw.print(" "); pw.print(pkg); pw.print(": "); 12832 pw.print(mode); pw.println(); 12833 } 12834 } 12835 } 12836 if (dumpPackage == null) { 12837 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12838 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12839 + " mLockScreenShown " + lockScreenShownToString()); 12840 } 12841 if (mShuttingDown || mRunningVoice) { 12842 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12843 } 12844 } 12845 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12846 || mOrigWaitForDebugger) { 12847 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12848 || dumpPackage.equals(mOrigDebugApp)) { 12849 if (needSep) { 12850 pw.println(); 12851 needSep = false; 12852 } 12853 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12854 + " mDebugTransient=" + mDebugTransient 12855 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12856 } 12857 } 12858 if (mOpenGlTraceApp != null) { 12859 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12860 if (needSep) { 12861 pw.println(); 12862 needSep = false; 12863 } 12864 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12865 } 12866 } 12867 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12868 || mProfileFd != null) { 12869 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12870 if (needSep) { 12871 pw.println(); 12872 needSep = false; 12873 } 12874 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12875 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12876 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12877 + mAutoStopProfiler); 12878 pw.println(" mProfileType=" + mProfileType); 12879 } 12880 } 12881 if (dumpPackage == null) { 12882 if (mAlwaysFinishActivities || mController != null) { 12883 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12884 + " mController=" + mController); 12885 } 12886 if (dumpAll) { 12887 pw.println(" Total persistent processes: " + numPers); 12888 pw.println(" mProcessesReady=" + mProcessesReady 12889 + " mSystemReady=" + mSystemReady 12890 + " mBooted=" + mBooted 12891 + " mFactoryTest=" + mFactoryTest); 12892 pw.println(" mBooting=" + mBooting 12893 + " mCallFinishBooting=" + mCallFinishBooting 12894 + " mBootAnimationComplete=" + mBootAnimationComplete); 12895 pw.print(" mLastPowerCheckRealtime="); 12896 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12897 pw.println(""); 12898 pw.print(" mLastPowerCheckUptime="); 12899 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12900 pw.println(""); 12901 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12902 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12903 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12904 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12905 + " (" + mLruProcesses.size() + " total)" 12906 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12907 + " mNumServiceProcs=" + mNumServiceProcs 12908 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12909 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12910 + " mLastMemoryLevel" + mLastMemoryLevel 12911 + " mLastNumProcesses" + mLastNumProcesses); 12912 long now = SystemClock.uptimeMillis(); 12913 pw.print(" mLastIdleTime="); 12914 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12915 pw.print(" mLowRamSinceLastIdle="); 12916 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12917 pw.println(); 12918 } 12919 } 12920 12921 if (!printedAnything) { 12922 pw.println(" (nothing)"); 12923 } 12924 } 12925 12926 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12927 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12928 if (mProcessesToGc.size() > 0) { 12929 boolean printed = false; 12930 long now = SystemClock.uptimeMillis(); 12931 for (int i=0; i<mProcessesToGc.size(); i++) { 12932 ProcessRecord proc = mProcessesToGc.get(i); 12933 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12934 continue; 12935 } 12936 if (!printed) { 12937 if (needSep) pw.println(); 12938 needSep = true; 12939 pw.println(" Processes that are waiting to GC:"); 12940 printed = true; 12941 } 12942 pw.print(" Process "); pw.println(proc); 12943 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12944 pw.print(", last gced="); 12945 pw.print(now-proc.lastRequestedGc); 12946 pw.print(" ms ago, last lowMem="); 12947 pw.print(now-proc.lastLowMemory); 12948 pw.println(" ms ago"); 12949 12950 } 12951 } 12952 return needSep; 12953 } 12954 12955 void printOomLevel(PrintWriter pw, String name, int adj) { 12956 pw.print(" "); 12957 if (adj >= 0) { 12958 pw.print(' '); 12959 if (adj < 10) pw.print(' '); 12960 } else { 12961 if (adj > -10) pw.print(' '); 12962 } 12963 pw.print(adj); 12964 pw.print(": "); 12965 pw.print(name); 12966 pw.print(" ("); 12967 pw.print(mProcessList.getMemLevel(adj)/1024); 12968 pw.println(" kB)"); 12969 } 12970 12971 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12972 int opti, boolean dumpAll) { 12973 boolean needSep = false; 12974 12975 if (mLruProcesses.size() > 0) { 12976 if (needSep) pw.println(); 12977 needSep = true; 12978 pw.println(" OOM levels:"); 12979 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12980 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12981 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12982 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12983 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12984 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12985 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12986 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12987 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12988 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12989 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12990 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12991 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12992 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12993 12994 if (needSep) pw.println(); 12995 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12996 pw.print(" total, non-act at "); 12997 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12998 pw.print(", non-svc at "); 12999 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13000 pw.println("):"); 13001 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13002 needSep = true; 13003 } 13004 13005 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13006 13007 pw.println(); 13008 pw.println(" mHomeProcess: " + mHomeProcess); 13009 pw.println(" mPreviousProcess: " + mPreviousProcess); 13010 if (mHeavyWeightProcess != null) { 13011 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13012 } 13013 13014 return true; 13015 } 13016 13017 /** 13018 * There are three ways to call this: 13019 * - no provider specified: dump all the providers 13020 * - a flattened component name that matched an existing provider was specified as the 13021 * first arg: dump that one provider 13022 * - the first arg isn't the flattened component name of an existing provider: 13023 * dump all providers whose component contains the first arg as a substring 13024 */ 13025 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13026 int opti, boolean dumpAll) { 13027 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13028 } 13029 13030 static class ItemMatcher { 13031 ArrayList<ComponentName> components; 13032 ArrayList<String> strings; 13033 ArrayList<Integer> objects; 13034 boolean all; 13035 13036 ItemMatcher() { 13037 all = true; 13038 } 13039 13040 void build(String name) { 13041 ComponentName componentName = ComponentName.unflattenFromString(name); 13042 if (componentName != null) { 13043 if (components == null) { 13044 components = new ArrayList<ComponentName>(); 13045 } 13046 components.add(componentName); 13047 all = false; 13048 } else { 13049 int objectId = 0; 13050 // Not a '/' separated full component name; maybe an object ID? 13051 try { 13052 objectId = Integer.parseInt(name, 16); 13053 if (objects == null) { 13054 objects = new ArrayList<Integer>(); 13055 } 13056 objects.add(objectId); 13057 all = false; 13058 } catch (RuntimeException e) { 13059 // Not an integer; just do string match. 13060 if (strings == null) { 13061 strings = new ArrayList<String>(); 13062 } 13063 strings.add(name); 13064 all = false; 13065 } 13066 } 13067 } 13068 13069 int build(String[] args, int opti) { 13070 for (; opti<args.length; opti++) { 13071 String name = args[opti]; 13072 if ("--".equals(name)) { 13073 return opti+1; 13074 } 13075 build(name); 13076 } 13077 return opti; 13078 } 13079 13080 boolean match(Object object, ComponentName comp) { 13081 if (all) { 13082 return true; 13083 } 13084 if (components != null) { 13085 for (int i=0; i<components.size(); i++) { 13086 if (components.get(i).equals(comp)) { 13087 return true; 13088 } 13089 } 13090 } 13091 if (objects != null) { 13092 for (int i=0; i<objects.size(); i++) { 13093 if (System.identityHashCode(object) == objects.get(i)) { 13094 return true; 13095 } 13096 } 13097 } 13098 if (strings != null) { 13099 String flat = comp.flattenToString(); 13100 for (int i=0; i<strings.size(); i++) { 13101 if (flat.contains(strings.get(i))) { 13102 return true; 13103 } 13104 } 13105 } 13106 return false; 13107 } 13108 } 13109 13110 /** 13111 * There are three things that cmd can be: 13112 * - a flattened component name that matches an existing activity 13113 * - the cmd arg isn't the flattened component name of an existing activity: 13114 * dump all activity whose component contains the cmd as a substring 13115 * - A hex number of the ActivityRecord object instance. 13116 */ 13117 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13118 int opti, boolean dumpAll) { 13119 ArrayList<ActivityRecord> activities; 13120 13121 synchronized (this) { 13122 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13123 } 13124 13125 if (activities.size() <= 0) { 13126 return false; 13127 } 13128 13129 String[] newArgs = new String[args.length - opti]; 13130 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13131 13132 TaskRecord lastTask = null; 13133 boolean needSep = false; 13134 for (int i=activities.size()-1; i>=0; i--) { 13135 ActivityRecord r = activities.get(i); 13136 if (needSep) { 13137 pw.println(); 13138 } 13139 needSep = true; 13140 synchronized (this) { 13141 if (lastTask != r.task) { 13142 lastTask = r.task; 13143 pw.print("TASK "); pw.print(lastTask.affinity); 13144 pw.print(" id="); pw.println(lastTask.taskId); 13145 if (dumpAll) { 13146 lastTask.dump(pw, " "); 13147 } 13148 } 13149 } 13150 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13151 } 13152 return true; 13153 } 13154 13155 /** 13156 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13157 * there is a thread associated with the activity. 13158 */ 13159 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13160 final ActivityRecord r, String[] args, boolean dumpAll) { 13161 String innerPrefix = prefix + " "; 13162 synchronized (this) { 13163 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13164 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13165 pw.print(" pid="); 13166 if (r.app != null) pw.println(r.app.pid); 13167 else pw.println("(not running)"); 13168 if (dumpAll) { 13169 r.dump(pw, innerPrefix); 13170 } 13171 } 13172 if (r.app != null && r.app.thread != null) { 13173 // flush anything that is already in the PrintWriter since the thread is going 13174 // to write to the file descriptor directly 13175 pw.flush(); 13176 try { 13177 TransferPipe tp = new TransferPipe(); 13178 try { 13179 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13180 r.appToken, innerPrefix, args); 13181 tp.go(fd); 13182 } finally { 13183 tp.kill(); 13184 } 13185 } catch (IOException e) { 13186 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13187 } catch (RemoteException e) { 13188 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13189 } 13190 } 13191 } 13192 13193 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13194 int opti, boolean dumpAll, String dumpPackage) { 13195 boolean needSep = false; 13196 boolean onlyHistory = false; 13197 boolean printedAnything = false; 13198 13199 if ("history".equals(dumpPackage)) { 13200 if (opti < args.length && "-s".equals(args[opti])) { 13201 dumpAll = false; 13202 } 13203 onlyHistory = true; 13204 dumpPackage = null; 13205 } 13206 13207 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13208 if (!onlyHistory && dumpAll) { 13209 if (mRegisteredReceivers.size() > 0) { 13210 boolean printed = false; 13211 Iterator it = mRegisteredReceivers.values().iterator(); 13212 while (it.hasNext()) { 13213 ReceiverList r = (ReceiverList)it.next(); 13214 if (dumpPackage != null && (r.app == null || 13215 !dumpPackage.equals(r.app.info.packageName))) { 13216 continue; 13217 } 13218 if (!printed) { 13219 pw.println(" Registered Receivers:"); 13220 needSep = true; 13221 printed = true; 13222 printedAnything = true; 13223 } 13224 pw.print(" * "); pw.println(r); 13225 r.dump(pw, " "); 13226 } 13227 } 13228 13229 if (mReceiverResolver.dump(pw, needSep ? 13230 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13231 " ", dumpPackage, false)) { 13232 needSep = true; 13233 printedAnything = true; 13234 } 13235 } 13236 13237 for (BroadcastQueue q : mBroadcastQueues) { 13238 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13239 printedAnything |= needSep; 13240 } 13241 13242 needSep = true; 13243 13244 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13245 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13246 if (needSep) { 13247 pw.println(); 13248 } 13249 needSep = true; 13250 printedAnything = true; 13251 pw.print(" Sticky broadcasts for user "); 13252 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13253 StringBuilder sb = new StringBuilder(128); 13254 for (Map.Entry<String, ArrayList<Intent>> ent 13255 : mStickyBroadcasts.valueAt(user).entrySet()) { 13256 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13257 if (dumpAll) { 13258 pw.println(":"); 13259 ArrayList<Intent> intents = ent.getValue(); 13260 final int N = intents.size(); 13261 for (int i=0; i<N; i++) { 13262 sb.setLength(0); 13263 sb.append(" Intent: "); 13264 intents.get(i).toShortString(sb, false, true, false, false); 13265 pw.println(sb.toString()); 13266 Bundle bundle = intents.get(i).getExtras(); 13267 if (bundle != null) { 13268 pw.print(" "); 13269 pw.println(bundle.toString()); 13270 } 13271 } 13272 } else { 13273 pw.println(""); 13274 } 13275 } 13276 } 13277 } 13278 13279 if (!onlyHistory && dumpAll) { 13280 pw.println(); 13281 for (BroadcastQueue queue : mBroadcastQueues) { 13282 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13283 + queue.mBroadcastsScheduled); 13284 } 13285 pw.println(" mHandler:"); 13286 mHandler.dump(new PrintWriterPrinter(pw), " "); 13287 needSep = true; 13288 printedAnything = true; 13289 } 13290 13291 if (!printedAnything) { 13292 pw.println(" (nothing)"); 13293 } 13294 } 13295 13296 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13297 int opti, boolean dumpAll, String dumpPackage) { 13298 boolean needSep; 13299 boolean printedAnything = false; 13300 13301 ItemMatcher matcher = new ItemMatcher(); 13302 matcher.build(args, opti); 13303 13304 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13305 13306 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13307 printedAnything |= needSep; 13308 13309 if (mLaunchingProviders.size() > 0) { 13310 boolean printed = false; 13311 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13312 ContentProviderRecord r = mLaunchingProviders.get(i); 13313 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13314 continue; 13315 } 13316 if (!printed) { 13317 if (needSep) pw.println(); 13318 needSep = true; 13319 pw.println(" Launching content providers:"); 13320 printed = true; 13321 printedAnything = true; 13322 } 13323 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13324 pw.println(r); 13325 } 13326 } 13327 13328 if (mGrantedUriPermissions.size() > 0) { 13329 boolean printed = false; 13330 int dumpUid = -2; 13331 if (dumpPackage != null) { 13332 try { 13333 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13334 } catch (NameNotFoundException e) { 13335 dumpUid = -1; 13336 } 13337 } 13338 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13339 int uid = mGrantedUriPermissions.keyAt(i); 13340 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13341 continue; 13342 } 13343 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13344 if (!printed) { 13345 if (needSep) pw.println(); 13346 needSep = true; 13347 pw.println(" Granted Uri Permissions:"); 13348 printed = true; 13349 printedAnything = true; 13350 } 13351 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13352 for (UriPermission perm : perms.values()) { 13353 pw.print(" "); pw.println(perm); 13354 if (dumpAll) { 13355 perm.dump(pw, " "); 13356 } 13357 } 13358 } 13359 } 13360 13361 if (!printedAnything) { 13362 pw.println(" (nothing)"); 13363 } 13364 } 13365 13366 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13367 int opti, boolean dumpAll, String dumpPackage) { 13368 boolean printed = false; 13369 13370 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13371 13372 if (mIntentSenderRecords.size() > 0) { 13373 Iterator<WeakReference<PendingIntentRecord>> it 13374 = mIntentSenderRecords.values().iterator(); 13375 while (it.hasNext()) { 13376 WeakReference<PendingIntentRecord> ref = it.next(); 13377 PendingIntentRecord rec = ref != null ? ref.get(): null; 13378 if (dumpPackage != null && (rec == null 13379 || !dumpPackage.equals(rec.key.packageName))) { 13380 continue; 13381 } 13382 printed = true; 13383 if (rec != null) { 13384 pw.print(" * "); pw.println(rec); 13385 if (dumpAll) { 13386 rec.dump(pw, " "); 13387 } 13388 } else { 13389 pw.print(" * "); pw.println(ref); 13390 } 13391 } 13392 } 13393 13394 if (!printed) { 13395 pw.println(" (nothing)"); 13396 } 13397 } 13398 13399 private static final int dumpProcessList(PrintWriter pw, 13400 ActivityManagerService service, List list, 13401 String prefix, String normalLabel, String persistentLabel, 13402 String dumpPackage) { 13403 int numPers = 0; 13404 final int N = list.size()-1; 13405 for (int i=N; i>=0; i--) { 13406 ProcessRecord r = (ProcessRecord)list.get(i); 13407 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13408 continue; 13409 } 13410 pw.println(String.format("%s%s #%2d: %s", 13411 prefix, (r.persistent ? persistentLabel : normalLabel), 13412 i, r.toString())); 13413 if (r.persistent) { 13414 numPers++; 13415 } 13416 } 13417 return numPers; 13418 } 13419 13420 private static final boolean dumpProcessOomList(PrintWriter pw, 13421 ActivityManagerService service, List<ProcessRecord> origList, 13422 String prefix, String normalLabel, String persistentLabel, 13423 boolean inclDetails, String dumpPackage) { 13424 13425 ArrayList<Pair<ProcessRecord, Integer>> list 13426 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13427 for (int i=0; i<origList.size(); i++) { 13428 ProcessRecord r = origList.get(i); 13429 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13430 continue; 13431 } 13432 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13433 } 13434 13435 if (list.size() <= 0) { 13436 return false; 13437 } 13438 13439 Comparator<Pair<ProcessRecord, Integer>> comparator 13440 = new Comparator<Pair<ProcessRecord, Integer>>() { 13441 @Override 13442 public int compare(Pair<ProcessRecord, Integer> object1, 13443 Pair<ProcessRecord, Integer> object2) { 13444 if (object1.first.setAdj != object2.first.setAdj) { 13445 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13446 } 13447 if (object1.second.intValue() != object2.second.intValue()) { 13448 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13449 } 13450 return 0; 13451 } 13452 }; 13453 13454 Collections.sort(list, comparator); 13455 13456 final long curRealtime = SystemClock.elapsedRealtime(); 13457 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13458 final long curUptime = SystemClock.uptimeMillis(); 13459 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13460 13461 for (int i=list.size()-1; i>=0; i--) { 13462 ProcessRecord r = list.get(i).first; 13463 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13464 char schedGroup; 13465 switch (r.setSchedGroup) { 13466 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13467 schedGroup = 'B'; 13468 break; 13469 case Process.THREAD_GROUP_DEFAULT: 13470 schedGroup = 'F'; 13471 break; 13472 default: 13473 schedGroup = '?'; 13474 break; 13475 } 13476 char foreground; 13477 if (r.foregroundActivities) { 13478 foreground = 'A'; 13479 } else if (r.foregroundServices) { 13480 foreground = 'S'; 13481 } else { 13482 foreground = ' '; 13483 } 13484 String procState = ProcessList.makeProcStateString(r.curProcState); 13485 pw.print(prefix); 13486 pw.print(r.persistent ? persistentLabel : normalLabel); 13487 pw.print(" #"); 13488 int num = (origList.size()-1)-list.get(i).second; 13489 if (num < 10) pw.print(' '); 13490 pw.print(num); 13491 pw.print(": "); 13492 pw.print(oomAdj); 13493 pw.print(' '); 13494 pw.print(schedGroup); 13495 pw.print('/'); 13496 pw.print(foreground); 13497 pw.print('/'); 13498 pw.print(procState); 13499 pw.print(" trm:"); 13500 if (r.trimMemoryLevel < 10) pw.print(' '); 13501 pw.print(r.trimMemoryLevel); 13502 pw.print(' '); 13503 pw.print(r.toShortString()); 13504 pw.print(" ("); 13505 pw.print(r.adjType); 13506 pw.println(')'); 13507 if (r.adjSource != null || r.adjTarget != null) { 13508 pw.print(prefix); 13509 pw.print(" "); 13510 if (r.adjTarget instanceof ComponentName) { 13511 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13512 } else if (r.adjTarget != null) { 13513 pw.print(r.adjTarget.toString()); 13514 } else { 13515 pw.print("{null}"); 13516 } 13517 pw.print("<="); 13518 if (r.adjSource instanceof ProcessRecord) { 13519 pw.print("Proc{"); 13520 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13521 pw.println("}"); 13522 } else if (r.adjSource != null) { 13523 pw.println(r.adjSource.toString()); 13524 } else { 13525 pw.println("{null}"); 13526 } 13527 } 13528 if (inclDetails) { 13529 pw.print(prefix); 13530 pw.print(" "); 13531 pw.print("oom: max="); pw.print(r.maxAdj); 13532 pw.print(" curRaw="); pw.print(r.curRawAdj); 13533 pw.print(" setRaw="); pw.print(r.setRawAdj); 13534 pw.print(" cur="); pw.print(r.curAdj); 13535 pw.print(" set="); pw.println(r.setAdj); 13536 pw.print(prefix); 13537 pw.print(" "); 13538 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13539 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13540 pw.print(" lastPss="); pw.print(r.lastPss); 13541 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13542 pw.print(prefix); 13543 pw.print(" "); 13544 pw.print("cached="); pw.print(r.cached); 13545 pw.print(" empty="); pw.print(r.empty); 13546 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13547 13548 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13549 if (r.lastWakeTime != 0) { 13550 long wtime; 13551 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13552 synchronized (stats) { 13553 wtime = stats.getProcessWakeTime(r.info.uid, 13554 r.pid, curRealtime); 13555 } 13556 long timeUsed = wtime - r.lastWakeTime; 13557 pw.print(prefix); 13558 pw.print(" "); 13559 pw.print("keep awake over "); 13560 TimeUtils.formatDuration(realtimeSince, pw); 13561 pw.print(" used "); 13562 TimeUtils.formatDuration(timeUsed, pw); 13563 pw.print(" ("); 13564 pw.print((timeUsed*100)/realtimeSince); 13565 pw.println("%)"); 13566 } 13567 if (r.lastCpuTime != 0) { 13568 long timeUsed = r.curCpuTime - r.lastCpuTime; 13569 pw.print(prefix); 13570 pw.print(" "); 13571 pw.print("run cpu over "); 13572 TimeUtils.formatDuration(uptimeSince, pw); 13573 pw.print(" used "); 13574 TimeUtils.formatDuration(timeUsed, pw); 13575 pw.print(" ("); 13576 pw.print((timeUsed*100)/uptimeSince); 13577 pw.println("%)"); 13578 } 13579 } 13580 } 13581 } 13582 return true; 13583 } 13584 13585 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13586 String[] args) { 13587 ArrayList<ProcessRecord> procs; 13588 synchronized (this) { 13589 if (args != null && args.length > start 13590 && args[start].charAt(0) != '-') { 13591 procs = new ArrayList<ProcessRecord>(); 13592 int pid = -1; 13593 try { 13594 pid = Integer.parseInt(args[start]); 13595 } catch (NumberFormatException e) { 13596 } 13597 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13598 ProcessRecord proc = mLruProcesses.get(i); 13599 if (proc.pid == pid) { 13600 procs.add(proc); 13601 } else if (allPkgs && proc.pkgList != null 13602 && proc.pkgList.containsKey(args[start])) { 13603 procs.add(proc); 13604 } else if (proc.processName.equals(args[start])) { 13605 procs.add(proc); 13606 } 13607 } 13608 if (procs.size() <= 0) { 13609 return null; 13610 } 13611 } else { 13612 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13613 } 13614 } 13615 return procs; 13616 } 13617 13618 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13619 PrintWriter pw, String[] args) { 13620 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13621 if (procs == null) { 13622 pw.println("No process found for: " + args[0]); 13623 return; 13624 } 13625 13626 long uptime = SystemClock.uptimeMillis(); 13627 long realtime = SystemClock.elapsedRealtime(); 13628 pw.println("Applications Graphics Acceleration Info:"); 13629 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13630 13631 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13632 ProcessRecord r = procs.get(i); 13633 if (r.thread != null) { 13634 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13635 pw.flush(); 13636 try { 13637 TransferPipe tp = new TransferPipe(); 13638 try { 13639 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13640 tp.go(fd); 13641 } finally { 13642 tp.kill(); 13643 } 13644 } catch (IOException e) { 13645 pw.println("Failure while dumping the app: " + r); 13646 pw.flush(); 13647 } catch (RemoteException e) { 13648 pw.println("Got a RemoteException while dumping the app " + r); 13649 pw.flush(); 13650 } 13651 } 13652 } 13653 } 13654 13655 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13656 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13657 if (procs == null) { 13658 pw.println("No process found for: " + args[0]); 13659 return; 13660 } 13661 13662 pw.println("Applications Database Info:"); 13663 13664 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13665 ProcessRecord r = procs.get(i); 13666 if (r.thread != null) { 13667 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13668 pw.flush(); 13669 try { 13670 TransferPipe tp = new TransferPipe(); 13671 try { 13672 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13673 tp.go(fd); 13674 } finally { 13675 tp.kill(); 13676 } 13677 } catch (IOException e) { 13678 pw.println("Failure while dumping the app: " + r); 13679 pw.flush(); 13680 } catch (RemoteException e) { 13681 pw.println("Got a RemoteException while dumping the app " + r); 13682 pw.flush(); 13683 } 13684 } 13685 } 13686 } 13687 13688 final static class MemItem { 13689 final boolean isProc; 13690 final String label; 13691 final String shortLabel; 13692 final long pss; 13693 final int id; 13694 final boolean hasActivities; 13695 ArrayList<MemItem> subitems; 13696 13697 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13698 boolean _hasActivities) { 13699 isProc = true; 13700 label = _label; 13701 shortLabel = _shortLabel; 13702 pss = _pss; 13703 id = _id; 13704 hasActivities = _hasActivities; 13705 } 13706 13707 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13708 isProc = false; 13709 label = _label; 13710 shortLabel = _shortLabel; 13711 pss = _pss; 13712 id = _id; 13713 hasActivities = false; 13714 } 13715 } 13716 13717 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13718 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13719 if (sort && !isCompact) { 13720 Collections.sort(items, new Comparator<MemItem>() { 13721 @Override 13722 public int compare(MemItem lhs, MemItem rhs) { 13723 if (lhs.pss < rhs.pss) { 13724 return 1; 13725 } else if (lhs.pss > rhs.pss) { 13726 return -1; 13727 } 13728 return 0; 13729 } 13730 }); 13731 } 13732 13733 for (int i=0; i<items.size(); i++) { 13734 MemItem mi = items.get(i); 13735 if (!isCompact) { 13736 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13737 } else if (mi.isProc) { 13738 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13739 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13740 pw.println(mi.hasActivities ? ",a" : ",e"); 13741 } else { 13742 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13743 pw.println(mi.pss); 13744 } 13745 if (mi.subitems != null) { 13746 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13747 true, isCompact); 13748 } 13749 } 13750 } 13751 13752 // These are in KB. 13753 static final long[] DUMP_MEM_BUCKETS = new long[] { 13754 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13755 120*1024, 160*1024, 200*1024, 13756 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13757 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13758 }; 13759 13760 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13761 boolean stackLike) { 13762 int start = label.lastIndexOf('.'); 13763 if (start >= 0) start++; 13764 else start = 0; 13765 int end = label.length(); 13766 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13767 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13768 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13769 out.append(bucket); 13770 out.append(stackLike ? "MB." : "MB "); 13771 out.append(label, start, end); 13772 return; 13773 } 13774 } 13775 out.append(memKB/1024); 13776 out.append(stackLike ? "MB." : "MB "); 13777 out.append(label, start, end); 13778 } 13779 13780 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13781 ProcessList.NATIVE_ADJ, 13782 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13783 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13784 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13785 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13786 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13787 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13788 }; 13789 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13790 "Native", 13791 "System", "Persistent", "Persistent Service", "Foreground", 13792 "Visible", "Perceptible", 13793 "Heavy Weight", "Backup", 13794 "A Services", "Home", 13795 "Previous", "B Services", "Cached" 13796 }; 13797 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13798 "native", 13799 "sys", "pers", "persvc", "fore", 13800 "vis", "percept", 13801 "heavy", "backup", 13802 "servicea", "home", 13803 "prev", "serviceb", "cached" 13804 }; 13805 13806 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13807 long realtime, boolean isCheckinRequest, boolean isCompact) { 13808 if (isCheckinRequest || isCompact) { 13809 // short checkin version 13810 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13811 } else { 13812 pw.println("Applications Memory Usage (kB):"); 13813 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13814 } 13815 } 13816 13817 private static final int KSM_SHARED = 0; 13818 private static final int KSM_SHARING = 1; 13819 private static final int KSM_UNSHARED = 2; 13820 private static final int KSM_VOLATILE = 3; 13821 13822 private final long[] getKsmInfo() { 13823 long[] longOut = new long[4]; 13824 final int[] SINGLE_LONG_FORMAT = new int[] { 13825 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13826 }; 13827 long[] longTmp = new long[1]; 13828 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13829 SINGLE_LONG_FORMAT, null, longTmp, null); 13830 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13831 longTmp[0] = 0; 13832 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13833 SINGLE_LONG_FORMAT, null, longTmp, null); 13834 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13835 longTmp[0] = 0; 13836 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13837 SINGLE_LONG_FORMAT, null, longTmp, null); 13838 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13839 longTmp[0] = 0; 13840 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13841 SINGLE_LONG_FORMAT, null, longTmp, null); 13842 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13843 return longOut; 13844 } 13845 13846 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13847 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13848 boolean dumpDetails = false; 13849 boolean dumpFullDetails = false; 13850 boolean dumpDalvik = false; 13851 boolean oomOnly = false; 13852 boolean isCompact = false; 13853 boolean localOnly = false; 13854 boolean packages = false; 13855 13856 int opti = 0; 13857 while (opti < args.length) { 13858 String opt = args[opti]; 13859 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13860 break; 13861 } 13862 opti++; 13863 if ("-a".equals(opt)) { 13864 dumpDetails = true; 13865 dumpFullDetails = true; 13866 dumpDalvik = true; 13867 } else if ("-d".equals(opt)) { 13868 dumpDalvik = true; 13869 } else if ("-c".equals(opt)) { 13870 isCompact = true; 13871 } else if ("--oom".equals(opt)) { 13872 oomOnly = true; 13873 } else if ("--local".equals(opt)) { 13874 localOnly = true; 13875 } else if ("--package".equals(opt)) { 13876 packages = true; 13877 } else if ("-h".equals(opt)) { 13878 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13879 pw.println(" -a: include all available information for each process."); 13880 pw.println(" -d: include dalvik details when dumping process details."); 13881 pw.println(" -c: dump in a compact machine-parseable representation."); 13882 pw.println(" --oom: only show processes organized by oom adj."); 13883 pw.println(" --local: only collect details locally, don't call process."); 13884 pw.println(" --package: interpret process arg as package, dumping all"); 13885 pw.println(" processes that have loaded that package."); 13886 pw.println("If [process] is specified it can be the name or "); 13887 pw.println("pid of a specific process to dump."); 13888 return; 13889 } else { 13890 pw.println("Unknown argument: " + opt + "; use -h for help"); 13891 } 13892 } 13893 13894 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13895 long uptime = SystemClock.uptimeMillis(); 13896 long realtime = SystemClock.elapsedRealtime(); 13897 final long[] tmpLong = new long[1]; 13898 13899 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13900 if (procs == null) { 13901 // No Java processes. Maybe they want to print a native process. 13902 if (args != null && args.length > opti 13903 && args[opti].charAt(0) != '-') { 13904 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13905 = new ArrayList<ProcessCpuTracker.Stats>(); 13906 updateCpuStatsNow(); 13907 int findPid = -1; 13908 try { 13909 findPid = Integer.parseInt(args[opti]); 13910 } catch (NumberFormatException e) { 13911 } 13912 synchronized (mProcessCpuTracker) { 13913 final int N = mProcessCpuTracker.countStats(); 13914 for (int i=0; i<N; i++) { 13915 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13916 if (st.pid == findPid || (st.baseName != null 13917 && st.baseName.equals(args[opti]))) { 13918 nativeProcs.add(st); 13919 } 13920 } 13921 } 13922 if (nativeProcs.size() > 0) { 13923 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13924 isCompact); 13925 Debug.MemoryInfo mi = null; 13926 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13927 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13928 final int pid = r.pid; 13929 if (!isCheckinRequest && dumpDetails) { 13930 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13931 } 13932 if (mi == null) { 13933 mi = new Debug.MemoryInfo(); 13934 } 13935 if (dumpDetails || (!brief && !oomOnly)) { 13936 Debug.getMemoryInfo(pid, mi); 13937 } else { 13938 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13939 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13940 } 13941 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13942 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13943 if (isCheckinRequest) { 13944 pw.println(); 13945 } 13946 } 13947 return; 13948 } 13949 } 13950 pw.println("No process found for: " + args[opti]); 13951 return; 13952 } 13953 13954 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13955 dumpDetails = true; 13956 } 13957 13958 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13959 13960 String[] innerArgs = new String[args.length-opti]; 13961 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13962 13963 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13964 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13965 long nativePss=0, dalvikPss=0, otherPss=0; 13966 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13967 13968 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13969 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13970 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13971 13972 long totalPss = 0; 13973 long cachedPss = 0; 13974 13975 Debug.MemoryInfo mi = null; 13976 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13977 final ProcessRecord r = procs.get(i); 13978 final IApplicationThread thread; 13979 final int pid; 13980 final int oomAdj; 13981 final boolean hasActivities; 13982 synchronized (this) { 13983 thread = r.thread; 13984 pid = r.pid; 13985 oomAdj = r.getSetAdjWithServices(); 13986 hasActivities = r.activities.size() > 0; 13987 } 13988 if (thread != null) { 13989 if (!isCheckinRequest && dumpDetails) { 13990 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13991 } 13992 if (mi == null) { 13993 mi = new Debug.MemoryInfo(); 13994 } 13995 if (dumpDetails || (!brief && !oomOnly)) { 13996 Debug.getMemoryInfo(pid, mi); 13997 } else { 13998 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13999 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14000 } 14001 if (dumpDetails) { 14002 if (localOnly) { 14003 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14004 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14005 if (isCheckinRequest) { 14006 pw.println(); 14007 } 14008 } else { 14009 try { 14010 pw.flush(); 14011 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14012 dumpDalvik, innerArgs); 14013 } catch (RemoteException e) { 14014 if (!isCheckinRequest) { 14015 pw.println("Got RemoteException!"); 14016 pw.flush(); 14017 } 14018 } 14019 } 14020 } 14021 14022 final long myTotalPss = mi.getTotalPss(); 14023 final long myTotalUss = mi.getTotalUss(); 14024 14025 synchronized (this) { 14026 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14027 // Record this for posterity if the process has been stable. 14028 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14029 } 14030 } 14031 14032 if (!isCheckinRequest && mi != null) { 14033 totalPss += myTotalPss; 14034 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14035 (hasActivities ? " / activities)" : ")"), 14036 r.processName, myTotalPss, pid, hasActivities); 14037 procMems.add(pssItem); 14038 procMemsMap.put(pid, pssItem); 14039 14040 nativePss += mi.nativePss; 14041 dalvikPss += mi.dalvikPss; 14042 otherPss += mi.otherPss; 14043 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14044 long mem = mi.getOtherPss(j); 14045 miscPss[j] += mem; 14046 otherPss -= mem; 14047 } 14048 14049 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14050 cachedPss += myTotalPss; 14051 } 14052 14053 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14054 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14055 || oomIndex == (oomPss.length-1)) { 14056 oomPss[oomIndex] += myTotalPss; 14057 if (oomProcs[oomIndex] == null) { 14058 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14059 } 14060 oomProcs[oomIndex].add(pssItem); 14061 break; 14062 } 14063 } 14064 } 14065 } 14066 } 14067 14068 long nativeProcTotalPss = 0; 14069 14070 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14071 // If we are showing aggregations, also look for native processes to 14072 // include so that our aggregations are more accurate. 14073 updateCpuStatsNow(); 14074 synchronized (mProcessCpuTracker) { 14075 final int N = mProcessCpuTracker.countStats(); 14076 for (int i=0; i<N; i++) { 14077 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14078 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14079 if (mi == null) { 14080 mi = new Debug.MemoryInfo(); 14081 } 14082 if (!brief && !oomOnly) { 14083 Debug.getMemoryInfo(st.pid, mi); 14084 } else { 14085 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14086 mi.nativePrivateDirty = (int)tmpLong[0]; 14087 } 14088 14089 final long myTotalPss = mi.getTotalPss(); 14090 totalPss += myTotalPss; 14091 nativeProcTotalPss += myTotalPss; 14092 14093 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14094 st.name, myTotalPss, st.pid, false); 14095 procMems.add(pssItem); 14096 14097 nativePss += mi.nativePss; 14098 dalvikPss += mi.dalvikPss; 14099 otherPss += mi.otherPss; 14100 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14101 long mem = mi.getOtherPss(j); 14102 miscPss[j] += mem; 14103 otherPss -= mem; 14104 } 14105 oomPss[0] += myTotalPss; 14106 if (oomProcs[0] == null) { 14107 oomProcs[0] = new ArrayList<MemItem>(); 14108 } 14109 oomProcs[0].add(pssItem); 14110 } 14111 } 14112 } 14113 14114 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14115 14116 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14117 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14118 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14119 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14120 String label = Debug.MemoryInfo.getOtherLabel(j); 14121 catMems.add(new MemItem(label, label, miscPss[j], j)); 14122 } 14123 14124 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14125 for (int j=0; j<oomPss.length; j++) { 14126 if (oomPss[j] != 0) { 14127 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14128 : DUMP_MEM_OOM_LABEL[j]; 14129 MemItem item = new MemItem(label, label, oomPss[j], 14130 DUMP_MEM_OOM_ADJ[j]); 14131 item.subitems = oomProcs[j]; 14132 oomMems.add(item); 14133 } 14134 } 14135 14136 if (!brief && !oomOnly && !isCompact) { 14137 pw.println(); 14138 pw.println("Total PSS by process:"); 14139 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14140 pw.println(); 14141 } 14142 if (!isCompact) { 14143 pw.println("Total PSS by OOM adjustment:"); 14144 } 14145 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14146 if (!brief && !oomOnly) { 14147 PrintWriter out = categoryPw != null ? categoryPw : pw; 14148 if (!isCompact) { 14149 out.println(); 14150 out.println("Total PSS by category:"); 14151 } 14152 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14153 } 14154 if (!isCompact) { 14155 pw.println(); 14156 } 14157 MemInfoReader memInfo = new MemInfoReader(); 14158 memInfo.readMemInfo(); 14159 if (nativeProcTotalPss > 0) { 14160 synchronized (this) { 14161 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14162 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14163 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14164 } 14165 } 14166 if (!brief) { 14167 if (!isCompact) { 14168 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14169 pw.print(" kB (status "); 14170 switch (mLastMemoryLevel) { 14171 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14172 pw.println("normal)"); 14173 break; 14174 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14175 pw.println("moderate)"); 14176 break; 14177 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14178 pw.println("low)"); 14179 break; 14180 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14181 pw.println("critical)"); 14182 break; 14183 default: 14184 pw.print(mLastMemoryLevel); 14185 pw.println(")"); 14186 break; 14187 } 14188 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14189 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14190 pw.print(cachedPss); pw.print(" cached pss + "); 14191 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14192 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14193 } else { 14194 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14195 pw.print(cachedPss + memInfo.getCachedSizeKb() 14196 + memInfo.getFreeSizeKb()); pw.print(","); 14197 pw.println(totalPss - cachedPss); 14198 } 14199 } 14200 if (!isCompact) { 14201 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14202 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14203 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14204 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14205 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14206 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14207 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14208 } 14209 if (!brief) { 14210 if (memInfo.getZramTotalSizeKb() != 0) { 14211 if (!isCompact) { 14212 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14213 pw.print(" kB physical used for "); 14214 pw.print(memInfo.getSwapTotalSizeKb() 14215 - memInfo.getSwapFreeSizeKb()); 14216 pw.print(" kB in swap ("); 14217 pw.print(memInfo.getSwapTotalSizeKb()); 14218 pw.println(" kB total swap)"); 14219 } else { 14220 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14221 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14222 pw.println(memInfo.getSwapFreeSizeKb()); 14223 } 14224 } 14225 final long[] ksm = getKsmInfo(); 14226 if (!isCompact) { 14227 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14228 || ksm[KSM_VOLATILE] != 0) { 14229 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14230 pw.print(" kB saved from shared "); 14231 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14232 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14233 pw.print(" kB unshared; "); 14234 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14235 } 14236 pw.print(" Tuning: "); 14237 pw.print(ActivityManager.staticGetMemoryClass()); 14238 pw.print(" (large "); 14239 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14240 pw.print("), oom "); 14241 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14242 pw.print(" kB"); 14243 pw.print(", restore limit "); 14244 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14245 pw.print(" kB"); 14246 if (ActivityManager.isLowRamDeviceStatic()) { 14247 pw.print(" (low-ram)"); 14248 } 14249 if (ActivityManager.isHighEndGfx()) { 14250 pw.print(" (high-end-gfx)"); 14251 } 14252 pw.println(); 14253 } else { 14254 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14255 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14256 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14257 pw.print("tuning,"); 14258 pw.print(ActivityManager.staticGetMemoryClass()); 14259 pw.print(','); 14260 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14261 pw.print(','); 14262 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14263 if (ActivityManager.isLowRamDeviceStatic()) { 14264 pw.print(",low-ram"); 14265 } 14266 if (ActivityManager.isHighEndGfx()) { 14267 pw.print(",high-end-gfx"); 14268 } 14269 pw.println(); 14270 } 14271 } 14272 } 14273 } 14274 14275 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14276 String name) { 14277 sb.append(" "); 14278 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14279 sb.append(' '); 14280 sb.append(ProcessList.makeProcStateString(procState)); 14281 sb.append(' '); 14282 ProcessList.appendRamKb(sb, pss); 14283 sb.append(" kB: "); 14284 sb.append(name); 14285 } 14286 14287 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14288 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14289 sb.append(" ("); 14290 sb.append(mi.pid); 14291 sb.append(") "); 14292 sb.append(mi.adjType); 14293 sb.append('\n'); 14294 if (mi.adjReason != null) { 14295 sb.append(" "); 14296 sb.append(mi.adjReason); 14297 sb.append('\n'); 14298 } 14299 } 14300 14301 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14302 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14303 for (int i=0, N=memInfos.size(); i<N; i++) { 14304 ProcessMemInfo mi = memInfos.get(i); 14305 infoMap.put(mi.pid, mi); 14306 } 14307 updateCpuStatsNow(); 14308 synchronized (mProcessCpuTracker) { 14309 final int N = mProcessCpuTracker.countStats(); 14310 for (int i=0; i<N; i++) { 14311 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14312 if (st.vsize > 0) { 14313 long pss = Debug.getPss(st.pid, null); 14314 if (pss > 0) { 14315 if (infoMap.indexOfKey(st.pid) < 0) { 14316 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14317 ProcessList.NATIVE_ADJ, -1, "native", null); 14318 mi.pss = pss; 14319 memInfos.add(mi); 14320 } 14321 } 14322 } 14323 } 14324 } 14325 14326 long totalPss = 0; 14327 for (int i=0, N=memInfos.size(); i<N; i++) { 14328 ProcessMemInfo mi = memInfos.get(i); 14329 if (mi.pss == 0) { 14330 mi.pss = Debug.getPss(mi.pid, null); 14331 } 14332 totalPss += mi.pss; 14333 } 14334 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14335 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14336 if (lhs.oomAdj != rhs.oomAdj) { 14337 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14338 } 14339 if (lhs.pss != rhs.pss) { 14340 return lhs.pss < rhs.pss ? 1 : -1; 14341 } 14342 return 0; 14343 } 14344 }); 14345 14346 StringBuilder tag = new StringBuilder(128); 14347 StringBuilder stack = new StringBuilder(128); 14348 tag.append("Low on memory -- "); 14349 appendMemBucket(tag, totalPss, "total", false); 14350 appendMemBucket(stack, totalPss, "total", true); 14351 14352 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14353 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14354 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14355 14356 boolean firstLine = true; 14357 int lastOomAdj = Integer.MIN_VALUE; 14358 long extraNativeRam = 0; 14359 long cachedPss = 0; 14360 for (int i=0, N=memInfos.size(); i<N; i++) { 14361 ProcessMemInfo mi = memInfos.get(i); 14362 14363 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14364 cachedPss += mi.pss; 14365 } 14366 14367 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14368 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14369 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14370 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14371 if (lastOomAdj != mi.oomAdj) { 14372 lastOomAdj = mi.oomAdj; 14373 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14374 tag.append(" / "); 14375 } 14376 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14377 if (firstLine) { 14378 stack.append(":"); 14379 firstLine = false; 14380 } 14381 stack.append("\n\t at "); 14382 } else { 14383 stack.append("$"); 14384 } 14385 } else { 14386 tag.append(" "); 14387 stack.append("$"); 14388 } 14389 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14390 appendMemBucket(tag, mi.pss, mi.name, false); 14391 } 14392 appendMemBucket(stack, mi.pss, mi.name, true); 14393 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14394 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14395 stack.append("("); 14396 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14397 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14398 stack.append(DUMP_MEM_OOM_LABEL[k]); 14399 stack.append(":"); 14400 stack.append(DUMP_MEM_OOM_ADJ[k]); 14401 } 14402 } 14403 stack.append(")"); 14404 } 14405 } 14406 14407 appendMemInfo(fullNativeBuilder, mi); 14408 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14409 // The short form only has native processes that are >= 1MB. 14410 if (mi.pss >= 1000) { 14411 appendMemInfo(shortNativeBuilder, mi); 14412 } else { 14413 extraNativeRam += mi.pss; 14414 } 14415 } else { 14416 // Short form has all other details, but if we have collected RAM 14417 // from smaller native processes let's dump a summary of that. 14418 if (extraNativeRam > 0) { 14419 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14420 -1, extraNativeRam, "(Other native)"); 14421 shortNativeBuilder.append('\n'); 14422 extraNativeRam = 0; 14423 } 14424 appendMemInfo(fullJavaBuilder, mi); 14425 } 14426 } 14427 14428 fullJavaBuilder.append(" "); 14429 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14430 fullJavaBuilder.append(" kB: TOTAL\n"); 14431 14432 MemInfoReader memInfo = new MemInfoReader(); 14433 memInfo.readMemInfo(); 14434 final long[] infos = memInfo.getRawInfo(); 14435 14436 StringBuilder memInfoBuilder = new StringBuilder(1024); 14437 Debug.getMemInfo(infos); 14438 memInfoBuilder.append(" MemInfo: "); 14439 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14440 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14441 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14442 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14443 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14444 memInfoBuilder.append(" "); 14445 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14446 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14447 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14448 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14449 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14450 memInfoBuilder.append(" ZRAM: "); 14451 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14452 memInfoBuilder.append(" kB RAM, "); 14453 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14454 memInfoBuilder.append(" kB swap total, "); 14455 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14456 memInfoBuilder.append(" kB swap free\n"); 14457 } 14458 final long[] ksm = getKsmInfo(); 14459 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14460 || ksm[KSM_VOLATILE] != 0) { 14461 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14462 memInfoBuilder.append(" kB saved from shared "); 14463 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14464 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14465 memInfoBuilder.append(" kB unshared; "); 14466 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14467 } 14468 memInfoBuilder.append(" Free RAM: "); 14469 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14470 + memInfo.getFreeSizeKb()); 14471 memInfoBuilder.append(" kB\n"); 14472 memInfoBuilder.append(" Used RAM: "); 14473 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14474 memInfoBuilder.append(" kB\n"); 14475 memInfoBuilder.append(" Lost RAM: "); 14476 memInfoBuilder.append(memInfo.getTotalSizeKb() 14477 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14478 - memInfo.getKernelUsedSizeKb()); 14479 memInfoBuilder.append(" kB\n"); 14480 Slog.i(TAG, "Low on memory:"); 14481 Slog.i(TAG, shortNativeBuilder.toString()); 14482 Slog.i(TAG, fullJavaBuilder.toString()); 14483 Slog.i(TAG, memInfoBuilder.toString()); 14484 14485 StringBuilder dropBuilder = new StringBuilder(1024); 14486 /* 14487 StringWriter oomSw = new StringWriter(); 14488 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14489 StringWriter catSw = new StringWriter(); 14490 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14491 String[] emptyArgs = new String[] { }; 14492 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14493 oomPw.flush(); 14494 String oomString = oomSw.toString(); 14495 */ 14496 dropBuilder.append("Low on memory:"); 14497 dropBuilder.append(stack); 14498 dropBuilder.append('\n'); 14499 dropBuilder.append(fullNativeBuilder); 14500 dropBuilder.append(fullJavaBuilder); 14501 dropBuilder.append('\n'); 14502 dropBuilder.append(memInfoBuilder); 14503 dropBuilder.append('\n'); 14504 /* 14505 dropBuilder.append(oomString); 14506 dropBuilder.append('\n'); 14507 */ 14508 StringWriter catSw = new StringWriter(); 14509 synchronized (ActivityManagerService.this) { 14510 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14511 String[] emptyArgs = new String[] { }; 14512 catPw.println(); 14513 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14514 catPw.println(); 14515 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14516 false, false, null); 14517 catPw.println(); 14518 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14519 catPw.flush(); 14520 } 14521 dropBuilder.append(catSw.toString()); 14522 addErrorToDropBox("lowmem", null, "system_server", null, 14523 null, tag.toString(), dropBuilder.toString(), null, null); 14524 //Slog.i(TAG, "Sent to dropbox:"); 14525 //Slog.i(TAG, dropBuilder.toString()); 14526 synchronized (ActivityManagerService.this) { 14527 long now = SystemClock.uptimeMillis(); 14528 if (mLastMemUsageReportTime < now) { 14529 mLastMemUsageReportTime = now; 14530 } 14531 } 14532 } 14533 14534 /** 14535 * Searches array of arguments for the specified string 14536 * @param args array of argument strings 14537 * @param value value to search for 14538 * @return true if the value is contained in the array 14539 */ 14540 private static boolean scanArgs(String[] args, String value) { 14541 if (args != null) { 14542 for (String arg : args) { 14543 if (value.equals(arg)) { 14544 return true; 14545 } 14546 } 14547 } 14548 return false; 14549 } 14550 14551 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14552 ContentProviderRecord cpr, boolean always) { 14553 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14554 14555 if (!inLaunching || always) { 14556 synchronized (cpr) { 14557 cpr.launchingApp = null; 14558 cpr.notifyAll(); 14559 } 14560 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14561 String names[] = cpr.info.authority.split(";"); 14562 for (int j = 0; j < names.length; j++) { 14563 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14564 } 14565 } 14566 14567 for (int i=0; i<cpr.connections.size(); i++) { 14568 ContentProviderConnection conn = cpr.connections.get(i); 14569 if (conn.waiting) { 14570 // If this connection is waiting for the provider, then we don't 14571 // need to mess with its process unless we are always removing 14572 // or for some reason the provider is not currently launching. 14573 if (inLaunching && !always) { 14574 continue; 14575 } 14576 } 14577 ProcessRecord capp = conn.client; 14578 conn.dead = true; 14579 if (conn.stableCount > 0) { 14580 if (!capp.persistent && capp.thread != null 14581 && capp.pid != 0 14582 && capp.pid != MY_PID) { 14583 capp.kill("depends on provider " 14584 + cpr.name.flattenToShortString() 14585 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14586 } 14587 } else if (capp.thread != null && conn.provider.provider != null) { 14588 try { 14589 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14590 } catch (RemoteException e) { 14591 } 14592 // In the protocol here, we don't expect the client to correctly 14593 // clean up this connection, we'll just remove it. 14594 cpr.connections.remove(i); 14595 conn.client.conProviders.remove(conn); 14596 } 14597 } 14598 14599 if (inLaunching && always) { 14600 mLaunchingProviders.remove(cpr); 14601 } 14602 return inLaunching; 14603 } 14604 14605 /** 14606 * Main code for cleaning up a process when it has gone away. This is 14607 * called both as a result of the process dying, or directly when stopping 14608 * a process when running in single process mode. 14609 * 14610 * @return Returns true if the given process has been restarted, so the 14611 * app that was passed in must remain on the process lists. 14612 */ 14613 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14614 boolean restarting, boolean allowRestart, int index) { 14615 if (index >= 0) { 14616 removeLruProcessLocked(app); 14617 ProcessList.remove(app.pid); 14618 } 14619 14620 mProcessesToGc.remove(app); 14621 mPendingPssProcesses.remove(app); 14622 14623 // Dismiss any open dialogs. 14624 if (app.crashDialog != null && !app.forceCrashReport) { 14625 app.crashDialog.dismiss(); 14626 app.crashDialog = null; 14627 } 14628 if (app.anrDialog != null) { 14629 app.anrDialog.dismiss(); 14630 app.anrDialog = null; 14631 } 14632 if (app.waitDialog != null) { 14633 app.waitDialog.dismiss(); 14634 app.waitDialog = null; 14635 } 14636 14637 app.crashing = false; 14638 app.notResponding = false; 14639 14640 app.resetPackageList(mProcessStats); 14641 app.unlinkDeathRecipient(); 14642 app.makeInactive(mProcessStats); 14643 app.waitingToKill = null; 14644 app.forcingToForeground = null; 14645 updateProcessForegroundLocked(app, false, false); 14646 app.foregroundActivities = false; 14647 app.hasShownUi = false; 14648 app.treatLikeActivity = false; 14649 app.hasAboveClient = false; 14650 app.hasClientActivities = false; 14651 14652 mServices.killServicesLocked(app, allowRestart); 14653 14654 boolean restart = false; 14655 14656 // Remove published content providers. 14657 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14658 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14659 final boolean always = app.bad || !allowRestart; 14660 if (removeDyingProviderLocked(app, cpr, always) || always) { 14661 // We left the provider in the launching list, need to 14662 // restart it. 14663 restart = true; 14664 } 14665 14666 cpr.provider = null; 14667 cpr.proc = null; 14668 } 14669 app.pubProviders.clear(); 14670 14671 // Take care of any launching providers waiting for this process. 14672 if (checkAppInLaunchingProvidersLocked(app, false)) { 14673 restart = true; 14674 } 14675 14676 // Unregister from connected content providers. 14677 if (!app.conProviders.isEmpty()) { 14678 for (int i=0; i<app.conProviders.size(); i++) { 14679 ContentProviderConnection conn = app.conProviders.get(i); 14680 conn.provider.connections.remove(conn); 14681 } 14682 app.conProviders.clear(); 14683 } 14684 14685 // At this point there may be remaining entries in mLaunchingProviders 14686 // where we were the only one waiting, so they are no longer of use. 14687 // Look for these and clean up if found. 14688 // XXX Commented out for now. Trying to figure out a way to reproduce 14689 // the actual situation to identify what is actually going on. 14690 if (false) { 14691 for (int i=0; i<mLaunchingProviders.size(); i++) { 14692 ContentProviderRecord cpr = (ContentProviderRecord) 14693 mLaunchingProviders.get(i); 14694 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14695 synchronized (cpr) { 14696 cpr.launchingApp = null; 14697 cpr.notifyAll(); 14698 } 14699 } 14700 } 14701 } 14702 14703 skipCurrentReceiverLocked(app); 14704 14705 // Unregister any receivers. 14706 for (int i=app.receivers.size()-1; i>=0; i--) { 14707 removeReceiverLocked(app.receivers.valueAt(i)); 14708 } 14709 app.receivers.clear(); 14710 14711 // If the app is undergoing backup, tell the backup manager about it 14712 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14713 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14714 + mBackupTarget.appInfo + " died during backup"); 14715 try { 14716 IBackupManager bm = IBackupManager.Stub.asInterface( 14717 ServiceManager.getService(Context.BACKUP_SERVICE)); 14718 bm.agentDisconnected(app.info.packageName); 14719 } catch (RemoteException e) { 14720 // can't happen; backup manager is local 14721 } 14722 } 14723 14724 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14725 ProcessChangeItem item = mPendingProcessChanges.get(i); 14726 if (item.pid == app.pid) { 14727 mPendingProcessChanges.remove(i); 14728 mAvailProcessChanges.add(item); 14729 } 14730 } 14731 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14732 14733 // If the caller is restarting this app, then leave it in its 14734 // current lists and let the caller take care of it. 14735 if (restarting) { 14736 return false; 14737 } 14738 14739 if (!app.persistent || app.isolated) { 14740 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14741 "Removing non-persistent process during cleanup: " + app); 14742 mProcessNames.remove(app.processName, app.uid); 14743 mIsolatedProcesses.remove(app.uid); 14744 if (mHeavyWeightProcess == app) { 14745 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14746 mHeavyWeightProcess.userId, 0)); 14747 mHeavyWeightProcess = null; 14748 } 14749 } else if (!app.removed) { 14750 // This app is persistent, so we need to keep its record around. 14751 // If it is not already on the pending app list, add it there 14752 // and start a new process for it. 14753 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14754 mPersistentStartingProcesses.add(app); 14755 restart = true; 14756 } 14757 } 14758 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14759 "Clean-up removing on hold: " + app); 14760 mProcessesOnHold.remove(app); 14761 14762 if (app == mHomeProcess) { 14763 mHomeProcess = null; 14764 } 14765 if (app == mPreviousProcess) { 14766 mPreviousProcess = null; 14767 } 14768 14769 if (restart && !app.isolated) { 14770 // We have components that still need to be running in the 14771 // process, so re-launch it. 14772 if (index < 0) { 14773 ProcessList.remove(app.pid); 14774 } 14775 mProcessNames.put(app.processName, app.uid, app); 14776 startProcessLocked(app, "restart", app.processName); 14777 return true; 14778 } else if (app.pid > 0 && app.pid != MY_PID) { 14779 // Goodbye! 14780 boolean removed; 14781 synchronized (mPidsSelfLocked) { 14782 mPidsSelfLocked.remove(app.pid); 14783 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14784 } 14785 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14786 if (app.isolated) { 14787 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14788 } 14789 app.setPid(0); 14790 } 14791 return false; 14792 } 14793 14794 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14795 // Look through the content providers we are waiting to have launched, 14796 // and if any run in this process then either schedule a restart of 14797 // the process or kill the client waiting for it if this process has 14798 // gone bad. 14799 int NL = mLaunchingProviders.size(); 14800 boolean restart = false; 14801 for (int i=0; i<NL; i++) { 14802 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14803 if (cpr.launchingApp == app) { 14804 if (!alwaysBad && !app.bad) { 14805 restart = true; 14806 } else { 14807 removeDyingProviderLocked(app, cpr, true); 14808 // cpr should have been removed from mLaunchingProviders 14809 NL = mLaunchingProviders.size(); 14810 i--; 14811 } 14812 } 14813 } 14814 return restart; 14815 } 14816 14817 // ========================================================= 14818 // SERVICES 14819 // ========================================================= 14820 14821 @Override 14822 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14823 int flags) { 14824 enforceNotIsolatedCaller("getServices"); 14825 synchronized (this) { 14826 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14827 } 14828 } 14829 14830 @Override 14831 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14832 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14833 synchronized (this) { 14834 return mServices.getRunningServiceControlPanelLocked(name); 14835 } 14836 } 14837 14838 @Override 14839 public ComponentName startService(IApplicationThread caller, Intent service, 14840 String resolvedType, int userId) { 14841 enforceNotIsolatedCaller("startService"); 14842 // Refuse possible leaked file descriptors 14843 if (service != null && service.hasFileDescriptors() == true) { 14844 throw new IllegalArgumentException("File descriptors passed in Intent"); 14845 } 14846 14847 if (DEBUG_SERVICE) 14848 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14849 synchronized(this) { 14850 final int callingPid = Binder.getCallingPid(); 14851 final int callingUid = Binder.getCallingUid(); 14852 final long origId = Binder.clearCallingIdentity(); 14853 ComponentName res = mServices.startServiceLocked(caller, service, 14854 resolvedType, callingPid, callingUid, userId); 14855 Binder.restoreCallingIdentity(origId); 14856 return res; 14857 } 14858 } 14859 14860 ComponentName startServiceInPackage(int uid, 14861 Intent service, String resolvedType, int userId) { 14862 synchronized(this) { 14863 if (DEBUG_SERVICE) 14864 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14865 final long origId = Binder.clearCallingIdentity(); 14866 ComponentName res = mServices.startServiceLocked(null, service, 14867 resolvedType, -1, uid, userId); 14868 Binder.restoreCallingIdentity(origId); 14869 return res; 14870 } 14871 } 14872 14873 @Override 14874 public int stopService(IApplicationThread caller, Intent service, 14875 String resolvedType, int userId) { 14876 enforceNotIsolatedCaller("stopService"); 14877 // Refuse possible leaked file descriptors 14878 if (service != null && service.hasFileDescriptors() == true) { 14879 throw new IllegalArgumentException("File descriptors passed in Intent"); 14880 } 14881 14882 synchronized(this) { 14883 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14884 } 14885 } 14886 14887 @Override 14888 public IBinder peekService(Intent service, String resolvedType) { 14889 enforceNotIsolatedCaller("peekService"); 14890 // Refuse possible leaked file descriptors 14891 if (service != null && service.hasFileDescriptors() == true) { 14892 throw new IllegalArgumentException("File descriptors passed in Intent"); 14893 } 14894 synchronized(this) { 14895 return mServices.peekServiceLocked(service, resolvedType); 14896 } 14897 } 14898 14899 @Override 14900 public boolean stopServiceToken(ComponentName className, IBinder token, 14901 int startId) { 14902 synchronized(this) { 14903 return mServices.stopServiceTokenLocked(className, token, startId); 14904 } 14905 } 14906 14907 @Override 14908 public void setServiceForeground(ComponentName className, IBinder token, 14909 int id, Notification notification, boolean removeNotification) { 14910 synchronized(this) { 14911 mServices.setServiceForegroundLocked(className, token, id, notification, 14912 removeNotification); 14913 } 14914 } 14915 14916 @Override 14917 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14918 boolean requireFull, String name, String callerPackage) { 14919 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14920 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14921 } 14922 14923 int unsafeConvertIncomingUser(int userId) { 14924 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14925 ? mCurrentUserId : userId; 14926 } 14927 14928 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14929 int allowMode, String name, String callerPackage) { 14930 final int callingUserId = UserHandle.getUserId(callingUid); 14931 if (callingUserId == userId) { 14932 return userId; 14933 } 14934 14935 // Note that we may be accessing mCurrentUserId outside of a lock... 14936 // shouldn't be a big deal, if this is being called outside 14937 // of a locked context there is intrinsically a race with 14938 // the value the caller will receive and someone else changing it. 14939 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14940 // we will switch to the calling user if access to the current user fails. 14941 int targetUserId = unsafeConvertIncomingUser(userId); 14942 14943 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14944 final boolean allow; 14945 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14946 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14947 // If the caller has this permission, they always pass go. And collect $200. 14948 allow = true; 14949 } else if (allowMode == ALLOW_FULL_ONLY) { 14950 // We require full access, sucks to be you. 14951 allow = false; 14952 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14953 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14954 // If the caller does not have either permission, they are always doomed. 14955 allow = false; 14956 } else if (allowMode == ALLOW_NON_FULL) { 14957 // We are blanket allowing non-full access, you lucky caller! 14958 allow = true; 14959 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14960 // We may or may not allow this depending on whether the two users are 14961 // in the same profile. 14962 synchronized (mUserProfileGroupIdsSelfLocked) { 14963 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14964 UserInfo.NO_PROFILE_GROUP_ID); 14965 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14966 UserInfo.NO_PROFILE_GROUP_ID); 14967 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14968 && callingProfile == targetProfile; 14969 } 14970 } else { 14971 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14972 } 14973 if (!allow) { 14974 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14975 // In this case, they would like to just execute as their 14976 // owner user instead of failing. 14977 targetUserId = callingUserId; 14978 } else { 14979 StringBuilder builder = new StringBuilder(128); 14980 builder.append("Permission Denial: "); 14981 builder.append(name); 14982 if (callerPackage != null) { 14983 builder.append(" from "); 14984 builder.append(callerPackage); 14985 } 14986 builder.append(" asks to run as user "); 14987 builder.append(userId); 14988 builder.append(" but is calling from user "); 14989 builder.append(UserHandle.getUserId(callingUid)); 14990 builder.append("; this requires "); 14991 builder.append(INTERACT_ACROSS_USERS_FULL); 14992 if (allowMode != ALLOW_FULL_ONLY) { 14993 builder.append(" or "); 14994 builder.append(INTERACT_ACROSS_USERS); 14995 } 14996 String msg = builder.toString(); 14997 Slog.w(TAG, msg); 14998 throw new SecurityException(msg); 14999 } 15000 } 15001 } 15002 if (!allowAll && targetUserId < 0) { 15003 throw new IllegalArgumentException( 15004 "Call does not support special user #" + targetUserId); 15005 } 15006 // Check shell permission 15007 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15008 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15009 targetUserId)) { 15010 throw new SecurityException("Shell does not have permission to access user " 15011 + targetUserId + "\n " + Debug.getCallers(3)); 15012 } 15013 } 15014 return targetUserId; 15015 } 15016 15017 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15018 String className, int flags) { 15019 boolean result = false; 15020 // For apps that don't have pre-defined UIDs, check for permission 15021 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15022 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15023 if (ActivityManager.checkUidPermission( 15024 INTERACT_ACROSS_USERS, 15025 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15026 ComponentName comp = new ComponentName(aInfo.packageName, className); 15027 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15028 + " requests FLAG_SINGLE_USER, but app does not hold " 15029 + INTERACT_ACROSS_USERS; 15030 Slog.w(TAG, msg); 15031 throw new SecurityException(msg); 15032 } 15033 // Permission passed 15034 result = true; 15035 } 15036 } else if ("system".equals(componentProcessName)) { 15037 result = true; 15038 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15039 // Phone app and persistent apps are allowed to export singleuser providers. 15040 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15041 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15042 } 15043 if (DEBUG_MU) { 15044 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15045 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15046 } 15047 return result; 15048 } 15049 15050 /** 15051 * Checks to see if the caller is in the same app as the singleton 15052 * component, or the component is in a special app. It allows special apps 15053 * to export singleton components but prevents exporting singleton 15054 * components for regular apps. 15055 */ 15056 boolean isValidSingletonCall(int callingUid, int componentUid) { 15057 int componentAppId = UserHandle.getAppId(componentUid); 15058 return UserHandle.isSameApp(callingUid, componentUid) 15059 || componentAppId == Process.SYSTEM_UID 15060 || componentAppId == Process.PHONE_UID 15061 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15062 == PackageManager.PERMISSION_GRANTED; 15063 } 15064 15065 public int bindService(IApplicationThread caller, IBinder token, 15066 Intent service, String resolvedType, 15067 IServiceConnection connection, int flags, int userId) { 15068 enforceNotIsolatedCaller("bindService"); 15069 15070 // Refuse possible leaked file descriptors 15071 if (service != null && service.hasFileDescriptors() == true) { 15072 throw new IllegalArgumentException("File descriptors passed in Intent"); 15073 } 15074 15075 synchronized(this) { 15076 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15077 connection, flags, userId); 15078 } 15079 } 15080 15081 public boolean unbindService(IServiceConnection connection) { 15082 synchronized (this) { 15083 return mServices.unbindServiceLocked(connection); 15084 } 15085 } 15086 15087 public void publishService(IBinder token, Intent intent, IBinder service) { 15088 // Refuse possible leaked file descriptors 15089 if (intent != null && intent.hasFileDescriptors() == true) { 15090 throw new IllegalArgumentException("File descriptors passed in Intent"); 15091 } 15092 15093 synchronized(this) { 15094 if (!(token instanceof ServiceRecord)) { 15095 throw new IllegalArgumentException("Invalid service token"); 15096 } 15097 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15098 } 15099 } 15100 15101 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15102 // Refuse possible leaked file descriptors 15103 if (intent != null && intent.hasFileDescriptors() == true) { 15104 throw new IllegalArgumentException("File descriptors passed in Intent"); 15105 } 15106 15107 synchronized(this) { 15108 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15109 } 15110 } 15111 15112 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15113 synchronized(this) { 15114 if (!(token instanceof ServiceRecord)) { 15115 throw new IllegalArgumentException("Invalid service token"); 15116 } 15117 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15118 } 15119 } 15120 15121 // ========================================================= 15122 // BACKUP AND RESTORE 15123 // ========================================================= 15124 15125 // Cause the target app to be launched if necessary and its backup agent 15126 // instantiated. The backup agent will invoke backupAgentCreated() on the 15127 // activity manager to announce its creation. 15128 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15129 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15130 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15131 15132 synchronized(this) { 15133 // !!! TODO: currently no check here that we're already bound 15134 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15135 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15136 synchronized (stats) { 15137 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15138 } 15139 15140 // Backup agent is now in use, its package can't be stopped. 15141 try { 15142 AppGlobals.getPackageManager().setPackageStoppedState( 15143 app.packageName, false, UserHandle.getUserId(app.uid)); 15144 } catch (RemoteException e) { 15145 } catch (IllegalArgumentException e) { 15146 Slog.w(TAG, "Failed trying to unstop package " 15147 + app.packageName + ": " + e); 15148 } 15149 15150 BackupRecord r = new BackupRecord(ss, app, backupMode); 15151 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15152 ? new ComponentName(app.packageName, app.backupAgentName) 15153 : new ComponentName("android", "FullBackupAgent"); 15154 // startProcessLocked() returns existing proc's record if it's already running 15155 ProcessRecord proc = startProcessLocked(app.processName, app, 15156 false, 0, "backup", hostingName, false, false, false); 15157 if (proc == null) { 15158 Slog.e(TAG, "Unable to start backup agent process " + r); 15159 return false; 15160 } 15161 15162 r.app = proc; 15163 mBackupTarget = r; 15164 mBackupAppName = app.packageName; 15165 15166 // Try not to kill the process during backup 15167 updateOomAdjLocked(proc); 15168 15169 // If the process is already attached, schedule the creation of the backup agent now. 15170 // If it is not yet live, this will be done when it attaches to the framework. 15171 if (proc.thread != null) { 15172 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15173 try { 15174 proc.thread.scheduleCreateBackupAgent(app, 15175 compatibilityInfoForPackageLocked(app), backupMode); 15176 } catch (RemoteException e) { 15177 // Will time out on the backup manager side 15178 } 15179 } else { 15180 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15181 } 15182 // Invariants: at this point, the target app process exists and the application 15183 // is either already running or in the process of coming up. mBackupTarget and 15184 // mBackupAppName describe the app, so that when it binds back to the AM we 15185 // know that it's scheduled for a backup-agent operation. 15186 } 15187 15188 return true; 15189 } 15190 15191 @Override 15192 public void clearPendingBackup() { 15193 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15194 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15195 15196 synchronized (this) { 15197 mBackupTarget = null; 15198 mBackupAppName = null; 15199 } 15200 } 15201 15202 // A backup agent has just come up 15203 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15204 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15205 + " = " + agent); 15206 15207 synchronized(this) { 15208 if (!agentPackageName.equals(mBackupAppName)) { 15209 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15210 return; 15211 } 15212 } 15213 15214 long oldIdent = Binder.clearCallingIdentity(); 15215 try { 15216 IBackupManager bm = IBackupManager.Stub.asInterface( 15217 ServiceManager.getService(Context.BACKUP_SERVICE)); 15218 bm.agentConnected(agentPackageName, agent); 15219 } catch (RemoteException e) { 15220 // can't happen; the backup manager service is local 15221 } catch (Exception e) { 15222 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15223 e.printStackTrace(); 15224 } finally { 15225 Binder.restoreCallingIdentity(oldIdent); 15226 } 15227 } 15228 15229 // done with this agent 15230 public void unbindBackupAgent(ApplicationInfo appInfo) { 15231 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15232 if (appInfo == null) { 15233 Slog.w(TAG, "unbind backup agent for null app"); 15234 return; 15235 } 15236 15237 synchronized(this) { 15238 try { 15239 if (mBackupAppName == null) { 15240 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15241 return; 15242 } 15243 15244 if (!mBackupAppName.equals(appInfo.packageName)) { 15245 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15246 return; 15247 } 15248 15249 // Not backing this app up any more; reset its OOM adjustment 15250 final ProcessRecord proc = mBackupTarget.app; 15251 updateOomAdjLocked(proc); 15252 15253 // If the app crashed during backup, 'thread' will be null here 15254 if (proc.thread != null) { 15255 try { 15256 proc.thread.scheduleDestroyBackupAgent(appInfo, 15257 compatibilityInfoForPackageLocked(appInfo)); 15258 } catch (Exception e) { 15259 Slog.e(TAG, "Exception when unbinding backup agent:"); 15260 e.printStackTrace(); 15261 } 15262 } 15263 } finally { 15264 mBackupTarget = null; 15265 mBackupAppName = null; 15266 } 15267 } 15268 } 15269 // ========================================================= 15270 // BROADCASTS 15271 // ========================================================= 15272 15273 private final List getStickiesLocked(String action, IntentFilter filter, 15274 List cur, int userId) { 15275 final ContentResolver resolver = mContext.getContentResolver(); 15276 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15277 if (stickies == null) { 15278 return cur; 15279 } 15280 final ArrayList<Intent> list = stickies.get(action); 15281 if (list == null) { 15282 return cur; 15283 } 15284 int N = list.size(); 15285 for (int i=0; i<N; i++) { 15286 Intent intent = list.get(i); 15287 if (filter.match(resolver, intent, true, TAG) >= 0) { 15288 if (cur == null) { 15289 cur = new ArrayList<Intent>(); 15290 } 15291 cur.add(intent); 15292 } 15293 } 15294 return cur; 15295 } 15296 15297 boolean isPendingBroadcastProcessLocked(int pid) { 15298 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15299 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15300 } 15301 15302 void skipPendingBroadcastLocked(int pid) { 15303 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15304 for (BroadcastQueue queue : mBroadcastQueues) { 15305 queue.skipPendingBroadcastLocked(pid); 15306 } 15307 } 15308 15309 // The app just attached; send any pending broadcasts that it should receive 15310 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15311 boolean didSomething = false; 15312 for (BroadcastQueue queue : mBroadcastQueues) { 15313 didSomething |= queue.sendPendingBroadcastsLocked(app); 15314 } 15315 return didSomething; 15316 } 15317 15318 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15319 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15320 enforceNotIsolatedCaller("registerReceiver"); 15321 int callingUid; 15322 int callingPid; 15323 synchronized(this) { 15324 ProcessRecord callerApp = null; 15325 if (caller != null) { 15326 callerApp = getRecordForAppLocked(caller); 15327 if (callerApp == null) { 15328 throw new SecurityException( 15329 "Unable to find app for caller " + caller 15330 + " (pid=" + Binder.getCallingPid() 15331 + ") when registering receiver " + receiver); 15332 } 15333 if (callerApp.info.uid != Process.SYSTEM_UID && 15334 !callerApp.pkgList.containsKey(callerPackage) && 15335 !"android".equals(callerPackage)) { 15336 throw new SecurityException("Given caller package " + callerPackage 15337 + " is not running in process " + callerApp); 15338 } 15339 callingUid = callerApp.info.uid; 15340 callingPid = callerApp.pid; 15341 } else { 15342 callerPackage = null; 15343 callingUid = Binder.getCallingUid(); 15344 callingPid = Binder.getCallingPid(); 15345 } 15346 15347 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15348 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15349 15350 List allSticky = null; 15351 15352 // Look for any matching sticky broadcasts... 15353 Iterator actions = filter.actionsIterator(); 15354 if (actions != null) { 15355 while (actions.hasNext()) { 15356 String action = (String)actions.next(); 15357 allSticky = getStickiesLocked(action, filter, allSticky, 15358 UserHandle.USER_ALL); 15359 allSticky = getStickiesLocked(action, filter, allSticky, 15360 UserHandle.getUserId(callingUid)); 15361 } 15362 } else { 15363 allSticky = getStickiesLocked(null, filter, allSticky, 15364 UserHandle.USER_ALL); 15365 allSticky = getStickiesLocked(null, filter, allSticky, 15366 UserHandle.getUserId(callingUid)); 15367 } 15368 15369 // The first sticky in the list is returned directly back to 15370 // the client. 15371 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15372 15373 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15374 + ": " + sticky); 15375 15376 if (receiver == null) { 15377 return sticky; 15378 } 15379 15380 ReceiverList rl 15381 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15382 if (rl == null) { 15383 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15384 userId, receiver); 15385 if (rl.app != null) { 15386 rl.app.receivers.add(rl); 15387 } else { 15388 try { 15389 receiver.asBinder().linkToDeath(rl, 0); 15390 } catch (RemoteException e) { 15391 return sticky; 15392 } 15393 rl.linkedToDeath = true; 15394 } 15395 mRegisteredReceivers.put(receiver.asBinder(), rl); 15396 } else if (rl.uid != callingUid) { 15397 throw new IllegalArgumentException( 15398 "Receiver requested to register for uid " + callingUid 15399 + " was previously registered for uid " + rl.uid); 15400 } else if (rl.pid != callingPid) { 15401 throw new IllegalArgumentException( 15402 "Receiver requested to register for pid " + callingPid 15403 + " was previously registered for pid " + rl.pid); 15404 } else if (rl.userId != userId) { 15405 throw new IllegalArgumentException( 15406 "Receiver requested to register for user " + userId 15407 + " was previously registered for user " + rl.userId); 15408 } 15409 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15410 permission, callingUid, userId); 15411 rl.add(bf); 15412 if (!bf.debugCheck()) { 15413 Slog.w(TAG, "==> For Dynamic broadast"); 15414 } 15415 mReceiverResolver.addFilter(bf); 15416 15417 // Enqueue broadcasts for all existing stickies that match 15418 // this filter. 15419 if (allSticky != null) { 15420 ArrayList receivers = new ArrayList(); 15421 receivers.add(bf); 15422 15423 int N = allSticky.size(); 15424 for (int i=0; i<N; i++) { 15425 Intent intent = (Intent)allSticky.get(i); 15426 BroadcastQueue queue = broadcastQueueForIntent(intent); 15427 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15428 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15429 null, null, false, true, true, -1); 15430 queue.enqueueParallelBroadcastLocked(r); 15431 queue.scheduleBroadcastsLocked(); 15432 } 15433 } 15434 15435 return sticky; 15436 } 15437 } 15438 15439 public void unregisterReceiver(IIntentReceiver receiver) { 15440 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15441 15442 final long origId = Binder.clearCallingIdentity(); 15443 try { 15444 boolean doTrim = false; 15445 15446 synchronized(this) { 15447 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15448 if (rl != null) { 15449 if (rl.curBroadcast != null) { 15450 BroadcastRecord r = rl.curBroadcast; 15451 final boolean doNext = finishReceiverLocked( 15452 receiver.asBinder(), r.resultCode, r.resultData, 15453 r.resultExtras, r.resultAbort); 15454 if (doNext) { 15455 doTrim = true; 15456 r.queue.processNextBroadcast(false); 15457 } 15458 } 15459 15460 if (rl.app != null) { 15461 rl.app.receivers.remove(rl); 15462 } 15463 removeReceiverLocked(rl); 15464 if (rl.linkedToDeath) { 15465 rl.linkedToDeath = false; 15466 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15467 } 15468 } 15469 } 15470 15471 // If we actually concluded any broadcasts, we might now be able 15472 // to trim the recipients' apps from our working set 15473 if (doTrim) { 15474 trimApplications(); 15475 return; 15476 } 15477 15478 } finally { 15479 Binder.restoreCallingIdentity(origId); 15480 } 15481 } 15482 15483 void removeReceiverLocked(ReceiverList rl) { 15484 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15485 int N = rl.size(); 15486 for (int i=0; i<N; i++) { 15487 mReceiverResolver.removeFilter(rl.get(i)); 15488 } 15489 } 15490 15491 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15492 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15493 ProcessRecord r = mLruProcesses.get(i); 15494 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15495 try { 15496 r.thread.dispatchPackageBroadcast(cmd, packages); 15497 } catch (RemoteException ex) { 15498 } 15499 } 15500 } 15501 } 15502 15503 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15504 int callingUid, int[] users) { 15505 List<ResolveInfo> receivers = null; 15506 try { 15507 HashSet<ComponentName> singleUserReceivers = null; 15508 boolean scannedFirstReceivers = false; 15509 for (int user : users) { 15510 // Skip users that have Shell restrictions 15511 if (callingUid == Process.SHELL_UID 15512 && getUserManagerLocked().hasUserRestriction( 15513 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15514 continue; 15515 } 15516 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15517 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15518 if (user != 0 && newReceivers != null) { 15519 // If this is not the primary user, we need to check for 15520 // any receivers that should be filtered out. 15521 for (int i=0; i<newReceivers.size(); i++) { 15522 ResolveInfo ri = newReceivers.get(i); 15523 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15524 newReceivers.remove(i); 15525 i--; 15526 } 15527 } 15528 } 15529 if (newReceivers != null && newReceivers.size() == 0) { 15530 newReceivers = null; 15531 } 15532 if (receivers == null) { 15533 receivers = newReceivers; 15534 } else if (newReceivers != null) { 15535 // We need to concatenate the additional receivers 15536 // found with what we have do far. This would be easy, 15537 // but we also need to de-dup any receivers that are 15538 // singleUser. 15539 if (!scannedFirstReceivers) { 15540 // Collect any single user receivers we had already retrieved. 15541 scannedFirstReceivers = true; 15542 for (int i=0; i<receivers.size(); i++) { 15543 ResolveInfo ri = receivers.get(i); 15544 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15545 ComponentName cn = new ComponentName( 15546 ri.activityInfo.packageName, ri.activityInfo.name); 15547 if (singleUserReceivers == null) { 15548 singleUserReceivers = new HashSet<ComponentName>(); 15549 } 15550 singleUserReceivers.add(cn); 15551 } 15552 } 15553 } 15554 // Add the new results to the existing results, tracking 15555 // and de-dupping single user receivers. 15556 for (int i=0; i<newReceivers.size(); i++) { 15557 ResolveInfo ri = newReceivers.get(i); 15558 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15559 ComponentName cn = new ComponentName( 15560 ri.activityInfo.packageName, ri.activityInfo.name); 15561 if (singleUserReceivers == null) { 15562 singleUserReceivers = new HashSet<ComponentName>(); 15563 } 15564 if (!singleUserReceivers.contains(cn)) { 15565 singleUserReceivers.add(cn); 15566 receivers.add(ri); 15567 } 15568 } else { 15569 receivers.add(ri); 15570 } 15571 } 15572 } 15573 } 15574 } catch (RemoteException ex) { 15575 // pm is in same process, this will never happen. 15576 } 15577 return receivers; 15578 } 15579 15580 private final int broadcastIntentLocked(ProcessRecord callerApp, 15581 String callerPackage, Intent intent, String resolvedType, 15582 IIntentReceiver resultTo, int resultCode, String resultData, 15583 Bundle map, String requiredPermission, int appOp, 15584 boolean ordered, boolean sticky, int callingPid, int callingUid, 15585 int userId) { 15586 intent = new Intent(intent); 15587 15588 // By default broadcasts do not go to stopped apps. 15589 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15590 15591 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15592 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15593 + " ordered=" + ordered + " userid=" + userId); 15594 if ((resultTo != null) && !ordered) { 15595 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15596 } 15597 15598 userId = handleIncomingUser(callingPid, callingUid, userId, 15599 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15600 15601 // Make sure that the user who is receiving this broadcast is started. 15602 // If not, we will just skip it. 15603 15604 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15605 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15606 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15607 Slog.w(TAG, "Skipping broadcast of " + intent 15608 + ": user " + userId + " is stopped"); 15609 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15610 } 15611 } 15612 15613 /* 15614 * Prevent non-system code (defined here to be non-persistent 15615 * processes) from sending protected broadcasts. 15616 */ 15617 int callingAppId = UserHandle.getAppId(callingUid); 15618 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15619 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15620 || callingAppId == Process.NFC_UID || callingUid == 0) { 15621 // Always okay. 15622 } else if (callerApp == null || !callerApp.persistent) { 15623 try { 15624 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15625 intent.getAction())) { 15626 String msg = "Permission Denial: not allowed to send broadcast " 15627 + intent.getAction() + " from pid=" 15628 + callingPid + ", uid=" + callingUid; 15629 Slog.w(TAG, msg); 15630 throw new SecurityException(msg); 15631 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15632 // Special case for compatibility: we don't want apps to send this, 15633 // but historically it has not been protected and apps may be using it 15634 // to poke their own app widget. So, instead of making it protected, 15635 // just limit it to the caller. 15636 if (callerApp == null) { 15637 String msg = "Permission Denial: not allowed to send broadcast " 15638 + intent.getAction() + " from unknown caller."; 15639 Slog.w(TAG, msg); 15640 throw new SecurityException(msg); 15641 } else if (intent.getComponent() != null) { 15642 // They are good enough to send to an explicit component... verify 15643 // it is being sent to the calling app. 15644 if (!intent.getComponent().getPackageName().equals( 15645 callerApp.info.packageName)) { 15646 String msg = "Permission Denial: not allowed to send broadcast " 15647 + intent.getAction() + " to " 15648 + intent.getComponent().getPackageName() + " from " 15649 + callerApp.info.packageName; 15650 Slog.w(TAG, msg); 15651 throw new SecurityException(msg); 15652 } 15653 } else { 15654 // Limit broadcast to their own package. 15655 intent.setPackage(callerApp.info.packageName); 15656 } 15657 } 15658 } catch (RemoteException e) { 15659 Slog.w(TAG, "Remote exception", e); 15660 return ActivityManager.BROADCAST_SUCCESS; 15661 } 15662 } 15663 15664 // Handle special intents: if this broadcast is from the package 15665 // manager about a package being removed, we need to remove all of 15666 // its activities from the history stack. 15667 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15668 intent.getAction()); 15669 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15670 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15671 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15672 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15673 || uidRemoved) { 15674 if (checkComponentPermission( 15675 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15676 callingPid, callingUid, -1, true) 15677 == PackageManager.PERMISSION_GRANTED) { 15678 if (uidRemoved) { 15679 final Bundle intentExtras = intent.getExtras(); 15680 final int uid = intentExtras != null 15681 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15682 if (uid >= 0) { 15683 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15684 synchronized (bs) { 15685 bs.removeUidStatsLocked(uid); 15686 } 15687 mAppOpsService.uidRemoved(uid); 15688 } 15689 } else { 15690 // If resources are unavailable just force stop all 15691 // those packages and flush the attribute cache as well. 15692 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15693 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15694 if (list != null && (list.length > 0)) { 15695 for (String pkg : list) { 15696 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15697 "storage unmount"); 15698 } 15699 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15700 sendPackageBroadcastLocked( 15701 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15702 } 15703 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15704 intent.getAction())) { 15705 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15706 } else { 15707 Uri data = intent.getData(); 15708 String ssp; 15709 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15710 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15711 intent.getAction()); 15712 boolean fullUninstall = removed && 15713 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15714 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15715 forceStopPackageLocked(ssp, UserHandle.getAppId( 15716 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15717 false, fullUninstall, userId, 15718 removed ? "pkg removed" : "pkg changed"); 15719 } 15720 if (removed) { 15721 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15722 new String[] {ssp}, userId); 15723 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15724 mAppOpsService.packageRemoved( 15725 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15726 15727 // Remove all permissions granted from/to this package 15728 removeUriPermissionsForPackageLocked(ssp, userId, true); 15729 } 15730 } 15731 } 15732 } 15733 } 15734 } else { 15735 String msg = "Permission Denial: " + intent.getAction() 15736 + " broadcast from " + callerPackage + " (pid=" + callingPid 15737 + ", uid=" + callingUid + ")" 15738 + " requires " 15739 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15740 Slog.w(TAG, msg); 15741 throw new SecurityException(msg); 15742 } 15743 15744 // Special case for adding a package: by default turn on compatibility 15745 // mode. 15746 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15747 Uri data = intent.getData(); 15748 String ssp; 15749 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15750 mCompatModePackages.handlePackageAddedLocked(ssp, 15751 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15752 } 15753 } 15754 15755 /* 15756 * If this is the time zone changed action, queue up a message that will reset the timezone 15757 * of all currently running processes. This message will get queued up before the broadcast 15758 * happens. 15759 */ 15760 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15761 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15762 } 15763 15764 /* 15765 * If the user set the time, let all running processes know. 15766 */ 15767 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15768 final int is24Hour = intent.getBooleanExtra( 15769 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15770 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15771 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15772 synchronized (stats) { 15773 stats.noteCurrentTimeChangedLocked(); 15774 } 15775 } 15776 15777 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15778 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15779 } 15780 15781 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15782 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15783 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15784 } 15785 15786 // Add to the sticky list if requested. 15787 if (sticky) { 15788 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15789 callingPid, callingUid) 15790 != PackageManager.PERMISSION_GRANTED) { 15791 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15792 + callingPid + ", uid=" + callingUid 15793 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15794 Slog.w(TAG, msg); 15795 throw new SecurityException(msg); 15796 } 15797 if (requiredPermission != null) { 15798 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15799 + " and enforce permission " + requiredPermission); 15800 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15801 } 15802 if (intent.getComponent() != null) { 15803 throw new SecurityException( 15804 "Sticky broadcasts can't target a specific component"); 15805 } 15806 // We use userId directly here, since the "all" target is maintained 15807 // as a separate set of sticky broadcasts. 15808 if (userId != UserHandle.USER_ALL) { 15809 // But first, if this is not a broadcast to all users, then 15810 // make sure it doesn't conflict with an existing broadcast to 15811 // all users. 15812 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15813 UserHandle.USER_ALL); 15814 if (stickies != null) { 15815 ArrayList<Intent> list = stickies.get(intent.getAction()); 15816 if (list != null) { 15817 int N = list.size(); 15818 int i; 15819 for (i=0; i<N; i++) { 15820 if (intent.filterEquals(list.get(i))) { 15821 throw new IllegalArgumentException( 15822 "Sticky broadcast " + intent + " for user " 15823 + userId + " conflicts with existing global broadcast"); 15824 } 15825 } 15826 } 15827 } 15828 } 15829 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15830 if (stickies == null) { 15831 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15832 mStickyBroadcasts.put(userId, stickies); 15833 } 15834 ArrayList<Intent> list = stickies.get(intent.getAction()); 15835 if (list == null) { 15836 list = new ArrayList<Intent>(); 15837 stickies.put(intent.getAction(), list); 15838 } 15839 int N = list.size(); 15840 int i; 15841 for (i=0; i<N; i++) { 15842 if (intent.filterEquals(list.get(i))) { 15843 // This sticky already exists, replace it. 15844 list.set(i, new Intent(intent)); 15845 break; 15846 } 15847 } 15848 if (i >= N) { 15849 list.add(new Intent(intent)); 15850 } 15851 } 15852 15853 int[] users; 15854 if (userId == UserHandle.USER_ALL) { 15855 // Caller wants broadcast to go to all started users. 15856 users = mStartedUserArray; 15857 } else { 15858 // Caller wants broadcast to go to one specific user. 15859 users = new int[] {userId}; 15860 } 15861 15862 // Figure out who all will receive this broadcast. 15863 List receivers = null; 15864 List<BroadcastFilter> registeredReceivers = null; 15865 // Need to resolve the intent to interested receivers... 15866 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15867 == 0) { 15868 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15869 } 15870 if (intent.getComponent() == null) { 15871 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15872 // Query one target user at a time, excluding shell-restricted users 15873 UserManagerService ums = getUserManagerLocked(); 15874 for (int i = 0; i < users.length; i++) { 15875 if (ums.hasUserRestriction( 15876 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15877 continue; 15878 } 15879 List<BroadcastFilter> registeredReceiversForUser = 15880 mReceiverResolver.queryIntent(intent, 15881 resolvedType, false, users[i]); 15882 if (registeredReceivers == null) { 15883 registeredReceivers = registeredReceiversForUser; 15884 } else if (registeredReceiversForUser != null) { 15885 registeredReceivers.addAll(registeredReceiversForUser); 15886 } 15887 } 15888 } else { 15889 registeredReceivers = mReceiverResolver.queryIntent(intent, 15890 resolvedType, false, userId); 15891 } 15892 } 15893 15894 final boolean replacePending = 15895 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15896 15897 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15898 + " replacePending=" + replacePending); 15899 15900 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15901 if (!ordered && NR > 0) { 15902 // If we are not serializing this broadcast, then send the 15903 // registered receivers separately so they don't wait for the 15904 // components to be launched. 15905 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15906 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15907 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15908 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15909 ordered, sticky, false, userId); 15910 if (DEBUG_BROADCAST) Slog.v( 15911 TAG, "Enqueueing parallel broadcast " + r); 15912 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15913 if (!replaced) { 15914 queue.enqueueParallelBroadcastLocked(r); 15915 queue.scheduleBroadcastsLocked(); 15916 } 15917 registeredReceivers = null; 15918 NR = 0; 15919 } 15920 15921 // Merge into one list. 15922 int ir = 0; 15923 if (receivers != null) { 15924 // A special case for PACKAGE_ADDED: do not allow the package 15925 // being added to see this broadcast. This prevents them from 15926 // using this as a back door to get run as soon as they are 15927 // installed. Maybe in the future we want to have a special install 15928 // broadcast or such for apps, but we'd like to deliberately make 15929 // this decision. 15930 String skipPackages[] = null; 15931 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15932 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15933 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15934 Uri data = intent.getData(); 15935 if (data != null) { 15936 String pkgName = data.getSchemeSpecificPart(); 15937 if (pkgName != null) { 15938 skipPackages = new String[] { pkgName }; 15939 } 15940 } 15941 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15942 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15943 } 15944 if (skipPackages != null && (skipPackages.length > 0)) { 15945 for (String skipPackage : skipPackages) { 15946 if (skipPackage != null) { 15947 int NT = receivers.size(); 15948 for (int it=0; it<NT; it++) { 15949 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15950 if (curt.activityInfo.packageName.equals(skipPackage)) { 15951 receivers.remove(it); 15952 it--; 15953 NT--; 15954 } 15955 } 15956 } 15957 } 15958 } 15959 15960 int NT = receivers != null ? receivers.size() : 0; 15961 int it = 0; 15962 ResolveInfo curt = null; 15963 BroadcastFilter curr = null; 15964 while (it < NT && ir < NR) { 15965 if (curt == null) { 15966 curt = (ResolveInfo)receivers.get(it); 15967 } 15968 if (curr == null) { 15969 curr = registeredReceivers.get(ir); 15970 } 15971 if (curr.getPriority() >= curt.priority) { 15972 // Insert this broadcast record into the final list. 15973 receivers.add(it, curr); 15974 ir++; 15975 curr = null; 15976 it++; 15977 NT++; 15978 } else { 15979 // Skip to the next ResolveInfo in the final list. 15980 it++; 15981 curt = null; 15982 } 15983 } 15984 } 15985 while (ir < NR) { 15986 if (receivers == null) { 15987 receivers = new ArrayList(); 15988 } 15989 receivers.add(registeredReceivers.get(ir)); 15990 ir++; 15991 } 15992 15993 if ((receivers != null && receivers.size() > 0) 15994 || resultTo != null) { 15995 BroadcastQueue queue = broadcastQueueForIntent(intent); 15996 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15997 callerPackage, callingPid, callingUid, resolvedType, 15998 requiredPermission, appOp, receivers, resultTo, resultCode, 15999 resultData, map, ordered, sticky, false, userId); 16000 if (DEBUG_BROADCAST) Slog.v( 16001 TAG, "Enqueueing ordered broadcast " + r 16002 + ": prev had " + queue.mOrderedBroadcasts.size()); 16003 if (DEBUG_BROADCAST) { 16004 int seq = r.intent.getIntExtra("seq", -1); 16005 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16006 } 16007 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16008 if (!replaced) { 16009 queue.enqueueOrderedBroadcastLocked(r); 16010 queue.scheduleBroadcastsLocked(); 16011 } 16012 } 16013 16014 return ActivityManager.BROADCAST_SUCCESS; 16015 } 16016 16017 final Intent verifyBroadcastLocked(Intent intent) { 16018 // Refuse possible leaked file descriptors 16019 if (intent != null && intent.hasFileDescriptors() == true) { 16020 throw new IllegalArgumentException("File descriptors passed in Intent"); 16021 } 16022 16023 int flags = intent.getFlags(); 16024 16025 if (!mProcessesReady) { 16026 // if the caller really truly claims to know what they're doing, go 16027 // ahead and allow the broadcast without launching any receivers 16028 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16029 intent = new Intent(intent); 16030 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16031 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16032 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16033 + " before boot completion"); 16034 throw new IllegalStateException("Cannot broadcast before boot completed"); 16035 } 16036 } 16037 16038 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16039 throw new IllegalArgumentException( 16040 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16041 } 16042 16043 return intent; 16044 } 16045 16046 public final int broadcastIntent(IApplicationThread caller, 16047 Intent intent, String resolvedType, IIntentReceiver resultTo, 16048 int resultCode, String resultData, Bundle map, 16049 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16050 enforceNotIsolatedCaller("broadcastIntent"); 16051 synchronized(this) { 16052 intent = verifyBroadcastLocked(intent); 16053 16054 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16055 final int callingPid = Binder.getCallingPid(); 16056 final int callingUid = Binder.getCallingUid(); 16057 final long origId = Binder.clearCallingIdentity(); 16058 int res = broadcastIntentLocked(callerApp, 16059 callerApp != null ? callerApp.info.packageName : null, 16060 intent, resolvedType, resultTo, 16061 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16062 callingPid, callingUid, userId); 16063 Binder.restoreCallingIdentity(origId); 16064 return res; 16065 } 16066 } 16067 16068 int broadcastIntentInPackage(String packageName, int uid, 16069 Intent intent, String resolvedType, IIntentReceiver resultTo, 16070 int resultCode, String resultData, Bundle map, 16071 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16072 synchronized(this) { 16073 intent = verifyBroadcastLocked(intent); 16074 16075 final long origId = Binder.clearCallingIdentity(); 16076 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16077 resultTo, resultCode, resultData, map, requiredPermission, 16078 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16079 Binder.restoreCallingIdentity(origId); 16080 return res; 16081 } 16082 } 16083 16084 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16085 // Refuse possible leaked file descriptors 16086 if (intent != null && intent.hasFileDescriptors() == true) { 16087 throw new IllegalArgumentException("File descriptors passed in Intent"); 16088 } 16089 16090 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16091 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16092 16093 synchronized(this) { 16094 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16095 != PackageManager.PERMISSION_GRANTED) { 16096 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16097 + Binder.getCallingPid() 16098 + ", uid=" + Binder.getCallingUid() 16099 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16100 Slog.w(TAG, msg); 16101 throw new SecurityException(msg); 16102 } 16103 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16104 if (stickies != null) { 16105 ArrayList<Intent> list = stickies.get(intent.getAction()); 16106 if (list != null) { 16107 int N = list.size(); 16108 int i; 16109 for (i=0; i<N; i++) { 16110 if (intent.filterEquals(list.get(i))) { 16111 list.remove(i); 16112 break; 16113 } 16114 } 16115 if (list.size() <= 0) { 16116 stickies.remove(intent.getAction()); 16117 } 16118 } 16119 if (stickies.size() <= 0) { 16120 mStickyBroadcasts.remove(userId); 16121 } 16122 } 16123 } 16124 } 16125 16126 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16127 String resultData, Bundle resultExtras, boolean resultAbort) { 16128 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16129 if (r == null) { 16130 Slog.w(TAG, "finishReceiver called but not found on queue"); 16131 return false; 16132 } 16133 16134 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16135 } 16136 16137 void backgroundServicesFinishedLocked(int userId) { 16138 for (BroadcastQueue queue : mBroadcastQueues) { 16139 queue.backgroundServicesFinishedLocked(userId); 16140 } 16141 } 16142 16143 public void finishReceiver(IBinder who, int resultCode, String resultData, 16144 Bundle resultExtras, boolean resultAbort) { 16145 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16146 16147 // Refuse possible leaked file descriptors 16148 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16149 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16150 } 16151 16152 final long origId = Binder.clearCallingIdentity(); 16153 try { 16154 boolean doNext = false; 16155 BroadcastRecord r; 16156 16157 synchronized(this) { 16158 r = broadcastRecordForReceiverLocked(who); 16159 if (r != null) { 16160 doNext = r.queue.finishReceiverLocked(r, resultCode, 16161 resultData, resultExtras, resultAbort, true); 16162 } 16163 } 16164 16165 if (doNext) { 16166 r.queue.processNextBroadcast(false); 16167 } 16168 trimApplications(); 16169 } finally { 16170 Binder.restoreCallingIdentity(origId); 16171 } 16172 } 16173 16174 // ========================================================= 16175 // INSTRUMENTATION 16176 // ========================================================= 16177 16178 public boolean startInstrumentation(ComponentName className, 16179 String profileFile, int flags, Bundle arguments, 16180 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16181 int userId, String abiOverride) { 16182 enforceNotIsolatedCaller("startInstrumentation"); 16183 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16184 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16185 // Refuse possible leaked file descriptors 16186 if (arguments != null && arguments.hasFileDescriptors()) { 16187 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16188 } 16189 16190 synchronized(this) { 16191 InstrumentationInfo ii = null; 16192 ApplicationInfo ai = null; 16193 try { 16194 ii = mContext.getPackageManager().getInstrumentationInfo( 16195 className, STOCK_PM_FLAGS); 16196 ai = AppGlobals.getPackageManager().getApplicationInfo( 16197 ii.targetPackage, STOCK_PM_FLAGS, userId); 16198 } catch (PackageManager.NameNotFoundException e) { 16199 } catch (RemoteException e) { 16200 } 16201 if (ii == null) { 16202 reportStartInstrumentationFailure(watcher, className, 16203 "Unable to find instrumentation info for: " + className); 16204 return false; 16205 } 16206 if (ai == null) { 16207 reportStartInstrumentationFailure(watcher, className, 16208 "Unable to find instrumentation target package: " + ii.targetPackage); 16209 return false; 16210 } 16211 16212 int match = mContext.getPackageManager().checkSignatures( 16213 ii.targetPackage, ii.packageName); 16214 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16215 String msg = "Permission Denial: starting instrumentation " 16216 + className + " from pid=" 16217 + Binder.getCallingPid() 16218 + ", uid=" + Binder.getCallingPid() 16219 + " not allowed because package " + ii.packageName 16220 + " does not have a signature matching the target " 16221 + ii.targetPackage; 16222 reportStartInstrumentationFailure(watcher, className, msg); 16223 throw new SecurityException(msg); 16224 } 16225 16226 final long origId = Binder.clearCallingIdentity(); 16227 // Instrumentation can kill and relaunch even persistent processes 16228 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16229 "start instr"); 16230 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16231 app.instrumentationClass = className; 16232 app.instrumentationInfo = ai; 16233 app.instrumentationProfileFile = profileFile; 16234 app.instrumentationArguments = arguments; 16235 app.instrumentationWatcher = watcher; 16236 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16237 app.instrumentationResultClass = className; 16238 Binder.restoreCallingIdentity(origId); 16239 } 16240 16241 return true; 16242 } 16243 16244 /** 16245 * Report errors that occur while attempting to start Instrumentation. Always writes the 16246 * error to the logs, but if somebody is watching, send the report there too. This enables 16247 * the "am" command to report errors with more information. 16248 * 16249 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16250 * @param cn The component name of the instrumentation. 16251 * @param report The error report. 16252 */ 16253 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16254 ComponentName cn, String report) { 16255 Slog.w(TAG, report); 16256 try { 16257 if (watcher != null) { 16258 Bundle results = new Bundle(); 16259 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16260 results.putString("Error", report); 16261 watcher.instrumentationStatus(cn, -1, results); 16262 } 16263 } catch (RemoteException e) { 16264 Slog.w(TAG, e); 16265 } 16266 } 16267 16268 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16269 if (app.instrumentationWatcher != null) { 16270 try { 16271 // NOTE: IInstrumentationWatcher *must* be oneway here 16272 app.instrumentationWatcher.instrumentationFinished( 16273 app.instrumentationClass, 16274 resultCode, 16275 results); 16276 } catch (RemoteException e) { 16277 } 16278 } 16279 if (app.instrumentationUiAutomationConnection != null) { 16280 try { 16281 app.instrumentationUiAutomationConnection.shutdown(); 16282 } catch (RemoteException re) { 16283 /* ignore */ 16284 } 16285 // Only a UiAutomation can set this flag and now that 16286 // it is finished we make sure it is reset to its default. 16287 mUserIsMonkey = false; 16288 } 16289 app.instrumentationWatcher = null; 16290 app.instrumentationUiAutomationConnection = null; 16291 app.instrumentationClass = null; 16292 app.instrumentationInfo = null; 16293 app.instrumentationProfileFile = null; 16294 app.instrumentationArguments = null; 16295 16296 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16297 "finished inst"); 16298 } 16299 16300 public void finishInstrumentation(IApplicationThread target, 16301 int resultCode, Bundle results) { 16302 int userId = UserHandle.getCallingUserId(); 16303 // Refuse possible leaked file descriptors 16304 if (results != null && results.hasFileDescriptors()) { 16305 throw new IllegalArgumentException("File descriptors passed in Intent"); 16306 } 16307 16308 synchronized(this) { 16309 ProcessRecord app = getRecordForAppLocked(target); 16310 if (app == null) { 16311 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16312 return; 16313 } 16314 final long origId = Binder.clearCallingIdentity(); 16315 finishInstrumentationLocked(app, resultCode, results); 16316 Binder.restoreCallingIdentity(origId); 16317 } 16318 } 16319 16320 // ========================================================= 16321 // CONFIGURATION 16322 // ========================================================= 16323 16324 public ConfigurationInfo getDeviceConfigurationInfo() { 16325 ConfigurationInfo config = new ConfigurationInfo(); 16326 synchronized (this) { 16327 config.reqTouchScreen = mConfiguration.touchscreen; 16328 config.reqKeyboardType = mConfiguration.keyboard; 16329 config.reqNavigation = mConfiguration.navigation; 16330 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16331 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16332 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16333 } 16334 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16335 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16336 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16337 } 16338 config.reqGlEsVersion = GL_ES_VERSION; 16339 } 16340 return config; 16341 } 16342 16343 ActivityStack getFocusedStack() { 16344 return mStackSupervisor.getFocusedStack(); 16345 } 16346 16347 public Configuration getConfiguration() { 16348 Configuration ci; 16349 synchronized(this) { 16350 ci = new Configuration(mConfiguration); 16351 } 16352 return ci; 16353 } 16354 16355 public void updatePersistentConfiguration(Configuration values) { 16356 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16357 "updateConfiguration()"); 16358 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16359 "updateConfiguration()"); 16360 if (values == null) { 16361 throw new NullPointerException("Configuration must not be null"); 16362 } 16363 16364 synchronized(this) { 16365 final long origId = Binder.clearCallingIdentity(); 16366 updateConfigurationLocked(values, null, true, false); 16367 Binder.restoreCallingIdentity(origId); 16368 } 16369 } 16370 16371 public void updateConfiguration(Configuration values) { 16372 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16373 "updateConfiguration()"); 16374 16375 synchronized(this) { 16376 if (values == null && mWindowManager != null) { 16377 // sentinel: fetch the current configuration from the window manager 16378 values = mWindowManager.computeNewConfiguration(); 16379 } 16380 16381 if (mWindowManager != null) { 16382 mProcessList.applyDisplaySize(mWindowManager); 16383 } 16384 16385 final long origId = Binder.clearCallingIdentity(); 16386 if (values != null) { 16387 Settings.System.clearConfiguration(values); 16388 } 16389 updateConfigurationLocked(values, null, false, false); 16390 Binder.restoreCallingIdentity(origId); 16391 } 16392 } 16393 16394 /** 16395 * Do either or both things: (1) change the current configuration, and (2) 16396 * make sure the given activity is running with the (now) current 16397 * configuration. Returns true if the activity has been left running, or 16398 * false if <var>starting</var> is being destroyed to match the new 16399 * configuration. 16400 * @param persistent TODO 16401 */ 16402 boolean updateConfigurationLocked(Configuration values, 16403 ActivityRecord starting, boolean persistent, boolean initLocale) { 16404 int changes = 0; 16405 16406 if (values != null) { 16407 Configuration newConfig = new Configuration(mConfiguration); 16408 changes = newConfig.updateFrom(values); 16409 if (changes != 0) { 16410 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16411 Slog.i(TAG, "Updating configuration to: " + values); 16412 } 16413 16414 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16415 16416 if (values.locale != null && !initLocale) { 16417 saveLocaleLocked(values.locale, 16418 !values.locale.equals(mConfiguration.locale), 16419 values.userSetLocale); 16420 } 16421 16422 mConfigurationSeq++; 16423 if (mConfigurationSeq <= 0) { 16424 mConfigurationSeq = 1; 16425 } 16426 newConfig.seq = mConfigurationSeq; 16427 mConfiguration = newConfig; 16428 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16429 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16430 //mUsageStatsService.noteStartConfig(newConfig); 16431 16432 final Configuration configCopy = new Configuration(mConfiguration); 16433 16434 // TODO: If our config changes, should we auto dismiss any currently 16435 // showing dialogs? 16436 mShowDialogs = shouldShowDialogs(newConfig); 16437 16438 AttributeCache ac = AttributeCache.instance(); 16439 if (ac != null) { 16440 ac.updateConfiguration(configCopy); 16441 } 16442 16443 // Make sure all resources in our process are updated 16444 // right now, so that anyone who is going to retrieve 16445 // resource values after we return will be sure to get 16446 // the new ones. This is especially important during 16447 // boot, where the first config change needs to guarantee 16448 // all resources have that config before following boot 16449 // code is executed. 16450 mSystemThread.applyConfigurationToResources(configCopy); 16451 16452 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16453 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16454 msg.obj = new Configuration(configCopy); 16455 mHandler.sendMessage(msg); 16456 } 16457 16458 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16459 ProcessRecord app = mLruProcesses.get(i); 16460 try { 16461 if (app.thread != null) { 16462 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16463 + app.processName + " new config " + mConfiguration); 16464 app.thread.scheduleConfigurationChanged(configCopy); 16465 } 16466 } catch (Exception e) { 16467 } 16468 } 16469 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16470 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16471 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16472 | Intent.FLAG_RECEIVER_FOREGROUND); 16473 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16474 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16475 Process.SYSTEM_UID, UserHandle.USER_ALL); 16476 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16477 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16478 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16479 broadcastIntentLocked(null, null, intent, 16480 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16481 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16482 } 16483 } 16484 } 16485 16486 boolean kept = true; 16487 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16488 // mainStack is null during startup. 16489 if (mainStack != null) { 16490 if (changes != 0 && starting == null) { 16491 // If the configuration changed, and the caller is not already 16492 // in the process of starting an activity, then find the top 16493 // activity to check if its configuration needs to change. 16494 starting = mainStack.topRunningActivityLocked(null); 16495 } 16496 16497 if (starting != null) { 16498 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16499 // And we need to make sure at this point that all other activities 16500 // are made visible with the correct configuration. 16501 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16502 } 16503 } 16504 16505 if (values != null && mWindowManager != null) { 16506 mWindowManager.setNewConfiguration(mConfiguration); 16507 } 16508 16509 return kept; 16510 } 16511 16512 /** 16513 * Decide based on the configuration whether we should shouw the ANR, 16514 * crash, etc dialogs. The idea is that if there is no affordnace to 16515 * press the on-screen buttons, we shouldn't show the dialog. 16516 * 16517 * A thought: SystemUI might also want to get told about this, the Power 16518 * dialog / global actions also might want different behaviors. 16519 */ 16520 private static final boolean shouldShowDialogs(Configuration config) { 16521 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16522 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16523 } 16524 16525 /** 16526 * Save the locale. You must be inside a synchronized (this) block. 16527 */ 16528 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16529 if(isDiff) { 16530 SystemProperties.set("user.language", l.getLanguage()); 16531 SystemProperties.set("user.region", l.getCountry()); 16532 } 16533 16534 if(isPersist) { 16535 SystemProperties.set("persist.sys.language", l.getLanguage()); 16536 SystemProperties.set("persist.sys.country", l.getCountry()); 16537 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16538 16539 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16540 } 16541 } 16542 16543 @Override 16544 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16545 synchronized (this) { 16546 ActivityRecord srec = ActivityRecord.forToken(token); 16547 if (srec.task != null && srec.task.stack != null) { 16548 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16549 } 16550 } 16551 return false; 16552 } 16553 16554 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16555 Intent resultData) { 16556 16557 synchronized (this) { 16558 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16559 if (stack != null) { 16560 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16561 } 16562 return false; 16563 } 16564 } 16565 16566 public int getLaunchedFromUid(IBinder activityToken) { 16567 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16568 if (srec == null) { 16569 return -1; 16570 } 16571 return srec.launchedFromUid; 16572 } 16573 16574 public String getLaunchedFromPackage(IBinder activityToken) { 16575 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16576 if (srec == null) { 16577 return null; 16578 } 16579 return srec.launchedFromPackage; 16580 } 16581 16582 // ========================================================= 16583 // LIFETIME MANAGEMENT 16584 // ========================================================= 16585 16586 // Returns which broadcast queue the app is the current [or imminent] receiver 16587 // on, or 'null' if the app is not an active broadcast recipient. 16588 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16589 BroadcastRecord r = app.curReceiver; 16590 if (r != null) { 16591 return r.queue; 16592 } 16593 16594 // It's not the current receiver, but it might be starting up to become one 16595 synchronized (this) { 16596 for (BroadcastQueue queue : mBroadcastQueues) { 16597 r = queue.mPendingBroadcast; 16598 if (r != null && r.curApp == app) { 16599 // found it; report which queue it's in 16600 return queue; 16601 } 16602 } 16603 } 16604 16605 return null; 16606 } 16607 16608 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16609 boolean doingAll, long now) { 16610 if (mAdjSeq == app.adjSeq) { 16611 // This adjustment has already been computed. 16612 return app.curRawAdj; 16613 } 16614 16615 if (app.thread == null) { 16616 app.adjSeq = mAdjSeq; 16617 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16618 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16619 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16620 } 16621 16622 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16623 app.adjSource = null; 16624 app.adjTarget = null; 16625 app.empty = false; 16626 app.cached = false; 16627 16628 final int activitiesSize = app.activities.size(); 16629 16630 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16631 // The max adjustment doesn't allow this app to be anything 16632 // below foreground, so it is not worth doing work for it. 16633 app.adjType = "fixed"; 16634 app.adjSeq = mAdjSeq; 16635 app.curRawAdj = app.maxAdj; 16636 app.foregroundActivities = false; 16637 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16638 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16639 // System processes can do UI, and when they do we want to have 16640 // them trim their memory after the user leaves the UI. To 16641 // facilitate this, here we need to determine whether or not it 16642 // is currently showing UI. 16643 app.systemNoUi = true; 16644 if (app == TOP_APP) { 16645 app.systemNoUi = false; 16646 } else if (activitiesSize > 0) { 16647 for (int j = 0; j < activitiesSize; j++) { 16648 final ActivityRecord r = app.activities.get(j); 16649 if (r.visible) { 16650 app.systemNoUi = false; 16651 } 16652 } 16653 } 16654 if (!app.systemNoUi) { 16655 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16656 } 16657 return (app.curAdj=app.maxAdj); 16658 } 16659 16660 app.systemNoUi = false; 16661 16662 // Determine the importance of the process, starting with most 16663 // important to least, and assign an appropriate OOM adjustment. 16664 int adj; 16665 int schedGroup; 16666 int procState; 16667 boolean foregroundActivities = false; 16668 BroadcastQueue queue; 16669 if (app == TOP_APP) { 16670 // The last app on the list is the foreground app. 16671 adj = ProcessList.FOREGROUND_APP_ADJ; 16672 schedGroup = Process.THREAD_GROUP_DEFAULT; 16673 app.adjType = "top-activity"; 16674 foregroundActivities = true; 16675 procState = ActivityManager.PROCESS_STATE_TOP; 16676 } else if (app.instrumentationClass != null) { 16677 // Don't want to kill running instrumentation. 16678 adj = ProcessList.FOREGROUND_APP_ADJ; 16679 schedGroup = Process.THREAD_GROUP_DEFAULT; 16680 app.adjType = "instrumentation"; 16681 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16682 } else if ((queue = isReceivingBroadcast(app)) != null) { 16683 // An app that is currently receiving a broadcast also 16684 // counts as being in the foreground for OOM killer purposes. 16685 // It's placed in a sched group based on the nature of the 16686 // broadcast as reflected by which queue it's active in. 16687 adj = ProcessList.FOREGROUND_APP_ADJ; 16688 schedGroup = (queue == mFgBroadcastQueue) 16689 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16690 app.adjType = "broadcast"; 16691 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16692 } else if (app.executingServices.size() > 0) { 16693 // An app that is currently executing a service callback also 16694 // counts as being in the foreground. 16695 adj = ProcessList.FOREGROUND_APP_ADJ; 16696 schedGroup = app.execServicesFg ? 16697 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16698 app.adjType = "exec-service"; 16699 procState = ActivityManager.PROCESS_STATE_SERVICE; 16700 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16701 } else { 16702 // As far as we know the process is empty. We may change our mind later. 16703 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16704 // At this point we don't actually know the adjustment. Use the cached adj 16705 // value that the caller wants us to. 16706 adj = cachedAdj; 16707 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16708 app.cached = true; 16709 app.empty = true; 16710 app.adjType = "cch-empty"; 16711 } 16712 16713 // Examine all activities if not already foreground. 16714 if (!foregroundActivities && activitiesSize > 0) { 16715 for (int j = 0; j < activitiesSize; j++) { 16716 final ActivityRecord r = app.activities.get(j); 16717 if (r.app != app) { 16718 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16719 + app + "?!?"); 16720 continue; 16721 } 16722 if (r.visible) { 16723 // App has a visible activity; only upgrade adjustment. 16724 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16725 adj = ProcessList.VISIBLE_APP_ADJ; 16726 app.adjType = "visible"; 16727 } 16728 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16729 procState = ActivityManager.PROCESS_STATE_TOP; 16730 } 16731 schedGroup = Process.THREAD_GROUP_DEFAULT; 16732 app.cached = false; 16733 app.empty = false; 16734 foregroundActivities = true; 16735 break; 16736 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16737 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16738 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16739 app.adjType = "pausing"; 16740 } 16741 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16742 procState = ActivityManager.PROCESS_STATE_TOP; 16743 } 16744 schedGroup = Process.THREAD_GROUP_DEFAULT; 16745 app.cached = false; 16746 app.empty = false; 16747 foregroundActivities = true; 16748 } else if (r.state == ActivityState.STOPPING) { 16749 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16750 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16751 app.adjType = "stopping"; 16752 } 16753 // For the process state, we will at this point consider the 16754 // process to be cached. It will be cached either as an activity 16755 // or empty depending on whether the activity is finishing. We do 16756 // this so that we can treat the process as cached for purposes of 16757 // memory trimming (determing current memory level, trim command to 16758 // send to process) since there can be an arbitrary number of stopping 16759 // processes and they should soon all go into the cached state. 16760 if (!r.finishing) { 16761 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16762 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16763 } 16764 } 16765 app.cached = false; 16766 app.empty = false; 16767 foregroundActivities = true; 16768 } else { 16769 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16770 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16771 app.adjType = "cch-act"; 16772 } 16773 } 16774 } 16775 } 16776 16777 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16778 if (app.foregroundServices) { 16779 // The user is aware of this app, so make it visible. 16780 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16781 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16782 app.cached = false; 16783 app.adjType = "fg-service"; 16784 schedGroup = Process.THREAD_GROUP_DEFAULT; 16785 } else if (app.forcingToForeground != null) { 16786 // The user is aware of this app, so make it visible. 16787 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16788 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16789 app.cached = false; 16790 app.adjType = "force-fg"; 16791 app.adjSource = app.forcingToForeground; 16792 schedGroup = Process.THREAD_GROUP_DEFAULT; 16793 } 16794 } 16795 16796 if (app == mHeavyWeightProcess) { 16797 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16798 // We don't want to kill the current heavy-weight process. 16799 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16800 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16801 app.cached = false; 16802 app.adjType = "heavy"; 16803 } 16804 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16805 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16806 } 16807 } 16808 16809 if (app == mHomeProcess) { 16810 if (adj > ProcessList.HOME_APP_ADJ) { 16811 // This process is hosting what we currently consider to be the 16812 // home app, so we don't want to let it go into the background. 16813 adj = ProcessList.HOME_APP_ADJ; 16814 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16815 app.cached = false; 16816 app.adjType = "home"; 16817 } 16818 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16819 procState = ActivityManager.PROCESS_STATE_HOME; 16820 } 16821 } 16822 16823 if (app == mPreviousProcess && app.activities.size() > 0) { 16824 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16825 // This was the previous process that showed UI to the user. 16826 // We want to try to keep it around more aggressively, to give 16827 // a good experience around switching between two apps. 16828 adj = ProcessList.PREVIOUS_APP_ADJ; 16829 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16830 app.cached = false; 16831 app.adjType = "previous"; 16832 } 16833 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16834 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16835 } 16836 } 16837 16838 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16839 + " reason=" + app.adjType); 16840 16841 // By default, we use the computed adjustment. It may be changed if 16842 // there are applications dependent on our services or providers, but 16843 // this gives us a baseline and makes sure we don't get into an 16844 // infinite recursion. 16845 app.adjSeq = mAdjSeq; 16846 app.curRawAdj = adj; 16847 app.hasStartedServices = false; 16848 16849 if (mBackupTarget != null && app == mBackupTarget.app) { 16850 // If possible we want to avoid killing apps while they're being backed up 16851 if (adj > ProcessList.BACKUP_APP_ADJ) { 16852 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16853 adj = ProcessList.BACKUP_APP_ADJ; 16854 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16855 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16856 } 16857 app.adjType = "backup"; 16858 app.cached = false; 16859 } 16860 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16861 procState = ActivityManager.PROCESS_STATE_BACKUP; 16862 } 16863 } 16864 16865 boolean mayBeTop = false; 16866 16867 for (int is = app.services.size()-1; 16868 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16869 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16870 || procState > ActivityManager.PROCESS_STATE_TOP); 16871 is--) { 16872 ServiceRecord s = app.services.valueAt(is); 16873 if (s.startRequested) { 16874 app.hasStartedServices = true; 16875 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16876 procState = ActivityManager.PROCESS_STATE_SERVICE; 16877 } 16878 if (app.hasShownUi && app != mHomeProcess) { 16879 // If this process has shown some UI, let it immediately 16880 // go to the LRU list because it may be pretty heavy with 16881 // UI stuff. We'll tag it with a label just to help 16882 // debug and understand what is going on. 16883 if (adj > ProcessList.SERVICE_ADJ) { 16884 app.adjType = "cch-started-ui-services"; 16885 } 16886 } else { 16887 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16888 // This service has seen some activity within 16889 // recent memory, so we will keep its process ahead 16890 // of the background processes. 16891 if (adj > ProcessList.SERVICE_ADJ) { 16892 adj = ProcessList.SERVICE_ADJ; 16893 app.adjType = "started-services"; 16894 app.cached = false; 16895 } 16896 } 16897 // If we have let the service slide into the background 16898 // state, still have some text describing what it is doing 16899 // even though the service no longer has an impact. 16900 if (adj > ProcessList.SERVICE_ADJ) { 16901 app.adjType = "cch-started-services"; 16902 } 16903 } 16904 } 16905 for (int conni = s.connections.size()-1; 16906 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16907 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16908 || procState > ActivityManager.PROCESS_STATE_TOP); 16909 conni--) { 16910 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16911 for (int i = 0; 16912 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16913 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16914 || procState > ActivityManager.PROCESS_STATE_TOP); 16915 i++) { 16916 // XXX should compute this based on the max of 16917 // all connected clients. 16918 ConnectionRecord cr = clist.get(i); 16919 if (cr.binding.client == app) { 16920 // Binding to ourself is not interesting. 16921 continue; 16922 } 16923 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16924 ProcessRecord client = cr.binding.client; 16925 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16926 TOP_APP, doingAll, now); 16927 int clientProcState = client.curProcState; 16928 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16929 // If the other app is cached for any reason, for purposes here 16930 // we are going to consider it empty. The specific cached state 16931 // doesn't propagate except under certain conditions. 16932 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16933 } 16934 String adjType = null; 16935 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16936 // Not doing bind OOM management, so treat 16937 // this guy more like a started service. 16938 if (app.hasShownUi && app != mHomeProcess) { 16939 // If this process has shown some UI, let it immediately 16940 // go to the LRU list because it may be pretty heavy with 16941 // UI stuff. We'll tag it with a label just to help 16942 // debug and understand what is going on. 16943 if (adj > clientAdj) { 16944 adjType = "cch-bound-ui-services"; 16945 } 16946 app.cached = false; 16947 clientAdj = adj; 16948 clientProcState = procState; 16949 } else { 16950 if (now >= (s.lastActivity 16951 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16952 // This service has not seen activity within 16953 // recent memory, so allow it to drop to the 16954 // LRU list if there is no other reason to keep 16955 // it around. We'll also tag it with a label just 16956 // to help debug and undertand what is going on. 16957 if (adj > clientAdj) { 16958 adjType = "cch-bound-services"; 16959 } 16960 clientAdj = adj; 16961 } 16962 } 16963 } 16964 if (adj > clientAdj) { 16965 // If this process has recently shown UI, and 16966 // the process that is binding to it is less 16967 // important than being visible, then we don't 16968 // care about the binding as much as we care 16969 // about letting this process get into the LRU 16970 // list to be killed and restarted if needed for 16971 // memory. 16972 if (app.hasShownUi && app != mHomeProcess 16973 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16974 adjType = "cch-bound-ui-services"; 16975 } else { 16976 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16977 |Context.BIND_IMPORTANT)) != 0) { 16978 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16979 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16980 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16981 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16982 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16983 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16984 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16985 adj = clientAdj; 16986 } else { 16987 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16988 adj = ProcessList.VISIBLE_APP_ADJ; 16989 } 16990 } 16991 if (!client.cached) { 16992 app.cached = false; 16993 } 16994 adjType = "service"; 16995 } 16996 } 16997 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16998 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16999 schedGroup = Process.THREAD_GROUP_DEFAULT; 17000 } 17001 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17002 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17003 // Special handling of clients who are in the top state. 17004 // We *may* want to consider this process to be in the 17005 // top state as well, but only if there is not another 17006 // reason for it to be running. Being on the top is a 17007 // special state, meaning you are specifically running 17008 // for the current top app. If the process is already 17009 // running in the background for some other reason, it 17010 // is more important to continue considering it to be 17011 // in the background state. 17012 mayBeTop = true; 17013 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17014 } else { 17015 // Special handling for above-top states (persistent 17016 // processes). These should not bring the current process 17017 // into the top state, since they are not on top. Instead 17018 // give them the best state after that. 17019 clientProcState = 17020 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17021 } 17022 } 17023 } else { 17024 if (clientProcState < 17025 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17026 clientProcState = 17027 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17028 } 17029 } 17030 if (procState > clientProcState) { 17031 procState = clientProcState; 17032 } 17033 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17034 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17035 app.pendingUiClean = true; 17036 } 17037 if (adjType != null) { 17038 app.adjType = adjType; 17039 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17040 .REASON_SERVICE_IN_USE; 17041 app.adjSource = cr.binding.client; 17042 app.adjSourceProcState = clientProcState; 17043 app.adjTarget = s.name; 17044 } 17045 } 17046 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17047 app.treatLikeActivity = true; 17048 } 17049 final ActivityRecord a = cr.activity; 17050 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17051 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17052 (a.visible || a.state == ActivityState.RESUMED 17053 || a.state == ActivityState.PAUSING)) { 17054 adj = ProcessList.FOREGROUND_APP_ADJ; 17055 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17056 schedGroup = Process.THREAD_GROUP_DEFAULT; 17057 } 17058 app.cached = false; 17059 app.adjType = "service"; 17060 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17061 .REASON_SERVICE_IN_USE; 17062 app.adjSource = a; 17063 app.adjSourceProcState = procState; 17064 app.adjTarget = s.name; 17065 } 17066 } 17067 } 17068 } 17069 } 17070 17071 for (int provi = app.pubProviders.size()-1; 17072 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17073 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17074 || procState > ActivityManager.PROCESS_STATE_TOP); 17075 provi--) { 17076 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17077 for (int i = cpr.connections.size()-1; 17078 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17079 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17080 || procState > ActivityManager.PROCESS_STATE_TOP); 17081 i--) { 17082 ContentProviderConnection conn = cpr.connections.get(i); 17083 ProcessRecord client = conn.client; 17084 if (client == app) { 17085 // Being our own client is not interesting. 17086 continue; 17087 } 17088 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17089 int clientProcState = client.curProcState; 17090 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17091 // If the other app is cached for any reason, for purposes here 17092 // we are going to consider it empty. 17093 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17094 } 17095 if (adj > clientAdj) { 17096 if (app.hasShownUi && app != mHomeProcess 17097 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17098 app.adjType = "cch-ui-provider"; 17099 } else { 17100 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17101 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17102 app.adjType = "provider"; 17103 } 17104 app.cached &= client.cached; 17105 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17106 .REASON_PROVIDER_IN_USE; 17107 app.adjSource = client; 17108 app.adjSourceProcState = clientProcState; 17109 app.adjTarget = cpr.name; 17110 } 17111 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17112 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17113 // Special handling of clients who are in the top state. 17114 // We *may* want to consider this process to be in the 17115 // top state as well, but only if there is not another 17116 // reason for it to be running. Being on the top is a 17117 // special state, meaning you are specifically running 17118 // for the current top app. If the process is already 17119 // running in the background for some other reason, it 17120 // is more important to continue considering it to be 17121 // in the background state. 17122 mayBeTop = true; 17123 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17124 } else { 17125 // Special handling for above-top states (persistent 17126 // processes). These should not bring the current process 17127 // into the top state, since they are not on top. Instead 17128 // give them the best state after that. 17129 clientProcState = 17130 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17131 } 17132 } 17133 if (procState > clientProcState) { 17134 procState = clientProcState; 17135 } 17136 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17137 schedGroup = Process.THREAD_GROUP_DEFAULT; 17138 } 17139 } 17140 // If the provider has external (non-framework) process 17141 // dependencies, ensure that its adjustment is at least 17142 // FOREGROUND_APP_ADJ. 17143 if (cpr.hasExternalProcessHandles()) { 17144 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17145 adj = ProcessList.FOREGROUND_APP_ADJ; 17146 schedGroup = Process.THREAD_GROUP_DEFAULT; 17147 app.cached = false; 17148 app.adjType = "provider"; 17149 app.adjTarget = cpr.name; 17150 } 17151 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17152 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17153 } 17154 } 17155 } 17156 17157 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17158 // A client of one of our services or providers is in the top state. We 17159 // *may* want to be in the top state, but not if we are already running in 17160 // the background for some other reason. For the decision here, we are going 17161 // to pick out a few specific states that we want to remain in when a client 17162 // is top (states that tend to be longer-term) and otherwise allow it to go 17163 // to the top state. 17164 switch (procState) { 17165 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17166 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17167 case ActivityManager.PROCESS_STATE_SERVICE: 17168 // These all are longer-term states, so pull them up to the top 17169 // of the background states, but not all the way to the top state. 17170 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17171 break; 17172 default: 17173 // Otherwise, top is a better choice, so take it. 17174 procState = ActivityManager.PROCESS_STATE_TOP; 17175 break; 17176 } 17177 } 17178 17179 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17180 if (app.hasClientActivities) { 17181 // This is a cached process, but with client activities. Mark it so. 17182 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17183 app.adjType = "cch-client-act"; 17184 } else if (app.treatLikeActivity) { 17185 // This is a cached process, but somebody wants us to treat it like it has 17186 // an activity, okay! 17187 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17188 app.adjType = "cch-as-act"; 17189 } 17190 } 17191 17192 if (adj == ProcessList.SERVICE_ADJ) { 17193 if (doingAll) { 17194 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17195 mNewNumServiceProcs++; 17196 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17197 if (!app.serviceb) { 17198 // This service isn't far enough down on the LRU list to 17199 // normally be a B service, but if we are low on RAM and it 17200 // is large we want to force it down since we would prefer to 17201 // keep launcher over it. 17202 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17203 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17204 app.serviceHighRam = true; 17205 app.serviceb = true; 17206 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17207 } else { 17208 mNewNumAServiceProcs++; 17209 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17210 } 17211 } else { 17212 app.serviceHighRam = false; 17213 } 17214 } 17215 if (app.serviceb) { 17216 adj = ProcessList.SERVICE_B_ADJ; 17217 } 17218 } 17219 17220 app.curRawAdj = adj; 17221 17222 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17223 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17224 if (adj > app.maxAdj) { 17225 adj = app.maxAdj; 17226 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17227 schedGroup = Process.THREAD_GROUP_DEFAULT; 17228 } 17229 } 17230 17231 // Do final modification to adj. Everything we do between here and applying 17232 // the final setAdj must be done in this function, because we will also use 17233 // it when computing the final cached adj later. Note that we don't need to 17234 // worry about this for max adj above, since max adj will always be used to 17235 // keep it out of the cached vaues. 17236 app.curAdj = app.modifyRawOomAdj(adj); 17237 app.curSchedGroup = schedGroup; 17238 app.curProcState = procState; 17239 app.foregroundActivities = foregroundActivities; 17240 17241 return app.curRawAdj; 17242 } 17243 17244 /** 17245 * Schedule PSS collection of a process. 17246 */ 17247 void requestPssLocked(ProcessRecord proc, int procState) { 17248 if (mPendingPssProcesses.contains(proc)) { 17249 return; 17250 } 17251 if (mPendingPssProcesses.size() == 0) { 17252 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17253 } 17254 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17255 proc.pssProcState = procState; 17256 mPendingPssProcesses.add(proc); 17257 } 17258 17259 /** 17260 * Schedule PSS collection of all processes. 17261 */ 17262 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17263 if (!always) { 17264 if (now < (mLastFullPssTime + 17265 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17266 return; 17267 } 17268 } 17269 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17270 mLastFullPssTime = now; 17271 mFullPssPending = true; 17272 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17273 mPendingPssProcesses.clear(); 17274 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17275 ProcessRecord app = mLruProcesses.get(i); 17276 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17277 app.pssProcState = app.setProcState; 17278 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17279 isSleeping(), now); 17280 mPendingPssProcesses.add(app); 17281 } 17282 } 17283 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17284 } 17285 17286 /** 17287 * Ask a given process to GC right now. 17288 */ 17289 final void performAppGcLocked(ProcessRecord app) { 17290 try { 17291 app.lastRequestedGc = SystemClock.uptimeMillis(); 17292 if (app.thread != null) { 17293 if (app.reportLowMemory) { 17294 app.reportLowMemory = false; 17295 app.thread.scheduleLowMemory(); 17296 } else { 17297 app.thread.processInBackground(); 17298 } 17299 } 17300 } catch (Exception e) { 17301 // whatever. 17302 } 17303 } 17304 17305 /** 17306 * Returns true if things are idle enough to perform GCs. 17307 */ 17308 private final boolean canGcNowLocked() { 17309 boolean processingBroadcasts = false; 17310 for (BroadcastQueue q : mBroadcastQueues) { 17311 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17312 processingBroadcasts = true; 17313 } 17314 } 17315 return !processingBroadcasts 17316 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17317 } 17318 17319 /** 17320 * Perform GCs on all processes that are waiting for it, but only 17321 * if things are idle. 17322 */ 17323 final void performAppGcsLocked() { 17324 final int N = mProcessesToGc.size(); 17325 if (N <= 0) { 17326 return; 17327 } 17328 if (canGcNowLocked()) { 17329 while (mProcessesToGc.size() > 0) { 17330 ProcessRecord proc = mProcessesToGc.remove(0); 17331 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17332 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17333 <= SystemClock.uptimeMillis()) { 17334 // To avoid spamming the system, we will GC processes one 17335 // at a time, waiting a few seconds between each. 17336 performAppGcLocked(proc); 17337 scheduleAppGcsLocked(); 17338 return; 17339 } else { 17340 // It hasn't been long enough since we last GCed this 17341 // process... put it in the list to wait for its time. 17342 addProcessToGcListLocked(proc); 17343 break; 17344 } 17345 } 17346 } 17347 17348 scheduleAppGcsLocked(); 17349 } 17350 } 17351 17352 /** 17353 * If all looks good, perform GCs on all processes waiting for them. 17354 */ 17355 final void performAppGcsIfAppropriateLocked() { 17356 if (canGcNowLocked()) { 17357 performAppGcsLocked(); 17358 return; 17359 } 17360 // Still not idle, wait some more. 17361 scheduleAppGcsLocked(); 17362 } 17363 17364 /** 17365 * Schedule the execution of all pending app GCs. 17366 */ 17367 final void scheduleAppGcsLocked() { 17368 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17369 17370 if (mProcessesToGc.size() > 0) { 17371 // Schedule a GC for the time to the next process. 17372 ProcessRecord proc = mProcessesToGc.get(0); 17373 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17374 17375 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17376 long now = SystemClock.uptimeMillis(); 17377 if (when < (now+GC_TIMEOUT)) { 17378 when = now + GC_TIMEOUT; 17379 } 17380 mHandler.sendMessageAtTime(msg, when); 17381 } 17382 } 17383 17384 /** 17385 * Add a process to the array of processes waiting to be GCed. Keeps the 17386 * list in sorted order by the last GC time. The process can't already be 17387 * on the list. 17388 */ 17389 final void addProcessToGcListLocked(ProcessRecord proc) { 17390 boolean added = false; 17391 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17392 if (mProcessesToGc.get(i).lastRequestedGc < 17393 proc.lastRequestedGc) { 17394 added = true; 17395 mProcessesToGc.add(i+1, proc); 17396 break; 17397 } 17398 } 17399 if (!added) { 17400 mProcessesToGc.add(0, proc); 17401 } 17402 } 17403 17404 /** 17405 * Set up to ask a process to GC itself. This will either do it 17406 * immediately, or put it on the list of processes to gc the next 17407 * time things are idle. 17408 */ 17409 final void scheduleAppGcLocked(ProcessRecord app) { 17410 long now = SystemClock.uptimeMillis(); 17411 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17412 return; 17413 } 17414 if (!mProcessesToGc.contains(app)) { 17415 addProcessToGcListLocked(app); 17416 scheduleAppGcsLocked(); 17417 } 17418 } 17419 17420 final void checkExcessivePowerUsageLocked(boolean doKills) { 17421 updateCpuStatsNow(); 17422 17423 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17424 boolean doWakeKills = doKills; 17425 boolean doCpuKills = doKills; 17426 if (mLastPowerCheckRealtime == 0) { 17427 doWakeKills = false; 17428 } 17429 if (mLastPowerCheckUptime == 0) { 17430 doCpuKills = false; 17431 } 17432 if (stats.isScreenOn()) { 17433 doWakeKills = false; 17434 } 17435 final long curRealtime = SystemClock.elapsedRealtime(); 17436 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17437 final long curUptime = SystemClock.uptimeMillis(); 17438 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17439 mLastPowerCheckRealtime = curRealtime; 17440 mLastPowerCheckUptime = curUptime; 17441 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17442 doWakeKills = false; 17443 } 17444 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17445 doCpuKills = false; 17446 } 17447 int i = mLruProcesses.size(); 17448 while (i > 0) { 17449 i--; 17450 ProcessRecord app = mLruProcesses.get(i); 17451 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17452 long wtime; 17453 synchronized (stats) { 17454 wtime = stats.getProcessWakeTime(app.info.uid, 17455 app.pid, curRealtime); 17456 } 17457 long wtimeUsed = wtime - app.lastWakeTime; 17458 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17459 if (DEBUG_POWER) { 17460 StringBuilder sb = new StringBuilder(128); 17461 sb.append("Wake for "); 17462 app.toShortString(sb); 17463 sb.append(": over "); 17464 TimeUtils.formatDuration(realtimeSince, sb); 17465 sb.append(" used "); 17466 TimeUtils.formatDuration(wtimeUsed, sb); 17467 sb.append(" ("); 17468 sb.append((wtimeUsed*100)/realtimeSince); 17469 sb.append("%)"); 17470 Slog.i(TAG, sb.toString()); 17471 sb.setLength(0); 17472 sb.append("CPU for "); 17473 app.toShortString(sb); 17474 sb.append(": over "); 17475 TimeUtils.formatDuration(uptimeSince, sb); 17476 sb.append(" used "); 17477 TimeUtils.formatDuration(cputimeUsed, sb); 17478 sb.append(" ("); 17479 sb.append((cputimeUsed*100)/uptimeSince); 17480 sb.append("%)"); 17481 Slog.i(TAG, sb.toString()); 17482 } 17483 // If a process has held a wake lock for more 17484 // than 50% of the time during this period, 17485 // that sounds bad. Kill! 17486 if (doWakeKills && realtimeSince > 0 17487 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17488 synchronized (stats) { 17489 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17490 realtimeSince, wtimeUsed); 17491 } 17492 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17493 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17494 } else if (doCpuKills && uptimeSince > 0 17495 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17496 synchronized (stats) { 17497 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17498 uptimeSince, cputimeUsed); 17499 } 17500 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17501 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17502 } else { 17503 app.lastWakeTime = wtime; 17504 app.lastCpuTime = app.curCpuTime; 17505 } 17506 } 17507 } 17508 } 17509 17510 private final boolean applyOomAdjLocked(ProcessRecord app, 17511 ProcessRecord TOP_APP, boolean doingAll, long now) { 17512 boolean success = true; 17513 17514 if (app.curRawAdj != app.setRawAdj) { 17515 app.setRawAdj = app.curRawAdj; 17516 } 17517 17518 int changes = 0; 17519 17520 if (app.curAdj != app.setAdj) { 17521 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17522 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17523 TAG, "Set " + app.pid + " " + app.processName + 17524 " adj " + app.curAdj + ": " + app.adjType); 17525 app.setAdj = app.curAdj; 17526 } 17527 17528 if (app.setSchedGroup != app.curSchedGroup) { 17529 app.setSchedGroup = app.curSchedGroup; 17530 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17531 "Setting process group of " + app.processName 17532 + " to " + app.curSchedGroup); 17533 if (app.waitingToKill != null && 17534 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17535 app.kill(app.waitingToKill, true); 17536 success = false; 17537 } else { 17538 if (true) { 17539 long oldId = Binder.clearCallingIdentity(); 17540 try { 17541 Process.setProcessGroup(app.pid, app.curSchedGroup); 17542 } catch (Exception e) { 17543 Slog.w(TAG, "Failed setting process group of " + app.pid 17544 + " to " + app.curSchedGroup); 17545 e.printStackTrace(); 17546 } finally { 17547 Binder.restoreCallingIdentity(oldId); 17548 } 17549 } else { 17550 if (app.thread != null) { 17551 try { 17552 app.thread.setSchedulingGroup(app.curSchedGroup); 17553 } catch (RemoteException e) { 17554 } 17555 } 17556 } 17557 Process.setSwappiness(app.pid, 17558 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17559 } 17560 } 17561 if (app.repForegroundActivities != app.foregroundActivities) { 17562 app.repForegroundActivities = app.foregroundActivities; 17563 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17564 } 17565 if (app.repProcState != app.curProcState) { 17566 app.repProcState = app.curProcState; 17567 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17568 if (app.thread != null) { 17569 try { 17570 if (false) { 17571 //RuntimeException h = new RuntimeException("here"); 17572 Slog.i(TAG, "Sending new process state " + app.repProcState 17573 + " to " + app /*, h*/); 17574 } 17575 app.thread.setProcessState(app.repProcState); 17576 } catch (RemoteException e) { 17577 } 17578 } 17579 } 17580 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17581 app.setProcState)) { 17582 app.lastStateTime = now; 17583 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17584 isSleeping(), now); 17585 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17586 + ProcessList.makeProcStateString(app.setProcState) + " to " 17587 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17588 + (app.nextPssTime-now) + ": " + app); 17589 } else { 17590 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17591 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17592 requestPssLocked(app, app.setProcState); 17593 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17594 isSleeping(), now); 17595 } else if (false && DEBUG_PSS) { 17596 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17597 } 17598 } 17599 if (app.setProcState != app.curProcState) { 17600 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17601 "Proc state change of " + app.processName 17602 + " to " + app.curProcState); 17603 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17604 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17605 if (setImportant && !curImportant) { 17606 // This app is no longer something we consider important enough to allow to 17607 // use arbitrary amounts of battery power. Note 17608 // its current wake lock time to later know to kill it if 17609 // it is not behaving well. 17610 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17611 synchronized (stats) { 17612 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17613 app.pid, SystemClock.elapsedRealtime()); 17614 } 17615 app.lastCpuTime = app.curCpuTime; 17616 17617 } 17618 app.setProcState = app.curProcState; 17619 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17620 app.notCachedSinceIdle = false; 17621 } 17622 if (!doingAll) { 17623 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17624 } else { 17625 app.procStateChanged = true; 17626 } 17627 } 17628 17629 if (changes != 0) { 17630 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17631 int i = mPendingProcessChanges.size()-1; 17632 ProcessChangeItem item = null; 17633 while (i >= 0) { 17634 item = mPendingProcessChanges.get(i); 17635 if (item.pid == app.pid) { 17636 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17637 break; 17638 } 17639 i--; 17640 } 17641 if (i < 0) { 17642 // No existing item in pending changes; need a new one. 17643 final int NA = mAvailProcessChanges.size(); 17644 if (NA > 0) { 17645 item = mAvailProcessChanges.remove(NA-1); 17646 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17647 } else { 17648 item = new ProcessChangeItem(); 17649 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17650 } 17651 item.changes = 0; 17652 item.pid = app.pid; 17653 item.uid = app.info.uid; 17654 if (mPendingProcessChanges.size() == 0) { 17655 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17656 "*** Enqueueing dispatch processes changed!"); 17657 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17658 } 17659 mPendingProcessChanges.add(item); 17660 } 17661 item.changes |= changes; 17662 item.processState = app.repProcState; 17663 item.foregroundActivities = app.repForegroundActivities; 17664 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17665 + Integer.toHexString(System.identityHashCode(item)) 17666 + " " + app.toShortString() + ": changes=" + item.changes 17667 + " procState=" + item.processState 17668 + " foreground=" + item.foregroundActivities 17669 + " type=" + app.adjType + " source=" + app.adjSource 17670 + " target=" + app.adjTarget); 17671 } 17672 17673 return success; 17674 } 17675 17676 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17677 if (proc.thread != null) { 17678 if (proc.baseProcessTracker != null) { 17679 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17680 } 17681 if (proc.repProcState >= 0) { 17682 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17683 proc.repProcState); 17684 } 17685 } 17686 } 17687 17688 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17689 ProcessRecord TOP_APP, boolean doingAll, long now) { 17690 if (app.thread == null) { 17691 return false; 17692 } 17693 17694 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17695 17696 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17697 } 17698 17699 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17700 boolean oomAdj) { 17701 if (isForeground != proc.foregroundServices) { 17702 proc.foregroundServices = isForeground; 17703 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17704 proc.info.uid); 17705 if (isForeground) { 17706 if (curProcs == null) { 17707 curProcs = new ArrayList<ProcessRecord>(); 17708 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17709 } 17710 if (!curProcs.contains(proc)) { 17711 curProcs.add(proc); 17712 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17713 proc.info.packageName, proc.info.uid); 17714 } 17715 } else { 17716 if (curProcs != null) { 17717 if (curProcs.remove(proc)) { 17718 mBatteryStatsService.noteEvent( 17719 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17720 proc.info.packageName, proc.info.uid); 17721 if (curProcs.size() <= 0) { 17722 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17723 } 17724 } 17725 } 17726 } 17727 if (oomAdj) { 17728 updateOomAdjLocked(); 17729 } 17730 } 17731 } 17732 17733 private final ActivityRecord resumedAppLocked() { 17734 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17735 String pkg; 17736 int uid; 17737 if (act != null) { 17738 pkg = act.packageName; 17739 uid = act.info.applicationInfo.uid; 17740 } else { 17741 pkg = null; 17742 uid = -1; 17743 } 17744 // Has the UID or resumed package name changed? 17745 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17746 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17747 if (mCurResumedPackage != null) { 17748 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17749 mCurResumedPackage, mCurResumedUid); 17750 } 17751 mCurResumedPackage = pkg; 17752 mCurResumedUid = uid; 17753 if (mCurResumedPackage != null) { 17754 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17755 mCurResumedPackage, mCurResumedUid); 17756 } 17757 } 17758 return act; 17759 } 17760 17761 final boolean updateOomAdjLocked(ProcessRecord app) { 17762 final ActivityRecord TOP_ACT = resumedAppLocked(); 17763 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17764 final boolean wasCached = app.cached; 17765 17766 mAdjSeq++; 17767 17768 // This is the desired cached adjusment we want to tell it to use. 17769 // If our app is currently cached, we know it, and that is it. Otherwise, 17770 // we don't know it yet, and it needs to now be cached we will then 17771 // need to do a complete oom adj. 17772 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17773 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17774 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17775 SystemClock.uptimeMillis()); 17776 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17777 // Changed to/from cached state, so apps after it in the LRU 17778 // list may also be changed. 17779 updateOomAdjLocked(); 17780 } 17781 return success; 17782 } 17783 17784 final void updateOomAdjLocked() { 17785 final ActivityRecord TOP_ACT = resumedAppLocked(); 17786 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17787 final long now = SystemClock.uptimeMillis(); 17788 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17789 final int N = mLruProcesses.size(); 17790 17791 if (false) { 17792 RuntimeException e = new RuntimeException(); 17793 e.fillInStackTrace(); 17794 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17795 } 17796 17797 mAdjSeq++; 17798 mNewNumServiceProcs = 0; 17799 mNewNumAServiceProcs = 0; 17800 17801 final int emptyProcessLimit; 17802 final int cachedProcessLimit; 17803 if (mProcessLimit <= 0) { 17804 emptyProcessLimit = cachedProcessLimit = 0; 17805 } else if (mProcessLimit == 1) { 17806 emptyProcessLimit = 1; 17807 cachedProcessLimit = 0; 17808 } else { 17809 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17810 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17811 } 17812 17813 // Let's determine how many processes we have running vs. 17814 // how many slots we have for background processes; we may want 17815 // to put multiple processes in a slot of there are enough of 17816 // them. 17817 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17818 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17819 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17820 if (numEmptyProcs > cachedProcessLimit) { 17821 // If there are more empty processes than our limit on cached 17822 // processes, then use the cached process limit for the factor. 17823 // This ensures that the really old empty processes get pushed 17824 // down to the bottom, so if we are running low on memory we will 17825 // have a better chance at keeping around more cached processes 17826 // instead of a gazillion empty processes. 17827 numEmptyProcs = cachedProcessLimit; 17828 } 17829 int emptyFactor = numEmptyProcs/numSlots; 17830 if (emptyFactor < 1) emptyFactor = 1; 17831 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17832 if (cachedFactor < 1) cachedFactor = 1; 17833 int stepCached = 0; 17834 int stepEmpty = 0; 17835 int numCached = 0; 17836 int numEmpty = 0; 17837 int numTrimming = 0; 17838 17839 mNumNonCachedProcs = 0; 17840 mNumCachedHiddenProcs = 0; 17841 17842 // First update the OOM adjustment for each of the 17843 // application processes based on their current state. 17844 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17845 int nextCachedAdj = curCachedAdj+1; 17846 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17847 int nextEmptyAdj = curEmptyAdj+2; 17848 for (int i=N-1; i>=0; i--) { 17849 ProcessRecord app = mLruProcesses.get(i); 17850 if (!app.killedByAm && app.thread != null) { 17851 app.procStateChanged = false; 17852 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17853 17854 // If we haven't yet assigned the final cached adj 17855 // to the process, do that now. 17856 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17857 switch (app.curProcState) { 17858 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17859 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17860 // This process is a cached process holding activities... 17861 // assign it the next cached value for that type, and then 17862 // step that cached level. 17863 app.curRawAdj = curCachedAdj; 17864 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17865 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17866 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17867 + ")"); 17868 if (curCachedAdj != nextCachedAdj) { 17869 stepCached++; 17870 if (stepCached >= cachedFactor) { 17871 stepCached = 0; 17872 curCachedAdj = nextCachedAdj; 17873 nextCachedAdj += 2; 17874 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17875 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17876 } 17877 } 17878 } 17879 break; 17880 default: 17881 // For everything else, assign next empty cached process 17882 // level and bump that up. Note that this means that 17883 // long-running services that have dropped down to the 17884 // cached level will be treated as empty (since their process 17885 // state is still as a service), which is what we want. 17886 app.curRawAdj = curEmptyAdj; 17887 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17888 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17889 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17890 + ")"); 17891 if (curEmptyAdj != nextEmptyAdj) { 17892 stepEmpty++; 17893 if (stepEmpty >= emptyFactor) { 17894 stepEmpty = 0; 17895 curEmptyAdj = nextEmptyAdj; 17896 nextEmptyAdj += 2; 17897 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17898 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17899 } 17900 } 17901 } 17902 break; 17903 } 17904 } 17905 17906 applyOomAdjLocked(app, TOP_APP, true, now); 17907 17908 // Count the number of process types. 17909 switch (app.curProcState) { 17910 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17911 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17912 mNumCachedHiddenProcs++; 17913 numCached++; 17914 if (numCached > cachedProcessLimit) { 17915 app.kill("cached #" + numCached, true); 17916 } 17917 break; 17918 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17919 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17920 && app.lastActivityTime < oldTime) { 17921 app.kill("empty for " 17922 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17923 / 1000) + "s", true); 17924 } else { 17925 numEmpty++; 17926 if (numEmpty > emptyProcessLimit) { 17927 app.kill("empty #" + numEmpty, true); 17928 } 17929 } 17930 break; 17931 default: 17932 mNumNonCachedProcs++; 17933 break; 17934 } 17935 17936 if (app.isolated && app.services.size() <= 0) { 17937 // If this is an isolated process, and there are no 17938 // services running in it, then the process is no longer 17939 // needed. We agressively kill these because we can by 17940 // definition not re-use the same process again, and it is 17941 // good to avoid having whatever code was running in them 17942 // left sitting around after no longer needed. 17943 app.kill("isolated not needed", true); 17944 } 17945 17946 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17947 && !app.killedByAm) { 17948 numTrimming++; 17949 } 17950 } 17951 } 17952 17953 mNumServiceProcs = mNewNumServiceProcs; 17954 17955 // Now determine the memory trimming level of background processes. 17956 // Unfortunately we need to start at the back of the list to do this 17957 // properly. We only do this if the number of background apps we 17958 // are managing to keep around is less than half the maximum we desire; 17959 // if we are keeping a good number around, we'll let them use whatever 17960 // memory they want. 17961 final int numCachedAndEmpty = numCached + numEmpty; 17962 int memFactor; 17963 if (numCached <= ProcessList.TRIM_CACHED_APPS 17964 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17965 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17966 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17967 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17968 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17969 } else { 17970 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17971 } 17972 } else { 17973 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17974 } 17975 // We always allow the memory level to go up (better). We only allow it to go 17976 // down if we are in a state where that is allowed, *and* the total number of processes 17977 // has gone down since last time. 17978 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17979 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17980 + " last=" + mLastNumProcesses); 17981 if (memFactor > mLastMemoryLevel) { 17982 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17983 memFactor = mLastMemoryLevel; 17984 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17985 } 17986 } 17987 mLastMemoryLevel = memFactor; 17988 mLastNumProcesses = mLruProcesses.size(); 17989 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17990 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17991 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17992 if (mLowRamStartTime == 0) { 17993 mLowRamStartTime = now; 17994 } 17995 int step = 0; 17996 int fgTrimLevel; 17997 switch (memFactor) { 17998 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17999 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18000 break; 18001 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18002 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18003 break; 18004 default: 18005 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18006 break; 18007 } 18008 int factor = numTrimming/3; 18009 int minFactor = 2; 18010 if (mHomeProcess != null) minFactor++; 18011 if (mPreviousProcess != null) minFactor++; 18012 if (factor < minFactor) factor = minFactor; 18013 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18014 for (int i=N-1; i>=0; i--) { 18015 ProcessRecord app = mLruProcesses.get(i); 18016 if (allChanged || app.procStateChanged) { 18017 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18018 app.procStateChanged = false; 18019 } 18020 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18021 && !app.killedByAm) { 18022 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18023 try { 18024 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18025 "Trimming memory of " + app.processName 18026 + " to " + curLevel); 18027 app.thread.scheduleTrimMemory(curLevel); 18028 } catch (RemoteException e) { 18029 } 18030 if (false) { 18031 // For now we won't do this; our memory trimming seems 18032 // to be good enough at this point that destroying 18033 // activities causes more harm than good. 18034 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18035 && app != mHomeProcess && app != mPreviousProcess) { 18036 // Need to do this on its own message because the stack may not 18037 // be in a consistent state at this point. 18038 // For these apps we will also finish their activities 18039 // to help them free memory. 18040 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18041 } 18042 } 18043 } 18044 app.trimMemoryLevel = curLevel; 18045 step++; 18046 if (step >= factor) { 18047 step = 0; 18048 switch (curLevel) { 18049 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18050 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18051 break; 18052 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18053 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18054 break; 18055 } 18056 } 18057 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18058 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18059 && app.thread != null) { 18060 try { 18061 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18062 "Trimming memory of heavy-weight " + app.processName 18063 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18064 app.thread.scheduleTrimMemory( 18065 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18066 } catch (RemoteException e) { 18067 } 18068 } 18069 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18070 } else { 18071 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18072 || app.systemNoUi) && app.pendingUiClean) { 18073 // If this application is now in the background and it 18074 // had done UI, then give it the special trim level to 18075 // have it free UI resources. 18076 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18077 if (app.trimMemoryLevel < level && app.thread != null) { 18078 try { 18079 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18080 "Trimming memory of bg-ui " + app.processName 18081 + " to " + level); 18082 app.thread.scheduleTrimMemory(level); 18083 } catch (RemoteException e) { 18084 } 18085 } 18086 app.pendingUiClean = false; 18087 } 18088 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18089 try { 18090 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18091 "Trimming memory of fg " + app.processName 18092 + " to " + fgTrimLevel); 18093 app.thread.scheduleTrimMemory(fgTrimLevel); 18094 } catch (RemoteException e) { 18095 } 18096 } 18097 app.trimMemoryLevel = fgTrimLevel; 18098 } 18099 } 18100 } else { 18101 if (mLowRamStartTime != 0) { 18102 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18103 mLowRamStartTime = 0; 18104 } 18105 for (int i=N-1; i>=0; i--) { 18106 ProcessRecord app = mLruProcesses.get(i); 18107 if (allChanged || app.procStateChanged) { 18108 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18109 app.procStateChanged = false; 18110 } 18111 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18112 || app.systemNoUi) && app.pendingUiClean) { 18113 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18114 && app.thread != null) { 18115 try { 18116 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18117 "Trimming memory of ui hidden " + app.processName 18118 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18119 app.thread.scheduleTrimMemory( 18120 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18121 } catch (RemoteException e) { 18122 } 18123 } 18124 app.pendingUiClean = false; 18125 } 18126 app.trimMemoryLevel = 0; 18127 } 18128 } 18129 18130 if (mAlwaysFinishActivities) { 18131 // Need to do this on its own message because the stack may not 18132 // be in a consistent state at this point. 18133 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18134 } 18135 18136 if (allChanged) { 18137 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18138 } 18139 18140 if (mProcessStats.shouldWriteNowLocked(now)) { 18141 mHandler.post(new Runnable() { 18142 @Override public void run() { 18143 synchronized (ActivityManagerService.this) { 18144 mProcessStats.writeStateAsyncLocked(); 18145 } 18146 } 18147 }); 18148 } 18149 18150 if (DEBUG_OOM_ADJ) { 18151 if (false) { 18152 RuntimeException here = new RuntimeException("here"); 18153 here.fillInStackTrace(); 18154 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18155 } else { 18156 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18157 } 18158 } 18159 } 18160 18161 final void trimApplications() { 18162 synchronized (this) { 18163 int i; 18164 18165 // First remove any unused application processes whose package 18166 // has been removed. 18167 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18168 final ProcessRecord app = mRemovedProcesses.get(i); 18169 if (app.activities.size() == 0 18170 && app.curReceiver == null && app.services.size() == 0) { 18171 Slog.i( 18172 TAG, "Exiting empty application process " 18173 + app.processName + " (" 18174 + (app.thread != null ? app.thread.asBinder() : null) 18175 + ")\n"); 18176 if (app.pid > 0 && app.pid != MY_PID) { 18177 app.kill("empty", false); 18178 } else { 18179 try { 18180 app.thread.scheduleExit(); 18181 } catch (Exception e) { 18182 // Ignore exceptions. 18183 } 18184 } 18185 cleanUpApplicationRecordLocked(app, false, true, -1); 18186 mRemovedProcesses.remove(i); 18187 18188 if (app.persistent) { 18189 addAppLocked(app.info, false, null /* ABI override */); 18190 } 18191 } 18192 } 18193 18194 // Now update the oom adj for all processes. 18195 updateOomAdjLocked(); 18196 } 18197 } 18198 18199 /** This method sends the specified signal to each of the persistent apps */ 18200 public void signalPersistentProcesses(int sig) throws RemoteException { 18201 if (sig != Process.SIGNAL_USR1) { 18202 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18203 } 18204 18205 synchronized (this) { 18206 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18207 != PackageManager.PERMISSION_GRANTED) { 18208 throw new SecurityException("Requires permission " 18209 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18210 } 18211 18212 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18213 ProcessRecord r = mLruProcesses.get(i); 18214 if (r.thread != null && r.persistent) { 18215 Process.sendSignal(r.pid, sig); 18216 } 18217 } 18218 } 18219 } 18220 18221 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18222 if (proc == null || proc == mProfileProc) { 18223 proc = mProfileProc; 18224 profileType = mProfileType; 18225 clearProfilerLocked(); 18226 } 18227 if (proc == null) { 18228 return; 18229 } 18230 try { 18231 proc.thread.profilerControl(false, null, profileType); 18232 } catch (RemoteException e) { 18233 throw new IllegalStateException("Process disappeared"); 18234 } 18235 } 18236 18237 private void clearProfilerLocked() { 18238 if (mProfileFd != null) { 18239 try { 18240 mProfileFd.close(); 18241 } catch (IOException e) { 18242 } 18243 } 18244 mProfileApp = null; 18245 mProfileProc = null; 18246 mProfileFile = null; 18247 mProfileType = 0; 18248 mAutoStopProfiler = false; 18249 mSamplingInterval = 0; 18250 } 18251 18252 public boolean profileControl(String process, int userId, boolean start, 18253 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18254 18255 try { 18256 synchronized (this) { 18257 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18258 // its own permission. 18259 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18260 != PackageManager.PERMISSION_GRANTED) { 18261 throw new SecurityException("Requires permission " 18262 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18263 } 18264 18265 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18266 throw new IllegalArgumentException("null profile info or fd"); 18267 } 18268 18269 ProcessRecord proc = null; 18270 if (process != null) { 18271 proc = findProcessLocked(process, userId, "profileControl"); 18272 } 18273 18274 if (start && (proc == null || proc.thread == null)) { 18275 throw new IllegalArgumentException("Unknown process: " + process); 18276 } 18277 18278 if (start) { 18279 stopProfilerLocked(null, 0); 18280 setProfileApp(proc.info, proc.processName, profilerInfo); 18281 mProfileProc = proc; 18282 mProfileType = profileType; 18283 ParcelFileDescriptor fd = profilerInfo.profileFd; 18284 try { 18285 fd = fd.dup(); 18286 } catch (IOException e) { 18287 fd = null; 18288 } 18289 profilerInfo.profileFd = fd; 18290 proc.thread.profilerControl(start, profilerInfo, profileType); 18291 fd = null; 18292 mProfileFd = null; 18293 } else { 18294 stopProfilerLocked(proc, profileType); 18295 if (profilerInfo != null && profilerInfo.profileFd != null) { 18296 try { 18297 profilerInfo.profileFd.close(); 18298 } catch (IOException e) { 18299 } 18300 } 18301 } 18302 18303 return true; 18304 } 18305 } catch (RemoteException e) { 18306 throw new IllegalStateException("Process disappeared"); 18307 } finally { 18308 if (profilerInfo != null && profilerInfo.profileFd != null) { 18309 try { 18310 profilerInfo.profileFd.close(); 18311 } catch (IOException e) { 18312 } 18313 } 18314 } 18315 } 18316 18317 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18318 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18319 userId, true, ALLOW_FULL_ONLY, callName, null); 18320 ProcessRecord proc = null; 18321 try { 18322 int pid = Integer.parseInt(process); 18323 synchronized (mPidsSelfLocked) { 18324 proc = mPidsSelfLocked.get(pid); 18325 } 18326 } catch (NumberFormatException e) { 18327 } 18328 18329 if (proc == null) { 18330 ArrayMap<String, SparseArray<ProcessRecord>> all 18331 = mProcessNames.getMap(); 18332 SparseArray<ProcessRecord> procs = all.get(process); 18333 if (procs != null && procs.size() > 0) { 18334 proc = procs.valueAt(0); 18335 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18336 for (int i=1; i<procs.size(); i++) { 18337 ProcessRecord thisProc = procs.valueAt(i); 18338 if (thisProc.userId == userId) { 18339 proc = thisProc; 18340 break; 18341 } 18342 } 18343 } 18344 } 18345 } 18346 18347 return proc; 18348 } 18349 18350 public boolean dumpHeap(String process, int userId, boolean managed, 18351 String path, ParcelFileDescriptor fd) throws RemoteException { 18352 18353 try { 18354 synchronized (this) { 18355 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18356 // its own permission (same as profileControl). 18357 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18358 != PackageManager.PERMISSION_GRANTED) { 18359 throw new SecurityException("Requires permission " 18360 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18361 } 18362 18363 if (fd == null) { 18364 throw new IllegalArgumentException("null fd"); 18365 } 18366 18367 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18368 if (proc == null || proc.thread == null) { 18369 throw new IllegalArgumentException("Unknown process: " + process); 18370 } 18371 18372 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18373 if (!isDebuggable) { 18374 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18375 throw new SecurityException("Process not debuggable: " + proc); 18376 } 18377 } 18378 18379 proc.thread.dumpHeap(managed, path, fd); 18380 fd = null; 18381 return true; 18382 } 18383 } catch (RemoteException e) { 18384 throw new IllegalStateException("Process disappeared"); 18385 } finally { 18386 if (fd != null) { 18387 try { 18388 fd.close(); 18389 } catch (IOException e) { 18390 } 18391 } 18392 } 18393 } 18394 18395 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18396 public void monitor() { 18397 synchronized (this) { } 18398 } 18399 18400 void onCoreSettingsChange(Bundle settings) { 18401 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18402 ProcessRecord processRecord = mLruProcesses.get(i); 18403 try { 18404 if (processRecord.thread != null) { 18405 processRecord.thread.setCoreSettings(settings); 18406 } 18407 } catch (RemoteException re) { 18408 /* ignore */ 18409 } 18410 } 18411 } 18412 18413 // Multi-user methods 18414 18415 /** 18416 * Start user, if its not already running, but don't bring it to foreground. 18417 */ 18418 @Override 18419 public boolean startUserInBackground(final int userId) { 18420 return startUser(userId, /* foreground */ false); 18421 } 18422 18423 /** 18424 * Start user, if its not already running, and bring it to foreground. 18425 */ 18426 boolean startUserInForeground(final int userId, Dialog dlg) { 18427 boolean result = startUser(userId, /* foreground */ true); 18428 dlg.dismiss(); 18429 return result; 18430 } 18431 18432 /** 18433 * Refreshes the list of users related to the current user when either a 18434 * user switch happens or when a new related user is started in the 18435 * background. 18436 */ 18437 private void updateCurrentProfileIdsLocked() { 18438 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18439 mCurrentUserId, false /* enabledOnly */); 18440 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18441 for (int i = 0; i < currentProfileIds.length; i++) { 18442 currentProfileIds[i] = profiles.get(i).id; 18443 } 18444 mCurrentProfileIds = currentProfileIds; 18445 18446 synchronized (mUserProfileGroupIdsSelfLocked) { 18447 mUserProfileGroupIdsSelfLocked.clear(); 18448 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18449 for (int i = 0; i < users.size(); i++) { 18450 UserInfo user = users.get(i); 18451 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18452 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18453 } 18454 } 18455 } 18456 } 18457 18458 private Set getProfileIdsLocked(int userId) { 18459 Set userIds = new HashSet<Integer>(); 18460 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18461 userId, false /* enabledOnly */); 18462 for (UserInfo user : profiles) { 18463 userIds.add(Integer.valueOf(user.id)); 18464 } 18465 return userIds; 18466 } 18467 18468 @Override 18469 public boolean switchUser(final int userId) { 18470 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18471 String userName; 18472 synchronized (this) { 18473 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18474 if (userInfo == null) { 18475 Slog.w(TAG, "No user info for user #" + userId); 18476 return false; 18477 } 18478 if (userInfo.isManagedProfile()) { 18479 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18480 return false; 18481 } 18482 userName = userInfo.name; 18483 mTargetUserId = userId; 18484 } 18485 mHandler.removeMessages(START_USER_SWITCH_MSG); 18486 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18487 return true; 18488 } 18489 18490 private void showUserSwitchDialog(int userId, String userName) { 18491 // The dialog will show and then initiate the user switch by calling startUserInForeground 18492 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18493 true /* above system */); 18494 d.show(); 18495 } 18496 18497 private boolean startUser(final int userId, final boolean foreground) { 18498 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18499 != PackageManager.PERMISSION_GRANTED) { 18500 String msg = "Permission Denial: switchUser() from pid=" 18501 + Binder.getCallingPid() 18502 + ", uid=" + Binder.getCallingUid() 18503 + " requires " + INTERACT_ACROSS_USERS_FULL; 18504 Slog.w(TAG, msg); 18505 throw new SecurityException(msg); 18506 } 18507 18508 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18509 18510 final long ident = Binder.clearCallingIdentity(); 18511 try { 18512 synchronized (this) { 18513 final int oldUserId = mCurrentUserId; 18514 if (oldUserId == userId) { 18515 return true; 18516 } 18517 18518 mStackSupervisor.setLockTaskModeLocked(null, false); 18519 18520 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18521 if (userInfo == null) { 18522 Slog.w(TAG, "No user info for user #" + userId); 18523 return false; 18524 } 18525 if (foreground && userInfo.isManagedProfile()) { 18526 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18527 return false; 18528 } 18529 18530 if (foreground) { 18531 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18532 R.anim.screen_user_enter); 18533 } 18534 18535 boolean needStart = false; 18536 18537 // If the user we are switching to is not currently started, then 18538 // we need to start it now. 18539 if (mStartedUsers.get(userId) == null) { 18540 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18541 updateStartedUserArrayLocked(); 18542 needStart = true; 18543 } 18544 18545 final Integer userIdInt = Integer.valueOf(userId); 18546 mUserLru.remove(userIdInt); 18547 mUserLru.add(userIdInt); 18548 18549 if (foreground) { 18550 mCurrentUserId = userId; 18551 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18552 updateCurrentProfileIdsLocked(); 18553 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18554 // Once the internal notion of the active user has switched, we lock the device 18555 // with the option to show the user switcher on the keyguard. 18556 mWindowManager.lockNow(null); 18557 } else { 18558 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18559 updateCurrentProfileIdsLocked(); 18560 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18561 mUserLru.remove(currentUserIdInt); 18562 mUserLru.add(currentUserIdInt); 18563 } 18564 18565 final UserStartedState uss = mStartedUsers.get(userId); 18566 18567 // Make sure user is in the started state. If it is currently 18568 // stopping, we need to knock that off. 18569 if (uss.mState == UserStartedState.STATE_STOPPING) { 18570 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18571 // so we can just fairly silently bring the user back from 18572 // the almost-dead. 18573 uss.mState = UserStartedState.STATE_RUNNING; 18574 updateStartedUserArrayLocked(); 18575 needStart = true; 18576 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18577 // This means ACTION_SHUTDOWN has been sent, so we will 18578 // need to treat this as a new boot of the user. 18579 uss.mState = UserStartedState.STATE_BOOTING; 18580 updateStartedUserArrayLocked(); 18581 needStart = true; 18582 } 18583 18584 if (uss.mState == UserStartedState.STATE_BOOTING) { 18585 // Booting up a new user, need to tell system services about it. 18586 // Note that this is on the same handler as scheduling of broadcasts, 18587 // which is important because it needs to go first. 18588 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18589 } 18590 18591 if (foreground) { 18592 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18593 oldUserId)); 18594 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18595 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18596 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18597 oldUserId, userId, uss)); 18598 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18599 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18600 } 18601 18602 if (needStart) { 18603 // Send USER_STARTED broadcast 18604 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18605 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18606 | Intent.FLAG_RECEIVER_FOREGROUND); 18607 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18608 broadcastIntentLocked(null, null, intent, 18609 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18610 false, false, MY_PID, Process.SYSTEM_UID, userId); 18611 } 18612 18613 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18614 if (userId != UserHandle.USER_OWNER) { 18615 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18616 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18617 broadcastIntentLocked(null, null, intent, null, 18618 new IIntentReceiver.Stub() { 18619 public void performReceive(Intent intent, int resultCode, 18620 String data, Bundle extras, boolean ordered, 18621 boolean sticky, int sendingUser) { 18622 onUserInitialized(uss, foreground, oldUserId, userId); 18623 } 18624 }, 0, null, null, null, AppOpsManager.OP_NONE, 18625 true, false, MY_PID, Process.SYSTEM_UID, 18626 userId); 18627 uss.initializing = true; 18628 } else { 18629 getUserManagerLocked().makeInitialized(userInfo.id); 18630 } 18631 } 18632 18633 if (foreground) { 18634 if (!uss.initializing) { 18635 moveUserToForeground(uss, oldUserId, userId); 18636 } 18637 } else { 18638 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18639 } 18640 18641 if (needStart) { 18642 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18643 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18644 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18645 broadcastIntentLocked(null, null, intent, 18646 null, new IIntentReceiver.Stub() { 18647 @Override 18648 public void performReceive(Intent intent, int resultCode, String data, 18649 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18650 throws RemoteException { 18651 } 18652 }, 0, null, null, 18653 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18654 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18655 } 18656 } 18657 } finally { 18658 Binder.restoreCallingIdentity(ident); 18659 } 18660 18661 return true; 18662 } 18663 18664 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18665 long ident = Binder.clearCallingIdentity(); 18666 try { 18667 Intent intent; 18668 if (oldUserId >= 0) { 18669 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18670 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18671 int count = profiles.size(); 18672 for (int i = 0; i < count; i++) { 18673 int profileUserId = profiles.get(i).id; 18674 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18675 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18676 | Intent.FLAG_RECEIVER_FOREGROUND); 18677 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18678 broadcastIntentLocked(null, null, intent, 18679 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18680 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18681 } 18682 } 18683 if (newUserId >= 0) { 18684 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18685 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18686 int count = profiles.size(); 18687 for (int i = 0; i < count; i++) { 18688 int profileUserId = profiles.get(i).id; 18689 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18690 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18691 | Intent.FLAG_RECEIVER_FOREGROUND); 18692 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18693 broadcastIntentLocked(null, null, intent, 18694 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18695 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18696 } 18697 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18698 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18699 | Intent.FLAG_RECEIVER_FOREGROUND); 18700 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18701 broadcastIntentLocked(null, null, intent, 18702 null, null, 0, null, null, 18703 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18704 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18705 } 18706 } finally { 18707 Binder.restoreCallingIdentity(ident); 18708 } 18709 } 18710 18711 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18712 final int newUserId) { 18713 final int N = mUserSwitchObservers.beginBroadcast(); 18714 if (N > 0) { 18715 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18716 int mCount = 0; 18717 @Override 18718 public void sendResult(Bundle data) throws RemoteException { 18719 synchronized (ActivityManagerService.this) { 18720 if (mCurUserSwitchCallback == this) { 18721 mCount++; 18722 if (mCount == N) { 18723 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18724 } 18725 } 18726 } 18727 } 18728 }; 18729 synchronized (this) { 18730 uss.switching = true; 18731 mCurUserSwitchCallback = callback; 18732 } 18733 for (int i=0; i<N; i++) { 18734 try { 18735 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18736 newUserId, callback); 18737 } catch (RemoteException e) { 18738 } 18739 } 18740 } else { 18741 synchronized (this) { 18742 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18743 } 18744 } 18745 mUserSwitchObservers.finishBroadcast(); 18746 } 18747 18748 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18749 synchronized (this) { 18750 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18751 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18752 } 18753 } 18754 18755 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18756 mCurUserSwitchCallback = null; 18757 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18758 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18759 oldUserId, newUserId, uss)); 18760 } 18761 18762 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18763 synchronized (this) { 18764 if (foreground) { 18765 moveUserToForeground(uss, oldUserId, newUserId); 18766 } 18767 } 18768 18769 completeSwitchAndInitalize(uss, newUserId, true, false); 18770 } 18771 18772 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18773 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18774 if (homeInFront) { 18775 startHomeActivityLocked(newUserId); 18776 } else { 18777 mStackSupervisor.resumeTopActivitiesLocked(); 18778 } 18779 EventLogTags.writeAmSwitchUser(newUserId); 18780 getUserManagerLocked().userForeground(newUserId); 18781 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18782 } 18783 18784 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18785 completeSwitchAndInitalize(uss, newUserId, false, true); 18786 } 18787 18788 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18789 boolean clearInitializing, boolean clearSwitching) { 18790 boolean unfrozen = false; 18791 synchronized (this) { 18792 if (clearInitializing) { 18793 uss.initializing = false; 18794 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18795 } 18796 if (clearSwitching) { 18797 uss.switching = false; 18798 } 18799 if (!uss.switching && !uss.initializing) { 18800 mWindowManager.stopFreezingScreen(); 18801 unfrozen = true; 18802 } 18803 } 18804 if (unfrozen) { 18805 final int N = mUserSwitchObservers.beginBroadcast(); 18806 for (int i=0; i<N; i++) { 18807 try { 18808 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18809 } catch (RemoteException e) { 18810 } 18811 } 18812 mUserSwitchObservers.finishBroadcast(); 18813 } 18814 } 18815 18816 void scheduleStartProfilesLocked() { 18817 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18818 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18819 DateUtils.SECOND_IN_MILLIS); 18820 } 18821 } 18822 18823 void startProfilesLocked() { 18824 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18825 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18826 mCurrentUserId, false /* enabledOnly */); 18827 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18828 for (UserInfo user : profiles) { 18829 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18830 && user.id != mCurrentUserId) { 18831 toStart.add(user); 18832 } 18833 } 18834 final int n = toStart.size(); 18835 int i = 0; 18836 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18837 startUserInBackground(toStart.get(i).id); 18838 } 18839 if (i < n) { 18840 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18841 } 18842 } 18843 18844 void finishUserBoot(UserStartedState uss) { 18845 synchronized (this) { 18846 if (uss.mState == UserStartedState.STATE_BOOTING 18847 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18848 uss.mState = UserStartedState.STATE_RUNNING; 18849 final int userId = uss.mHandle.getIdentifier(); 18850 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18851 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18852 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18853 broadcastIntentLocked(null, null, intent, 18854 null, null, 0, null, null, 18855 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18856 true, false, MY_PID, Process.SYSTEM_UID, userId); 18857 } 18858 } 18859 } 18860 18861 void finishUserSwitch(UserStartedState uss) { 18862 synchronized (this) { 18863 finishUserBoot(uss); 18864 18865 startProfilesLocked(); 18866 18867 int num = mUserLru.size(); 18868 int i = 0; 18869 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18870 Integer oldUserId = mUserLru.get(i); 18871 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18872 if (oldUss == null) { 18873 // Shouldn't happen, but be sane if it does. 18874 mUserLru.remove(i); 18875 num--; 18876 continue; 18877 } 18878 if (oldUss.mState == UserStartedState.STATE_STOPPING 18879 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18880 // This user is already stopping, doesn't count. 18881 num--; 18882 i++; 18883 continue; 18884 } 18885 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18886 // Owner and current can't be stopped, but count as running. 18887 i++; 18888 continue; 18889 } 18890 // This is a user to be stopped. 18891 stopUserLocked(oldUserId, null); 18892 num--; 18893 i++; 18894 } 18895 } 18896 } 18897 18898 @Override 18899 public int stopUser(final int userId, final IStopUserCallback callback) { 18900 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18901 != PackageManager.PERMISSION_GRANTED) { 18902 String msg = "Permission Denial: switchUser() from pid=" 18903 + Binder.getCallingPid() 18904 + ", uid=" + Binder.getCallingUid() 18905 + " requires " + INTERACT_ACROSS_USERS_FULL; 18906 Slog.w(TAG, msg); 18907 throw new SecurityException(msg); 18908 } 18909 if (userId <= 0) { 18910 throw new IllegalArgumentException("Can't stop primary user " + userId); 18911 } 18912 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18913 synchronized (this) { 18914 return stopUserLocked(userId, callback); 18915 } 18916 } 18917 18918 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18919 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18920 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18921 return ActivityManager.USER_OP_IS_CURRENT; 18922 } 18923 18924 final UserStartedState uss = mStartedUsers.get(userId); 18925 if (uss == null) { 18926 // User is not started, nothing to do... but we do need to 18927 // callback if requested. 18928 if (callback != null) { 18929 mHandler.post(new Runnable() { 18930 @Override 18931 public void run() { 18932 try { 18933 callback.userStopped(userId); 18934 } catch (RemoteException e) { 18935 } 18936 } 18937 }); 18938 } 18939 return ActivityManager.USER_OP_SUCCESS; 18940 } 18941 18942 if (callback != null) { 18943 uss.mStopCallbacks.add(callback); 18944 } 18945 18946 if (uss.mState != UserStartedState.STATE_STOPPING 18947 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18948 uss.mState = UserStartedState.STATE_STOPPING; 18949 updateStartedUserArrayLocked(); 18950 18951 long ident = Binder.clearCallingIdentity(); 18952 try { 18953 // We are going to broadcast ACTION_USER_STOPPING and then 18954 // once that is done send a final ACTION_SHUTDOWN and then 18955 // stop the user. 18956 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18957 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18958 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18959 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18960 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18961 // This is the result receiver for the final shutdown broadcast. 18962 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18963 @Override 18964 public void performReceive(Intent intent, int resultCode, String data, 18965 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18966 finishUserStop(uss); 18967 } 18968 }; 18969 // This is the result receiver for the initial stopping broadcast. 18970 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18971 @Override 18972 public void performReceive(Intent intent, int resultCode, String data, 18973 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18974 // On to the next. 18975 synchronized (ActivityManagerService.this) { 18976 if (uss.mState != UserStartedState.STATE_STOPPING) { 18977 // Whoops, we are being started back up. Abort, abort! 18978 return; 18979 } 18980 uss.mState = UserStartedState.STATE_SHUTDOWN; 18981 } 18982 mBatteryStatsService.noteEvent( 18983 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18984 Integer.toString(userId), userId); 18985 mSystemServiceManager.stopUser(userId); 18986 broadcastIntentLocked(null, null, shutdownIntent, 18987 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18988 true, false, MY_PID, Process.SYSTEM_UID, userId); 18989 } 18990 }; 18991 // Kick things off. 18992 broadcastIntentLocked(null, null, stoppingIntent, 18993 null, stoppingReceiver, 0, null, null, 18994 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18995 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18996 } finally { 18997 Binder.restoreCallingIdentity(ident); 18998 } 18999 } 19000 19001 return ActivityManager.USER_OP_SUCCESS; 19002 } 19003 19004 void finishUserStop(UserStartedState uss) { 19005 final int userId = uss.mHandle.getIdentifier(); 19006 boolean stopped; 19007 ArrayList<IStopUserCallback> callbacks; 19008 synchronized (this) { 19009 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19010 if (mStartedUsers.get(userId) != uss) { 19011 stopped = false; 19012 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19013 stopped = false; 19014 } else { 19015 stopped = true; 19016 // User can no longer run. 19017 mStartedUsers.remove(userId); 19018 mUserLru.remove(Integer.valueOf(userId)); 19019 updateStartedUserArrayLocked(); 19020 19021 // Clean up all state and processes associated with the user. 19022 // Kill all the processes for the user. 19023 forceStopUserLocked(userId, "finish user"); 19024 } 19025 19026 // Explicitly remove the old information in mRecentTasks. 19027 removeRecentTasksForUserLocked(userId); 19028 } 19029 19030 for (int i=0; i<callbacks.size(); i++) { 19031 try { 19032 if (stopped) callbacks.get(i).userStopped(userId); 19033 else callbacks.get(i).userStopAborted(userId); 19034 } catch (RemoteException e) { 19035 } 19036 } 19037 19038 if (stopped) { 19039 mSystemServiceManager.cleanupUser(userId); 19040 synchronized (this) { 19041 mStackSupervisor.removeUserLocked(userId); 19042 } 19043 } 19044 } 19045 19046 @Override 19047 public UserInfo getCurrentUser() { 19048 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19049 != PackageManager.PERMISSION_GRANTED) && ( 19050 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19051 != PackageManager.PERMISSION_GRANTED)) { 19052 String msg = "Permission Denial: getCurrentUser() from pid=" 19053 + Binder.getCallingPid() 19054 + ", uid=" + Binder.getCallingUid() 19055 + " requires " + INTERACT_ACROSS_USERS; 19056 Slog.w(TAG, msg); 19057 throw new SecurityException(msg); 19058 } 19059 synchronized (this) { 19060 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19061 return getUserManagerLocked().getUserInfo(userId); 19062 } 19063 } 19064 19065 int getCurrentUserIdLocked() { 19066 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19067 } 19068 19069 @Override 19070 public boolean isUserRunning(int userId, boolean orStopped) { 19071 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19072 != PackageManager.PERMISSION_GRANTED) { 19073 String msg = "Permission Denial: isUserRunning() from pid=" 19074 + Binder.getCallingPid() 19075 + ", uid=" + Binder.getCallingUid() 19076 + " requires " + INTERACT_ACROSS_USERS; 19077 Slog.w(TAG, msg); 19078 throw new SecurityException(msg); 19079 } 19080 synchronized (this) { 19081 return isUserRunningLocked(userId, orStopped); 19082 } 19083 } 19084 19085 boolean isUserRunningLocked(int userId, boolean orStopped) { 19086 UserStartedState state = mStartedUsers.get(userId); 19087 if (state == null) { 19088 return false; 19089 } 19090 if (orStopped) { 19091 return true; 19092 } 19093 return state.mState != UserStartedState.STATE_STOPPING 19094 && state.mState != UserStartedState.STATE_SHUTDOWN; 19095 } 19096 19097 @Override 19098 public int[] getRunningUserIds() { 19099 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19100 != PackageManager.PERMISSION_GRANTED) { 19101 String msg = "Permission Denial: isUserRunning() from pid=" 19102 + Binder.getCallingPid() 19103 + ", uid=" + Binder.getCallingUid() 19104 + " requires " + INTERACT_ACROSS_USERS; 19105 Slog.w(TAG, msg); 19106 throw new SecurityException(msg); 19107 } 19108 synchronized (this) { 19109 return mStartedUserArray; 19110 } 19111 } 19112 19113 private void updateStartedUserArrayLocked() { 19114 int num = 0; 19115 for (int i=0; i<mStartedUsers.size(); i++) { 19116 UserStartedState uss = mStartedUsers.valueAt(i); 19117 // This list does not include stopping users. 19118 if (uss.mState != UserStartedState.STATE_STOPPING 19119 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19120 num++; 19121 } 19122 } 19123 mStartedUserArray = new int[num]; 19124 num = 0; 19125 for (int i=0; i<mStartedUsers.size(); i++) { 19126 UserStartedState uss = mStartedUsers.valueAt(i); 19127 if (uss.mState != UserStartedState.STATE_STOPPING 19128 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19129 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19130 num++; 19131 } 19132 } 19133 } 19134 19135 @Override 19136 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19137 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19138 != PackageManager.PERMISSION_GRANTED) { 19139 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19140 + Binder.getCallingPid() 19141 + ", uid=" + Binder.getCallingUid() 19142 + " requires " + INTERACT_ACROSS_USERS_FULL; 19143 Slog.w(TAG, msg); 19144 throw new SecurityException(msg); 19145 } 19146 19147 mUserSwitchObservers.register(observer); 19148 } 19149 19150 @Override 19151 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19152 mUserSwitchObservers.unregister(observer); 19153 } 19154 19155 private boolean userExists(int userId) { 19156 if (userId == 0) { 19157 return true; 19158 } 19159 UserManagerService ums = getUserManagerLocked(); 19160 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19161 } 19162 19163 int[] getUsersLocked() { 19164 UserManagerService ums = getUserManagerLocked(); 19165 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19166 } 19167 19168 UserManagerService getUserManagerLocked() { 19169 if (mUserManager == null) { 19170 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19171 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19172 } 19173 return mUserManager; 19174 } 19175 19176 private int applyUserId(int uid, int userId) { 19177 return UserHandle.getUid(userId, uid); 19178 } 19179 19180 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19181 if (info == null) return null; 19182 ApplicationInfo newInfo = new ApplicationInfo(info); 19183 newInfo.uid = applyUserId(info.uid, userId); 19184 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19185 + info.packageName; 19186 return newInfo; 19187 } 19188 19189 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19190 if (aInfo == null 19191 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19192 return aInfo; 19193 } 19194 19195 ActivityInfo info = new ActivityInfo(aInfo); 19196 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19197 return info; 19198 } 19199 19200 private final class LocalService extends ActivityManagerInternal { 19201 @Override 19202 public void goingToSleep() { 19203 ActivityManagerService.this.goingToSleep(); 19204 } 19205 19206 @Override 19207 public void wakingUp() { 19208 ActivityManagerService.this.wakingUp(); 19209 } 19210 19211 @Override 19212 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19213 String processName, String abiOverride, int uid, Runnable crashHandler) { 19214 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19215 processName, abiOverride, uid, crashHandler); 19216 } 19217 } 19218 19219 /** 19220 * An implementation of IAppTask, that allows an app to manage its own tasks via 19221 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19222 * only the process that calls getAppTasks() can call the AppTask methods. 19223 */ 19224 class AppTaskImpl extends IAppTask.Stub { 19225 private int mTaskId; 19226 private int mCallingUid; 19227 19228 public AppTaskImpl(int taskId, int callingUid) { 19229 mTaskId = taskId; 19230 mCallingUid = callingUid; 19231 } 19232 19233 private void checkCaller() { 19234 if (mCallingUid != Binder.getCallingUid()) { 19235 throw new SecurityException("Caller " + mCallingUid 19236 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19237 } 19238 } 19239 19240 @Override 19241 public void finishAndRemoveTask() { 19242 checkCaller(); 19243 19244 synchronized (ActivityManagerService.this) { 19245 long origId = Binder.clearCallingIdentity(); 19246 try { 19247 if (!removeTaskByIdLocked(mTaskId, false)) { 19248 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19249 } 19250 } finally { 19251 Binder.restoreCallingIdentity(origId); 19252 } 19253 } 19254 } 19255 19256 @Override 19257 public ActivityManager.RecentTaskInfo getTaskInfo() { 19258 checkCaller(); 19259 19260 synchronized (ActivityManagerService.this) { 19261 long origId = Binder.clearCallingIdentity(); 19262 try { 19263 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19264 if (tr == null) { 19265 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19266 } 19267 return createRecentTaskInfoFromTaskRecord(tr); 19268 } finally { 19269 Binder.restoreCallingIdentity(origId); 19270 } 19271 } 19272 } 19273 19274 @Override 19275 public void moveToFront() { 19276 checkCaller(); 19277 19278 final TaskRecord tr; 19279 synchronized (ActivityManagerService.this) { 19280 tr = recentTaskForIdLocked(mTaskId); 19281 if (tr == null) { 19282 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19283 } 19284 if (tr.getRootActivity() != null) { 19285 moveTaskToFrontLocked(tr.taskId, 0, null); 19286 return; 19287 } 19288 } 19289 19290 startActivityFromRecentsInner(tr.taskId, null); 19291 } 19292 19293 @Override 19294 public int startActivity(IBinder whoThread, String callingPackage, 19295 Intent intent, String resolvedType, Bundle options) { 19296 checkCaller(); 19297 19298 int callingUser = UserHandle.getCallingUserId(); 19299 TaskRecord tr; 19300 IApplicationThread appThread; 19301 synchronized (ActivityManagerService.this) { 19302 tr = recentTaskForIdLocked(mTaskId); 19303 if (tr == null) { 19304 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19305 } 19306 appThread = ApplicationThreadNative.asInterface(whoThread); 19307 if (appThread == null) { 19308 throw new IllegalArgumentException("Bad app thread " + appThread); 19309 } 19310 } 19311 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19312 resolvedType, null, null, null, null, 0, 0, null, null, 19313 null, options, callingUser, null, tr); 19314 } 19315 19316 @Override 19317 public void setExcludeFromRecents(boolean exclude) { 19318 checkCaller(); 19319 19320 synchronized (ActivityManagerService.this) { 19321 long origId = Binder.clearCallingIdentity(); 19322 try { 19323 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19324 if (tr == null) { 19325 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19326 } 19327 Intent intent = tr.getBaseIntent(); 19328 if (exclude) { 19329 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19330 } else { 19331 intent.setFlags(intent.getFlags() 19332 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19333 } 19334 } finally { 19335 Binder.restoreCallingIdentity(origId); 19336 } 19337 } 19338 } 19339 } 19340} 19341