ActivityManagerService.java revision 83b6ef01a07d2e7f06dfee7fd698b27bd62ca9a0
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.UserManagerService; 85import com.android.server.wm.AppTransition; 86import com.android.server.wm.WindowManagerService; 87import com.google.android.collect.Lists; 88import com.google.android.collect.Maps; 89 90import libcore.io.IoUtils; 91 92import org.xmlpull.v1.XmlPullParser; 93import org.xmlpull.v1.XmlPullParserException; 94import org.xmlpull.v1.XmlSerializer; 95 96import android.app.Activity; 97import android.app.ActivityManager; 98import android.app.ActivityManager.RunningTaskInfo; 99import android.app.ActivityManager.StackInfo; 100import android.app.ActivityManagerInternal; 101import android.app.ActivityManagerNative; 102import android.app.ActivityOptions; 103import android.app.ActivityThread; 104import android.app.AlertDialog; 105import android.app.AppGlobals; 106import android.app.ApplicationErrorReport; 107import android.app.Dialog; 108import android.app.IActivityController; 109import android.app.IApplicationThread; 110import android.app.IInstrumentationWatcher; 111import android.app.INotificationManager; 112import android.app.IProcessObserver; 113import android.app.IServiceConnection; 114import android.app.IStopUserCallback; 115import android.app.IUiAutomationConnection; 116import android.app.IUserSwitchObserver; 117import android.app.Instrumentation; 118import android.app.Notification; 119import android.app.NotificationManager; 120import android.app.PendingIntent; 121import android.app.backup.IBackupManager; 122import android.content.ActivityNotFoundException; 123import android.content.BroadcastReceiver; 124import android.content.ClipData; 125import android.content.ComponentCallbacks2; 126import android.content.ComponentName; 127import android.content.ContentProvider; 128import android.content.ContentResolver; 129import android.content.Context; 130import android.content.DialogInterface; 131import android.content.IContentProvider; 132import android.content.IIntentReceiver; 133import android.content.IIntentSender; 134import android.content.Intent; 135import android.content.IntentFilter; 136import android.content.IntentSender; 137import android.content.pm.ActivityInfo; 138import android.content.pm.ApplicationInfo; 139import android.content.pm.ConfigurationInfo; 140import android.content.pm.IPackageDataObserver; 141import android.content.pm.IPackageManager; 142import android.content.pm.InstrumentationInfo; 143import android.content.pm.PackageInfo; 144import android.content.pm.PackageManager; 145import android.content.pm.ParceledListSlice; 146import android.content.pm.UserInfo; 147import android.content.pm.PackageManager.NameNotFoundException; 148import android.content.pm.PathPermission; 149import android.content.pm.ProviderInfo; 150import android.content.pm.ResolveInfo; 151import android.content.pm.ServiceInfo; 152import android.content.res.CompatibilityInfo; 153import android.content.res.Configuration; 154import android.net.Proxy; 155import android.net.ProxyInfo; 156import android.net.Uri; 157import android.os.Binder; 158import android.os.Build; 159import android.os.Bundle; 160import android.os.Debug; 161import android.os.DropBoxManager; 162import android.os.Environment; 163import android.os.FactoryTest; 164import android.os.FileObserver; 165import android.os.FileUtils; 166import android.os.Handler; 167import android.os.IBinder; 168import android.os.IPermissionController; 169import android.os.IRemoteCallback; 170import android.os.IUserManager; 171import android.os.Looper; 172import android.os.Message; 173import android.os.Parcel; 174import android.os.ParcelFileDescriptor; 175import android.os.Process; 176import android.os.RemoteCallbackList; 177import android.os.RemoteException; 178import android.os.SELinux; 179import android.os.ServiceManager; 180import android.os.StrictMode; 181import android.os.SystemClock; 182import android.os.SystemProperties; 183import android.os.UpdateLock; 184import android.os.UserHandle; 185import android.os.UserManager; 186import android.provider.Settings; 187import android.text.format.DateUtils; 188import android.text.format.Time; 189import android.util.AtomicFile; 190import android.util.EventLog; 191import android.util.Log; 192import android.util.Pair; 193import android.util.PrintWriterPrinter; 194import android.util.Slog; 195import android.util.SparseArray; 196import android.util.TimeUtils; 197import android.util.Xml; 198import android.view.Gravity; 199import android.view.LayoutInflater; 200import android.view.View; 201import android.view.WindowManager; 202import dalvik.system.VMRuntime; 203 204import java.io.BufferedInputStream; 205import java.io.BufferedOutputStream; 206import java.io.DataInputStream; 207import java.io.DataOutputStream; 208import java.io.File; 209import java.io.FileDescriptor; 210import java.io.FileInputStream; 211import java.io.FileNotFoundException; 212import java.io.FileOutputStream; 213import java.io.IOException; 214import java.io.InputStreamReader; 215import java.io.PrintWriter; 216import java.io.StringWriter; 217import java.lang.ref.WeakReference; 218import java.util.ArrayList; 219import java.util.Arrays; 220import java.util.Collections; 221import java.util.Comparator; 222import java.util.HashMap; 223import java.util.HashSet; 224import java.util.Iterator; 225import java.util.List; 226import java.util.Locale; 227import java.util.Map; 228import java.util.Set; 229import java.util.concurrent.atomic.AtomicBoolean; 230import java.util.concurrent.atomic.AtomicLong; 231 232public final class ActivityManagerService extends ActivityManagerNative 233 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 234 235 private static final String USER_DATA_DIR = "/data/user/"; 236 // File that stores last updated system version and called preboot receivers 237 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 238 239 static final String TAG = "ActivityManager"; 240 static final String TAG_MU = "ActivityManagerServiceMU"; 241 static final boolean DEBUG = false; 242 static final boolean localLOGV = DEBUG; 243 static final boolean DEBUG_BACKUP = localLOGV || false; 244 static final boolean DEBUG_BROADCAST = localLOGV || false; 245 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 246 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_CLEANUP = localLOGV || false; 248 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 249 static final boolean DEBUG_FOCUS = false; 250 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 251 static final boolean DEBUG_MU = localLOGV || false; 252 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 253 static final boolean DEBUG_LRU = localLOGV || false; 254 static final boolean DEBUG_PAUSE = localLOGV || false; 255 static final boolean DEBUG_POWER = localLOGV || false; 256 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 257 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 258 static final boolean DEBUG_PROCESSES = localLOGV || false; 259 static final boolean DEBUG_PROVIDER = localLOGV || false; 260 static final boolean DEBUG_RESULTS = localLOGV || false; 261 static final boolean DEBUG_SERVICE = localLOGV || false; 262 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 263 static final boolean DEBUG_STACK = localLOGV || false; 264 static final boolean DEBUG_SWITCH = localLOGV || false; 265 static final boolean DEBUG_TASKS = localLOGV || false; 266 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 267 static final boolean DEBUG_TRANSITION = localLOGV || false; 268 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 269 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 270 static final boolean DEBUG_VISBILITY = localLOGV || false; 271 static final boolean DEBUG_PSS = localLOGV || false; 272 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 273 static final boolean DEBUG_RECENTS = localLOGV || false; 274 static final boolean VALIDATE_TOKENS = false; 275 static final boolean SHOW_ACTIVITY_START_TIME = true; 276 277 // Control over CPU and battery monitoring. 278 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 279 static final boolean MONITOR_CPU_USAGE = true; 280 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 281 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 282 static final boolean MONITOR_THREAD_CPU_USAGE = false; 283 284 // The flags that are set for all calls we make to the package manager. 285 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 286 287 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 288 289 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 290 291 // Maximum number recent bitmaps to keep in memory. 292 static final int MAX_RECENT_BITMAPS = 5; 293 294 // Amount of time after a call to stopAppSwitches() during which we will 295 // prevent further untrusted switches from happening. 296 static final long APP_SWITCH_DELAY_TIME = 5*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real. 300 static final int PROC_START_TIMEOUT = 10*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real, when the process was 304 // started with a wrapper for instrumentation (such as Valgrind) because it 305 // could take much longer than usual. 306 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 307 308 // How long to wait after going idle before forcing apps to GC. 309 static final int GC_TIMEOUT = 5*1000; 310 311 // The minimum amount of time between successive GC requests for a process. 312 static final int GC_MIN_INTERVAL = 60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process. 315 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process 318 // when the request is due to the memory state being lowered. 319 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 320 321 // The rate at which we check for apps using excessive power -- 15 mins. 322 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on wake locks to start killing things. 326 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on CPU usage to start killing things. 330 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // How long we allow a receiver to run before giving up on it. 333 static final int BROADCAST_FG_TIMEOUT = 10*1000; 334 static final int BROADCAST_BG_TIMEOUT = 60*1000; 335 336 // How long we wait until we timeout on key dispatching. 337 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 338 339 // How long we wait until we timeout on key dispatching during instrumentation. 340 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 341 342 // Amount of time we wait for observers to handle a user switch before 343 // giving up on them and unfreezing the screen. 344 static final int USER_SWITCH_TIMEOUT = 2*1000; 345 346 // Maximum number of users we allow to be running at a time. 347 static final int MAX_RUNNING_USERS = 3; 348 349 // How long to wait in getAssistContextExtras for the activity and foreground services 350 // to respond with the result. 351 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 352 353 // Maximum number of persisted Uri grants a package is allowed 354 static final int MAX_PERSISTED_URI_GRANTS = 128; 355 356 static final int MY_PID = Process.myPid(); 357 358 static final String[] EMPTY_STRING_ARRAY = new String[0]; 359 360 // How many bytes to write into the dropbox log before truncating 361 static final int DROPBOX_MAX_SIZE = 256 * 1024; 362 363 // Access modes for handleIncomingUser. 364 static final int ALLOW_NON_FULL = 0; 365 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 366 static final int ALLOW_FULL_ONLY = 2; 367 368 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 369 370 /** All system services */ 371 SystemServiceManager mSystemServiceManager; 372 373 /** Run all ActivityStacks through this */ 374 ActivityStackSupervisor mStackSupervisor; 375 376 public IntentFirewall mIntentFirewall; 377 378 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 379 // default actuion automatically. Important for devices without direct input 380 // devices. 381 private boolean mShowDialogs = true; 382 383 BroadcastQueue mFgBroadcastQueue; 384 BroadcastQueue mBgBroadcastQueue; 385 // Convenient for easy iteration over the queues. Foreground is first 386 // so that dispatch of foreground broadcasts gets precedence. 387 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 388 389 BroadcastQueue broadcastQueueForIntent(Intent intent) { 390 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 391 if (DEBUG_BACKGROUND_BROADCAST) { 392 Slog.i(TAG, "Broadcast intent " + intent + " on " 393 + (isFg ? "foreground" : "background") 394 + " queue"); 395 } 396 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 397 } 398 399 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 400 for (BroadcastQueue queue : mBroadcastQueues) { 401 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 402 if (r != null) { 403 return r; 404 } 405 } 406 return null; 407 } 408 409 /** 410 * Activity we have told the window manager to have key focus. 411 */ 412 ActivityRecord mFocusedActivity = null; 413 414 /** 415 * List of intents that were used to start the most recent tasks. 416 */ 417 ArrayList<TaskRecord> mRecentTasks; 418 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 419 420 /** 421 * For addAppTask: cached of the last activity component that was added. 422 */ 423 ComponentName mLastAddedTaskComponent; 424 425 /** 426 * For addAppTask: cached of the last activity uid that was added. 427 */ 428 int mLastAddedTaskUid; 429 430 /** 431 * For addAppTask: cached of the last ActivityInfo that was added. 432 */ 433 ActivityInfo mLastAddedTaskActivity; 434 435 public class PendingAssistExtras extends Binder implements Runnable { 436 public final ActivityRecord activity; 437 public final Bundle extras; 438 public final Intent intent; 439 public final String hint; 440 public final int userHandle; 441 public boolean haveResult = false; 442 public Bundle result = null; 443 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 444 String _hint, int _userHandle) { 445 activity = _activity; 446 extras = _extras; 447 intent = _intent; 448 hint = _hint; 449 userHandle = _userHandle; 450 } 451 @Override 452 public void run() { 453 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 454 synchronized (this) { 455 haveResult = true; 456 notifyAll(); 457 } 458 } 459 } 460 461 final ArrayList<PendingAssistExtras> mPendingAssistExtras 462 = new ArrayList<PendingAssistExtras>(); 463 464 /** 465 * Process management. 466 */ 467 final ProcessList mProcessList = new ProcessList(); 468 469 /** 470 * All of the applications we currently have running organized by name. 471 * The keys are strings of the application package name (as 472 * returned by the package manager), and the keys are ApplicationRecord 473 * objects. 474 */ 475 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 476 477 /** 478 * Tracking long-term execution of processes to look for abuse and other 479 * bad app behavior. 480 */ 481 final ProcessStatsService mProcessStats; 482 483 /** 484 * The currently running isolated processes. 485 */ 486 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 487 488 /** 489 * Counter for assigning isolated process uids, to avoid frequently reusing the 490 * same ones. 491 */ 492 int mNextIsolatedProcessUid = 0; 493 494 /** 495 * The currently running heavy-weight process, if any. 496 */ 497 ProcessRecord mHeavyWeightProcess = null; 498 499 /** 500 * The last time that various processes have crashed. 501 */ 502 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 503 504 /** 505 * Information about a process that is currently marked as bad. 506 */ 507 static final class BadProcessInfo { 508 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 509 this.time = time; 510 this.shortMsg = shortMsg; 511 this.longMsg = longMsg; 512 this.stack = stack; 513 } 514 515 final long time; 516 final String shortMsg; 517 final String longMsg; 518 final String stack; 519 } 520 521 /** 522 * Set of applications that we consider to be bad, and will reject 523 * incoming broadcasts from (which the user has no control over). 524 * Processes are added to this set when they have crashed twice within 525 * a minimum amount of time; they are removed from it when they are 526 * later restarted (hopefully due to some user action). The value is the 527 * time it was added to the list. 528 */ 529 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 530 531 /** 532 * All of the processes we currently have running organized by pid. 533 * The keys are the pid running the application. 534 * 535 * <p>NOTE: This object is protected by its own lock, NOT the global 536 * activity manager lock! 537 */ 538 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 539 540 /** 541 * All of the processes that have been forced to be foreground. The key 542 * is the pid of the caller who requested it (we hold a death 543 * link on it). 544 */ 545 abstract class ForegroundToken implements IBinder.DeathRecipient { 546 int pid; 547 IBinder token; 548 } 549 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 550 551 /** 552 * List of records for processes that someone had tried to start before the 553 * system was ready. We don't start them at that point, but ensure they 554 * are started by the time booting is complete. 555 */ 556 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of persistent applications that are in the process 560 * of being started. 561 */ 562 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Processes that are being forcibly torn down. 566 */ 567 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * List of running applications, sorted by recent usage. 571 * The first entry in the list is the least recently used. 572 */ 573 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * Where in mLruProcesses that the processes hosting activities start. 577 */ 578 int mLruProcessActivityStart = 0; 579 580 /** 581 * Where in mLruProcesses that the processes hosting services start. 582 * This is after (lower index) than mLruProcessesActivityStart. 583 */ 584 int mLruProcessServiceStart = 0; 585 586 /** 587 * List of processes that should gc as soon as things are idle. 588 */ 589 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 590 591 /** 592 * Processes we want to collect PSS data from. 593 */ 594 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Last time we requested PSS data of all processes. 598 */ 599 long mLastFullPssTime = SystemClock.uptimeMillis(); 600 601 /** 602 * If set, the next time we collect PSS data we should do a full collection 603 * with data from native processes and the kernel. 604 */ 605 boolean mFullPssPending = false; 606 607 /** 608 * This is the process holding what we currently consider to be 609 * the "home" activity. 610 */ 611 ProcessRecord mHomeProcess; 612 613 /** 614 * This is the process holding the activity the user last visited that 615 * is in a different process from the one they are currently in. 616 */ 617 ProcessRecord mPreviousProcess; 618 619 /** 620 * The time at which the previous process was last visible. 621 */ 622 long mPreviousProcessVisibleTime; 623 624 /** 625 * Which uses have been started, so are allowed to run code. 626 */ 627 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 628 629 /** 630 * LRU list of history of current users. Most recently current is at the end. 631 */ 632 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 633 634 /** 635 * Constant array of the users that are currently started. 636 */ 637 int[] mStartedUserArray = new int[] { 0 }; 638 639 /** 640 * Registered observers of the user switching mechanics. 641 */ 642 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 643 = new RemoteCallbackList<IUserSwitchObserver>(); 644 645 /** 646 * Currently active user switch. 647 */ 648 Object mCurUserSwitchCallback; 649 650 /** 651 * Packages that the user has asked to have run in screen size 652 * compatibility mode instead of filling the screen. 653 */ 654 final CompatModePackages mCompatModePackages; 655 656 /** 657 * Set of IntentSenderRecord objects that are currently active. 658 */ 659 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 660 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 661 662 /** 663 * Fingerprints (hashCode()) of stack traces that we've 664 * already logged DropBox entries for. Guarded by itself. If 665 * something (rogue user app) forces this over 666 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 667 */ 668 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 669 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 670 671 /** 672 * Strict Mode background batched logging state. 673 * 674 * The string buffer is guarded by itself, and its lock is also 675 * used to determine if another batched write is already 676 * in-flight. 677 */ 678 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 679 680 /** 681 * Keeps track of all IIntentReceivers that have been registered for 682 * broadcasts. Hash keys are the receiver IBinder, hash value is 683 * a ReceiverList. 684 */ 685 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 686 new HashMap<IBinder, ReceiverList>(); 687 688 /** 689 * Resolver for broadcast intents to registered receivers. 690 * Holds BroadcastFilter (subclass of IntentFilter). 691 */ 692 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 693 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 694 @Override 695 protected boolean allowFilterResult( 696 BroadcastFilter filter, List<BroadcastFilter> dest) { 697 IBinder target = filter.receiverList.receiver.asBinder(); 698 for (int i=dest.size()-1; i>=0; i--) { 699 if (dest.get(i).receiverList.receiver.asBinder() == target) { 700 return false; 701 } 702 } 703 return true; 704 } 705 706 @Override 707 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 708 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 709 || userId == filter.owningUserId) { 710 return super.newResult(filter, match, userId); 711 } 712 return null; 713 } 714 715 @Override 716 protected BroadcastFilter[] newArray(int size) { 717 return new BroadcastFilter[size]; 718 } 719 720 @Override 721 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 722 return packageName.equals(filter.packageName); 723 } 724 }; 725 726 /** 727 * State of all active sticky broadcasts per user. Keys are the action of the 728 * sticky Intent, values are an ArrayList of all broadcasted intents with 729 * that action (which should usually be one). The SparseArray is keyed 730 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 731 * for stickies that are sent to all users. 732 */ 733 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 734 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 735 736 final ActiveServices mServices; 737 738 /** 739 * Backup/restore process management 740 */ 741 String mBackupAppName = null; 742 BackupRecord mBackupTarget = null; 743 744 final ProviderMap mProviderMap; 745 746 /** 747 * List of content providers who have clients waiting for them. The 748 * application is currently being launched and the provider will be 749 * removed from this list once it is published. 750 */ 751 final ArrayList<ContentProviderRecord> mLaunchingProviders 752 = new ArrayList<ContentProviderRecord>(); 753 754 /** 755 * File storing persisted {@link #mGrantedUriPermissions}. 756 */ 757 private final AtomicFile mGrantFile; 758 759 /** XML constants used in {@link #mGrantFile} */ 760 private static final String TAG_URI_GRANTS = "uri-grants"; 761 private static final String TAG_URI_GRANT = "uri-grant"; 762 private static final String ATTR_USER_HANDLE = "userHandle"; 763 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 764 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 765 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 766 private static final String ATTR_TARGET_PKG = "targetPkg"; 767 private static final String ATTR_URI = "uri"; 768 private static final String ATTR_MODE_FLAGS = "modeFlags"; 769 private static final String ATTR_CREATED_TIME = "createdTime"; 770 private static final String ATTR_PREFIX = "prefix"; 771 772 /** 773 * Global set of specific {@link Uri} permissions that have been granted. 774 * This optimized lookup structure maps from {@link UriPermission#targetUid} 775 * to {@link UriPermission#uri} to {@link UriPermission}. 776 */ 777 @GuardedBy("this") 778 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 779 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 780 781 public static class GrantUri { 782 public final int sourceUserId; 783 public final Uri uri; 784 public boolean prefix; 785 786 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 787 this.sourceUserId = sourceUserId; 788 this.uri = uri; 789 this.prefix = prefix; 790 } 791 792 @Override 793 public int hashCode() { 794 return toString().hashCode(); 795 } 796 797 @Override 798 public boolean equals(Object o) { 799 if (o instanceof GrantUri) { 800 GrantUri other = (GrantUri) o; 801 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 802 && prefix == other.prefix; 803 } 804 return false; 805 } 806 807 @Override 808 public String toString() { 809 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 810 if (prefix) result += " [prefix]"; 811 return result; 812 } 813 814 public String toSafeString() { 815 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 816 if (prefix) result += " [prefix]"; 817 return result; 818 } 819 820 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 821 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 822 ContentProvider.getUriWithoutUserId(uri), false); 823 } 824 } 825 826 CoreSettingsObserver mCoreSettingsObserver; 827 828 /** 829 * Thread-local storage used to carry caller permissions over through 830 * indirect content-provider access. 831 */ 832 private class Identity { 833 public int pid; 834 public int uid; 835 836 Identity(int _pid, int _uid) { 837 pid = _pid; 838 uid = _uid; 839 } 840 } 841 842 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 843 844 /** 845 * All information we have collected about the runtime performance of 846 * any user id that can impact battery performance. 847 */ 848 final BatteryStatsService mBatteryStatsService; 849 850 /** 851 * Information about component usage 852 */ 853 UsageStatsManagerInternal mUsageStatsService; 854 855 /** 856 * Information about and control over application operations 857 */ 858 final AppOpsService mAppOpsService; 859 860 /** 861 * Save recent tasks information across reboots. 862 */ 863 final TaskPersister mTaskPersister; 864 865 /** 866 * Current configuration information. HistoryRecord objects are given 867 * a reference to this object to indicate which configuration they are 868 * currently running in, so this object must be kept immutable. 869 */ 870 Configuration mConfiguration = new Configuration(); 871 872 /** 873 * Current sequencing integer of the configuration, for skipping old 874 * configurations. 875 */ 876 int mConfigurationSeq = 0; 877 878 /** 879 * Hardware-reported OpenGLES version. 880 */ 881 final int GL_ES_VERSION; 882 883 /** 884 * List of initialization arguments to pass to all processes when binding applications to them. 885 * For example, references to the commonly used services. 886 */ 887 HashMap<String, IBinder> mAppBindArgs; 888 889 /** 890 * Temporary to avoid allocations. Protected by main lock. 891 */ 892 final StringBuilder mStringBuilder = new StringBuilder(256); 893 894 /** 895 * Used to control how we initialize the service. 896 */ 897 ComponentName mTopComponent; 898 String mTopAction = Intent.ACTION_MAIN; 899 String mTopData; 900 boolean mProcessesReady = false; 901 boolean mSystemReady = false; 902 boolean mBooting = false; 903 boolean mCallFinishBooting = false; 904 boolean mBootAnimationComplete = false; 905 boolean mWaitingUpdate = false; 906 boolean mDidUpdate = false; 907 boolean mOnBattery = false; 908 boolean mLaunchWarningShown = false; 909 910 Context mContext; 911 912 int mFactoryTest; 913 914 boolean mCheckedForSetup; 915 916 /** 917 * The time at which we will allow normal application switches again, 918 * after a call to {@link #stopAppSwitches()}. 919 */ 920 long mAppSwitchesAllowedTime; 921 922 /** 923 * This is set to true after the first switch after mAppSwitchesAllowedTime 924 * is set; any switches after that will clear the time. 925 */ 926 boolean mDidAppSwitch; 927 928 /** 929 * Last time (in realtime) at which we checked for power usage. 930 */ 931 long mLastPowerCheckRealtime; 932 933 /** 934 * Last time (in uptime) at which we checked for power usage. 935 */ 936 long mLastPowerCheckUptime; 937 938 /** 939 * Set while we are wanting to sleep, to prevent any 940 * activities from being started/resumed. 941 */ 942 private boolean mSleeping = false; 943 944 /** 945 * Set while we are running a voice interaction. This overrides 946 * sleeping while it is active. 947 */ 948 private boolean mRunningVoice = false; 949 950 /** 951 * State of external calls telling us if the device is asleep. 952 */ 953 private boolean mWentToSleep = false; 954 955 static final int LOCK_SCREEN_HIDDEN = 0; 956 static final int LOCK_SCREEN_LEAVING = 1; 957 static final int LOCK_SCREEN_SHOWN = 2; 958 /** 959 * State of external call telling us if the lock screen is shown. 960 */ 961 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 962 963 /** 964 * Set if we are shutting down the system, similar to sleeping. 965 */ 966 boolean mShuttingDown = false; 967 968 /** 969 * Current sequence id for oom_adj computation traversal. 970 */ 971 int mAdjSeq = 0; 972 973 /** 974 * Current sequence id for process LRU updating. 975 */ 976 int mLruSeq = 0; 977 978 /** 979 * Keep track of the non-cached/empty process we last found, to help 980 * determine how to distribute cached/empty processes next time. 981 */ 982 int mNumNonCachedProcs = 0; 983 984 /** 985 * Keep track of the number of cached hidden procs, to balance oom adj 986 * distribution between those and empty procs. 987 */ 988 int mNumCachedHiddenProcs = 0; 989 990 /** 991 * Keep track of the number of service processes we last found, to 992 * determine on the next iteration which should be B services. 993 */ 994 int mNumServiceProcs = 0; 995 int mNewNumAServiceProcs = 0; 996 int mNewNumServiceProcs = 0; 997 998 /** 999 * Allow the current computed overall memory level of the system to go down? 1000 * This is set to false when we are killing processes for reasons other than 1001 * memory management, so that the now smaller process list will not be taken as 1002 * an indication that memory is tighter. 1003 */ 1004 boolean mAllowLowerMemLevel = false; 1005 1006 /** 1007 * The last computed memory level, for holding when we are in a state that 1008 * processes are going away for other reasons. 1009 */ 1010 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1011 1012 /** 1013 * The last total number of process we have, to determine if changes actually look 1014 * like a shrinking number of process due to lower RAM. 1015 */ 1016 int mLastNumProcesses; 1017 1018 /** 1019 * The uptime of the last time we performed idle maintenance. 1020 */ 1021 long mLastIdleTime = SystemClock.uptimeMillis(); 1022 1023 /** 1024 * Total time spent with RAM that has been added in the past since the last idle time. 1025 */ 1026 long mLowRamTimeSinceLastIdle = 0; 1027 1028 /** 1029 * If RAM is currently low, when that horrible situation started. 1030 */ 1031 long mLowRamStartTime = 0; 1032 1033 /** 1034 * For reporting to battery stats the current top application. 1035 */ 1036 private String mCurResumedPackage = null; 1037 private int mCurResumedUid = -1; 1038 1039 /** 1040 * For reporting to battery stats the apps currently running foreground 1041 * service. The ProcessMap is package/uid tuples; each of these contain 1042 * an array of the currently foreground processes. 1043 */ 1044 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1045 = new ProcessMap<ArrayList<ProcessRecord>>(); 1046 1047 /** 1048 * This is set if we had to do a delayed dexopt of an app before launching 1049 * it, to increase the ANR timeouts in that case. 1050 */ 1051 boolean mDidDexOpt; 1052 1053 /** 1054 * Set if the systemServer made a call to enterSafeMode. 1055 */ 1056 boolean mSafeMode; 1057 1058 String mDebugApp = null; 1059 boolean mWaitForDebugger = false; 1060 boolean mDebugTransient = false; 1061 String mOrigDebugApp = null; 1062 boolean mOrigWaitForDebugger = false; 1063 boolean mAlwaysFinishActivities = false; 1064 IActivityController mController = null; 1065 String mProfileApp = null; 1066 ProcessRecord mProfileProc = null; 1067 String mProfileFile; 1068 ParcelFileDescriptor mProfileFd; 1069 int mSamplingInterval = 0; 1070 boolean mAutoStopProfiler = false; 1071 int mProfileType = 0; 1072 String mOpenGlTraceApp = null; 1073 1074 static class ProcessChangeItem { 1075 static final int CHANGE_ACTIVITIES = 1<<0; 1076 static final int CHANGE_PROCESS_STATE = 1<<1; 1077 int changes; 1078 int uid; 1079 int pid; 1080 int processState; 1081 boolean foregroundActivities; 1082 } 1083 1084 final RemoteCallbackList<IProcessObserver> mProcessObservers 1085 = new RemoteCallbackList<IProcessObserver>(); 1086 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1087 1088 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1089 = new ArrayList<ProcessChangeItem>(); 1090 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1091 = new ArrayList<ProcessChangeItem>(); 1092 1093 /** 1094 * Runtime CPU use collection thread. This object's lock is used to 1095 * perform synchronization with the thread (notifying it to run). 1096 */ 1097 final Thread mProcessCpuThread; 1098 1099 /** 1100 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1101 * Must acquire this object's lock when accessing it. 1102 * NOTE: this lock will be held while doing long operations (trawling 1103 * through all processes in /proc), so it should never be acquired by 1104 * any critical paths such as when holding the main activity manager lock. 1105 */ 1106 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1107 MONITOR_THREAD_CPU_USAGE); 1108 final AtomicLong mLastCpuTime = new AtomicLong(0); 1109 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1110 1111 long mLastWriteTime = 0; 1112 1113 /** 1114 * Used to retain an update lock when the foreground activity is in 1115 * immersive mode. 1116 */ 1117 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1118 1119 /** 1120 * Set to true after the system has finished booting. 1121 */ 1122 boolean mBooted = false; 1123 1124 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1125 int mProcessLimitOverride = -1; 1126 1127 WindowManagerService mWindowManager; 1128 1129 final ActivityThread mSystemThread; 1130 1131 // Holds the current foreground user's id 1132 int mCurrentUserId = 0; 1133 // Holds the target user's id during a user switch 1134 int mTargetUserId = UserHandle.USER_NULL; 1135 // If there are multiple profiles for the current user, their ids are here 1136 // Currently only the primary user can have managed profiles 1137 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1138 1139 /** 1140 * Mapping from each known user ID to the profile group ID it is associated with. 1141 */ 1142 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1143 1144 private UserManagerService mUserManager; 1145 1146 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1147 final ProcessRecord mApp; 1148 final int mPid; 1149 final IApplicationThread mAppThread; 1150 1151 AppDeathRecipient(ProcessRecord app, int pid, 1152 IApplicationThread thread) { 1153 if (localLOGV) Slog.v( 1154 TAG, "New death recipient " + this 1155 + " for thread " + thread.asBinder()); 1156 mApp = app; 1157 mPid = pid; 1158 mAppThread = thread; 1159 } 1160 1161 @Override 1162 public void binderDied() { 1163 if (localLOGV) Slog.v( 1164 TAG, "Death received in " + this 1165 + " for thread " + mAppThread.asBinder()); 1166 synchronized(ActivityManagerService.this) { 1167 appDiedLocked(mApp, mPid, mAppThread); 1168 } 1169 } 1170 } 1171 1172 static final int SHOW_ERROR_MSG = 1; 1173 static final int SHOW_NOT_RESPONDING_MSG = 2; 1174 static final int SHOW_FACTORY_ERROR_MSG = 3; 1175 static final int UPDATE_CONFIGURATION_MSG = 4; 1176 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1177 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1178 static final int SERVICE_TIMEOUT_MSG = 12; 1179 static final int UPDATE_TIME_ZONE = 13; 1180 static final int SHOW_UID_ERROR_MSG = 14; 1181 static final int IM_FEELING_LUCKY_MSG = 15; 1182 static final int PROC_START_TIMEOUT_MSG = 20; 1183 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1184 static final int KILL_APPLICATION_MSG = 22; 1185 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1186 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1187 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1188 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1189 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1190 static final int CLEAR_DNS_CACHE_MSG = 28; 1191 static final int UPDATE_HTTP_PROXY_MSG = 29; 1192 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1193 static final int DISPATCH_PROCESSES_CHANGED = 31; 1194 static final int DISPATCH_PROCESS_DIED = 32; 1195 static final int REPORT_MEM_USAGE_MSG = 33; 1196 static final int REPORT_USER_SWITCH_MSG = 34; 1197 static final int CONTINUE_USER_SWITCH_MSG = 35; 1198 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1199 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1200 static final int PERSIST_URI_GRANTS_MSG = 38; 1201 static final int REQUEST_ALL_PSS_MSG = 39; 1202 static final int START_PROFILES_MSG = 40; 1203 static final int UPDATE_TIME = 41; 1204 static final int SYSTEM_USER_START_MSG = 42; 1205 static final int SYSTEM_USER_CURRENT_MSG = 43; 1206 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1207 static final int FINISH_BOOTING_MSG = 45; 1208 static final int START_USER_SWITCH_MSG = 46; 1209 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1210 1211 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1212 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1213 static final int FIRST_COMPAT_MODE_MSG = 300; 1214 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1215 1216 AlertDialog mUidAlert; 1217 CompatModeDialog mCompatModeDialog; 1218 long mLastMemUsageReportTime = 0; 1219 1220 private LockToAppRequestDialog mLockToAppRequest; 1221 1222 /** 1223 * Flag whether the current user is a "monkey", i.e. whether 1224 * the UI is driven by a UI automation tool. 1225 */ 1226 private boolean mUserIsMonkey; 1227 1228 /** Flag whether the device has a Recents UI */ 1229 boolean mHasRecents; 1230 1231 /** The dimensions of the thumbnails in the Recents UI. */ 1232 int mThumbnailWidth; 1233 int mThumbnailHeight; 1234 1235 final ServiceThread mHandlerThread; 1236 final MainHandler mHandler; 1237 1238 final class MainHandler extends Handler { 1239 public MainHandler(Looper looper) { 1240 super(looper, null, true); 1241 } 1242 1243 @Override 1244 public void handleMessage(Message msg) { 1245 switch (msg.what) { 1246 case SHOW_ERROR_MSG: { 1247 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1248 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1249 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1250 synchronized (ActivityManagerService.this) { 1251 ProcessRecord proc = (ProcessRecord)data.get("app"); 1252 AppErrorResult res = (AppErrorResult) data.get("result"); 1253 if (proc != null && proc.crashDialog != null) { 1254 Slog.e(TAG, "App already has crash dialog: " + proc); 1255 if (res != null) { 1256 res.set(0); 1257 } 1258 return; 1259 } 1260 boolean isBackground = (UserHandle.getAppId(proc.uid) 1261 >= Process.FIRST_APPLICATION_UID 1262 && proc.pid != MY_PID); 1263 for (int userId : mCurrentProfileIds) { 1264 isBackground &= (proc.userId != userId); 1265 } 1266 if (isBackground && !showBackground) { 1267 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1268 if (res != null) { 1269 res.set(0); 1270 } 1271 return; 1272 } 1273 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1274 Dialog d = new AppErrorDialog(mContext, 1275 ActivityManagerService.this, res, proc); 1276 d.show(); 1277 proc.crashDialog = d; 1278 } else { 1279 // The device is asleep, so just pretend that the user 1280 // saw a crash dialog and hit "force quit". 1281 if (res != null) { 1282 res.set(0); 1283 } 1284 } 1285 } 1286 1287 ensureBootCompleted(); 1288 } break; 1289 case SHOW_NOT_RESPONDING_MSG: { 1290 synchronized (ActivityManagerService.this) { 1291 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1292 ProcessRecord proc = (ProcessRecord)data.get("app"); 1293 if (proc != null && proc.anrDialog != null) { 1294 Slog.e(TAG, "App already has anr dialog: " + proc); 1295 return; 1296 } 1297 1298 Intent intent = new Intent("android.intent.action.ANR"); 1299 if (!mProcessesReady) { 1300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1301 | Intent.FLAG_RECEIVER_FOREGROUND); 1302 } 1303 broadcastIntentLocked(null, null, intent, 1304 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1305 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1306 1307 if (mShowDialogs) { 1308 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1309 mContext, proc, (ActivityRecord)data.get("activity"), 1310 msg.arg1 != 0); 1311 d.show(); 1312 proc.anrDialog = d; 1313 } else { 1314 // Just kill the app if there is no dialog to be shown. 1315 killAppAtUsersRequest(proc, null); 1316 } 1317 } 1318 1319 ensureBootCompleted(); 1320 } break; 1321 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1322 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1323 synchronized (ActivityManagerService.this) { 1324 ProcessRecord proc = (ProcessRecord) data.get("app"); 1325 if (proc == null) { 1326 Slog.e(TAG, "App not found when showing strict mode dialog."); 1327 break; 1328 } 1329 if (proc.crashDialog != null) { 1330 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1331 return; 1332 } 1333 AppErrorResult res = (AppErrorResult) data.get("result"); 1334 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1335 Dialog d = new StrictModeViolationDialog(mContext, 1336 ActivityManagerService.this, res, proc); 1337 d.show(); 1338 proc.crashDialog = d; 1339 } else { 1340 // The device is asleep, so just pretend that the user 1341 // saw a crash dialog and hit "force quit". 1342 res.set(0); 1343 } 1344 } 1345 ensureBootCompleted(); 1346 } break; 1347 case SHOW_FACTORY_ERROR_MSG: { 1348 Dialog d = new FactoryErrorDialog( 1349 mContext, msg.getData().getCharSequence("msg")); 1350 d.show(); 1351 ensureBootCompleted(); 1352 } break; 1353 case UPDATE_CONFIGURATION_MSG: { 1354 final ContentResolver resolver = mContext.getContentResolver(); 1355 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1356 } break; 1357 case GC_BACKGROUND_PROCESSES_MSG: { 1358 synchronized (ActivityManagerService.this) { 1359 performAppGcsIfAppropriateLocked(); 1360 } 1361 } break; 1362 case WAIT_FOR_DEBUGGER_MSG: { 1363 synchronized (ActivityManagerService.this) { 1364 ProcessRecord app = (ProcessRecord)msg.obj; 1365 if (msg.arg1 != 0) { 1366 if (!app.waitedForDebugger) { 1367 Dialog d = new AppWaitingForDebuggerDialog( 1368 ActivityManagerService.this, 1369 mContext, app); 1370 app.waitDialog = d; 1371 app.waitedForDebugger = true; 1372 d.show(); 1373 } 1374 } else { 1375 if (app.waitDialog != null) { 1376 app.waitDialog.dismiss(); 1377 app.waitDialog = null; 1378 } 1379 } 1380 } 1381 } break; 1382 case SERVICE_TIMEOUT_MSG: { 1383 if (mDidDexOpt) { 1384 mDidDexOpt = false; 1385 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1386 nmsg.obj = msg.obj; 1387 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1388 return; 1389 } 1390 mServices.serviceTimeout((ProcessRecord)msg.obj); 1391 } break; 1392 case UPDATE_TIME_ZONE: { 1393 synchronized (ActivityManagerService.this) { 1394 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1395 ProcessRecord r = mLruProcesses.get(i); 1396 if (r.thread != null) { 1397 try { 1398 r.thread.updateTimeZone(); 1399 } catch (RemoteException ex) { 1400 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1401 } 1402 } 1403 } 1404 } 1405 } break; 1406 case CLEAR_DNS_CACHE_MSG: { 1407 synchronized (ActivityManagerService.this) { 1408 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1409 ProcessRecord r = mLruProcesses.get(i); 1410 if (r.thread != null) { 1411 try { 1412 r.thread.clearDnsCache(); 1413 } catch (RemoteException ex) { 1414 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1415 } 1416 } 1417 } 1418 } 1419 } break; 1420 case UPDATE_HTTP_PROXY_MSG: { 1421 ProxyInfo proxy = (ProxyInfo)msg.obj; 1422 String host = ""; 1423 String port = ""; 1424 String exclList = ""; 1425 Uri pacFileUrl = Uri.EMPTY; 1426 if (proxy != null) { 1427 host = proxy.getHost(); 1428 port = Integer.toString(proxy.getPort()); 1429 exclList = proxy.getExclusionListAsString(); 1430 pacFileUrl = proxy.getPacFileUrl(); 1431 } 1432 synchronized (ActivityManagerService.this) { 1433 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1434 ProcessRecord r = mLruProcesses.get(i); 1435 if (r.thread != null) { 1436 try { 1437 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1438 } catch (RemoteException ex) { 1439 Slog.w(TAG, "Failed to update http proxy for: " + 1440 r.info.processName); 1441 } 1442 } 1443 } 1444 } 1445 } break; 1446 case SHOW_UID_ERROR_MSG: { 1447 String title = "System UIDs Inconsistent"; 1448 String text = "UIDs on the system are inconsistent, you need to wipe your" 1449 + " data partition or your device will be unstable."; 1450 Log.e(TAG, title + ": " + text); 1451 if (mShowDialogs) { 1452 // XXX This is a temporary dialog, no need to localize. 1453 AlertDialog d = new BaseErrorDialog(mContext); 1454 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1455 d.setCancelable(false); 1456 d.setTitle(title); 1457 d.setMessage(text); 1458 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1459 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1460 mUidAlert = d; 1461 d.show(); 1462 } 1463 } break; 1464 case IM_FEELING_LUCKY_MSG: { 1465 if (mUidAlert != null) { 1466 mUidAlert.dismiss(); 1467 mUidAlert = null; 1468 } 1469 } break; 1470 case PROC_START_TIMEOUT_MSG: { 1471 if (mDidDexOpt) { 1472 mDidDexOpt = false; 1473 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1474 nmsg.obj = msg.obj; 1475 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1476 return; 1477 } 1478 ProcessRecord app = (ProcessRecord)msg.obj; 1479 synchronized (ActivityManagerService.this) { 1480 processStartTimedOutLocked(app); 1481 } 1482 } break; 1483 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1484 synchronized (ActivityManagerService.this) { 1485 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1486 } 1487 } break; 1488 case KILL_APPLICATION_MSG: { 1489 synchronized (ActivityManagerService.this) { 1490 int appid = msg.arg1; 1491 boolean restart = (msg.arg2 == 1); 1492 Bundle bundle = (Bundle)msg.obj; 1493 String pkg = bundle.getString("pkg"); 1494 String reason = bundle.getString("reason"); 1495 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1496 false, UserHandle.USER_ALL, reason); 1497 } 1498 } break; 1499 case FINALIZE_PENDING_INTENT_MSG: { 1500 ((PendingIntentRecord)msg.obj).completeFinalize(); 1501 } break; 1502 case POST_HEAVY_NOTIFICATION_MSG: { 1503 INotificationManager inm = NotificationManager.getService(); 1504 if (inm == null) { 1505 return; 1506 } 1507 1508 ActivityRecord root = (ActivityRecord)msg.obj; 1509 ProcessRecord process = root.app; 1510 if (process == null) { 1511 return; 1512 } 1513 1514 try { 1515 Context context = mContext.createPackageContext(process.info.packageName, 0); 1516 String text = mContext.getString(R.string.heavy_weight_notification, 1517 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1518 Notification notification = new Notification(); 1519 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1520 notification.when = 0; 1521 notification.flags = Notification.FLAG_ONGOING_EVENT; 1522 notification.tickerText = text; 1523 notification.defaults = 0; // please be quiet 1524 notification.sound = null; 1525 notification.vibrate = null; 1526 notification.color = mContext.getResources().getColor( 1527 com.android.internal.R.color.system_notification_accent_color); 1528 notification.setLatestEventInfo(context, text, 1529 mContext.getText(R.string.heavy_weight_notification_detail), 1530 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1531 PendingIntent.FLAG_CANCEL_CURRENT, null, 1532 new UserHandle(root.userId))); 1533 1534 try { 1535 int[] outId = new int[1]; 1536 inm.enqueueNotificationWithTag("android", "android", null, 1537 R.string.heavy_weight_notification, 1538 notification, outId, root.userId); 1539 } catch (RuntimeException e) { 1540 Slog.w(ActivityManagerService.TAG, 1541 "Error showing notification for heavy-weight app", e); 1542 } catch (RemoteException e) { 1543 } 1544 } catch (NameNotFoundException e) { 1545 Slog.w(TAG, "Unable to create context for heavy notification", e); 1546 } 1547 } break; 1548 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1549 INotificationManager inm = NotificationManager.getService(); 1550 if (inm == null) { 1551 return; 1552 } 1553 try { 1554 inm.cancelNotificationWithTag("android", null, 1555 R.string.heavy_weight_notification, msg.arg1); 1556 } catch (RuntimeException e) { 1557 Slog.w(ActivityManagerService.TAG, 1558 "Error canceling notification for service", e); 1559 } catch (RemoteException e) { 1560 } 1561 } break; 1562 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1563 synchronized (ActivityManagerService.this) { 1564 checkExcessivePowerUsageLocked(true); 1565 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1566 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1567 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1568 } 1569 } break; 1570 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1571 synchronized (ActivityManagerService.this) { 1572 ActivityRecord ar = (ActivityRecord)msg.obj; 1573 if (mCompatModeDialog != null) { 1574 if (mCompatModeDialog.mAppInfo.packageName.equals( 1575 ar.info.applicationInfo.packageName)) { 1576 return; 1577 } 1578 mCompatModeDialog.dismiss(); 1579 mCompatModeDialog = null; 1580 } 1581 if (ar != null && false) { 1582 if (mCompatModePackages.getPackageAskCompatModeLocked( 1583 ar.packageName)) { 1584 int mode = mCompatModePackages.computeCompatModeLocked( 1585 ar.info.applicationInfo); 1586 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1587 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1588 mCompatModeDialog = new CompatModeDialog( 1589 ActivityManagerService.this, mContext, 1590 ar.info.applicationInfo); 1591 mCompatModeDialog.show(); 1592 } 1593 } 1594 } 1595 } 1596 break; 1597 } 1598 case DISPATCH_PROCESSES_CHANGED: { 1599 dispatchProcessesChanged(); 1600 break; 1601 } 1602 case DISPATCH_PROCESS_DIED: { 1603 final int pid = msg.arg1; 1604 final int uid = msg.arg2; 1605 dispatchProcessDied(pid, uid); 1606 break; 1607 } 1608 case REPORT_MEM_USAGE_MSG: { 1609 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1610 Thread thread = new Thread() { 1611 @Override public void run() { 1612 reportMemUsage(memInfos); 1613 } 1614 }; 1615 thread.start(); 1616 break; 1617 } 1618 case START_USER_SWITCH_MSG: { 1619 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1620 break; 1621 } 1622 case REPORT_USER_SWITCH_MSG: { 1623 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1624 break; 1625 } 1626 case CONTINUE_USER_SWITCH_MSG: { 1627 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1628 break; 1629 } 1630 case USER_SWITCH_TIMEOUT_MSG: { 1631 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1632 break; 1633 } 1634 case IMMERSIVE_MODE_LOCK_MSG: { 1635 final boolean nextState = (msg.arg1 != 0); 1636 if (mUpdateLock.isHeld() != nextState) { 1637 if (DEBUG_IMMERSIVE) { 1638 final ActivityRecord r = (ActivityRecord) msg.obj; 1639 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1640 } 1641 if (nextState) { 1642 mUpdateLock.acquire(); 1643 } else { 1644 mUpdateLock.release(); 1645 } 1646 } 1647 break; 1648 } 1649 case PERSIST_URI_GRANTS_MSG: { 1650 writeGrantedUriPermissions(); 1651 break; 1652 } 1653 case REQUEST_ALL_PSS_MSG: { 1654 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1655 break; 1656 } 1657 case START_PROFILES_MSG: { 1658 synchronized (ActivityManagerService.this) { 1659 startProfilesLocked(); 1660 } 1661 break; 1662 } 1663 case UPDATE_TIME: { 1664 synchronized (ActivityManagerService.this) { 1665 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1666 ProcessRecord r = mLruProcesses.get(i); 1667 if (r.thread != null) { 1668 try { 1669 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1670 } catch (RemoteException ex) { 1671 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1672 } 1673 } 1674 } 1675 } 1676 break; 1677 } 1678 case SYSTEM_USER_START_MSG: { 1679 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1680 Integer.toString(msg.arg1), msg.arg1); 1681 mSystemServiceManager.startUser(msg.arg1); 1682 break; 1683 } 1684 case SYSTEM_USER_CURRENT_MSG: { 1685 mBatteryStatsService.noteEvent( 1686 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1687 Integer.toString(msg.arg2), msg.arg2); 1688 mBatteryStatsService.noteEvent( 1689 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1690 Integer.toString(msg.arg1), msg.arg1); 1691 mSystemServiceManager.switchUser(msg.arg1); 1692 mLockToAppRequest.clearPrompt(); 1693 break; 1694 } 1695 case ENTER_ANIMATION_COMPLETE_MSG: { 1696 synchronized (ActivityManagerService.this) { 1697 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1698 if (r != null && r.app != null && r.app.thread != null) { 1699 try { 1700 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1701 } catch (RemoteException e) { 1702 } 1703 } 1704 } 1705 break; 1706 } 1707 case FINISH_BOOTING_MSG: { 1708 if (msg.arg1 != 0) { 1709 finishBooting(); 1710 } 1711 if (msg.arg2 != 0) { 1712 enableScreenAfterBoot(); 1713 } 1714 break; 1715 } 1716 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1717 try { 1718 Locale l = (Locale) msg.obj; 1719 IBinder service = ServiceManager.getService("mount"); 1720 IMountService mountService = IMountService.Stub.asInterface(service); 1721 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1722 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1723 } catch (RemoteException e) { 1724 Log.e(TAG, "Error storing locale for decryption UI", e); 1725 } 1726 break; 1727 } 1728 } 1729 } 1730 }; 1731 1732 static final int COLLECT_PSS_BG_MSG = 1; 1733 1734 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1735 @Override 1736 public void handleMessage(Message msg) { 1737 switch (msg.what) { 1738 case COLLECT_PSS_BG_MSG: { 1739 long start = SystemClock.uptimeMillis(); 1740 MemInfoReader memInfo = null; 1741 synchronized (ActivityManagerService.this) { 1742 if (mFullPssPending) { 1743 mFullPssPending = false; 1744 memInfo = new MemInfoReader(); 1745 } 1746 } 1747 if (memInfo != null) { 1748 updateCpuStatsNow(); 1749 long nativeTotalPss = 0; 1750 synchronized (mProcessCpuTracker) { 1751 final int N = mProcessCpuTracker.countStats(); 1752 for (int j=0; j<N; j++) { 1753 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1754 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1755 // This is definitely an application process; skip it. 1756 continue; 1757 } 1758 synchronized (mPidsSelfLocked) { 1759 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1760 // This is one of our own processes; skip it. 1761 continue; 1762 } 1763 } 1764 nativeTotalPss += Debug.getPss(st.pid, null); 1765 } 1766 } 1767 memInfo.readMemInfo(); 1768 synchronized (ActivityManagerService.this) { 1769 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1770 + (SystemClock.uptimeMillis()-start) + "ms"); 1771 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1772 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1773 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1774 } 1775 } 1776 1777 int i=0, num=0; 1778 long[] tmp = new long[1]; 1779 do { 1780 ProcessRecord proc; 1781 int procState; 1782 int pid; 1783 synchronized (ActivityManagerService.this) { 1784 if (i >= mPendingPssProcesses.size()) { 1785 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1786 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1787 mPendingPssProcesses.clear(); 1788 return; 1789 } 1790 proc = mPendingPssProcesses.get(i); 1791 procState = proc.pssProcState; 1792 if (proc.thread != null && procState == proc.setProcState) { 1793 pid = proc.pid; 1794 } else { 1795 proc = null; 1796 pid = 0; 1797 } 1798 i++; 1799 } 1800 if (proc != null) { 1801 long pss = Debug.getPss(pid, tmp); 1802 synchronized (ActivityManagerService.this) { 1803 if (proc.thread != null && proc.setProcState == procState 1804 && proc.pid == pid) { 1805 num++; 1806 proc.lastPssTime = SystemClock.uptimeMillis(); 1807 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1808 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1809 + ": " + pss + " lastPss=" + proc.lastPss 1810 + " state=" + ProcessList.makeProcStateString(procState)); 1811 if (proc.initialIdlePss == 0) { 1812 proc.initialIdlePss = pss; 1813 } 1814 proc.lastPss = pss; 1815 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1816 proc.lastCachedPss = pss; 1817 } 1818 } 1819 } 1820 } 1821 } while (true); 1822 } 1823 } 1824 } 1825 }; 1826 1827 /** 1828 * Monitor for package changes and update our internal state. 1829 */ 1830 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1831 @Override 1832 public void onPackageRemoved(String packageName, int uid) { 1833 // Remove all tasks with activities in the specified package from the list of recent tasks 1834 final int eventUserId = getChangingUserId(); 1835 synchronized (ActivityManagerService.this) { 1836 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1837 TaskRecord tr = mRecentTasks.get(i); 1838 if (tr.userId != eventUserId) continue; 1839 1840 ComponentName cn = tr.intent.getComponent(); 1841 if (cn != null && cn.getPackageName().equals(packageName)) { 1842 // If the package name matches, remove the task 1843 removeTaskByIdLocked(tr.taskId, true); 1844 } 1845 } 1846 } 1847 } 1848 1849 @Override 1850 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1851 onPackageModified(packageName); 1852 return true; 1853 } 1854 1855 @Override 1856 public void onPackageModified(String packageName) { 1857 final int eventUserId = getChangingUserId(); 1858 final IPackageManager pm = AppGlobals.getPackageManager(); 1859 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1860 new ArrayList<Pair<Intent, Integer>>(); 1861 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1862 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1863 // Copy the list of recent tasks so that we don't hold onto the lock on 1864 // ActivityManagerService for long periods while checking if components exist. 1865 synchronized (ActivityManagerService.this) { 1866 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1867 TaskRecord tr = mRecentTasks.get(i); 1868 if (tr.userId != eventUserId) continue; 1869 1870 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1871 } 1872 } 1873 // Check the recent tasks and filter out all tasks with components that no longer exist. 1874 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1875 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1876 ComponentName cn = p.first.getComponent(); 1877 if (cn != null && cn.getPackageName().equals(packageName)) { 1878 if (componentsKnownToExist.contains(cn)) { 1879 // If we know that the component still exists in the package, then skip 1880 continue; 1881 } 1882 try { 1883 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1884 if (info != null) { 1885 componentsKnownToExist.add(cn); 1886 } else { 1887 tasksToRemove.add(p.second); 1888 } 1889 } catch (RemoteException e) { 1890 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1891 } 1892 } 1893 } 1894 // Prune all the tasks with removed components from the list of recent tasks 1895 synchronized (ActivityManagerService.this) { 1896 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1897 removeTaskByIdLocked(tasksToRemove.get(i), false); 1898 } 1899 } 1900 } 1901 1902 @Override 1903 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1904 // Force stop the specified packages 1905 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1906 if (packages != null) { 1907 for (String pkg : packages) { 1908 synchronized (ActivityManagerService.this) { 1909 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1910 userId, "finished booting")) { 1911 return true; 1912 } 1913 } 1914 } 1915 } 1916 return false; 1917 } 1918 }; 1919 1920 public void setSystemProcess() { 1921 try { 1922 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1923 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1924 ServiceManager.addService("meminfo", new MemBinder(this)); 1925 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1926 ServiceManager.addService("dbinfo", new DbBinder(this)); 1927 if (MONITOR_CPU_USAGE) { 1928 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1929 } 1930 ServiceManager.addService("permission", new PermissionController(this)); 1931 1932 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1933 "android", STOCK_PM_FLAGS); 1934 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1935 1936 synchronized (this) { 1937 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1938 app.persistent = true; 1939 app.pid = MY_PID; 1940 app.maxAdj = ProcessList.SYSTEM_ADJ; 1941 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1942 mProcessNames.put(app.processName, app.uid, app); 1943 synchronized (mPidsSelfLocked) { 1944 mPidsSelfLocked.put(app.pid, app); 1945 } 1946 updateLruProcessLocked(app, false, null); 1947 updateOomAdjLocked(); 1948 } 1949 } catch (PackageManager.NameNotFoundException e) { 1950 throw new RuntimeException( 1951 "Unable to find android system package", e); 1952 } 1953 } 1954 1955 public void setWindowManager(WindowManagerService wm) { 1956 mWindowManager = wm; 1957 mStackSupervisor.setWindowManager(wm); 1958 } 1959 1960 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1961 mUsageStatsService = usageStatsManager; 1962 } 1963 1964 public void startObservingNativeCrashes() { 1965 final NativeCrashListener ncl = new NativeCrashListener(this); 1966 ncl.start(); 1967 } 1968 1969 public IAppOpsService getAppOpsService() { 1970 return mAppOpsService; 1971 } 1972 1973 static class MemBinder extends Binder { 1974 ActivityManagerService mActivityManagerService; 1975 MemBinder(ActivityManagerService activityManagerService) { 1976 mActivityManagerService = activityManagerService; 1977 } 1978 1979 @Override 1980 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1981 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1982 != PackageManager.PERMISSION_GRANTED) { 1983 pw.println("Permission Denial: can't dump meminfo from from pid=" 1984 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1985 + " without permission " + android.Manifest.permission.DUMP); 1986 return; 1987 } 1988 1989 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1990 } 1991 } 1992 1993 static class GraphicsBinder extends Binder { 1994 ActivityManagerService mActivityManagerService; 1995 GraphicsBinder(ActivityManagerService activityManagerService) { 1996 mActivityManagerService = activityManagerService; 1997 } 1998 1999 @Override 2000 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2001 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2002 != PackageManager.PERMISSION_GRANTED) { 2003 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2004 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2005 + " without permission " + android.Manifest.permission.DUMP); 2006 return; 2007 } 2008 2009 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2010 } 2011 } 2012 2013 static class DbBinder extends Binder { 2014 ActivityManagerService mActivityManagerService; 2015 DbBinder(ActivityManagerService activityManagerService) { 2016 mActivityManagerService = activityManagerService; 2017 } 2018 2019 @Override 2020 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2021 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2022 != PackageManager.PERMISSION_GRANTED) { 2023 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2024 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2025 + " without permission " + android.Manifest.permission.DUMP); 2026 return; 2027 } 2028 2029 mActivityManagerService.dumpDbInfo(fd, pw, args); 2030 } 2031 } 2032 2033 static class CpuBinder extends Binder { 2034 ActivityManagerService mActivityManagerService; 2035 CpuBinder(ActivityManagerService activityManagerService) { 2036 mActivityManagerService = activityManagerService; 2037 } 2038 2039 @Override 2040 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2041 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2042 != PackageManager.PERMISSION_GRANTED) { 2043 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2044 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2045 + " without permission " + android.Manifest.permission.DUMP); 2046 return; 2047 } 2048 2049 synchronized (mActivityManagerService.mProcessCpuTracker) { 2050 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2051 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2052 SystemClock.uptimeMillis())); 2053 } 2054 } 2055 } 2056 2057 public static final class Lifecycle extends SystemService { 2058 private final ActivityManagerService mService; 2059 2060 public Lifecycle(Context context) { 2061 super(context); 2062 mService = new ActivityManagerService(context); 2063 } 2064 2065 @Override 2066 public void onStart() { 2067 mService.start(); 2068 } 2069 2070 public ActivityManagerService getService() { 2071 return mService; 2072 } 2073 } 2074 2075 // Note: This method is invoked on the main thread but may need to attach various 2076 // handlers to other threads. So take care to be explicit about the looper. 2077 public ActivityManagerService(Context systemContext) { 2078 mContext = systemContext; 2079 mFactoryTest = FactoryTest.getMode(); 2080 mSystemThread = ActivityThread.currentActivityThread(); 2081 2082 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2083 2084 mHandlerThread = new ServiceThread(TAG, 2085 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2086 mHandlerThread.start(); 2087 mHandler = new MainHandler(mHandlerThread.getLooper()); 2088 2089 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2090 "foreground", BROADCAST_FG_TIMEOUT, false); 2091 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2092 "background", BROADCAST_BG_TIMEOUT, true); 2093 mBroadcastQueues[0] = mFgBroadcastQueue; 2094 mBroadcastQueues[1] = mBgBroadcastQueue; 2095 2096 mServices = new ActiveServices(this); 2097 mProviderMap = new ProviderMap(this); 2098 2099 // TODO: Move creation of battery stats service outside of activity manager service. 2100 File dataDir = Environment.getDataDirectory(); 2101 File systemDir = new File(dataDir, "system"); 2102 systemDir.mkdirs(); 2103 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2104 mBatteryStatsService.getActiveStatistics().readLocked(); 2105 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2106 mOnBattery = DEBUG_POWER ? true 2107 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2108 mBatteryStatsService.getActiveStatistics().setCallback(this); 2109 2110 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2111 2112 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2113 2114 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2115 2116 // User 0 is the first and only user that runs at boot. 2117 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2118 mUserLru.add(Integer.valueOf(0)); 2119 updateStartedUserArrayLocked(); 2120 2121 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2122 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2123 2124 mConfiguration.setToDefaults(); 2125 mConfiguration.setLocale(Locale.getDefault()); 2126 2127 mConfigurationSeq = mConfiguration.seq = 1; 2128 mProcessCpuTracker.init(); 2129 2130 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2131 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2132 mStackSupervisor = new ActivityStackSupervisor(this); 2133 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2134 2135 mProcessCpuThread = new Thread("CpuTracker") { 2136 @Override 2137 public void run() { 2138 while (true) { 2139 try { 2140 try { 2141 synchronized(this) { 2142 final long now = SystemClock.uptimeMillis(); 2143 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2144 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2145 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2146 // + ", write delay=" + nextWriteDelay); 2147 if (nextWriteDelay < nextCpuDelay) { 2148 nextCpuDelay = nextWriteDelay; 2149 } 2150 if (nextCpuDelay > 0) { 2151 mProcessCpuMutexFree.set(true); 2152 this.wait(nextCpuDelay); 2153 } 2154 } 2155 } catch (InterruptedException e) { 2156 } 2157 updateCpuStatsNow(); 2158 } catch (Exception e) { 2159 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2160 } 2161 } 2162 } 2163 }; 2164 2165 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 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 private void start() { 2176 Process.removeAllProcessGroups(); 2177 mProcessCpuThread.start(); 2178 2179 mBatteryStatsService.publish(mContext); 2180 mAppOpsService.publish(mContext); 2181 Slog.d("AppOps", "AppOpsService published"); 2182 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2183 } 2184 2185 public void initPowerManagement() { 2186 mStackSupervisor.initPowerManagement(); 2187 mBatteryStatsService.initPowerManagement(); 2188 } 2189 2190 @Override 2191 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2192 throws RemoteException { 2193 if (code == SYSPROPS_TRANSACTION) { 2194 // We need to tell all apps about the system property change. 2195 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2196 synchronized(this) { 2197 final int NP = mProcessNames.getMap().size(); 2198 for (int ip=0; ip<NP; ip++) { 2199 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2200 final int NA = apps.size(); 2201 for (int ia=0; ia<NA; ia++) { 2202 ProcessRecord app = apps.valueAt(ia); 2203 if (app.thread != null) { 2204 procs.add(app.thread.asBinder()); 2205 } 2206 } 2207 } 2208 } 2209 2210 int N = procs.size(); 2211 for (int i=0; i<N; i++) { 2212 Parcel data2 = Parcel.obtain(); 2213 try { 2214 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2215 } catch (RemoteException e) { 2216 } 2217 data2.recycle(); 2218 } 2219 } 2220 try { 2221 return super.onTransact(code, data, reply, flags); 2222 } catch (RuntimeException e) { 2223 // The activity manager only throws security exceptions, so let's 2224 // log all others. 2225 if (!(e instanceof SecurityException)) { 2226 Slog.wtf(TAG, "Activity Manager Crash", e); 2227 } 2228 throw e; 2229 } 2230 } 2231 2232 void updateCpuStats() { 2233 final long now = SystemClock.uptimeMillis(); 2234 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2235 return; 2236 } 2237 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2238 synchronized (mProcessCpuThread) { 2239 mProcessCpuThread.notify(); 2240 } 2241 } 2242 } 2243 2244 void updateCpuStatsNow() { 2245 synchronized (mProcessCpuTracker) { 2246 mProcessCpuMutexFree.set(false); 2247 final long now = SystemClock.uptimeMillis(); 2248 boolean haveNewCpuStats = false; 2249 2250 if (MONITOR_CPU_USAGE && 2251 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2252 mLastCpuTime.set(now); 2253 haveNewCpuStats = true; 2254 mProcessCpuTracker.update(); 2255 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2256 //Slog.i(TAG, "Total CPU usage: " 2257 // + mProcessCpu.getTotalCpuPercent() + "%"); 2258 2259 // Slog the cpu usage if the property is set. 2260 if ("true".equals(SystemProperties.get("events.cpu"))) { 2261 int user = mProcessCpuTracker.getLastUserTime(); 2262 int system = mProcessCpuTracker.getLastSystemTime(); 2263 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2264 int irq = mProcessCpuTracker.getLastIrqTime(); 2265 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2266 int idle = mProcessCpuTracker.getLastIdleTime(); 2267 2268 int total = user + system + iowait + irq + softIrq + idle; 2269 if (total == 0) total = 1; 2270 2271 EventLog.writeEvent(EventLogTags.CPU, 2272 ((user+system+iowait+irq+softIrq) * 100) / total, 2273 (user * 100) / total, 2274 (system * 100) / total, 2275 (iowait * 100) / total, 2276 (irq * 100) / total, 2277 (softIrq * 100) / total); 2278 } 2279 } 2280 2281 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2282 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2283 synchronized(bstats) { 2284 synchronized(mPidsSelfLocked) { 2285 if (haveNewCpuStats) { 2286 if (mOnBattery) { 2287 int perc = bstats.startAddingCpuLocked(); 2288 int totalUTime = 0; 2289 int totalSTime = 0; 2290 final int N = mProcessCpuTracker.countStats(); 2291 for (int i=0; i<N; i++) { 2292 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2293 if (!st.working) { 2294 continue; 2295 } 2296 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2297 int otherUTime = (st.rel_utime*perc)/100; 2298 int otherSTime = (st.rel_stime*perc)/100; 2299 totalUTime += otherUTime; 2300 totalSTime += otherSTime; 2301 if (pr != null) { 2302 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2303 if (ps == null || !ps.isActive()) { 2304 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2305 pr.info.uid, pr.processName); 2306 } 2307 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2308 st.rel_stime-otherSTime); 2309 ps.addSpeedStepTimes(cpuSpeedTimes); 2310 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2311 } else { 2312 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2313 if (ps == null || !ps.isActive()) { 2314 st.batteryStats = ps = bstats.getProcessStatsLocked( 2315 bstats.mapUid(st.uid), st.name); 2316 } 2317 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2318 st.rel_stime-otherSTime); 2319 ps.addSpeedStepTimes(cpuSpeedTimes); 2320 } 2321 } 2322 bstats.finishAddingCpuLocked(perc, totalUTime, 2323 totalSTime, cpuSpeedTimes); 2324 } 2325 } 2326 } 2327 2328 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2329 mLastWriteTime = now; 2330 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2331 } 2332 } 2333 } 2334 } 2335 2336 @Override 2337 public void batteryNeedsCpuUpdate() { 2338 updateCpuStatsNow(); 2339 } 2340 2341 @Override 2342 public void batteryPowerChanged(boolean onBattery) { 2343 // When plugging in, update the CPU stats first before changing 2344 // the plug state. 2345 updateCpuStatsNow(); 2346 synchronized (this) { 2347 synchronized(mPidsSelfLocked) { 2348 mOnBattery = DEBUG_POWER ? true : onBattery; 2349 } 2350 } 2351 } 2352 2353 /** 2354 * Initialize the application bind args. These are passed to each 2355 * process when the bindApplication() IPC is sent to the process. They're 2356 * lazily setup to make sure the services are running when they're asked for. 2357 */ 2358 private HashMap<String, IBinder> getCommonServicesLocked() { 2359 if (mAppBindArgs == null) { 2360 mAppBindArgs = new HashMap<String, IBinder>(); 2361 2362 // Setup the application init args 2363 mAppBindArgs.put("package", ServiceManager.getService("package")); 2364 mAppBindArgs.put("window", ServiceManager.getService("window")); 2365 mAppBindArgs.put(Context.ALARM_SERVICE, 2366 ServiceManager.getService(Context.ALARM_SERVICE)); 2367 } 2368 return mAppBindArgs; 2369 } 2370 2371 final void setFocusedActivityLocked(ActivityRecord r) { 2372 if (mFocusedActivity != r) { 2373 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2374 mFocusedActivity = r; 2375 if (r.task != null && r.task.voiceInteractor != null) { 2376 startRunningVoiceLocked(); 2377 } else { 2378 finishRunningVoiceLocked(); 2379 } 2380 mStackSupervisor.setFocusedStack(r); 2381 if (r != null) { 2382 mWindowManager.setFocusedApp(r.appToken, true); 2383 } 2384 applyUpdateLockStateLocked(r); 2385 } 2386 } 2387 2388 final void clearFocusedActivity(ActivityRecord r) { 2389 if (mFocusedActivity == r) { 2390 mFocusedActivity = null; 2391 } 2392 } 2393 2394 @Override 2395 public void setFocusedStack(int stackId) { 2396 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2397 synchronized (ActivityManagerService.this) { 2398 ActivityStack stack = mStackSupervisor.getStack(stackId); 2399 if (stack != null) { 2400 ActivityRecord r = stack.topRunningActivityLocked(null); 2401 if (r != null) { 2402 setFocusedActivityLocked(r); 2403 } 2404 } 2405 } 2406 } 2407 2408 @Override 2409 public void notifyActivityDrawn(IBinder token) { 2410 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2411 synchronized (this) { 2412 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2413 if (r != null) { 2414 r.task.stack.notifyActivityDrawnLocked(r); 2415 } 2416 } 2417 } 2418 2419 final void applyUpdateLockStateLocked(ActivityRecord r) { 2420 // Modifications to the UpdateLock state are done on our handler, outside 2421 // the activity manager's locks. The new state is determined based on the 2422 // state *now* of the relevant activity record. The object is passed to 2423 // the handler solely for logging detail, not to be consulted/modified. 2424 final boolean nextState = r != null && r.immersive; 2425 mHandler.sendMessage( 2426 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2427 } 2428 2429 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2430 Message msg = Message.obtain(); 2431 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2432 msg.obj = r.task.askedCompatMode ? null : r; 2433 mHandler.sendMessage(msg); 2434 } 2435 2436 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2437 String what, Object obj, ProcessRecord srcApp) { 2438 app.lastActivityTime = now; 2439 2440 if (app.activities.size() > 0) { 2441 // Don't want to touch dependent processes that are hosting activities. 2442 return index; 2443 } 2444 2445 int lrui = mLruProcesses.lastIndexOf(app); 2446 if (lrui < 0) { 2447 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2448 + what + " " + obj + " from " + srcApp); 2449 return index; 2450 } 2451 2452 if (lrui >= index) { 2453 // Don't want to cause this to move dependent processes *back* in the 2454 // list as if they were less frequently used. 2455 return index; 2456 } 2457 2458 if (lrui >= mLruProcessActivityStart) { 2459 // Don't want to touch dependent processes that are hosting activities. 2460 return index; 2461 } 2462 2463 mLruProcesses.remove(lrui); 2464 if (index > 0) { 2465 index--; 2466 } 2467 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2468 + " in LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 return index; 2471 } 2472 2473 final void removeLruProcessLocked(ProcessRecord app) { 2474 int lrui = mLruProcesses.lastIndexOf(app); 2475 if (lrui >= 0) { 2476 if (!app.killed) { 2477 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2478 Process.killProcessQuiet(app.pid); 2479 Process.killProcessGroup(app.info.uid, app.pid); 2480 } 2481 if (lrui <= mLruProcessActivityStart) { 2482 mLruProcessActivityStart--; 2483 } 2484 if (lrui <= mLruProcessServiceStart) { 2485 mLruProcessServiceStart--; 2486 } 2487 mLruProcesses.remove(lrui); 2488 } 2489 } 2490 2491 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2492 ProcessRecord client) { 2493 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2494 || app.treatLikeActivity; 2495 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2496 if (!activityChange && hasActivity) { 2497 // The process has activities, so we are only allowing activity-based adjustments 2498 // to move it. It should be kept in the front of the list with other 2499 // processes that have activities, and we don't want those to change their 2500 // order except due to activity operations. 2501 return; 2502 } 2503 2504 mLruSeq++; 2505 final long now = SystemClock.uptimeMillis(); 2506 app.lastActivityTime = now; 2507 2508 // First a quick reject: if the app is already at the position we will 2509 // put it, then there is nothing to do. 2510 if (hasActivity) { 2511 final int N = mLruProcesses.size(); 2512 if (N > 0 && mLruProcesses.get(N-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2514 return; 2515 } 2516 } else { 2517 if (mLruProcessServiceStart > 0 2518 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2519 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2520 return; 2521 } 2522 } 2523 2524 int lrui = mLruProcesses.lastIndexOf(app); 2525 2526 if (app.persistent && lrui >= 0) { 2527 // We don't care about the position of persistent processes, as long as 2528 // they are in the list. 2529 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2530 return; 2531 } 2532 2533 /* In progress: compute new position first, so we can avoid doing work 2534 if the process is not actually going to move. Not yet working. 2535 int addIndex; 2536 int nextIndex; 2537 boolean inActivity = false, inService = false; 2538 if (hasActivity) { 2539 // Process has activities, put it at the very tipsy-top. 2540 addIndex = mLruProcesses.size(); 2541 nextIndex = mLruProcessServiceStart; 2542 inActivity = true; 2543 } else if (hasService) { 2544 // Process has services, put it at the top of the service list. 2545 addIndex = mLruProcessActivityStart; 2546 nextIndex = mLruProcessServiceStart; 2547 inActivity = true; 2548 inService = true; 2549 } else { 2550 // Process not otherwise of interest, it goes to the top of the non-service area. 2551 addIndex = mLruProcessServiceStart; 2552 if (client != null) { 2553 int clientIndex = mLruProcesses.lastIndexOf(client); 2554 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2555 + app); 2556 if (clientIndex >= 0 && addIndex > clientIndex) { 2557 addIndex = clientIndex; 2558 } 2559 } 2560 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2561 } 2562 2563 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2564 + mLruProcessActivityStart + "): " + app); 2565 */ 2566 2567 if (lrui >= 0) { 2568 if (lrui < mLruProcessActivityStart) { 2569 mLruProcessActivityStart--; 2570 } 2571 if (lrui < mLruProcessServiceStart) { 2572 mLruProcessServiceStart--; 2573 } 2574 /* 2575 if (addIndex > lrui) { 2576 addIndex--; 2577 } 2578 if (nextIndex > lrui) { 2579 nextIndex--; 2580 } 2581 */ 2582 mLruProcesses.remove(lrui); 2583 } 2584 2585 /* 2586 mLruProcesses.add(addIndex, app); 2587 if (inActivity) { 2588 mLruProcessActivityStart++; 2589 } 2590 if (inService) { 2591 mLruProcessActivityStart++; 2592 } 2593 */ 2594 2595 int nextIndex; 2596 if (hasActivity) { 2597 final int N = mLruProcesses.size(); 2598 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2599 // Process doesn't have activities, but has clients with 2600 // activities... move it up, but one below the top (the top 2601 // should always have a real activity). 2602 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2603 mLruProcesses.add(N-1, app); 2604 // To keep it from spamming the LRU list (by making a bunch of clients), 2605 // we will push down any other entries owned by the app. 2606 final int uid = app.info.uid; 2607 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2608 ProcessRecord subProc = mLruProcesses.get(i); 2609 if (subProc.info.uid == uid) { 2610 // We want to push this one down the list. If the process after 2611 // it is for the same uid, however, don't do so, because we don't 2612 // want them internally to be re-ordered. 2613 if (mLruProcesses.get(i-1).info.uid != uid) { 2614 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2615 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2616 ProcessRecord tmp = mLruProcesses.get(i); 2617 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2618 mLruProcesses.set(i-1, tmp); 2619 i--; 2620 } 2621 } else { 2622 // A gap, we can stop here. 2623 break; 2624 } 2625 } 2626 } else { 2627 // Process has activities, put it at the very tipsy-top. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2629 mLruProcesses.add(app); 2630 } 2631 nextIndex = mLruProcessServiceStart; 2632 } else if (hasService) { 2633 // Process has services, put it at the top of the service list. 2634 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2635 mLruProcesses.add(mLruProcessActivityStart, app); 2636 nextIndex = mLruProcessServiceStart; 2637 mLruProcessActivityStart++; 2638 } else { 2639 // Process not otherwise of interest, it goes to the top of the non-service area. 2640 int index = mLruProcessServiceStart; 2641 if (client != null) { 2642 // If there is a client, don't allow the process to be moved up higher 2643 // in the list than that client. 2644 int clientIndex = mLruProcesses.lastIndexOf(client); 2645 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2646 + " when updating " + app); 2647 if (clientIndex <= lrui) { 2648 // Don't allow the client index restriction to push it down farther in the 2649 // list than it already is. 2650 clientIndex = lrui; 2651 } 2652 if (clientIndex >= 0 && index > clientIndex) { 2653 index = clientIndex; 2654 } 2655 } 2656 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2657 mLruProcesses.add(index, app); 2658 nextIndex = index-1; 2659 mLruProcessActivityStart++; 2660 mLruProcessServiceStart++; 2661 } 2662 2663 // If the app is currently using a content provider or service, 2664 // bump those processes as well. 2665 for (int j=app.connections.size()-1; j>=0; j--) { 2666 ConnectionRecord cr = app.connections.valueAt(j); 2667 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2668 && cr.binding.service.app != null 2669 && cr.binding.service.app.lruSeq != mLruSeq 2670 && !cr.binding.service.app.persistent) { 2671 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2672 "service connection", cr, app); 2673 } 2674 } 2675 for (int j=app.conProviders.size()-1; j>=0; j--) { 2676 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2677 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2678 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2679 "provider reference", cpr, app); 2680 } 2681 } 2682 } 2683 2684 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2685 if (uid == Process.SYSTEM_UID) { 2686 // The system gets to run in any process. If there are multiple 2687 // processes with the same uid, just pick the first (this 2688 // should never happen). 2689 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2690 if (procs == null) return null; 2691 final int N = procs.size(); 2692 for (int i = 0; i < N; i++) { 2693 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2694 } 2695 } 2696 ProcessRecord proc = mProcessNames.get(processName, uid); 2697 if (false && proc != null && !keepIfLarge 2698 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2699 && proc.lastCachedPss >= 4000) { 2700 // Turn this condition on to cause killing to happen regularly, for testing. 2701 if (proc.baseProcessTracker != null) { 2702 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2703 } 2704 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2705 } else if (proc != null && !keepIfLarge 2706 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2707 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2708 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2709 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2710 if (proc.baseProcessTracker != null) { 2711 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2712 } 2713 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2714 } 2715 } 2716 return proc; 2717 } 2718 2719 void ensurePackageDexOpt(String packageName) { 2720 IPackageManager pm = AppGlobals.getPackageManager(); 2721 try { 2722 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2723 mDidDexOpt = true; 2724 } 2725 } catch (RemoteException e) { 2726 } 2727 } 2728 2729 boolean isNextTransitionForward() { 2730 int transit = mWindowManager.getPendingAppTransition(); 2731 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2732 || transit == AppTransition.TRANSIT_TASK_OPEN 2733 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2734 } 2735 2736 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2737 String processName, String abiOverride, int uid, Runnable crashHandler) { 2738 synchronized(this) { 2739 ApplicationInfo info = new ApplicationInfo(); 2740 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2741 // For isolated processes, the former contains the parent's uid and the latter the 2742 // actual uid of the isolated process. 2743 // In the special case introduced by this method (which is, starting an isolated 2744 // process directly from the SystemServer without an actual parent app process) the 2745 // closest thing to a parent's uid is SYSTEM_UID. 2746 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2747 // the |isolated| logic in the ProcessRecord constructor. 2748 info.uid = Process.SYSTEM_UID; 2749 info.processName = processName; 2750 info.className = entryPoint; 2751 info.packageName = "android"; 2752 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2753 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2754 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2755 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2756 crashHandler); 2757 return proc != null ? proc.pid : 0; 2758 } 2759 } 2760 2761 final ProcessRecord startProcessLocked(String processName, 2762 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2763 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2764 boolean isolated, boolean keepIfLarge) { 2765 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2766 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2767 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2768 null /* crashHandler */); 2769 } 2770 2771 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2772 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2773 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2774 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2775 long startTime = SystemClock.elapsedRealtime(); 2776 ProcessRecord app; 2777 if (!isolated) { 2778 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2779 checkTime(startTime, "startProcess: after getProcessRecord"); 2780 } else { 2781 // If this is an isolated process, it can't re-use an existing process. 2782 app = null; 2783 } 2784 // We don't have to do anything more if: 2785 // (1) There is an existing application record; and 2786 // (2) The caller doesn't think it is dead, OR there is no thread 2787 // object attached to it so we know it couldn't have crashed; and 2788 // (3) There is a pid assigned to it, so it is either starting or 2789 // already running. 2790 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2791 + " app=" + app + " knownToBeDead=" + knownToBeDead 2792 + " thread=" + (app != null ? app.thread : null) 2793 + " pid=" + (app != null ? app.pid : -1)); 2794 if (app != null && app.pid > 0) { 2795 if (!knownToBeDead || app.thread == null) { 2796 // We already have the app running, or are waiting for it to 2797 // come up (we have a pid but not yet its thread), so keep it. 2798 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2799 // If this is a new package in the process, add the package to the list 2800 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2801 checkTime(startTime, "startProcess: done, added package to proc"); 2802 return app; 2803 } 2804 2805 // An application record is attached to a previous process, 2806 // clean it up now. 2807 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2808 checkTime(startTime, "startProcess: bad proc running, killing"); 2809 Process.killProcessGroup(app.info.uid, app.pid); 2810 handleAppDiedLocked(app, true, true); 2811 checkTime(startTime, "startProcess: done killing old proc"); 2812 } 2813 2814 String hostingNameStr = hostingName != null 2815 ? hostingName.flattenToShortString() : null; 2816 2817 if (!isolated) { 2818 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2819 // If we are in the background, then check to see if this process 2820 // is bad. If so, we will just silently fail. 2821 if (mBadProcesses.get(info.processName, info.uid) != null) { 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2823 + "/" + info.processName); 2824 return null; 2825 } 2826 } else { 2827 // When the user is explicitly starting a process, then clear its 2828 // crash count so that we won't make it bad until they see at 2829 // least one crash dialog again, and make the process good again 2830 // if it had been bad. 2831 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2832 + "/" + info.processName); 2833 mProcessCrashTimes.remove(info.processName, info.uid); 2834 if (mBadProcesses.get(info.processName, info.uid) != null) { 2835 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2836 UserHandle.getUserId(info.uid), info.uid, 2837 info.processName); 2838 mBadProcesses.remove(info.processName, info.uid); 2839 if (app != null) { 2840 app.bad = false; 2841 } 2842 } 2843 } 2844 } 2845 2846 if (app == null) { 2847 checkTime(startTime, "startProcess: creating new process record"); 2848 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2849 app.crashHandler = crashHandler; 2850 if (app == null) { 2851 Slog.w(TAG, "Failed making new process record for " 2852 + processName + "/" + info.uid + " isolated=" + isolated); 2853 return null; 2854 } 2855 mProcessNames.put(processName, app.uid, app); 2856 if (isolated) { 2857 mIsolatedProcesses.put(app.uid, app); 2858 } 2859 checkTime(startTime, "startProcess: done creating new process record"); 2860 } else { 2861 // If this is a new package in the process, add the package to the list 2862 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2863 checkTime(startTime, "startProcess: added package to existing proc"); 2864 } 2865 2866 // If the system is not ready yet, then hold off on starting this 2867 // process until it is. 2868 if (!mProcessesReady 2869 && !isAllowedWhileBooting(info) 2870 && !allowWhileBooting) { 2871 if (!mProcessesOnHold.contains(app)) { 2872 mProcessesOnHold.add(app); 2873 } 2874 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2875 checkTime(startTime, "startProcess: returning with proc on hold"); 2876 return app; 2877 } 2878 2879 checkTime(startTime, "startProcess: stepping in to startProcess"); 2880 startProcessLocked( 2881 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2882 checkTime(startTime, "startProcess: done starting proc!"); 2883 return (app.pid != 0) ? app : null; 2884 } 2885 2886 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2887 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2888 } 2889 2890 private final void startProcessLocked(ProcessRecord app, 2891 String hostingType, String hostingNameStr) { 2892 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2893 null /* entryPoint */, null /* entryPointArgs */); 2894 } 2895 2896 private final void startProcessLocked(ProcessRecord app, String hostingType, 2897 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2898 long startTime = SystemClock.elapsedRealtime(); 2899 if (app.pid > 0 && app.pid != MY_PID) { 2900 checkTime(startTime, "startProcess: removing from pids map"); 2901 synchronized (mPidsSelfLocked) { 2902 mPidsSelfLocked.remove(app.pid); 2903 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2904 } 2905 checkTime(startTime, "startProcess: done removing from pids map"); 2906 app.setPid(0); 2907 } 2908 2909 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2910 "startProcessLocked removing on hold: " + app); 2911 mProcessesOnHold.remove(app); 2912 2913 checkTime(startTime, "startProcess: starting to update cpu stats"); 2914 updateCpuStats(); 2915 checkTime(startTime, "startProcess: done updating cpu stats"); 2916 2917 try { 2918 int uid = app.uid; 2919 2920 int[] gids = null; 2921 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2922 if (!app.isolated) { 2923 int[] permGids = null; 2924 try { 2925 checkTime(startTime, "startProcess: getting gids from package manager"); 2926 final PackageManager pm = mContext.getPackageManager(); 2927 permGids = pm.getPackageGids(app.info.packageName); 2928 2929 if (Environment.isExternalStorageEmulated()) { 2930 checkTime(startTime, "startProcess: checking external storage perm"); 2931 if (pm.checkPermission( 2932 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2933 app.info.packageName) == PERMISSION_GRANTED) { 2934 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2935 } else { 2936 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2937 } 2938 } 2939 } catch (PackageManager.NameNotFoundException e) { 2940 Slog.w(TAG, "Unable to retrieve gids", e); 2941 } 2942 2943 /* 2944 * Add shared application and profile GIDs so applications can share some 2945 * resources like shared libraries and access user-wide resources 2946 */ 2947 if (permGids == null) { 2948 gids = new int[2]; 2949 } else { 2950 gids = new int[permGids.length + 2]; 2951 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2952 } 2953 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2954 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2955 } 2956 checkTime(startTime, "startProcess: building args"); 2957 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2958 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2959 && mTopComponent != null 2960 && app.processName.equals(mTopComponent.getPackageName())) { 2961 uid = 0; 2962 } 2963 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2964 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2965 uid = 0; 2966 } 2967 } 2968 int debugFlags = 0; 2969 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2970 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2971 // Also turn on CheckJNI for debuggable apps. It's quite 2972 // awkward to turn on otherwise. 2973 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2974 } 2975 // Run the app in safe mode if its manifest requests so or the 2976 // system is booted in safe mode. 2977 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2978 mSafeMode == true) { 2979 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2980 } 2981 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2986 } 2987 if ("1".equals(SystemProperties.get("debug.assert"))) { 2988 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2989 } 2990 2991 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2992 if (requiredAbi == null) { 2993 requiredAbi = Build.SUPPORTED_ABIS[0]; 2994 } 2995 2996 String instructionSet = null; 2997 if (app.info.primaryCpuAbi != null) { 2998 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2999 } 3000 3001 // Start the process. It will either succeed and return a result containing 3002 // the PID of the new process, or else throw a RuntimeException. 3003 boolean isActivityProcess = (entryPoint == null); 3004 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3005 checkTime(startTime, "startProcess: asking zygote to start proc"); 3006 Process.ProcessStartResult startResult = Process.start(entryPoint, 3007 app.processName, uid, uid, gids, debugFlags, mountExternal, 3008 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3009 app.info.dataDir, entryPointArgs); 3010 checkTime(startTime, "startProcess: returned from zygote!"); 3011 3012 if (app.isolated) { 3013 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3014 } 3015 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3016 checkTime(startTime, "startProcess: done updating battery stats"); 3017 3018 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3019 UserHandle.getUserId(uid), startResult.pid, uid, 3020 app.processName, hostingType, 3021 hostingNameStr != null ? hostingNameStr : ""); 3022 3023 if (app.persistent) { 3024 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3025 } 3026 3027 checkTime(startTime, "startProcess: building log message"); 3028 StringBuilder buf = mStringBuilder; 3029 buf.setLength(0); 3030 buf.append("Start proc "); 3031 buf.append(app.processName); 3032 if (!isActivityProcess) { 3033 buf.append(" ["); 3034 buf.append(entryPoint); 3035 buf.append("]"); 3036 } 3037 buf.append(" for "); 3038 buf.append(hostingType); 3039 if (hostingNameStr != null) { 3040 buf.append(" "); 3041 buf.append(hostingNameStr); 3042 } 3043 buf.append(": pid="); 3044 buf.append(startResult.pid); 3045 buf.append(" uid="); 3046 buf.append(uid); 3047 buf.append(" gids={"); 3048 if (gids != null) { 3049 for (int gi=0; gi<gids.length; gi++) { 3050 if (gi != 0) buf.append(", "); 3051 buf.append(gids[gi]); 3052 3053 } 3054 } 3055 buf.append("}"); 3056 if (requiredAbi != null) { 3057 buf.append(" abi="); 3058 buf.append(requiredAbi); 3059 } 3060 Slog.i(TAG, buf.toString()); 3061 app.setPid(startResult.pid); 3062 app.usingWrapper = startResult.usingWrapper; 3063 app.removed = false; 3064 app.killed = false; 3065 app.killedByAm = false; 3066 checkTime(startTime, "startProcess: starting to update pids map"); 3067 synchronized (mPidsSelfLocked) { 3068 this.mPidsSelfLocked.put(startResult.pid, app); 3069 if (isActivityProcess) { 3070 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3071 msg.obj = app; 3072 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3073 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3074 } 3075 } 3076 checkTime(startTime, "startProcess: done updating pids map"); 3077 } catch (RuntimeException e) { 3078 // XXX do better error recovery. 3079 app.setPid(0); 3080 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3081 if (app.isolated) { 3082 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3083 } 3084 Slog.e(TAG, "Failure starting process " + app.processName, e); 3085 } 3086 } 3087 3088 void updateUsageStats(ActivityRecord component, boolean resumed) { 3089 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3090 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3091 if (resumed) { 3092 if (mUsageStatsService != null) { 3093 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3094 UsageEvents.Event.MOVE_TO_FOREGROUND); 3095 } 3096 synchronized (stats) { 3097 stats.noteActivityResumedLocked(component.app.uid); 3098 } 3099 } else { 3100 if (mUsageStatsService != null) { 3101 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3102 UsageEvents.Event.MOVE_TO_BACKGROUND); 3103 } 3104 synchronized (stats) { 3105 stats.noteActivityPausedLocked(component.app.uid); 3106 } 3107 } 3108 } 3109 3110 Intent getHomeIntent() { 3111 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3112 intent.setComponent(mTopComponent); 3113 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3114 intent.addCategory(Intent.CATEGORY_HOME); 3115 } 3116 return intent; 3117 } 3118 3119 boolean startHomeActivityLocked(int userId) { 3120 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3121 && mTopAction == null) { 3122 // We are running in factory test mode, but unable to find 3123 // the factory test app, so just sit around displaying the 3124 // error message and don't try to start anything. 3125 return false; 3126 } 3127 Intent intent = getHomeIntent(); 3128 ActivityInfo aInfo = 3129 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3130 if (aInfo != null) { 3131 intent.setComponent(new ComponentName( 3132 aInfo.applicationInfo.packageName, aInfo.name)); 3133 // Don't do this if the home app is currently being 3134 // instrumented. 3135 aInfo = new ActivityInfo(aInfo); 3136 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3137 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3138 aInfo.applicationInfo.uid, true); 3139 if (app == null || app.instrumentationClass == null) { 3140 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3141 mStackSupervisor.startHomeActivity(intent, aInfo); 3142 } 3143 } 3144 3145 return true; 3146 } 3147 3148 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3149 ActivityInfo ai = null; 3150 ComponentName comp = intent.getComponent(); 3151 try { 3152 if (comp != null) { 3153 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3154 } else { 3155 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3156 intent, 3157 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3158 flags, userId); 3159 3160 if (info != null) { 3161 ai = info.activityInfo; 3162 } 3163 } 3164 } catch (RemoteException e) { 3165 // ignore 3166 } 3167 3168 return ai; 3169 } 3170 3171 /** 3172 * Starts the "new version setup screen" if appropriate. 3173 */ 3174 void startSetupActivityLocked() { 3175 // Only do this once per boot. 3176 if (mCheckedForSetup) { 3177 return; 3178 } 3179 3180 // We will show this screen if the current one is a different 3181 // version than the last one shown, and we are not running in 3182 // low-level factory test mode. 3183 final ContentResolver resolver = mContext.getContentResolver(); 3184 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3185 Settings.Global.getInt(resolver, 3186 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3187 mCheckedForSetup = true; 3188 3189 // See if we should be showing the platform update setup UI. 3190 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3191 List<ResolveInfo> ris = mContext.getPackageManager() 3192 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3193 3194 // We don't allow third party apps to replace this. 3195 ResolveInfo ri = null; 3196 for (int i=0; ris != null && i<ris.size(); i++) { 3197 if ((ris.get(i).activityInfo.applicationInfo.flags 3198 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3199 ri = ris.get(i); 3200 break; 3201 } 3202 } 3203 3204 if (ri != null) { 3205 String vers = ri.activityInfo.metaData != null 3206 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3207 : null; 3208 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3209 vers = ri.activityInfo.applicationInfo.metaData.getString( 3210 Intent.METADATA_SETUP_VERSION); 3211 } 3212 String lastVers = Settings.Secure.getString( 3213 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3214 if (vers != null && !vers.equals(lastVers)) { 3215 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3216 intent.setComponent(new ComponentName( 3217 ri.activityInfo.packageName, ri.activityInfo.name)); 3218 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3219 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3220 null); 3221 } 3222 } 3223 } 3224 } 3225 3226 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3227 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3228 } 3229 3230 void enforceNotIsolatedCaller(String caller) { 3231 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3232 throw new SecurityException("Isolated process not allowed to call " + caller); 3233 } 3234 } 3235 3236 void enforceShellRestriction(String restriction, int userHandle) { 3237 if (Binder.getCallingUid() == Process.SHELL_UID) { 3238 if (userHandle < 0 3239 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3240 throw new SecurityException("Shell does not have permission to access user " 3241 + userHandle); 3242 } 3243 } 3244 } 3245 3246 @Override 3247 public int getFrontActivityScreenCompatMode() { 3248 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3249 synchronized (this) { 3250 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3251 } 3252 } 3253 3254 @Override 3255 public void setFrontActivityScreenCompatMode(int mode) { 3256 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3257 "setFrontActivityScreenCompatMode"); 3258 synchronized (this) { 3259 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3260 } 3261 } 3262 3263 @Override 3264 public int getPackageScreenCompatMode(String packageName) { 3265 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3266 synchronized (this) { 3267 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3268 } 3269 } 3270 3271 @Override 3272 public void setPackageScreenCompatMode(String packageName, int mode) { 3273 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3274 "setPackageScreenCompatMode"); 3275 synchronized (this) { 3276 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3277 } 3278 } 3279 3280 @Override 3281 public boolean getPackageAskScreenCompat(String packageName) { 3282 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3283 synchronized (this) { 3284 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3285 } 3286 } 3287 3288 @Override 3289 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3290 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3291 "setPackageAskScreenCompat"); 3292 synchronized (this) { 3293 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3294 } 3295 } 3296 3297 private void dispatchProcessesChanged() { 3298 int N; 3299 synchronized (this) { 3300 N = mPendingProcessChanges.size(); 3301 if (mActiveProcessChanges.length < N) { 3302 mActiveProcessChanges = new ProcessChangeItem[N]; 3303 } 3304 mPendingProcessChanges.toArray(mActiveProcessChanges); 3305 mAvailProcessChanges.addAll(mPendingProcessChanges); 3306 mPendingProcessChanges.clear(); 3307 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3308 } 3309 3310 int i = mProcessObservers.beginBroadcast(); 3311 while (i > 0) { 3312 i--; 3313 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3314 if (observer != null) { 3315 try { 3316 for (int j=0; j<N; j++) { 3317 ProcessChangeItem item = mActiveProcessChanges[j]; 3318 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3320 + item.pid + " uid=" + item.uid + ": " 3321 + item.foregroundActivities); 3322 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3323 item.foregroundActivities); 3324 } 3325 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3326 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3327 + item.pid + " uid=" + item.uid + ": " + item.processState); 3328 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3329 } 3330 } 3331 } catch (RemoteException e) { 3332 } 3333 } 3334 } 3335 mProcessObservers.finishBroadcast(); 3336 } 3337 3338 private void dispatchProcessDied(int pid, int uid) { 3339 int i = mProcessObservers.beginBroadcast(); 3340 while (i > 0) { 3341 i--; 3342 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3343 if (observer != null) { 3344 try { 3345 observer.onProcessDied(pid, uid); 3346 } catch (RemoteException e) { 3347 } 3348 } 3349 } 3350 mProcessObservers.finishBroadcast(); 3351 } 3352 3353 @Override 3354 public final int startActivity(IApplicationThread caller, String callingPackage, 3355 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3356 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3357 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3358 resultWho, requestCode, startFlags, profilerInfo, options, 3359 UserHandle.getCallingUserId()); 3360 } 3361 3362 @Override 3363 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3364 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3365 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3366 enforceNotIsolatedCaller("startActivity"); 3367 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3368 false, ALLOW_FULL_ONLY, "startActivity", null); 3369 // TODO: Switch to user app stacks here. 3370 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3371 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3372 profilerInfo, null, null, options, userId, null, null); 3373 } 3374 3375 @Override 3376 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3377 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3378 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3379 3380 // This is very dangerous -- it allows you to perform a start activity (including 3381 // permission grants) as any app that may launch one of your own activities. So 3382 // we will only allow this to be done from activities that are part of the core framework, 3383 // and then only when they are running as the system. 3384 final ActivityRecord sourceRecord; 3385 final int targetUid; 3386 final String targetPackage; 3387 synchronized (this) { 3388 if (resultTo == null) { 3389 throw new SecurityException("Must be called from an activity"); 3390 } 3391 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3392 if (sourceRecord == null) { 3393 throw new SecurityException("Called with bad activity token: " + resultTo); 3394 } 3395 if (!sourceRecord.info.packageName.equals("android")) { 3396 throw new SecurityException( 3397 "Must be called from an activity that is declared in the android package"); 3398 } 3399 if (sourceRecord.app == null) { 3400 throw new SecurityException("Called without a process attached to activity"); 3401 } 3402 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3403 // This is still okay, as long as this activity is running under the 3404 // uid of the original calling activity. 3405 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3406 throw new SecurityException( 3407 "Calling activity in uid " + sourceRecord.app.uid 3408 + " must be system uid or original calling uid " 3409 + sourceRecord.launchedFromUid); 3410 } 3411 } 3412 targetUid = sourceRecord.launchedFromUid; 3413 targetPackage = sourceRecord.launchedFromPackage; 3414 } 3415 3416 if (userId == UserHandle.USER_NULL) { 3417 userId = UserHandle.getUserId(sourceRecord.app.uid); 3418 } 3419 3420 // TODO: Switch to user app stacks here. 3421 try { 3422 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3423 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3424 null, null, options, userId, null, null); 3425 return ret; 3426 } catch (SecurityException e) { 3427 // XXX need to figure out how to propagate to original app. 3428 // A SecurityException here is generally actually a fault of the original 3429 // calling activity (such as a fairly granting permissions), so propagate it 3430 // back to them. 3431 /* 3432 StringBuilder msg = new StringBuilder(); 3433 msg.append("While launching"); 3434 msg.append(intent.toString()); 3435 msg.append(": "); 3436 msg.append(e.getMessage()); 3437 */ 3438 throw e; 3439 } 3440 } 3441 3442 @Override 3443 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3444 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3445 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3446 enforceNotIsolatedCaller("startActivityAndWait"); 3447 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3448 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3449 WaitResult res = new WaitResult(); 3450 // TODO: Switch to user app stacks here. 3451 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3452 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3453 options, userId, null, null); 3454 return res; 3455 } 3456 3457 @Override 3458 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3459 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3460 int startFlags, Configuration config, Bundle options, int userId) { 3461 enforceNotIsolatedCaller("startActivityWithConfig"); 3462 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3463 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3464 // TODO: Switch to user app stacks here. 3465 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3466 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3467 null, null, config, options, userId, null, null); 3468 return ret; 3469 } 3470 3471 @Override 3472 public int startActivityIntentSender(IApplicationThread caller, 3473 IntentSender intent, Intent fillInIntent, String resolvedType, 3474 IBinder resultTo, String resultWho, int requestCode, 3475 int flagsMask, int flagsValues, Bundle options) { 3476 enforceNotIsolatedCaller("startActivityIntentSender"); 3477 // Refuse possible leaked file descriptors 3478 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3479 throw new IllegalArgumentException("File descriptors passed in Intent"); 3480 } 3481 3482 IIntentSender sender = intent.getTarget(); 3483 if (!(sender instanceof PendingIntentRecord)) { 3484 throw new IllegalArgumentException("Bad PendingIntent object"); 3485 } 3486 3487 PendingIntentRecord pir = (PendingIntentRecord)sender; 3488 3489 synchronized (this) { 3490 // If this is coming from the currently resumed activity, it is 3491 // effectively saying that app switches are allowed at this point. 3492 final ActivityStack stack = getFocusedStack(); 3493 if (stack.mResumedActivity != null && 3494 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3495 mAppSwitchesAllowedTime = 0; 3496 } 3497 } 3498 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3499 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3500 return ret; 3501 } 3502 3503 @Override 3504 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3505 Intent intent, String resolvedType, IVoiceInteractionSession session, 3506 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3507 Bundle options, int userId) { 3508 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3509 != PackageManager.PERMISSION_GRANTED) { 3510 String msg = "Permission Denial: startVoiceActivity() from pid=" 3511 + Binder.getCallingPid() 3512 + ", uid=" + Binder.getCallingUid() 3513 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3514 Slog.w(TAG, msg); 3515 throw new SecurityException(msg); 3516 } 3517 if (session == null || interactor == null) { 3518 throw new NullPointerException("null session or interactor"); 3519 } 3520 userId = handleIncomingUser(callingPid, callingUid, userId, 3521 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3522 // TODO: Switch to user app stacks here. 3523 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3524 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3525 null, options, userId, null, null); 3526 } 3527 3528 @Override 3529 public boolean startNextMatchingActivity(IBinder callingActivity, 3530 Intent intent, Bundle options) { 3531 // Refuse possible leaked file descriptors 3532 if (intent != null && intent.hasFileDescriptors() == true) { 3533 throw new IllegalArgumentException("File descriptors passed in Intent"); 3534 } 3535 3536 synchronized (this) { 3537 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3538 if (r == null) { 3539 ActivityOptions.abort(options); 3540 return false; 3541 } 3542 if (r.app == null || r.app.thread == null) { 3543 // The caller is not running... d'oh! 3544 ActivityOptions.abort(options); 3545 return false; 3546 } 3547 intent = new Intent(intent); 3548 // The caller is not allowed to change the data. 3549 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3550 // And we are resetting to find the next component... 3551 intent.setComponent(null); 3552 3553 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3554 3555 ActivityInfo aInfo = null; 3556 try { 3557 List<ResolveInfo> resolves = 3558 AppGlobals.getPackageManager().queryIntentActivities( 3559 intent, r.resolvedType, 3560 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3561 UserHandle.getCallingUserId()); 3562 3563 // Look for the original activity in the list... 3564 final int N = resolves != null ? resolves.size() : 0; 3565 for (int i=0; i<N; i++) { 3566 ResolveInfo rInfo = resolves.get(i); 3567 if (rInfo.activityInfo.packageName.equals(r.packageName) 3568 && rInfo.activityInfo.name.equals(r.info.name)) { 3569 // We found the current one... the next matching is 3570 // after it. 3571 i++; 3572 if (i<N) { 3573 aInfo = resolves.get(i).activityInfo; 3574 } 3575 if (debug) { 3576 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3577 + "/" + r.info.name); 3578 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3579 + "/" + aInfo.name); 3580 } 3581 break; 3582 } 3583 } 3584 } catch (RemoteException e) { 3585 } 3586 3587 if (aInfo == null) { 3588 // Nobody who is next! 3589 ActivityOptions.abort(options); 3590 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3591 return false; 3592 } 3593 3594 intent.setComponent(new ComponentName( 3595 aInfo.applicationInfo.packageName, aInfo.name)); 3596 intent.setFlags(intent.getFlags()&~( 3597 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3598 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3599 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3600 Intent.FLAG_ACTIVITY_NEW_TASK)); 3601 3602 // Okay now we need to start the new activity, replacing the 3603 // currently running activity. This is a little tricky because 3604 // we want to start the new one as if the current one is finished, 3605 // but not finish the current one first so that there is no flicker. 3606 // And thus... 3607 final boolean wasFinishing = r.finishing; 3608 r.finishing = true; 3609 3610 // Propagate reply information over to the new activity. 3611 final ActivityRecord resultTo = r.resultTo; 3612 final String resultWho = r.resultWho; 3613 final int requestCode = r.requestCode; 3614 r.resultTo = null; 3615 if (resultTo != null) { 3616 resultTo.removeResultsLocked(r, resultWho, requestCode); 3617 } 3618 3619 final long origId = Binder.clearCallingIdentity(); 3620 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3621 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3622 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3623 -1, r.launchedFromUid, 0, options, false, null, null, null); 3624 Binder.restoreCallingIdentity(origId); 3625 3626 r.finishing = wasFinishing; 3627 if (res != ActivityManager.START_SUCCESS) { 3628 return false; 3629 } 3630 return true; 3631 } 3632 } 3633 3634 @Override 3635 public final int startActivityFromRecents(int taskId, Bundle options) { 3636 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3637 String msg = "Permission Denial: startActivityFromRecents called without " + 3638 START_TASKS_FROM_RECENTS; 3639 Slog.w(TAG, msg); 3640 throw new SecurityException(msg); 3641 } 3642 return startActivityFromRecentsInner(taskId, options); 3643 } 3644 3645 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3646 final TaskRecord task; 3647 final int callingUid; 3648 final String callingPackage; 3649 final Intent intent; 3650 final int userId; 3651 synchronized (this) { 3652 task = recentTaskForIdLocked(taskId); 3653 if (task == null) { 3654 throw new IllegalArgumentException("Task " + taskId + " not found."); 3655 } 3656 callingUid = task.mCallingUid; 3657 callingPackage = task.mCallingPackage; 3658 intent = task.intent; 3659 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3660 userId = task.userId; 3661 } 3662 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3663 options, userId, null, task); 3664 } 3665 3666 final int startActivityInPackage(int uid, String callingPackage, 3667 Intent intent, String resolvedType, IBinder resultTo, 3668 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3669 IActivityContainer container, TaskRecord inTask) { 3670 3671 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3672 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3673 3674 // TODO: Switch to user app stacks here. 3675 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3676 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3677 null, null, null, options, userId, container, inTask); 3678 return ret; 3679 } 3680 3681 @Override 3682 public final int startActivities(IApplicationThread caller, String callingPackage, 3683 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3684 int userId) { 3685 enforceNotIsolatedCaller("startActivities"); 3686 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3687 false, ALLOW_FULL_ONLY, "startActivity", null); 3688 // TODO: Switch to user app stacks here. 3689 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3690 resolvedTypes, resultTo, options, userId); 3691 return ret; 3692 } 3693 3694 final int startActivitiesInPackage(int uid, String callingPackage, 3695 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3696 Bundle options, int userId) { 3697 3698 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3699 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3700 // TODO: Switch to user app stacks here. 3701 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3702 resultTo, options, userId); 3703 return ret; 3704 } 3705 3706 //explicitly remove thd old information in mRecentTasks when removing existing user. 3707 private void removeRecentTasksForUserLocked(int userId) { 3708 if(userId <= 0) { 3709 Slog.i(TAG, "Can't remove recent task on user " + userId); 3710 return; 3711 } 3712 3713 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3714 TaskRecord tr = mRecentTasks.get(i); 3715 if (tr.userId == userId) { 3716 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3717 + " when finishing user" + userId); 3718 mRecentTasks.remove(i); 3719 tr.removedFromRecents(mTaskPersister); 3720 } 3721 } 3722 3723 // Remove tasks from persistent storage. 3724 mTaskPersister.wakeup(null, true); 3725 } 3726 3727 // Sort by taskId 3728 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3729 @Override 3730 public int compare(TaskRecord lhs, TaskRecord rhs) { 3731 return rhs.taskId - lhs.taskId; 3732 } 3733 }; 3734 3735 // Extract the affiliates of the chain containing mRecentTasks[start]. 3736 private int processNextAffiliateChain(int start) { 3737 final TaskRecord startTask = mRecentTasks.get(start); 3738 final int affiliateId = startTask.mAffiliatedTaskId; 3739 3740 // Quick identification of isolated tasks. I.e. those not launched behind. 3741 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3742 startTask.mNextAffiliate == null) { 3743 // There is still a slim chance that there are other tasks that point to this task 3744 // and that the chain is so messed up that this task no longer points to them but 3745 // the gain of this optimization outweighs the risk. 3746 startTask.inRecents = true; 3747 return start + 1; 3748 } 3749 3750 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3751 mTmpRecents.clear(); 3752 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3753 final TaskRecord task = mRecentTasks.get(i); 3754 if (task.mAffiliatedTaskId == affiliateId) { 3755 mRecentTasks.remove(i); 3756 mTmpRecents.add(task); 3757 } 3758 } 3759 3760 // Sort them all by taskId. That is the order they were create in and that order will 3761 // always be correct. 3762 Collections.sort(mTmpRecents, mTaskRecordComparator); 3763 3764 // Go through and fix up the linked list. 3765 // The first one is the end of the chain and has no next. 3766 final TaskRecord first = mTmpRecents.get(0); 3767 first.inRecents = true; 3768 if (first.mNextAffiliate != null) { 3769 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3770 first.setNextAffiliate(null); 3771 mTaskPersister.wakeup(first, false); 3772 } 3773 // Everything in the middle is doubly linked from next to prev. 3774 final int tmpSize = mTmpRecents.size(); 3775 for (int i = 0; i < tmpSize - 1; ++i) { 3776 final TaskRecord next = mTmpRecents.get(i); 3777 final TaskRecord prev = mTmpRecents.get(i + 1); 3778 if (next.mPrevAffiliate != prev) { 3779 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3780 " setting prev=" + prev); 3781 next.setPrevAffiliate(prev); 3782 mTaskPersister.wakeup(next, false); 3783 } 3784 if (prev.mNextAffiliate != next) { 3785 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3786 " setting next=" + next); 3787 prev.setNextAffiliate(next); 3788 mTaskPersister.wakeup(prev, false); 3789 } 3790 prev.inRecents = true; 3791 } 3792 // The last one is the beginning of the list and has no prev. 3793 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3794 if (last.mPrevAffiliate != null) { 3795 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3796 last.setPrevAffiliate(null); 3797 mTaskPersister.wakeup(last, false); 3798 } 3799 3800 // Insert the group back into mRecentTasks at start. 3801 mRecentTasks.addAll(start, mTmpRecents); 3802 3803 // Let the caller know where we left off. 3804 return start + tmpSize; 3805 } 3806 3807 /** 3808 * Update the recent tasks lists: make sure tasks should still be here (their 3809 * applications / activities still exist), update their availability, fixup ordering 3810 * of affiliations. 3811 */ 3812 void cleanupRecentTasksLocked(int userId) { 3813 if (mRecentTasks == null) { 3814 // Happens when called from the packagemanager broadcast before boot. 3815 return; 3816 } 3817 3818 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3819 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3820 final IPackageManager pm = AppGlobals.getPackageManager(); 3821 final ActivityInfo dummyAct = new ActivityInfo(); 3822 final ApplicationInfo dummyApp = new ApplicationInfo(); 3823 3824 int N = mRecentTasks.size(); 3825 3826 int[] users = userId == UserHandle.USER_ALL 3827 ? getUsersLocked() : new int[] { userId }; 3828 for (int user : users) { 3829 for (int i = 0; i < N; i++) { 3830 TaskRecord task = mRecentTasks.get(i); 3831 if (task.userId != user) { 3832 // Only look at tasks for the user ID of interest. 3833 continue; 3834 } 3835 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3836 // This situation is broken, and we should just get rid of it now. 3837 mRecentTasks.remove(i); 3838 task.removedFromRecents(mTaskPersister); 3839 i--; 3840 N--; 3841 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3842 continue; 3843 } 3844 // Check whether this activity is currently available. 3845 if (task.realActivity != null) { 3846 ActivityInfo ai = availActCache.get(task.realActivity); 3847 if (ai == null) { 3848 try { 3849 ai = pm.getActivityInfo(task.realActivity, 3850 PackageManager.GET_UNINSTALLED_PACKAGES 3851 | PackageManager.GET_DISABLED_COMPONENTS, user); 3852 } catch (RemoteException e) { 3853 // Will never happen. 3854 continue; 3855 } 3856 if (ai == null) { 3857 ai = dummyAct; 3858 } 3859 availActCache.put(task.realActivity, ai); 3860 } 3861 if (ai == dummyAct) { 3862 // This could be either because the activity no longer exists, or the 3863 // app is temporarily gone. For the former we want to remove the recents 3864 // entry; for the latter we want to mark it as unavailable. 3865 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3866 if (app == null) { 3867 try { 3868 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3869 PackageManager.GET_UNINSTALLED_PACKAGES 3870 | PackageManager.GET_DISABLED_COMPONENTS, user); 3871 } catch (RemoteException e) { 3872 // Will never happen. 3873 continue; 3874 } 3875 if (app == null) { 3876 app = dummyApp; 3877 } 3878 availAppCache.put(task.realActivity.getPackageName(), app); 3879 } 3880 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3881 // Doesn't exist any more! Good-bye. 3882 mRecentTasks.remove(i); 3883 task.removedFromRecents(mTaskPersister); 3884 i--; 3885 N--; 3886 Slog.w(TAG, "Removing no longer valid recent: " + task); 3887 continue; 3888 } else { 3889 // Otherwise just not available for now. 3890 if (task.isAvailable) { 3891 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3892 + task); 3893 } 3894 task.isAvailable = false; 3895 } 3896 } else { 3897 if (!ai.enabled || !ai.applicationInfo.enabled 3898 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3899 if (task.isAvailable) { 3900 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3901 + task + " (enabled=" + ai.enabled + "/" 3902 + ai.applicationInfo.enabled + " flags=" 3903 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3904 } 3905 task.isAvailable = false; 3906 } else { 3907 if (!task.isAvailable) { 3908 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3909 + task); 3910 } 3911 task.isAvailable = true; 3912 } 3913 } 3914 } 3915 } 3916 } 3917 3918 // Verify the affiliate chain for each task. 3919 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3920 } 3921 3922 mTmpRecents.clear(); 3923 // mRecentTasks is now in sorted, affiliated order. 3924 } 3925 3926 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3927 int N = mRecentTasks.size(); 3928 TaskRecord top = task; 3929 int topIndex = taskIndex; 3930 while (top.mNextAffiliate != null && topIndex > 0) { 3931 top = top.mNextAffiliate; 3932 topIndex--; 3933 } 3934 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3935 + topIndex + " from intial " + taskIndex); 3936 // Find the end of the chain, doing a sanity check along the way. 3937 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3938 int endIndex = topIndex; 3939 TaskRecord prev = top; 3940 while (endIndex < N) { 3941 TaskRecord cur = mRecentTasks.get(endIndex); 3942 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3943 + endIndex + " " + cur); 3944 if (cur == top) { 3945 // Verify start of the chain. 3946 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3947 Slog.wtf(TAG, "Bad chain @" + endIndex 3948 + ": first task has next affiliate: " + prev); 3949 sane = false; 3950 break; 3951 } 3952 } else { 3953 // Verify middle of the chain's next points back to the one before. 3954 if (cur.mNextAffiliate != prev 3955 || cur.mNextAffiliateTaskId != prev.taskId) { 3956 Slog.wtf(TAG, "Bad chain @" + endIndex 3957 + ": middle task " + cur + " @" + endIndex 3958 + " has bad next affiliate " 3959 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3960 + ", expected " + prev); 3961 sane = false; 3962 break; 3963 } 3964 } 3965 if (cur.mPrevAffiliateTaskId == -1) { 3966 // Chain ends here. 3967 if (cur.mPrevAffiliate != null) { 3968 Slog.wtf(TAG, "Bad chain @" + endIndex 3969 + ": last task " + cur + " has previous affiliate " 3970 + cur.mPrevAffiliate); 3971 sane = false; 3972 } 3973 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3974 break; 3975 } else { 3976 // Verify middle of the chain's prev points to a valid item. 3977 if (cur.mPrevAffiliate == null) { 3978 Slog.wtf(TAG, "Bad chain @" + endIndex 3979 + ": task " + cur + " has previous affiliate " 3980 + cur.mPrevAffiliate + " but should be id " 3981 + cur.mPrevAffiliate); 3982 sane = false; 3983 break; 3984 } 3985 } 3986 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3987 Slog.wtf(TAG, "Bad chain @" + endIndex 3988 + ": task " + cur + " has affiliated id " 3989 + cur.mAffiliatedTaskId + " but should be " 3990 + task.mAffiliatedTaskId); 3991 sane = false; 3992 break; 3993 } 3994 prev = cur; 3995 endIndex++; 3996 if (endIndex >= N) { 3997 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3998 + ": last task " + prev); 3999 sane = false; 4000 break; 4001 } 4002 } 4003 if (sane) { 4004 if (endIndex < taskIndex) { 4005 Slog.wtf(TAG, "Bad chain @" + endIndex 4006 + ": did not extend to task " + task + " @" + taskIndex); 4007 sane = false; 4008 } 4009 } 4010 if (sane) { 4011 // All looks good, we can just move all of the affiliated tasks 4012 // to the top. 4013 for (int i=topIndex; i<=endIndex; i++) { 4014 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4015 + " from " + i + " to " + (i-topIndex)); 4016 TaskRecord cur = mRecentTasks.remove(i); 4017 mRecentTasks.add(i-topIndex, cur); 4018 } 4019 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4020 + " to " + endIndex); 4021 return true; 4022 } 4023 4024 // Whoops, couldn't do it. 4025 return false; 4026 } 4027 4028 final void addRecentTaskLocked(TaskRecord task) { 4029 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4030 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4031 4032 int N = mRecentTasks.size(); 4033 // Quick case: check if the top-most recent task is the same. 4034 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4035 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4036 return; 4037 } 4038 // Another quick case: check if this is part of a set of affiliated 4039 // tasks that are at the top. 4040 if (isAffiliated && N > 0 && task.inRecents 4041 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4042 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4043 + " at top when adding " + task); 4044 return; 4045 } 4046 // Another quick case: never add voice sessions. 4047 if (task.voiceSession != null) { 4048 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4049 return; 4050 } 4051 4052 boolean needAffiliationFix = false; 4053 4054 // Slightly less quick case: the task is already in recents, so all we need 4055 // to do is move it. 4056 if (task.inRecents) { 4057 int taskIndex = mRecentTasks.indexOf(task); 4058 if (taskIndex >= 0) { 4059 if (!isAffiliated) { 4060 // Simple case: this is not an affiliated task, so we just move it to the front. 4061 mRecentTasks.remove(taskIndex); 4062 mRecentTasks.add(0, task); 4063 notifyTaskPersisterLocked(task, false); 4064 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4065 + " from " + taskIndex); 4066 return; 4067 } else { 4068 // More complicated: need to keep all affiliated tasks together. 4069 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4070 // All went well. 4071 return; 4072 } 4073 4074 // Uh oh... something bad in the affiliation chain, try to rebuild 4075 // everything and then go through our general path of adding a new task. 4076 needAffiliationFix = true; 4077 } 4078 } else { 4079 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4080 needAffiliationFix = true; 4081 } 4082 } 4083 4084 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4085 trimRecentsForTask(task, true); 4086 4087 N = mRecentTasks.size(); 4088 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4089 final TaskRecord tr = mRecentTasks.remove(N - 1); 4090 tr.removedFromRecents(mTaskPersister); 4091 N--; 4092 } 4093 task.inRecents = true; 4094 if (!isAffiliated || needAffiliationFix) { 4095 // If this is a simple non-affiliated task, or we had some failure trying to 4096 // handle it as part of an affilated task, then just place it at the top. 4097 mRecentTasks.add(0, task); 4098 } else if (isAffiliated) { 4099 // If this is a new affiliated task, then move all of the affiliated tasks 4100 // to the front and insert this new one. 4101 TaskRecord other = task.mNextAffiliate; 4102 if (other == null) { 4103 other = task.mPrevAffiliate; 4104 } 4105 if (other != null) { 4106 int otherIndex = mRecentTasks.indexOf(other); 4107 if (otherIndex >= 0) { 4108 // Insert new task at appropriate location. 4109 int taskIndex; 4110 if (other == task.mNextAffiliate) { 4111 // We found the index of our next affiliation, which is who is 4112 // before us in the list, so add after that point. 4113 taskIndex = otherIndex+1; 4114 } else { 4115 // We found the index of our previous affiliation, which is who is 4116 // after us in the list, so add at their position. 4117 taskIndex = otherIndex; 4118 } 4119 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4120 + taskIndex + ": " + task); 4121 mRecentTasks.add(taskIndex, task); 4122 4123 // Now move everything to the front. 4124 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4125 // All went well. 4126 return; 4127 } 4128 4129 // Uh oh... something bad in the affiliation chain, try to rebuild 4130 // everything and then go through our general path of adding a new task. 4131 needAffiliationFix = true; 4132 } else { 4133 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4134 + other); 4135 needAffiliationFix = true; 4136 } 4137 } else { 4138 if (DEBUG_RECENTS) Slog.d(TAG, 4139 "addRecent: adding affiliated task without next/prev:" + task); 4140 needAffiliationFix = true; 4141 } 4142 } 4143 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4144 4145 if (needAffiliationFix) { 4146 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4147 cleanupRecentTasksLocked(task.userId); 4148 } 4149 } 4150 4151 /** 4152 * If needed, remove oldest existing entries in recents that are for the same kind 4153 * of task as the given one. 4154 */ 4155 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4156 int N = mRecentTasks.size(); 4157 final Intent intent = task.intent; 4158 final boolean document = intent != null && intent.isDocument(); 4159 4160 int maxRecents = task.maxRecents - 1; 4161 for (int i=0; i<N; i++) { 4162 final TaskRecord tr = mRecentTasks.get(i); 4163 if (task != tr) { 4164 if (task.userId != tr.userId) { 4165 continue; 4166 } 4167 if (i > MAX_RECENT_BITMAPS) { 4168 tr.freeLastThumbnail(); 4169 } 4170 final Intent trIntent = tr.intent; 4171 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4172 (intent == null || !intent.filterEquals(trIntent))) { 4173 continue; 4174 } 4175 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4176 if (document && trIsDocument) { 4177 // These are the same document activity (not necessarily the same doc). 4178 if (maxRecents > 0) { 4179 --maxRecents; 4180 continue; 4181 } 4182 // Hit the maximum number of documents for this task. Fall through 4183 // and remove this document from recents. 4184 } else if (document || trIsDocument) { 4185 // Only one of these is a document. Not the droid we're looking for. 4186 continue; 4187 } 4188 } 4189 4190 if (!doTrim) { 4191 // If the caller is not actually asking for a trim, just tell them we reached 4192 // a point where the trim would happen. 4193 return i; 4194 } 4195 4196 // Either task and tr are the same or, their affinities match or their intents match 4197 // and neither of them is a document, or they are documents using the same activity 4198 // and their maxRecents has been reached. 4199 tr.disposeThumbnail(); 4200 mRecentTasks.remove(i); 4201 if (task != tr) { 4202 tr.removedFromRecents(mTaskPersister); 4203 } 4204 i--; 4205 N--; 4206 if (task.intent == null) { 4207 // If the new recent task we are adding is not fully 4208 // specified, then replace it with the existing recent task. 4209 task = tr; 4210 } 4211 notifyTaskPersisterLocked(tr, false); 4212 } 4213 4214 return -1; 4215 } 4216 4217 @Override 4218 public void reportActivityFullyDrawn(IBinder token) { 4219 synchronized (this) { 4220 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4221 if (r == null) { 4222 return; 4223 } 4224 r.reportFullyDrawnLocked(); 4225 } 4226 } 4227 4228 @Override 4229 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4230 synchronized (this) { 4231 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4232 if (r == null) { 4233 return; 4234 } 4235 final long origId = Binder.clearCallingIdentity(); 4236 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4237 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4238 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4239 if (config != null) { 4240 r.frozenBeforeDestroy = true; 4241 if (!updateConfigurationLocked(config, r, false, false)) { 4242 mStackSupervisor.resumeTopActivitiesLocked(); 4243 } 4244 } 4245 Binder.restoreCallingIdentity(origId); 4246 } 4247 } 4248 4249 @Override 4250 public int getRequestedOrientation(IBinder token) { 4251 synchronized (this) { 4252 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4253 if (r == null) { 4254 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4255 } 4256 return mWindowManager.getAppOrientation(r.appToken); 4257 } 4258 } 4259 4260 /** 4261 * This is the internal entry point for handling Activity.finish(). 4262 * 4263 * @param token The Binder token referencing the Activity we want to finish. 4264 * @param resultCode Result code, if any, from this Activity. 4265 * @param resultData Result data (Intent), if any, from this Activity. 4266 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4267 * the root Activity in the task. 4268 * 4269 * @return Returns true if the activity successfully finished, or false if it is still running. 4270 */ 4271 @Override 4272 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4273 boolean finishTask) { 4274 // Refuse possible leaked file descriptors 4275 if (resultData != null && resultData.hasFileDescriptors() == true) { 4276 throw new IllegalArgumentException("File descriptors passed in Intent"); 4277 } 4278 4279 synchronized(this) { 4280 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4281 if (r == null) { 4282 return true; 4283 } 4284 // Keep track of the root activity of the task before we finish it 4285 TaskRecord tr = r.task; 4286 ActivityRecord rootR = tr.getRootActivity(); 4287 if (rootR == null) { 4288 Slog.w(TAG, "Finishing task with all activities already finished"); 4289 } 4290 // Do not allow task to finish in Lock Task mode. 4291 if (tr == mStackSupervisor.mLockTaskModeTask) { 4292 if (rootR == r) { 4293 Slog.i(TAG, "Not finishing task in lock task mode"); 4294 mStackSupervisor.showLockTaskToast(); 4295 return false; 4296 } 4297 } 4298 if (mController != null) { 4299 // Find the first activity that is not finishing. 4300 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4301 if (next != null) { 4302 // ask watcher if this is allowed 4303 boolean resumeOK = true; 4304 try { 4305 resumeOK = mController.activityResuming(next.packageName); 4306 } catch (RemoteException e) { 4307 mController = null; 4308 Watchdog.getInstance().setActivityController(null); 4309 } 4310 4311 if (!resumeOK) { 4312 Slog.i(TAG, "Not finishing activity because controller resumed"); 4313 return false; 4314 } 4315 } 4316 } 4317 final long origId = Binder.clearCallingIdentity(); 4318 try { 4319 boolean res; 4320 if (finishTask && r == rootR) { 4321 // If requested, remove the task that is associated to this activity only if it 4322 // was the root activity in the task. The result code and data is ignored 4323 // because we don't support returning them across task boundaries. 4324 res = removeTaskByIdLocked(tr.taskId, false); 4325 if (!res) { 4326 Slog.i(TAG, "Removing task failed to finish activity"); 4327 } 4328 } else { 4329 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4330 resultData, "app-request", true); 4331 if (!res) { 4332 Slog.i(TAG, "Failed to finish by app-request"); 4333 } 4334 } 4335 return res; 4336 } finally { 4337 Binder.restoreCallingIdentity(origId); 4338 } 4339 } 4340 } 4341 4342 @Override 4343 public final void finishHeavyWeightApp() { 4344 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4345 != PackageManager.PERMISSION_GRANTED) { 4346 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4347 + Binder.getCallingPid() 4348 + ", uid=" + Binder.getCallingUid() 4349 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4350 Slog.w(TAG, msg); 4351 throw new SecurityException(msg); 4352 } 4353 4354 synchronized(this) { 4355 if (mHeavyWeightProcess == null) { 4356 return; 4357 } 4358 4359 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4360 mHeavyWeightProcess.activities); 4361 for (int i=0; i<activities.size(); i++) { 4362 ActivityRecord r = activities.get(i); 4363 if (!r.finishing) { 4364 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4365 null, "finish-heavy", true); 4366 } 4367 } 4368 4369 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4370 mHeavyWeightProcess.userId, 0)); 4371 mHeavyWeightProcess = null; 4372 } 4373 } 4374 4375 @Override 4376 public void crashApplication(int uid, int initialPid, String packageName, 4377 String message) { 4378 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4379 != PackageManager.PERMISSION_GRANTED) { 4380 String msg = "Permission Denial: crashApplication() from pid=" 4381 + Binder.getCallingPid() 4382 + ", uid=" + Binder.getCallingUid() 4383 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4384 Slog.w(TAG, msg); 4385 throw new SecurityException(msg); 4386 } 4387 4388 synchronized(this) { 4389 ProcessRecord proc = null; 4390 4391 // Figure out which process to kill. We don't trust that initialPid 4392 // still has any relation to current pids, so must scan through the 4393 // list. 4394 synchronized (mPidsSelfLocked) { 4395 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4396 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4397 if (p.uid != uid) { 4398 continue; 4399 } 4400 if (p.pid == initialPid) { 4401 proc = p; 4402 break; 4403 } 4404 if (p.pkgList.containsKey(packageName)) { 4405 proc = p; 4406 } 4407 } 4408 } 4409 4410 if (proc == null) { 4411 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4412 + " initialPid=" + initialPid 4413 + " packageName=" + packageName); 4414 return; 4415 } 4416 4417 if (proc.thread != null) { 4418 if (proc.pid == Process.myPid()) { 4419 Log.w(TAG, "crashApplication: trying to crash self!"); 4420 return; 4421 } 4422 long ident = Binder.clearCallingIdentity(); 4423 try { 4424 proc.thread.scheduleCrash(message); 4425 } catch (RemoteException e) { 4426 } 4427 Binder.restoreCallingIdentity(ident); 4428 } 4429 } 4430 } 4431 4432 @Override 4433 public final void finishSubActivity(IBinder token, String resultWho, 4434 int requestCode) { 4435 synchronized(this) { 4436 final long origId = Binder.clearCallingIdentity(); 4437 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4438 if (r != null) { 4439 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4440 } 4441 Binder.restoreCallingIdentity(origId); 4442 } 4443 } 4444 4445 @Override 4446 public boolean finishActivityAffinity(IBinder token) { 4447 synchronized(this) { 4448 final long origId = Binder.clearCallingIdentity(); 4449 try { 4450 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4451 4452 ActivityRecord rootR = r.task.getRootActivity(); 4453 // Do not allow task to finish in Lock Task mode. 4454 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4455 if (rootR == r) { 4456 mStackSupervisor.showLockTaskToast(); 4457 return false; 4458 } 4459 } 4460 boolean res = false; 4461 if (r != null) { 4462 res = r.task.stack.finishActivityAffinityLocked(r); 4463 } 4464 return res; 4465 } finally { 4466 Binder.restoreCallingIdentity(origId); 4467 } 4468 } 4469 } 4470 4471 @Override 4472 public void finishVoiceTask(IVoiceInteractionSession session) { 4473 synchronized(this) { 4474 final long origId = Binder.clearCallingIdentity(); 4475 try { 4476 mStackSupervisor.finishVoiceTask(session); 4477 } finally { 4478 Binder.restoreCallingIdentity(origId); 4479 } 4480 } 4481 4482 } 4483 4484 @Override 4485 public boolean releaseActivityInstance(IBinder token) { 4486 synchronized(this) { 4487 final long origId = Binder.clearCallingIdentity(); 4488 try { 4489 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4490 if (r.task == null || r.task.stack == null) { 4491 return false; 4492 } 4493 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4494 } finally { 4495 Binder.restoreCallingIdentity(origId); 4496 } 4497 } 4498 } 4499 4500 @Override 4501 public void releaseSomeActivities(IApplicationThread appInt) { 4502 synchronized(this) { 4503 final long origId = Binder.clearCallingIdentity(); 4504 try { 4505 ProcessRecord app = getRecordForAppLocked(appInt); 4506 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4507 } finally { 4508 Binder.restoreCallingIdentity(origId); 4509 } 4510 } 4511 } 4512 4513 @Override 4514 public boolean willActivityBeVisible(IBinder token) { 4515 synchronized(this) { 4516 ActivityStack stack = ActivityRecord.getStackLocked(token); 4517 if (stack != null) { 4518 return stack.willActivityBeVisibleLocked(token); 4519 } 4520 return false; 4521 } 4522 } 4523 4524 @Override 4525 public void overridePendingTransition(IBinder token, String packageName, 4526 int enterAnim, int exitAnim) { 4527 synchronized(this) { 4528 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4529 if (self == null) { 4530 return; 4531 } 4532 4533 final long origId = Binder.clearCallingIdentity(); 4534 4535 if (self.state == ActivityState.RESUMED 4536 || self.state == ActivityState.PAUSING) { 4537 mWindowManager.overridePendingAppTransition(packageName, 4538 enterAnim, exitAnim, null); 4539 } 4540 4541 Binder.restoreCallingIdentity(origId); 4542 } 4543 } 4544 4545 /** 4546 * Main function for removing an existing process from the activity manager 4547 * as a result of that process going away. Clears out all connections 4548 * to the process. 4549 */ 4550 private final void handleAppDiedLocked(ProcessRecord app, 4551 boolean restarting, boolean allowRestart) { 4552 int pid = app.pid; 4553 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4554 if (!kept && !restarting) { 4555 removeLruProcessLocked(app); 4556 if (pid > 0) { 4557 ProcessList.remove(pid); 4558 } 4559 } 4560 4561 if (mProfileProc == app) { 4562 clearProfilerLocked(); 4563 } 4564 4565 // Remove this application's activities from active lists. 4566 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4567 4568 app.activities.clear(); 4569 4570 if (app.instrumentationClass != null) { 4571 Slog.w(TAG, "Crash of app " + app.processName 4572 + " running instrumentation " + app.instrumentationClass); 4573 Bundle info = new Bundle(); 4574 info.putString("shortMsg", "Process crashed."); 4575 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4576 } 4577 4578 if (!restarting) { 4579 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4580 // If there was nothing to resume, and we are not already 4581 // restarting this process, but there is a visible activity that 4582 // is hosted by the process... then make sure all visible 4583 // activities are running, taking care of restarting this 4584 // process. 4585 if (hasVisibleActivities) { 4586 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4587 } 4588 } 4589 } 4590 } 4591 4592 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4593 IBinder threadBinder = thread.asBinder(); 4594 // Find the application record. 4595 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4596 ProcessRecord rec = mLruProcesses.get(i); 4597 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4598 return i; 4599 } 4600 } 4601 return -1; 4602 } 4603 4604 final ProcessRecord getRecordForAppLocked( 4605 IApplicationThread thread) { 4606 if (thread == null) { 4607 return null; 4608 } 4609 4610 int appIndex = getLRURecordIndexForAppLocked(thread); 4611 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4612 } 4613 4614 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4615 // If there are no longer any background processes running, 4616 // and the app that died was not running instrumentation, 4617 // then tell everyone we are now low on memory. 4618 boolean haveBg = false; 4619 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4620 ProcessRecord rec = mLruProcesses.get(i); 4621 if (rec.thread != null 4622 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4623 haveBg = true; 4624 break; 4625 } 4626 } 4627 4628 if (!haveBg) { 4629 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4630 if (doReport) { 4631 long now = SystemClock.uptimeMillis(); 4632 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4633 doReport = false; 4634 } else { 4635 mLastMemUsageReportTime = now; 4636 } 4637 } 4638 final ArrayList<ProcessMemInfo> memInfos 4639 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4640 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4641 long now = SystemClock.uptimeMillis(); 4642 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4643 ProcessRecord rec = mLruProcesses.get(i); 4644 if (rec == dyingProc || rec.thread == null) { 4645 continue; 4646 } 4647 if (doReport) { 4648 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4649 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4650 } 4651 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4652 // The low memory report is overriding any current 4653 // state for a GC request. Make sure to do 4654 // heavy/important/visible/foreground processes first. 4655 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4656 rec.lastRequestedGc = 0; 4657 } else { 4658 rec.lastRequestedGc = rec.lastLowMemory; 4659 } 4660 rec.reportLowMemory = true; 4661 rec.lastLowMemory = now; 4662 mProcessesToGc.remove(rec); 4663 addProcessToGcListLocked(rec); 4664 } 4665 } 4666 if (doReport) { 4667 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4668 mHandler.sendMessage(msg); 4669 } 4670 scheduleAppGcsLocked(); 4671 } 4672 } 4673 4674 final void appDiedLocked(ProcessRecord app) { 4675 appDiedLocked(app, app.pid, app.thread); 4676 } 4677 4678 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4679 // First check if this ProcessRecord is actually active for the pid. 4680 synchronized (mPidsSelfLocked) { 4681 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4682 if (curProc != app) { 4683 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4684 return; 4685 } 4686 } 4687 4688 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4689 synchronized (stats) { 4690 stats.noteProcessDiedLocked(app.info.uid, pid); 4691 } 4692 4693 Process.killProcessQuiet(pid); 4694 Process.killProcessGroup(app.info.uid, pid); 4695 app.killed = true; 4696 4697 // Clean up already done if the process has been re-started. 4698 if (app.pid == pid && app.thread != null && 4699 app.thread.asBinder() == thread.asBinder()) { 4700 boolean doLowMem = app.instrumentationClass == null; 4701 boolean doOomAdj = doLowMem; 4702 if (!app.killedByAm) { 4703 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4704 + ") has died"); 4705 mAllowLowerMemLevel = true; 4706 } else { 4707 // Note that we always want to do oom adj to update our state with the 4708 // new number of procs. 4709 mAllowLowerMemLevel = false; 4710 doLowMem = false; 4711 } 4712 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4713 if (DEBUG_CLEANUP) Slog.v( 4714 TAG, "Dying app: " + app + ", pid: " + pid 4715 + ", thread: " + thread.asBinder()); 4716 handleAppDiedLocked(app, false, true); 4717 4718 if (doOomAdj) { 4719 updateOomAdjLocked(); 4720 } 4721 if (doLowMem) { 4722 doLowMemReportIfNeededLocked(app); 4723 } 4724 } else if (app.pid != pid) { 4725 // A new process has already been started. 4726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4727 + ") has died and restarted (pid " + app.pid + ")."); 4728 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4729 } else if (DEBUG_PROCESSES) { 4730 Slog.d(TAG, "Received spurious death notification for thread " 4731 + thread.asBinder()); 4732 } 4733 } 4734 4735 /** 4736 * If a stack trace dump file is configured, dump process stack traces. 4737 * @param clearTraces causes the dump file to be erased prior to the new 4738 * traces being written, if true; when false, the new traces will be 4739 * appended to any existing file content. 4740 * @param firstPids of dalvik VM processes to dump stack traces for first 4741 * @param lastPids of dalvik VM processes to dump stack traces for last 4742 * @param nativeProcs optional list of native process names to dump stack crawls 4743 * @return file containing stack traces, or null if no dump file is configured 4744 */ 4745 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4746 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4747 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4748 if (tracesPath == null || tracesPath.length() == 0) { 4749 return null; 4750 } 4751 4752 File tracesFile = new File(tracesPath); 4753 try { 4754 File tracesDir = tracesFile.getParentFile(); 4755 if (!tracesDir.exists()) { 4756 tracesDir.mkdirs(); 4757 if (!SELinux.restorecon(tracesDir)) { 4758 return null; 4759 } 4760 } 4761 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4762 4763 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4764 tracesFile.createNewFile(); 4765 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4766 } catch (IOException e) { 4767 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4768 return null; 4769 } 4770 4771 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4772 return tracesFile; 4773 } 4774 4775 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4776 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4777 // Use a FileObserver to detect when traces finish writing. 4778 // The order of traces is considered important to maintain for legibility. 4779 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4780 @Override 4781 public synchronized void onEvent(int event, String path) { notify(); } 4782 }; 4783 4784 try { 4785 observer.startWatching(); 4786 4787 // First collect all of the stacks of the most important pids. 4788 if (firstPids != null) { 4789 try { 4790 int num = firstPids.size(); 4791 for (int i = 0; i < num; i++) { 4792 synchronized (observer) { 4793 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4794 observer.wait(200); // Wait for write-close, give up after 200msec 4795 } 4796 } 4797 } catch (InterruptedException e) { 4798 Slog.wtf(TAG, e); 4799 } 4800 } 4801 4802 // Next collect the stacks of the native pids 4803 if (nativeProcs != null) { 4804 int[] pids = Process.getPidsForCommands(nativeProcs); 4805 if (pids != null) { 4806 for (int pid : pids) { 4807 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4808 } 4809 } 4810 } 4811 4812 // Lastly, measure CPU usage. 4813 if (processCpuTracker != null) { 4814 processCpuTracker.init(); 4815 System.gc(); 4816 processCpuTracker.update(); 4817 try { 4818 synchronized (processCpuTracker) { 4819 processCpuTracker.wait(500); // measure over 1/2 second. 4820 } 4821 } catch (InterruptedException e) { 4822 } 4823 processCpuTracker.update(); 4824 4825 // We'll take the stack crawls of just the top apps using CPU. 4826 final int N = processCpuTracker.countWorkingStats(); 4827 int numProcs = 0; 4828 for (int i=0; i<N && numProcs<5; i++) { 4829 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4830 if (lastPids.indexOfKey(stats.pid) >= 0) { 4831 numProcs++; 4832 try { 4833 synchronized (observer) { 4834 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4835 observer.wait(200); // Wait for write-close, give up after 200msec 4836 } 4837 } catch (InterruptedException e) { 4838 Slog.wtf(TAG, e); 4839 } 4840 4841 } 4842 } 4843 } 4844 } finally { 4845 observer.stopWatching(); 4846 } 4847 } 4848 4849 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4850 if (true || IS_USER_BUILD) { 4851 return; 4852 } 4853 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4854 if (tracesPath == null || tracesPath.length() == 0) { 4855 return; 4856 } 4857 4858 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4859 StrictMode.allowThreadDiskWrites(); 4860 try { 4861 final File tracesFile = new File(tracesPath); 4862 final File tracesDir = tracesFile.getParentFile(); 4863 final File tracesTmp = new File(tracesDir, "__tmp__"); 4864 try { 4865 if (!tracesDir.exists()) { 4866 tracesDir.mkdirs(); 4867 if (!SELinux.restorecon(tracesDir.getPath())) { 4868 return; 4869 } 4870 } 4871 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4872 4873 if (tracesFile.exists()) { 4874 tracesTmp.delete(); 4875 tracesFile.renameTo(tracesTmp); 4876 } 4877 StringBuilder sb = new StringBuilder(); 4878 Time tobj = new Time(); 4879 tobj.set(System.currentTimeMillis()); 4880 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4881 sb.append(": "); 4882 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4883 sb.append(" since "); 4884 sb.append(msg); 4885 FileOutputStream fos = new FileOutputStream(tracesFile); 4886 fos.write(sb.toString().getBytes()); 4887 if (app == null) { 4888 fos.write("\n*** No application process!".getBytes()); 4889 } 4890 fos.close(); 4891 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4892 } catch (IOException e) { 4893 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4894 return; 4895 } 4896 4897 if (app != null) { 4898 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4899 firstPids.add(app.pid); 4900 dumpStackTraces(tracesPath, firstPids, null, null, null); 4901 } 4902 4903 File lastTracesFile = null; 4904 File curTracesFile = null; 4905 for (int i=9; i>=0; i--) { 4906 String name = String.format(Locale.US, "slow%02d.txt", i); 4907 curTracesFile = new File(tracesDir, name); 4908 if (curTracesFile.exists()) { 4909 if (lastTracesFile != null) { 4910 curTracesFile.renameTo(lastTracesFile); 4911 } else { 4912 curTracesFile.delete(); 4913 } 4914 } 4915 lastTracesFile = curTracesFile; 4916 } 4917 tracesFile.renameTo(curTracesFile); 4918 if (tracesTmp.exists()) { 4919 tracesTmp.renameTo(tracesFile); 4920 } 4921 } finally { 4922 StrictMode.setThreadPolicy(oldPolicy); 4923 } 4924 } 4925 4926 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4927 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4928 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4929 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4930 4931 if (mController != null) { 4932 try { 4933 // 0 == continue, -1 = kill process immediately 4934 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4935 if (res < 0 && app.pid != MY_PID) { 4936 app.kill("anr", true); 4937 } 4938 } catch (RemoteException e) { 4939 mController = null; 4940 Watchdog.getInstance().setActivityController(null); 4941 } 4942 } 4943 4944 long anrTime = SystemClock.uptimeMillis(); 4945 if (MONITOR_CPU_USAGE) { 4946 updateCpuStatsNow(); 4947 } 4948 4949 synchronized (this) { 4950 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4951 if (mShuttingDown) { 4952 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4953 return; 4954 } else if (app.notResponding) { 4955 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4956 return; 4957 } else if (app.crashing) { 4958 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4959 return; 4960 } 4961 4962 // In case we come through here for the same app before completing 4963 // this one, mark as anring now so we will bail out. 4964 app.notResponding = true; 4965 4966 // Log the ANR to the event log. 4967 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4968 app.processName, app.info.flags, annotation); 4969 4970 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4971 firstPids.add(app.pid); 4972 4973 int parentPid = app.pid; 4974 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4975 if (parentPid != app.pid) firstPids.add(parentPid); 4976 4977 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4978 4979 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4980 ProcessRecord r = mLruProcesses.get(i); 4981 if (r != null && r.thread != null) { 4982 int pid = r.pid; 4983 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4984 if (r.persistent) { 4985 firstPids.add(pid); 4986 } else { 4987 lastPids.put(pid, Boolean.TRUE); 4988 } 4989 } 4990 } 4991 } 4992 } 4993 4994 // Log the ANR to the main log. 4995 StringBuilder info = new StringBuilder(); 4996 info.setLength(0); 4997 info.append("ANR in ").append(app.processName); 4998 if (activity != null && activity.shortComponentName != null) { 4999 info.append(" (").append(activity.shortComponentName).append(")"); 5000 } 5001 info.append("\n"); 5002 info.append("PID: ").append(app.pid).append("\n"); 5003 if (annotation != null) { 5004 info.append("Reason: ").append(annotation).append("\n"); 5005 } 5006 if (parent != null && parent != activity) { 5007 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5008 } 5009 5010 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5011 5012 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5013 NATIVE_STACKS_OF_INTEREST); 5014 5015 String cpuInfo = null; 5016 if (MONITOR_CPU_USAGE) { 5017 updateCpuStatsNow(); 5018 synchronized (mProcessCpuTracker) { 5019 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5020 } 5021 info.append(processCpuTracker.printCurrentLoad()); 5022 info.append(cpuInfo); 5023 } 5024 5025 info.append(processCpuTracker.printCurrentState(anrTime)); 5026 5027 Slog.e(TAG, info.toString()); 5028 if (tracesFile == null) { 5029 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5030 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5031 } 5032 5033 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5034 cpuInfo, tracesFile, null); 5035 5036 if (mController != null) { 5037 try { 5038 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5039 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5040 if (res != 0) { 5041 if (res < 0 && app.pid != MY_PID) { 5042 app.kill("anr", true); 5043 } else { 5044 synchronized (this) { 5045 mServices.scheduleServiceTimeoutLocked(app); 5046 } 5047 } 5048 return; 5049 } 5050 } catch (RemoteException e) { 5051 mController = null; 5052 Watchdog.getInstance().setActivityController(null); 5053 } 5054 } 5055 5056 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5057 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5058 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5059 5060 synchronized (this) { 5061 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5062 app.kill("bg anr", true); 5063 return; 5064 } 5065 5066 // Set the app's notResponding state, and look up the errorReportReceiver 5067 makeAppNotRespondingLocked(app, 5068 activity != null ? activity.shortComponentName : null, 5069 annotation != null ? "ANR " + annotation : "ANR", 5070 info.toString()); 5071 5072 // Bring up the infamous App Not Responding dialog 5073 Message msg = Message.obtain(); 5074 HashMap<String, Object> map = new HashMap<String, Object>(); 5075 msg.what = SHOW_NOT_RESPONDING_MSG; 5076 msg.obj = map; 5077 msg.arg1 = aboveSystem ? 1 : 0; 5078 map.put("app", app); 5079 if (activity != null) { 5080 map.put("activity", activity); 5081 } 5082 5083 mHandler.sendMessage(msg); 5084 } 5085 } 5086 5087 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5088 if (!mLaunchWarningShown) { 5089 mLaunchWarningShown = true; 5090 mHandler.post(new Runnable() { 5091 @Override 5092 public void run() { 5093 synchronized (ActivityManagerService.this) { 5094 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5095 d.show(); 5096 mHandler.postDelayed(new Runnable() { 5097 @Override 5098 public void run() { 5099 synchronized (ActivityManagerService.this) { 5100 d.dismiss(); 5101 mLaunchWarningShown = false; 5102 } 5103 } 5104 }, 4000); 5105 } 5106 } 5107 }); 5108 } 5109 } 5110 5111 @Override 5112 public boolean clearApplicationUserData(final String packageName, 5113 final IPackageDataObserver observer, int userId) { 5114 enforceNotIsolatedCaller("clearApplicationUserData"); 5115 int uid = Binder.getCallingUid(); 5116 int pid = Binder.getCallingPid(); 5117 userId = handleIncomingUser(pid, uid, 5118 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5119 long callingId = Binder.clearCallingIdentity(); 5120 try { 5121 IPackageManager pm = AppGlobals.getPackageManager(); 5122 int pkgUid = -1; 5123 synchronized(this) { 5124 try { 5125 pkgUid = pm.getPackageUid(packageName, userId); 5126 } catch (RemoteException e) { 5127 } 5128 if (pkgUid == -1) { 5129 Slog.w(TAG, "Invalid packageName: " + packageName); 5130 if (observer != null) { 5131 try { 5132 observer.onRemoveCompleted(packageName, false); 5133 } catch (RemoteException e) { 5134 Slog.i(TAG, "Observer no longer exists."); 5135 } 5136 } 5137 return false; 5138 } 5139 if (uid == pkgUid || checkComponentPermission( 5140 android.Manifest.permission.CLEAR_APP_USER_DATA, 5141 pid, uid, -1, true) 5142 == PackageManager.PERMISSION_GRANTED) { 5143 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5144 } else { 5145 throw new SecurityException("PID " + pid + " does not have permission " 5146 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5147 + " of package " + packageName); 5148 } 5149 5150 // Remove all tasks match the cleared application package and user 5151 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5152 final TaskRecord tr = mRecentTasks.get(i); 5153 final String taskPackageName = 5154 tr.getBaseIntent().getComponent().getPackageName(); 5155 if (tr.userId != userId) continue; 5156 if (!taskPackageName.equals(packageName)) continue; 5157 removeTaskByIdLocked(tr.taskId, false); 5158 } 5159 } 5160 5161 try { 5162 // Clear application user data 5163 pm.clearApplicationUserData(packageName, observer, userId); 5164 5165 synchronized(this) { 5166 // Remove all permissions granted from/to this package 5167 removeUriPermissionsForPackageLocked(packageName, userId, true); 5168 } 5169 5170 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5171 Uri.fromParts("package", packageName, null)); 5172 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5173 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5174 null, null, 0, null, null, null, false, false, userId); 5175 } catch (RemoteException e) { 5176 } 5177 } finally { 5178 Binder.restoreCallingIdentity(callingId); 5179 } 5180 return true; 5181 } 5182 5183 @Override 5184 public void killBackgroundProcesses(final String packageName, int userId) { 5185 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5186 != PackageManager.PERMISSION_GRANTED && 5187 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5188 != PackageManager.PERMISSION_GRANTED) { 5189 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5190 + Binder.getCallingPid() 5191 + ", uid=" + Binder.getCallingUid() 5192 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5193 Slog.w(TAG, msg); 5194 throw new SecurityException(msg); 5195 } 5196 5197 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5198 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5199 long callingId = Binder.clearCallingIdentity(); 5200 try { 5201 IPackageManager pm = AppGlobals.getPackageManager(); 5202 synchronized(this) { 5203 int appId = -1; 5204 try { 5205 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5206 } catch (RemoteException e) { 5207 } 5208 if (appId == -1) { 5209 Slog.w(TAG, "Invalid packageName: " + packageName); 5210 return; 5211 } 5212 killPackageProcessesLocked(packageName, appId, userId, 5213 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5214 } 5215 } finally { 5216 Binder.restoreCallingIdentity(callingId); 5217 } 5218 } 5219 5220 @Override 5221 public void killAllBackgroundProcesses() { 5222 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5223 != PackageManager.PERMISSION_GRANTED) { 5224 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5225 + Binder.getCallingPid() 5226 + ", uid=" + Binder.getCallingUid() 5227 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5228 Slog.w(TAG, msg); 5229 throw new SecurityException(msg); 5230 } 5231 5232 long callingId = Binder.clearCallingIdentity(); 5233 try { 5234 synchronized(this) { 5235 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5236 final int NP = mProcessNames.getMap().size(); 5237 for (int ip=0; ip<NP; ip++) { 5238 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5239 final int NA = apps.size(); 5240 for (int ia=0; ia<NA; ia++) { 5241 ProcessRecord app = apps.valueAt(ia); 5242 if (app.persistent) { 5243 // we don't kill persistent processes 5244 continue; 5245 } 5246 if (app.removed) { 5247 procs.add(app); 5248 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5249 app.removed = true; 5250 procs.add(app); 5251 } 5252 } 5253 } 5254 5255 int N = procs.size(); 5256 for (int i=0; i<N; i++) { 5257 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5258 } 5259 mAllowLowerMemLevel = true; 5260 updateOomAdjLocked(); 5261 doLowMemReportIfNeededLocked(null); 5262 } 5263 } finally { 5264 Binder.restoreCallingIdentity(callingId); 5265 } 5266 } 5267 5268 @Override 5269 public void forceStopPackage(final String packageName, int userId) { 5270 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5271 != PackageManager.PERMISSION_GRANTED) { 5272 String msg = "Permission Denial: forceStopPackage() from pid=" 5273 + Binder.getCallingPid() 5274 + ", uid=" + Binder.getCallingUid() 5275 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5276 Slog.w(TAG, msg); 5277 throw new SecurityException(msg); 5278 } 5279 final int callingPid = Binder.getCallingPid(); 5280 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5281 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5282 long callingId = Binder.clearCallingIdentity(); 5283 try { 5284 IPackageManager pm = AppGlobals.getPackageManager(); 5285 synchronized(this) { 5286 int[] users = userId == UserHandle.USER_ALL 5287 ? getUsersLocked() : new int[] { userId }; 5288 for (int user : users) { 5289 int pkgUid = -1; 5290 try { 5291 pkgUid = pm.getPackageUid(packageName, user); 5292 } catch (RemoteException e) { 5293 } 5294 if (pkgUid == -1) { 5295 Slog.w(TAG, "Invalid packageName: " + packageName); 5296 continue; 5297 } 5298 try { 5299 pm.setPackageStoppedState(packageName, true, user); 5300 } catch (RemoteException e) { 5301 } catch (IllegalArgumentException e) { 5302 Slog.w(TAG, "Failed trying to unstop package " 5303 + packageName + ": " + e); 5304 } 5305 if (isUserRunningLocked(user, false)) { 5306 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5307 } 5308 } 5309 } 5310 } finally { 5311 Binder.restoreCallingIdentity(callingId); 5312 } 5313 } 5314 5315 @Override 5316 public void addPackageDependency(String packageName) { 5317 synchronized (this) { 5318 int callingPid = Binder.getCallingPid(); 5319 if (callingPid == Process.myPid()) { 5320 // Yeah, um, no. 5321 Slog.w(TAG, "Can't addPackageDependency on system process"); 5322 return; 5323 } 5324 ProcessRecord proc; 5325 synchronized (mPidsSelfLocked) { 5326 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5327 } 5328 if (proc != null) { 5329 if (proc.pkgDeps == null) { 5330 proc.pkgDeps = new ArraySet<String>(1); 5331 } 5332 proc.pkgDeps.add(packageName); 5333 } 5334 } 5335 } 5336 5337 /* 5338 * The pkg name and app id have to be specified. 5339 */ 5340 @Override 5341 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5342 if (pkg == null) { 5343 return; 5344 } 5345 // Make sure the uid is valid. 5346 if (appid < 0) { 5347 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5348 return; 5349 } 5350 int callerUid = Binder.getCallingUid(); 5351 // Only the system server can kill an application 5352 if (callerUid == Process.SYSTEM_UID) { 5353 // Post an aysnc message to kill the application 5354 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5355 msg.arg1 = appid; 5356 msg.arg2 = 0; 5357 Bundle bundle = new Bundle(); 5358 bundle.putString("pkg", pkg); 5359 bundle.putString("reason", reason); 5360 msg.obj = bundle; 5361 mHandler.sendMessage(msg); 5362 } else { 5363 throw new SecurityException(callerUid + " cannot kill pkg: " + 5364 pkg); 5365 } 5366 } 5367 5368 @Override 5369 public void closeSystemDialogs(String reason) { 5370 enforceNotIsolatedCaller("closeSystemDialogs"); 5371 5372 final int pid = Binder.getCallingPid(); 5373 final int uid = Binder.getCallingUid(); 5374 final long origId = Binder.clearCallingIdentity(); 5375 try { 5376 synchronized (this) { 5377 // Only allow this from foreground processes, so that background 5378 // applications can't abuse it to prevent system UI from being shown. 5379 if (uid >= Process.FIRST_APPLICATION_UID) { 5380 ProcessRecord proc; 5381 synchronized (mPidsSelfLocked) { 5382 proc = mPidsSelfLocked.get(pid); 5383 } 5384 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5385 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5386 + " from background process " + proc); 5387 return; 5388 } 5389 } 5390 closeSystemDialogsLocked(reason); 5391 } 5392 } finally { 5393 Binder.restoreCallingIdentity(origId); 5394 } 5395 } 5396 5397 void closeSystemDialogsLocked(String reason) { 5398 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5399 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5400 | Intent.FLAG_RECEIVER_FOREGROUND); 5401 if (reason != null) { 5402 intent.putExtra("reason", reason); 5403 } 5404 mWindowManager.closeSystemDialogs(reason); 5405 5406 mStackSupervisor.closeSystemDialogsLocked(); 5407 5408 broadcastIntentLocked(null, null, intent, null, 5409 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5410 Process.SYSTEM_UID, UserHandle.USER_ALL); 5411 } 5412 5413 @Override 5414 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5415 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5416 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5417 for (int i=pids.length-1; i>=0; i--) { 5418 ProcessRecord proc; 5419 int oomAdj; 5420 synchronized (this) { 5421 synchronized (mPidsSelfLocked) { 5422 proc = mPidsSelfLocked.get(pids[i]); 5423 oomAdj = proc != null ? proc.setAdj : 0; 5424 } 5425 } 5426 infos[i] = new Debug.MemoryInfo(); 5427 Debug.getMemoryInfo(pids[i], infos[i]); 5428 if (proc != null) { 5429 synchronized (this) { 5430 if (proc.thread != null && proc.setAdj == oomAdj) { 5431 // Record this for posterity if the process has been stable. 5432 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5433 infos[i].getTotalUss(), false, proc.pkgList); 5434 } 5435 } 5436 } 5437 } 5438 return infos; 5439 } 5440 5441 @Override 5442 public long[] getProcessPss(int[] pids) { 5443 enforceNotIsolatedCaller("getProcessPss"); 5444 long[] pss = new long[pids.length]; 5445 for (int i=pids.length-1; i>=0; i--) { 5446 ProcessRecord proc; 5447 int oomAdj; 5448 synchronized (this) { 5449 synchronized (mPidsSelfLocked) { 5450 proc = mPidsSelfLocked.get(pids[i]); 5451 oomAdj = proc != null ? proc.setAdj : 0; 5452 } 5453 } 5454 long[] tmpUss = new long[1]; 5455 pss[i] = Debug.getPss(pids[i], tmpUss); 5456 if (proc != null) { 5457 synchronized (this) { 5458 if (proc.thread != null && proc.setAdj == oomAdj) { 5459 // Record this for posterity if the process has been stable. 5460 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5461 } 5462 } 5463 } 5464 } 5465 return pss; 5466 } 5467 5468 @Override 5469 public void killApplicationProcess(String processName, int uid) { 5470 if (processName == null) { 5471 return; 5472 } 5473 5474 int callerUid = Binder.getCallingUid(); 5475 // Only the system server can kill an application 5476 if (callerUid == Process.SYSTEM_UID) { 5477 synchronized (this) { 5478 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5479 if (app != null && app.thread != null) { 5480 try { 5481 app.thread.scheduleSuicide(); 5482 } catch (RemoteException e) { 5483 // If the other end already died, then our work here is done. 5484 } 5485 } else { 5486 Slog.w(TAG, "Process/uid not found attempting kill of " 5487 + processName + " / " + uid); 5488 } 5489 } 5490 } else { 5491 throw new SecurityException(callerUid + " cannot kill app process: " + 5492 processName); 5493 } 5494 } 5495 5496 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5497 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5498 false, true, false, false, UserHandle.getUserId(uid), reason); 5499 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5500 Uri.fromParts("package", packageName, null)); 5501 if (!mProcessesReady) { 5502 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5503 | Intent.FLAG_RECEIVER_FOREGROUND); 5504 } 5505 intent.putExtra(Intent.EXTRA_UID, uid); 5506 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5507 broadcastIntentLocked(null, null, intent, 5508 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5509 false, false, 5510 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5511 } 5512 5513 private void forceStopUserLocked(int userId, String reason) { 5514 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5515 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5517 | Intent.FLAG_RECEIVER_FOREGROUND); 5518 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5519 broadcastIntentLocked(null, null, intent, 5520 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5521 false, false, 5522 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5523 } 5524 5525 private final boolean killPackageProcessesLocked(String packageName, int appId, 5526 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5527 boolean doit, boolean evenPersistent, String reason) { 5528 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5529 5530 // Remove all processes this package may have touched: all with the 5531 // same UID (except for the system or root user), and all whose name 5532 // matches the package name. 5533 final int NP = mProcessNames.getMap().size(); 5534 for (int ip=0; ip<NP; ip++) { 5535 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5536 final int NA = apps.size(); 5537 for (int ia=0; ia<NA; ia++) { 5538 ProcessRecord app = apps.valueAt(ia); 5539 if (app.persistent && !evenPersistent) { 5540 // we don't kill persistent processes 5541 continue; 5542 } 5543 if (app.removed) { 5544 if (doit) { 5545 procs.add(app); 5546 } 5547 continue; 5548 } 5549 5550 // Skip process if it doesn't meet our oom adj requirement. 5551 if (app.setAdj < minOomAdj) { 5552 continue; 5553 } 5554 5555 // If no package is specified, we call all processes under the 5556 // give user id. 5557 if (packageName == null) { 5558 if (app.userId != userId) { 5559 continue; 5560 } 5561 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5562 continue; 5563 } 5564 // Package has been specified, we want to hit all processes 5565 // that match it. We need to qualify this by the processes 5566 // that are running under the specified app and user ID. 5567 } else { 5568 final boolean isDep = app.pkgDeps != null 5569 && app.pkgDeps.contains(packageName); 5570 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5571 continue; 5572 } 5573 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5574 continue; 5575 } 5576 if (!app.pkgList.containsKey(packageName) && !isDep) { 5577 continue; 5578 } 5579 } 5580 5581 // Process has passed all conditions, kill it! 5582 if (!doit) { 5583 return true; 5584 } 5585 app.removed = true; 5586 procs.add(app); 5587 } 5588 } 5589 5590 int N = procs.size(); 5591 for (int i=0; i<N; i++) { 5592 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5593 } 5594 updateOomAdjLocked(); 5595 return N > 0; 5596 } 5597 5598 private final boolean forceStopPackageLocked(String name, int appId, 5599 boolean callerWillRestart, boolean purgeCache, boolean doit, 5600 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5601 int i; 5602 int N; 5603 5604 if (userId == UserHandle.USER_ALL && name == null) { 5605 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5606 } 5607 5608 if (appId < 0 && name != null) { 5609 try { 5610 appId = UserHandle.getAppId( 5611 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5612 } catch (RemoteException e) { 5613 } 5614 } 5615 5616 if (doit) { 5617 if (name != null) { 5618 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5619 + " user=" + userId + ": " + reason); 5620 } else { 5621 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5622 } 5623 5624 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5625 for (int ip=pmap.size()-1; ip>=0; ip--) { 5626 SparseArray<Long> ba = pmap.valueAt(ip); 5627 for (i=ba.size()-1; i>=0; i--) { 5628 boolean remove = false; 5629 final int entUid = ba.keyAt(i); 5630 if (name != null) { 5631 if (userId == UserHandle.USER_ALL) { 5632 if (UserHandle.getAppId(entUid) == appId) { 5633 remove = true; 5634 } 5635 } else { 5636 if (entUid == UserHandle.getUid(userId, appId)) { 5637 remove = true; 5638 } 5639 } 5640 } else if (UserHandle.getUserId(entUid) == userId) { 5641 remove = true; 5642 } 5643 if (remove) { 5644 ba.removeAt(i); 5645 } 5646 } 5647 if (ba.size() == 0) { 5648 pmap.removeAt(ip); 5649 } 5650 } 5651 } 5652 5653 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5654 -100, callerWillRestart, true, doit, evenPersistent, 5655 name == null ? ("stop user " + userId) : ("stop " + name)); 5656 5657 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5658 if (!doit) { 5659 return true; 5660 } 5661 didSomething = true; 5662 } 5663 5664 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5665 if (!doit) { 5666 return true; 5667 } 5668 didSomething = true; 5669 } 5670 5671 if (name == null) { 5672 // Remove all sticky broadcasts from this user. 5673 mStickyBroadcasts.remove(userId); 5674 } 5675 5676 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5677 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5678 userId, providers)) { 5679 if (!doit) { 5680 return true; 5681 } 5682 didSomething = true; 5683 } 5684 N = providers.size(); 5685 for (i=0; i<N; i++) { 5686 removeDyingProviderLocked(null, providers.get(i), true); 5687 } 5688 5689 // Remove transient permissions granted from/to this package/user 5690 removeUriPermissionsForPackageLocked(name, userId, false); 5691 5692 if (name == null || uninstalling) { 5693 // Remove pending intents. For now we only do this when force 5694 // stopping users, because we have some problems when doing this 5695 // for packages -- app widgets are not currently cleaned up for 5696 // such packages, so they can be left with bad pending intents. 5697 if (mIntentSenderRecords.size() > 0) { 5698 Iterator<WeakReference<PendingIntentRecord>> it 5699 = mIntentSenderRecords.values().iterator(); 5700 while (it.hasNext()) { 5701 WeakReference<PendingIntentRecord> wpir = it.next(); 5702 if (wpir == null) { 5703 it.remove(); 5704 continue; 5705 } 5706 PendingIntentRecord pir = wpir.get(); 5707 if (pir == null) { 5708 it.remove(); 5709 continue; 5710 } 5711 if (name == null) { 5712 // Stopping user, remove all objects for the user. 5713 if (pir.key.userId != userId) { 5714 // Not the same user, skip it. 5715 continue; 5716 } 5717 } else { 5718 if (UserHandle.getAppId(pir.uid) != appId) { 5719 // Different app id, skip it. 5720 continue; 5721 } 5722 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5723 // Different user, skip it. 5724 continue; 5725 } 5726 if (!pir.key.packageName.equals(name)) { 5727 // Different package, skip it. 5728 continue; 5729 } 5730 } 5731 if (!doit) { 5732 return true; 5733 } 5734 didSomething = true; 5735 it.remove(); 5736 pir.canceled = true; 5737 if (pir.key.activity != null) { 5738 pir.key.activity.pendingResults.remove(pir.ref); 5739 } 5740 } 5741 } 5742 } 5743 5744 if (doit) { 5745 if (purgeCache && name != null) { 5746 AttributeCache ac = AttributeCache.instance(); 5747 if (ac != null) { 5748 ac.removePackage(name); 5749 } 5750 } 5751 if (mBooted) { 5752 mStackSupervisor.resumeTopActivitiesLocked(); 5753 mStackSupervisor.scheduleIdleLocked(); 5754 } 5755 } 5756 5757 return didSomething; 5758 } 5759 5760 private final boolean removeProcessLocked(ProcessRecord app, 5761 boolean callerWillRestart, boolean allowRestart, String reason) { 5762 final String name = app.processName; 5763 final int uid = app.uid; 5764 if (DEBUG_PROCESSES) Slog.d( 5765 TAG, "Force removing proc " + app.toShortString() + " (" + name 5766 + "/" + uid + ")"); 5767 5768 mProcessNames.remove(name, uid); 5769 mIsolatedProcesses.remove(app.uid); 5770 if (mHeavyWeightProcess == app) { 5771 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5772 mHeavyWeightProcess.userId, 0)); 5773 mHeavyWeightProcess = null; 5774 } 5775 boolean needRestart = false; 5776 if (app.pid > 0 && app.pid != MY_PID) { 5777 int pid = app.pid; 5778 synchronized (mPidsSelfLocked) { 5779 mPidsSelfLocked.remove(pid); 5780 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5781 } 5782 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5783 if (app.isolated) { 5784 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5785 } 5786 app.kill(reason, true); 5787 handleAppDiedLocked(app, true, allowRestart); 5788 removeLruProcessLocked(app); 5789 5790 if (app.persistent && !app.isolated) { 5791 if (!callerWillRestart) { 5792 addAppLocked(app.info, false, null /* ABI override */); 5793 } else { 5794 needRestart = true; 5795 } 5796 } 5797 } else { 5798 mRemovedProcesses.add(app); 5799 } 5800 5801 return needRestart; 5802 } 5803 5804 private final void processStartTimedOutLocked(ProcessRecord app) { 5805 final int pid = app.pid; 5806 boolean gone = false; 5807 synchronized (mPidsSelfLocked) { 5808 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5809 if (knownApp != null && knownApp.thread == null) { 5810 mPidsSelfLocked.remove(pid); 5811 gone = true; 5812 } 5813 } 5814 5815 if (gone) { 5816 Slog.w(TAG, "Process " + app + " failed to attach"); 5817 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5818 pid, app.uid, app.processName); 5819 mProcessNames.remove(app.processName, app.uid); 5820 mIsolatedProcesses.remove(app.uid); 5821 if (mHeavyWeightProcess == app) { 5822 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5823 mHeavyWeightProcess.userId, 0)); 5824 mHeavyWeightProcess = null; 5825 } 5826 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5827 if (app.isolated) { 5828 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5829 } 5830 // Take care of any launching providers waiting for this process. 5831 checkAppInLaunchingProvidersLocked(app, true); 5832 // Take care of any services that are waiting for the process. 5833 mServices.processStartTimedOutLocked(app); 5834 app.kill("start timeout", true); 5835 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5836 Slog.w(TAG, "Unattached app died before backup, skipping"); 5837 try { 5838 IBackupManager bm = IBackupManager.Stub.asInterface( 5839 ServiceManager.getService(Context.BACKUP_SERVICE)); 5840 bm.agentDisconnected(app.info.packageName); 5841 } catch (RemoteException e) { 5842 // Can't happen; the backup manager is local 5843 } 5844 } 5845 if (isPendingBroadcastProcessLocked(pid)) { 5846 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5847 skipPendingBroadcastLocked(pid); 5848 } 5849 } else { 5850 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5851 } 5852 } 5853 5854 private final boolean attachApplicationLocked(IApplicationThread thread, 5855 int pid) { 5856 5857 // Find the application record that is being attached... either via 5858 // the pid if we are running in multiple processes, or just pull the 5859 // next app record if we are emulating process with anonymous threads. 5860 ProcessRecord app; 5861 if (pid != MY_PID && pid >= 0) { 5862 synchronized (mPidsSelfLocked) { 5863 app = mPidsSelfLocked.get(pid); 5864 } 5865 } else { 5866 app = null; 5867 } 5868 5869 if (app == null) { 5870 Slog.w(TAG, "No pending application record for pid " + pid 5871 + " (IApplicationThread " + thread + "); dropping process"); 5872 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5873 if (pid > 0 && pid != MY_PID) { 5874 Process.killProcessQuiet(pid); 5875 //TODO: Process.killProcessGroup(app.info.uid, pid); 5876 } else { 5877 try { 5878 thread.scheduleExit(); 5879 } catch (Exception e) { 5880 // Ignore exceptions. 5881 } 5882 } 5883 return false; 5884 } 5885 5886 // If this application record is still attached to a previous 5887 // process, clean it up now. 5888 if (app.thread != null) { 5889 handleAppDiedLocked(app, true, true); 5890 } 5891 5892 // Tell the process all about itself. 5893 5894 if (localLOGV) Slog.v( 5895 TAG, "Binding process pid " + pid + " to record " + app); 5896 5897 final String processName = app.processName; 5898 try { 5899 AppDeathRecipient adr = new AppDeathRecipient( 5900 app, pid, thread); 5901 thread.asBinder().linkToDeath(adr, 0); 5902 app.deathRecipient = adr; 5903 } catch (RemoteException e) { 5904 app.resetPackageList(mProcessStats); 5905 startProcessLocked(app, "link fail", processName); 5906 return false; 5907 } 5908 5909 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5910 5911 app.makeActive(thread, mProcessStats); 5912 app.curAdj = app.setAdj = -100; 5913 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5914 app.forcingToForeground = null; 5915 updateProcessForegroundLocked(app, false, false); 5916 app.hasShownUi = false; 5917 app.debugging = false; 5918 app.cached = false; 5919 5920 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5921 5922 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5923 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5924 5925 if (!normalMode) { 5926 Slog.i(TAG, "Launching preboot mode app: " + app); 5927 } 5928 5929 if (localLOGV) Slog.v( 5930 TAG, "New app record " + app 5931 + " thread=" + thread.asBinder() + " pid=" + pid); 5932 try { 5933 int testMode = IApplicationThread.DEBUG_OFF; 5934 if (mDebugApp != null && mDebugApp.equals(processName)) { 5935 testMode = mWaitForDebugger 5936 ? IApplicationThread.DEBUG_WAIT 5937 : IApplicationThread.DEBUG_ON; 5938 app.debugging = true; 5939 if (mDebugTransient) { 5940 mDebugApp = mOrigDebugApp; 5941 mWaitForDebugger = mOrigWaitForDebugger; 5942 } 5943 } 5944 String profileFile = app.instrumentationProfileFile; 5945 ParcelFileDescriptor profileFd = null; 5946 int samplingInterval = 0; 5947 boolean profileAutoStop = false; 5948 if (mProfileApp != null && mProfileApp.equals(processName)) { 5949 mProfileProc = app; 5950 profileFile = mProfileFile; 5951 profileFd = mProfileFd; 5952 samplingInterval = mSamplingInterval; 5953 profileAutoStop = mAutoStopProfiler; 5954 } 5955 boolean enableOpenGlTrace = false; 5956 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5957 enableOpenGlTrace = true; 5958 mOpenGlTraceApp = null; 5959 } 5960 5961 // If the app is being launched for restore or full backup, set it up specially 5962 boolean isRestrictedBackupMode = false; 5963 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5964 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5965 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5966 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5967 } 5968 5969 ensurePackageDexOpt(app.instrumentationInfo != null 5970 ? app.instrumentationInfo.packageName 5971 : app.info.packageName); 5972 if (app.instrumentationClass != null) { 5973 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5974 } 5975 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5976 + processName + " with config " + mConfiguration); 5977 ApplicationInfo appInfo = app.instrumentationInfo != null 5978 ? app.instrumentationInfo : app.info; 5979 app.compat = compatibilityInfoForPackageLocked(appInfo); 5980 if (profileFd != null) { 5981 profileFd = profileFd.dup(); 5982 } 5983 ProfilerInfo profilerInfo = profileFile == null ? null 5984 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5985 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5986 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5987 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5988 isRestrictedBackupMode || !normalMode, app.persistent, 5989 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5990 mCoreSettingsObserver.getCoreSettingsLocked()); 5991 updateLruProcessLocked(app, false, null); 5992 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5993 } catch (Exception e) { 5994 // todo: Yikes! What should we do? For now we will try to 5995 // start another process, but that could easily get us in 5996 // an infinite loop of restarting processes... 5997 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5998 5999 app.resetPackageList(mProcessStats); 6000 app.unlinkDeathRecipient(); 6001 startProcessLocked(app, "bind fail", processName); 6002 return false; 6003 } 6004 6005 // Remove this record from the list of starting applications. 6006 mPersistentStartingProcesses.remove(app); 6007 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6008 "Attach application locked removing on hold: " + app); 6009 mProcessesOnHold.remove(app); 6010 6011 boolean badApp = false; 6012 boolean didSomething = false; 6013 6014 // See if the top visible activity is waiting to run in this process... 6015 if (normalMode) { 6016 try { 6017 if (mStackSupervisor.attachApplicationLocked(app)) { 6018 didSomething = true; 6019 } 6020 } catch (Exception e) { 6021 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6022 badApp = true; 6023 } 6024 } 6025 6026 // Find any services that should be running in this process... 6027 if (!badApp) { 6028 try { 6029 didSomething |= mServices.attachApplicationLocked(app, processName); 6030 } catch (Exception e) { 6031 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6032 badApp = true; 6033 } 6034 } 6035 6036 // Check if a next-broadcast receiver is in this process... 6037 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6038 try { 6039 didSomething |= sendPendingBroadcastsLocked(app); 6040 } catch (Exception e) { 6041 // If the app died trying to launch the receiver we declare it 'bad' 6042 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6043 badApp = true; 6044 } 6045 } 6046 6047 // Check whether the next backup agent is in this process... 6048 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6049 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6050 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6051 try { 6052 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6053 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6054 mBackupTarget.backupMode); 6055 } catch (Exception e) { 6056 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6057 badApp = true; 6058 } 6059 } 6060 6061 if (badApp) { 6062 app.kill("error during init", true); 6063 handleAppDiedLocked(app, false, true); 6064 return false; 6065 } 6066 6067 if (!didSomething) { 6068 updateOomAdjLocked(); 6069 } 6070 6071 return true; 6072 } 6073 6074 @Override 6075 public final void attachApplication(IApplicationThread thread) { 6076 synchronized (this) { 6077 int callingPid = Binder.getCallingPid(); 6078 final long origId = Binder.clearCallingIdentity(); 6079 attachApplicationLocked(thread, callingPid); 6080 Binder.restoreCallingIdentity(origId); 6081 } 6082 } 6083 6084 @Override 6085 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6086 final long origId = Binder.clearCallingIdentity(); 6087 synchronized (this) { 6088 ActivityStack stack = ActivityRecord.getStackLocked(token); 6089 if (stack != null) { 6090 ActivityRecord r = 6091 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6092 if (stopProfiling) { 6093 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6094 try { 6095 mProfileFd.close(); 6096 } catch (IOException e) { 6097 } 6098 clearProfilerLocked(); 6099 } 6100 } 6101 } 6102 } 6103 Binder.restoreCallingIdentity(origId); 6104 } 6105 6106 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6107 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6108 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6109 } 6110 6111 void enableScreenAfterBoot() { 6112 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6113 SystemClock.uptimeMillis()); 6114 mWindowManager.enableScreenAfterBoot(); 6115 6116 synchronized (this) { 6117 updateEventDispatchingLocked(); 6118 } 6119 } 6120 6121 @Override 6122 public void showBootMessage(final CharSequence msg, final boolean always) { 6123 enforceNotIsolatedCaller("showBootMessage"); 6124 mWindowManager.showBootMessage(msg, always); 6125 } 6126 6127 @Override 6128 public void keyguardWaitingForActivityDrawn() { 6129 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6130 final long token = Binder.clearCallingIdentity(); 6131 try { 6132 synchronized (this) { 6133 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6134 mWindowManager.keyguardWaitingForActivityDrawn(); 6135 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6136 mLockScreenShown = LOCK_SCREEN_LEAVING; 6137 } 6138 } 6139 } finally { 6140 Binder.restoreCallingIdentity(token); 6141 } 6142 } 6143 6144 final void finishBooting() { 6145 synchronized (this) { 6146 if (!mBootAnimationComplete) { 6147 mCallFinishBooting = true; 6148 return; 6149 } 6150 mCallFinishBooting = false; 6151 } 6152 6153 // Register receivers to handle package update events 6154 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6155 6156 // Let system services know. 6157 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6158 6159 synchronized (this) { 6160 // Ensure that any processes we had put on hold are now started 6161 // up. 6162 final int NP = mProcessesOnHold.size(); 6163 if (NP > 0) { 6164 ArrayList<ProcessRecord> procs = 6165 new ArrayList<ProcessRecord>(mProcessesOnHold); 6166 for (int ip=0; ip<NP; ip++) { 6167 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6168 + procs.get(ip)); 6169 startProcessLocked(procs.get(ip), "on-hold", null); 6170 } 6171 } 6172 6173 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6174 // Start looking for apps that are abusing wake locks. 6175 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6176 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6177 // Tell anyone interested that we are done booting! 6178 SystemProperties.set("sys.boot_completed", "1"); 6179 6180 // And trigger dev.bootcomplete if we are not showing encryption progress 6181 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6182 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6183 SystemProperties.set("dev.bootcomplete", "1"); 6184 } 6185 for (int i=0; i<mStartedUsers.size(); i++) { 6186 UserStartedState uss = mStartedUsers.valueAt(i); 6187 if (uss.mState == UserStartedState.STATE_BOOTING) { 6188 uss.mState = UserStartedState.STATE_RUNNING; 6189 final int userId = mStartedUsers.keyAt(i); 6190 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6191 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6192 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6193 broadcastIntentLocked(null, null, intent, null, 6194 new IIntentReceiver.Stub() { 6195 @Override 6196 public void performReceive(Intent intent, int resultCode, 6197 String data, Bundle extras, boolean ordered, 6198 boolean sticky, int sendingUser) { 6199 synchronized (ActivityManagerService.this) { 6200 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6201 true, false); 6202 } 6203 } 6204 }, 6205 0, null, null, 6206 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6207 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6208 userId); 6209 } 6210 } 6211 scheduleStartProfilesLocked(); 6212 } 6213 } 6214 } 6215 6216 @Override 6217 public void bootAnimationComplete() { 6218 final boolean callFinishBooting; 6219 synchronized (this) { 6220 callFinishBooting = mCallFinishBooting; 6221 mBootAnimationComplete = true; 6222 } 6223 if (callFinishBooting) { 6224 finishBooting(); 6225 } 6226 } 6227 6228 final void ensureBootCompleted() { 6229 boolean booting; 6230 boolean enableScreen; 6231 synchronized (this) { 6232 booting = mBooting; 6233 mBooting = false; 6234 enableScreen = !mBooted; 6235 mBooted = true; 6236 } 6237 6238 if (booting) { 6239 finishBooting(); 6240 } 6241 6242 if (enableScreen) { 6243 enableScreenAfterBoot(); 6244 } 6245 } 6246 6247 @Override 6248 public final void activityResumed(IBinder token) { 6249 final long origId = Binder.clearCallingIdentity(); 6250 synchronized(this) { 6251 ActivityStack stack = ActivityRecord.getStackLocked(token); 6252 if (stack != null) { 6253 ActivityRecord.activityResumedLocked(token); 6254 } 6255 } 6256 Binder.restoreCallingIdentity(origId); 6257 } 6258 6259 @Override 6260 public final void activityPaused(IBinder token) { 6261 final long origId = Binder.clearCallingIdentity(); 6262 synchronized(this) { 6263 ActivityStack stack = ActivityRecord.getStackLocked(token); 6264 if (stack != null) { 6265 stack.activityPausedLocked(token, false); 6266 } 6267 } 6268 Binder.restoreCallingIdentity(origId); 6269 } 6270 6271 @Override 6272 public final void activityStopped(IBinder token, Bundle icicle, 6273 PersistableBundle persistentState, CharSequence description) { 6274 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6275 6276 // Refuse possible leaked file descriptors 6277 if (icicle != null && icicle.hasFileDescriptors()) { 6278 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6279 } 6280 6281 final long origId = Binder.clearCallingIdentity(); 6282 6283 synchronized (this) { 6284 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6285 if (r != null) { 6286 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6287 } 6288 } 6289 6290 trimApplications(); 6291 6292 Binder.restoreCallingIdentity(origId); 6293 } 6294 6295 @Override 6296 public final void activityDestroyed(IBinder token) { 6297 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6298 synchronized (this) { 6299 ActivityStack stack = ActivityRecord.getStackLocked(token); 6300 if (stack != null) { 6301 stack.activityDestroyedLocked(token); 6302 } 6303 } 6304 } 6305 6306 @Override 6307 public final void backgroundResourcesReleased(IBinder token) { 6308 final long origId = Binder.clearCallingIdentity(); 6309 try { 6310 synchronized (this) { 6311 ActivityStack stack = ActivityRecord.getStackLocked(token); 6312 if (stack != null) { 6313 stack.backgroundResourcesReleased(token); 6314 } 6315 } 6316 } finally { 6317 Binder.restoreCallingIdentity(origId); 6318 } 6319 } 6320 6321 @Override 6322 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6323 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6324 } 6325 6326 @Override 6327 public final void notifyEnterAnimationComplete(IBinder token) { 6328 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6329 } 6330 6331 @Override 6332 public String getCallingPackage(IBinder token) { 6333 synchronized (this) { 6334 ActivityRecord r = getCallingRecordLocked(token); 6335 return r != null ? r.info.packageName : null; 6336 } 6337 } 6338 6339 @Override 6340 public ComponentName getCallingActivity(IBinder token) { 6341 synchronized (this) { 6342 ActivityRecord r = getCallingRecordLocked(token); 6343 return r != null ? r.intent.getComponent() : null; 6344 } 6345 } 6346 6347 private ActivityRecord getCallingRecordLocked(IBinder token) { 6348 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6349 if (r == null) { 6350 return null; 6351 } 6352 return r.resultTo; 6353 } 6354 6355 @Override 6356 public ComponentName getActivityClassForToken(IBinder token) { 6357 synchronized(this) { 6358 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6359 if (r == null) { 6360 return null; 6361 } 6362 return r.intent.getComponent(); 6363 } 6364 } 6365 6366 @Override 6367 public String getPackageForToken(IBinder token) { 6368 synchronized(this) { 6369 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6370 if (r == null) { 6371 return null; 6372 } 6373 return r.packageName; 6374 } 6375 } 6376 6377 @Override 6378 public IIntentSender getIntentSender(int type, 6379 String packageName, IBinder token, String resultWho, 6380 int requestCode, Intent[] intents, String[] resolvedTypes, 6381 int flags, Bundle options, int userId) { 6382 enforceNotIsolatedCaller("getIntentSender"); 6383 // Refuse possible leaked file descriptors 6384 if (intents != null) { 6385 if (intents.length < 1) { 6386 throw new IllegalArgumentException("Intents array length must be >= 1"); 6387 } 6388 for (int i=0; i<intents.length; i++) { 6389 Intent intent = intents[i]; 6390 if (intent != null) { 6391 if (intent.hasFileDescriptors()) { 6392 throw new IllegalArgumentException("File descriptors passed in Intent"); 6393 } 6394 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6395 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6396 throw new IllegalArgumentException( 6397 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6398 } 6399 intents[i] = new Intent(intent); 6400 } 6401 } 6402 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6403 throw new IllegalArgumentException( 6404 "Intent array length does not match resolvedTypes length"); 6405 } 6406 } 6407 if (options != null) { 6408 if (options.hasFileDescriptors()) { 6409 throw new IllegalArgumentException("File descriptors passed in options"); 6410 } 6411 } 6412 6413 synchronized(this) { 6414 int callingUid = Binder.getCallingUid(); 6415 int origUserId = userId; 6416 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6417 type == ActivityManager.INTENT_SENDER_BROADCAST, 6418 ALLOW_NON_FULL, "getIntentSender", null); 6419 if (origUserId == UserHandle.USER_CURRENT) { 6420 // We don't want to evaluate this until the pending intent is 6421 // actually executed. However, we do want to always do the 6422 // security checking for it above. 6423 userId = UserHandle.USER_CURRENT; 6424 } 6425 try { 6426 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6427 int uid = AppGlobals.getPackageManager() 6428 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6429 if (!UserHandle.isSameApp(callingUid, uid)) { 6430 String msg = "Permission Denial: getIntentSender() from pid=" 6431 + Binder.getCallingPid() 6432 + ", uid=" + Binder.getCallingUid() 6433 + ", (need uid=" + uid + ")" 6434 + " is not allowed to send as package " + packageName; 6435 Slog.w(TAG, msg); 6436 throw new SecurityException(msg); 6437 } 6438 } 6439 6440 return getIntentSenderLocked(type, packageName, callingUid, userId, 6441 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6442 6443 } catch (RemoteException e) { 6444 throw new SecurityException(e); 6445 } 6446 } 6447 } 6448 6449 IIntentSender getIntentSenderLocked(int type, String packageName, 6450 int callingUid, int userId, IBinder token, String resultWho, 6451 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6452 Bundle options) { 6453 if (DEBUG_MU) 6454 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6455 ActivityRecord activity = null; 6456 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6457 activity = ActivityRecord.isInStackLocked(token); 6458 if (activity == null) { 6459 return null; 6460 } 6461 if (activity.finishing) { 6462 return null; 6463 } 6464 } 6465 6466 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6467 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6468 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6469 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6470 |PendingIntent.FLAG_UPDATE_CURRENT); 6471 6472 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6473 type, packageName, activity, resultWho, 6474 requestCode, intents, resolvedTypes, flags, options, userId); 6475 WeakReference<PendingIntentRecord> ref; 6476 ref = mIntentSenderRecords.get(key); 6477 PendingIntentRecord rec = ref != null ? ref.get() : null; 6478 if (rec != null) { 6479 if (!cancelCurrent) { 6480 if (updateCurrent) { 6481 if (rec.key.requestIntent != null) { 6482 rec.key.requestIntent.replaceExtras(intents != null ? 6483 intents[intents.length - 1] : null); 6484 } 6485 if (intents != null) { 6486 intents[intents.length-1] = rec.key.requestIntent; 6487 rec.key.allIntents = intents; 6488 rec.key.allResolvedTypes = resolvedTypes; 6489 } else { 6490 rec.key.allIntents = null; 6491 rec.key.allResolvedTypes = null; 6492 } 6493 } 6494 return rec; 6495 } 6496 rec.canceled = true; 6497 mIntentSenderRecords.remove(key); 6498 } 6499 if (noCreate) { 6500 return rec; 6501 } 6502 rec = new PendingIntentRecord(this, key, callingUid); 6503 mIntentSenderRecords.put(key, rec.ref); 6504 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6505 if (activity.pendingResults == null) { 6506 activity.pendingResults 6507 = new HashSet<WeakReference<PendingIntentRecord>>(); 6508 } 6509 activity.pendingResults.add(rec.ref); 6510 } 6511 return rec; 6512 } 6513 6514 @Override 6515 public void cancelIntentSender(IIntentSender sender) { 6516 if (!(sender instanceof PendingIntentRecord)) { 6517 return; 6518 } 6519 synchronized(this) { 6520 PendingIntentRecord rec = (PendingIntentRecord)sender; 6521 try { 6522 int uid = AppGlobals.getPackageManager() 6523 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6524 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6525 String msg = "Permission Denial: cancelIntentSender() from pid=" 6526 + Binder.getCallingPid() 6527 + ", uid=" + Binder.getCallingUid() 6528 + " is not allowed to cancel packges " 6529 + rec.key.packageName; 6530 Slog.w(TAG, msg); 6531 throw new SecurityException(msg); 6532 } 6533 } catch (RemoteException e) { 6534 throw new SecurityException(e); 6535 } 6536 cancelIntentSenderLocked(rec, true); 6537 } 6538 } 6539 6540 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6541 rec.canceled = true; 6542 mIntentSenderRecords.remove(rec.key); 6543 if (cleanActivity && rec.key.activity != null) { 6544 rec.key.activity.pendingResults.remove(rec.ref); 6545 } 6546 } 6547 6548 @Override 6549 public String getPackageForIntentSender(IIntentSender pendingResult) { 6550 if (!(pendingResult instanceof PendingIntentRecord)) { 6551 return null; 6552 } 6553 try { 6554 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6555 return res.key.packageName; 6556 } catch (ClassCastException e) { 6557 } 6558 return null; 6559 } 6560 6561 @Override 6562 public int getUidForIntentSender(IIntentSender sender) { 6563 if (sender instanceof PendingIntentRecord) { 6564 try { 6565 PendingIntentRecord res = (PendingIntentRecord)sender; 6566 return res.uid; 6567 } catch (ClassCastException e) { 6568 } 6569 } 6570 return -1; 6571 } 6572 6573 @Override 6574 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6575 if (!(pendingResult instanceof PendingIntentRecord)) { 6576 return false; 6577 } 6578 try { 6579 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6580 if (res.key.allIntents == null) { 6581 return false; 6582 } 6583 for (int i=0; i<res.key.allIntents.length; i++) { 6584 Intent intent = res.key.allIntents[i]; 6585 if (intent.getPackage() != null && intent.getComponent() != null) { 6586 return false; 6587 } 6588 } 6589 return true; 6590 } catch (ClassCastException e) { 6591 } 6592 return false; 6593 } 6594 6595 @Override 6596 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6597 if (!(pendingResult instanceof PendingIntentRecord)) { 6598 return false; 6599 } 6600 try { 6601 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6602 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6603 return true; 6604 } 6605 return false; 6606 } catch (ClassCastException e) { 6607 } 6608 return false; 6609 } 6610 6611 @Override 6612 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6613 if (!(pendingResult instanceof PendingIntentRecord)) { 6614 return null; 6615 } 6616 try { 6617 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6618 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6619 } catch (ClassCastException e) { 6620 } 6621 return null; 6622 } 6623 6624 @Override 6625 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6626 if (!(pendingResult instanceof PendingIntentRecord)) { 6627 return null; 6628 } 6629 try { 6630 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6631 Intent intent = res.key.requestIntent; 6632 if (intent != null) { 6633 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6634 || res.lastTagPrefix.equals(prefix))) { 6635 return res.lastTag; 6636 } 6637 res.lastTagPrefix = prefix; 6638 StringBuilder sb = new StringBuilder(128); 6639 if (prefix != null) { 6640 sb.append(prefix); 6641 } 6642 if (intent.getAction() != null) { 6643 sb.append(intent.getAction()); 6644 } else if (intent.getComponent() != null) { 6645 intent.getComponent().appendShortString(sb); 6646 } else { 6647 sb.append("?"); 6648 } 6649 return res.lastTag = sb.toString(); 6650 } 6651 } catch (ClassCastException e) { 6652 } 6653 return null; 6654 } 6655 6656 @Override 6657 public void setProcessLimit(int max) { 6658 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6659 "setProcessLimit()"); 6660 synchronized (this) { 6661 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6662 mProcessLimitOverride = max; 6663 } 6664 trimApplications(); 6665 } 6666 6667 @Override 6668 public int getProcessLimit() { 6669 synchronized (this) { 6670 return mProcessLimitOverride; 6671 } 6672 } 6673 6674 void foregroundTokenDied(ForegroundToken token) { 6675 synchronized (ActivityManagerService.this) { 6676 synchronized (mPidsSelfLocked) { 6677 ForegroundToken cur 6678 = mForegroundProcesses.get(token.pid); 6679 if (cur != token) { 6680 return; 6681 } 6682 mForegroundProcesses.remove(token.pid); 6683 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6684 if (pr == null) { 6685 return; 6686 } 6687 pr.forcingToForeground = null; 6688 updateProcessForegroundLocked(pr, false, false); 6689 } 6690 updateOomAdjLocked(); 6691 } 6692 } 6693 6694 @Override 6695 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6696 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6697 "setProcessForeground()"); 6698 synchronized(this) { 6699 boolean changed = false; 6700 6701 synchronized (mPidsSelfLocked) { 6702 ProcessRecord pr = mPidsSelfLocked.get(pid); 6703 if (pr == null && isForeground) { 6704 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6705 return; 6706 } 6707 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6708 if (oldToken != null) { 6709 oldToken.token.unlinkToDeath(oldToken, 0); 6710 mForegroundProcesses.remove(pid); 6711 if (pr != null) { 6712 pr.forcingToForeground = null; 6713 } 6714 changed = true; 6715 } 6716 if (isForeground && token != null) { 6717 ForegroundToken newToken = new ForegroundToken() { 6718 @Override 6719 public void binderDied() { 6720 foregroundTokenDied(this); 6721 } 6722 }; 6723 newToken.pid = pid; 6724 newToken.token = token; 6725 try { 6726 token.linkToDeath(newToken, 0); 6727 mForegroundProcesses.put(pid, newToken); 6728 pr.forcingToForeground = token; 6729 changed = true; 6730 } catch (RemoteException e) { 6731 // If the process died while doing this, we will later 6732 // do the cleanup with the process death link. 6733 } 6734 } 6735 } 6736 6737 if (changed) { 6738 updateOomAdjLocked(); 6739 } 6740 } 6741 } 6742 6743 // ========================================================= 6744 // PERMISSIONS 6745 // ========================================================= 6746 6747 static class PermissionController extends IPermissionController.Stub { 6748 ActivityManagerService mActivityManagerService; 6749 PermissionController(ActivityManagerService activityManagerService) { 6750 mActivityManagerService = activityManagerService; 6751 } 6752 6753 @Override 6754 public boolean checkPermission(String permission, int pid, int uid) { 6755 return mActivityManagerService.checkPermission(permission, pid, 6756 uid) == PackageManager.PERMISSION_GRANTED; 6757 } 6758 } 6759 6760 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6761 @Override 6762 public int checkComponentPermission(String permission, int pid, int uid, 6763 int owningUid, boolean exported) { 6764 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6765 owningUid, exported); 6766 } 6767 6768 @Override 6769 public Object getAMSLock() { 6770 return ActivityManagerService.this; 6771 } 6772 } 6773 6774 /** 6775 * This can be called with or without the global lock held. 6776 */ 6777 int checkComponentPermission(String permission, int pid, int uid, 6778 int owningUid, boolean exported) { 6779 // We might be performing an operation on behalf of an indirect binder 6780 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6781 // client identity accordingly before proceeding. 6782 Identity tlsIdentity = sCallerIdentity.get(); 6783 if (tlsIdentity != null) { 6784 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6785 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6786 uid = tlsIdentity.uid; 6787 pid = tlsIdentity.pid; 6788 } 6789 6790 if (pid == MY_PID) { 6791 return PackageManager.PERMISSION_GRANTED; 6792 } 6793 6794 return ActivityManager.checkComponentPermission(permission, uid, 6795 owningUid, exported); 6796 } 6797 6798 /** 6799 * As the only public entry point for permissions checking, this method 6800 * can enforce the semantic that requesting a check on a null global 6801 * permission is automatically denied. (Internally a null permission 6802 * string is used when calling {@link #checkComponentPermission} in cases 6803 * when only uid-based security is needed.) 6804 * 6805 * This can be called with or without the global lock held. 6806 */ 6807 @Override 6808 public int checkPermission(String permission, int pid, int uid) { 6809 if (permission == null) { 6810 return PackageManager.PERMISSION_DENIED; 6811 } 6812 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6813 } 6814 6815 /** 6816 * Binder IPC calls go through the public entry point. 6817 * This can be called with or without the global lock held. 6818 */ 6819 int checkCallingPermission(String permission) { 6820 return checkPermission(permission, 6821 Binder.getCallingPid(), 6822 UserHandle.getAppId(Binder.getCallingUid())); 6823 } 6824 6825 /** 6826 * This can be called with or without the global lock held. 6827 */ 6828 void enforceCallingPermission(String permission, String func) { 6829 if (checkCallingPermission(permission) 6830 == PackageManager.PERMISSION_GRANTED) { 6831 return; 6832 } 6833 6834 String msg = "Permission Denial: " + func + " from pid=" 6835 + Binder.getCallingPid() 6836 + ", uid=" + Binder.getCallingUid() 6837 + " requires " + permission; 6838 Slog.w(TAG, msg); 6839 throw new SecurityException(msg); 6840 } 6841 6842 /** 6843 * Determine if UID is holding permissions required to access {@link Uri} in 6844 * the given {@link ProviderInfo}. Final permission checking is always done 6845 * in {@link ContentProvider}. 6846 */ 6847 private final boolean checkHoldingPermissionsLocked( 6848 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6849 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6850 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6851 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6852 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6853 != PERMISSION_GRANTED) { 6854 return false; 6855 } 6856 } 6857 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6858 } 6859 6860 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6861 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6862 if (pi.applicationInfo.uid == uid) { 6863 return true; 6864 } else if (!pi.exported) { 6865 return false; 6866 } 6867 6868 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6869 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6870 try { 6871 // check if target holds top-level <provider> permissions 6872 if (!readMet && pi.readPermission != null && considerUidPermissions 6873 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6874 readMet = true; 6875 } 6876 if (!writeMet && pi.writePermission != null && considerUidPermissions 6877 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6878 writeMet = true; 6879 } 6880 6881 // track if unprotected read/write is allowed; any denied 6882 // <path-permission> below removes this ability 6883 boolean allowDefaultRead = pi.readPermission == null; 6884 boolean allowDefaultWrite = pi.writePermission == null; 6885 6886 // check if target holds any <path-permission> that match uri 6887 final PathPermission[] pps = pi.pathPermissions; 6888 if (pps != null) { 6889 final String path = grantUri.uri.getPath(); 6890 int i = pps.length; 6891 while (i > 0 && (!readMet || !writeMet)) { 6892 i--; 6893 PathPermission pp = pps[i]; 6894 if (pp.match(path)) { 6895 if (!readMet) { 6896 final String pprperm = pp.getReadPermission(); 6897 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6898 + pprperm + " for " + pp.getPath() 6899 + ": match=" + pp.match(path) 6900 + " check=" + pm.checkUidPermission(pprperm, uid)); 6901 if (pprperm != null) { 6902 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6903 == PERMISSION_GRANTED) { 6904 readMet = true; 6905 } else { 6906 allowDefaultRead = false; 6907 } 6908 } 6909 } 6910 if (!writeMet) { 6911 final String ppwperm = pp.getWritePermission(); 6912 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6913 + ppwperm + " for " + pp.getPath() 6914 + ": match=" + pp.match(path) 6915 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6916 if (ppwperm != null) { 6917 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6918 == PERMISSION_GRANTED) { 6919 writeMet = true; 6920 } else { 6921 allowDefaultWrite = false; 6922 } 6923 } 6924 } 6925 } 6926 } 6927 } 6928 6929 // grant unprotected <provider> read/write, if not blocked by 6930 // <path-permission> above 6931 if (allowDefaultRead) readMet = true; 6932 if (allowDefaultWrite) writeMet = true; 6933 6934 } catch (RemoteException e) { 6935 return false; 6936 } 6937 6938 return readMet && writeMet; 6939 } 6940 6941 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6942 ProviderInfo pi = null; 6943 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6944 if (cpr != null) { 6945 pi = cpr.info; 6946 } else { 6947 try { 6948 pi = AppGlobals.getPackageManager().resolveContentProvider( 6949 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6950 } catch (RemoteException ex) { 6951 } 6952 } 6953 return pi; 6954 } 6955 6956 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6957 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6958 if (targetUris != null) { 6959 return targetUris.get(grantUri); 6960 } 6961 return null; 6962 } 6963 6964 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6965 String targetPkg, int targetUid, GrantUri grantUri) { 6966 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6967 if (targetUris == null) { 6968 targetUris = Maps.newArrayMap(); 6969 mGrantedUriPermissions.put(targetUid, targetUris); 6970 } 6971 6972 UriPermission perm = targetUris.get(grantUri); 6973 if (perm == null) { 6974 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6975 targetUris.put(grantUri, perm); 6976 } 6977 6978 return perm; 6979 } 6980 6981 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6982 final int modeFlags) { 6983 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6984 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6985 : UriPermission.STRENGTH_OWNED; 6986 6987 // Root gets to do everything. 6988 if (uid == 0) { 6989 return true; 6990 } 6991 6992 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6993 if (perms == null) return false; 6994 6995 // First look for exact match 6996 final UriPermission exactPerm = perms.get(grantUri); 6997 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6998 return true; 6999 } 7000 7001 // No exact match, look for prefixes 7002 final int N = perms.size(); 7003 for (int i = 0; i < N; i++) { 7004 final UriPermission perm = perms.valueAt(i); 7005 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7006 && perm.getStrength(modeFlags) >= minStrength) { 7007 return true; 7008 } 7009 } 7010 7011 return false; 7012 } 7013 7014 /** 7015 * @param uri This uri must NOT contain an embedded userId. 7016 * @param userId The userId in which the uri is to be resolved. 7017 */ 7018 @Override 7019 public int checkUriPermission(Uri uri, int pid, int uid, 7020 final int modeFlags, int userId) { 7021 enforceNotIsolatedCaller("checkUriPermission"); 7022 7023 // Another redirected-binder-call permissions check as in 7024 // {@link checkComponentPermission}. 7025 Identity tlsIdentity = sCallerIdentity.get(); 7026 if (tlsIdentity != null) { 7027 uid = tlsIdentity.uid; 7028 pid = tlsIdentity.pid; 7029 } 7030 7031 // Our own process gets to do everything. 7032 if (pid == MY_PID) { 7033 return PackageManager.PERMISSION_GRANTED; 7034 } 7035 synchronized (this) { 7036 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7037 ? PackageManager.PERMISSION_GRANTED 7038 : PackageManager.PERMISSION_DENIED; 7039 } 7040 } 7041 7042 /** 7043 * Check if the targetPkg can be granted permission to access uri by 7044 * the callingUid using the given modeFlags. Throws a security exception 7045 * if callingUid is not allowed to do this. Returns the uid of the target 7046 * if the URI permission grant should be performed; returns -1 if it is not 7047 * needed (for example targetPkg already has permission to access the URI). 7048 * If you already know the uid of the target, you can supply it in 7049 * lastTargetUid else set that to -1. 7050 */ 7051 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7052 final int modeFlags, int lastTargetUid) { 7053 if (!Intent.isAccessUriMode(modeFlags)) { 7054 return -1; 7055 } 7056 7057 if (targetPkg != null) { 7058 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7059 "Checking grant " + targetPkg + " permission to " + grantUri); 7060 } 7061 7062 final IPackageManager pm = AppGlobals.getPackageManager(); 7063 7064 // If this is not a content: uri, we can't do anything with it. 7065 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7066 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7067 "Can't grant URI permission for non-content URI: " + grantUri); 7068 return -1; 7069 } 7070 7071 final String authority = grantUri.uri.getAuthority(); 7072 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7073 if (pi == null) { 7074 Slog.w(TAG, "No content provider found for permission check: " + 7075 grantUri.uri.toSafeString()); 7076 return -1; 7077 } 7078 7079 int targetUid = lastTargetUid; 7080 if (targetUid < 0 && targetPkg != null) { 7081 try { 7082 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7083 if (targetUid < 0) { 7084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7085 "Can't grant URI permission no uid for: " + targetPkg); 7086 return -1; 7087 } 7088 } catch (RemoteException ex) { 7089 return -1; 7090 } 7091 } 7092 7093 if (targetUid >= 0) { 7094 // First... does the target actually need this permission? 7095 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7096 // No need to grant the target this permission. 7097 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7098 "Target " + targetPkg + " already has full permission to " + grantUri); 7099 return -1; 7100 } 7101 } else { 7102 // First... there is no target package, so can anyone access it? 7103 boolean allowed = pi.exported; 7104 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7105 if (pi.readPermission != null) { 7106 allowed = false; 7107 } 7108 } 7109 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7110 if (pi.writePermission != null) { 7111 allowed = false; 7112 } 7113 } 7114 if (allowed) { 7115 return -1; 7116 } 7117 } 7118 7119 /* There is a special cross user grant if: 7120 * - The target is on another user. 7121 * - Apps on the current user can access the uri without any uid permissions. 7122 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7123 * grant uri permissions. 7124 */ 7125 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7126 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7127 modeFlags, false /*without considering the uid permissions*/); 7128 7129 // Second... is the provider allowing granting of URI permissions? 7130 if (!specialCrossUserGrant) { 7131 if (!pi.grantUriPermissions) { 7132 throw new SecurityException("Provider " + pi.packageName 7133 + "/" + pi.name 7134 + " does not allow granting of Uri permissions (uri " 7135 + grantUri + ")"); 7136 } 7137 if (pi.uriPermissionPatterns != null) { 7138 final int N = pi.uriPermissionPatterns.length; 7139 boolean allowed = false; 7140 for (int i=0; i<N; i++) { 7141 if (pi.uriPermissionPatterns[i] != null 7142 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7143 allowed = true; 7144 break; 7145 } 7146 } 7147 if (!allowed) { 7148 throw new SecurityException("Provider " + pi.packageName 7149 + "/" + pi.name 7150 + " does not allow granting of permission to path of Uri " 7151 + grantUri); 7152 } 7153 } 7154 } 7155 7156 // Third... does the caller itself have permission to access 7157 // this uri? 7158 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7159 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7160 // Require they hold a strong enough Uri permission 7161 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7162 throw new SecurityException("Uid " + callingUid 7163 + " does not have permission to uri " + grantUri); 7164 } 7165 } 7166 } 7167 return targetUid; 7168 } 7169 7170 /** 7171 * @param uri This uri must NOT contain an embedded userId. 7172 * @param userId The userId in which the uri is to be resolved. 7173 */ 7174 @Override 7175 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7176 final int modeFlags, int userId) { 7177 enforceNotIsolatedCaller("checkGrantUriPermission"); 7178 synchronized(this) { 7179 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7180 new GrantUri(userId, uri, false), modeFlags, -1); 7181 } 7182 } 7183 7184 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7185 final int modeFlags, UriPermissionOwner owner) { 7186 if (!Intent.isAccessUriMode(modeFlags)) { 7187 return; 7188 } 7189 7190 // So here we are: the caller has the assumed permission 7191 // to the uri, and the target doesn't. Let's now give this to 7192 // the target. 7193 7194 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7195 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7196 7197 final String authority = grantUri.uri.getAuthority(); 7198 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7199 if (pi == null) { 7200 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7201 return; 7202 } 7203 7204 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7205 grantUri.prefix = true; 7206 } 7207 final UriPermission perm = findOrCreateUriPermissionLocked( 7208 pi.packageName, targetPkg, targetUid, grantUri); 7209 perm.grantModes(modeFlags, owner); 7210 } 7211 7212 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7213 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7214 if (targetPkg == null) { 7215 throw new NullPointerException("targetPkg"); 7216 } 7217 int targetUid; 7218 final IPackageManager pm = AppGlobals.getPackageManager(); 7219 try { 7220 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7221 } catch (RemoteException ex) { 7222 return; 7223 } 7224 7225 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7226 targetUid); 7227 if (targetUid < 0) { 7228 return; 7229 } 7230 7231 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7232 owner); 7233 } 7234 7235 static class NeededUriGrants extends ArrayList<GrantUri> { 7236 final String targetPkg; 7237 final int targetUid; 7238 final int flags; 7239 7240 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7241 this.targetPkg = targetPkg; 7242 this.targetUid = targetUid; 7243 this.flags = flags; 7244 } 7245 } 7246 7247 /** 7248 * Like checkGrantUriPermissionLocked, but takes an Intent. 7249 */ 7250 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7251 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7252 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7253 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7254 + " clip=" + (intent != null ? intent.getClipData() : null) 7255 + " from " + intent + "; flags=0x" 7256 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7257 7258 if (targetPkg == null) { 7259 throw new NullPointerException("targetPkg"); 7260 } 7261 7262 if (intent == null) { 7263 return null; 7264 } 7265 Uri data = intent.getData(); 7266 ClipData clip = intent.getClipData(); 7267 if (data == null && clip == null) { 7268 return null; 7269 } 7270 // Default userId for uris in the intent (if they don't specify it themselves) 7271 int contentUserHint = intent.getContentUserHint(); 7272 if (contentUserHint == UserHandle.USER_CURRENT) { 7273 contentUserHint = UserHandle.getUserId(callingUid); 7274 } 7275 final IPackageManager pm = AppGlobals.getPackageManager(); 7276 int targetUid; 7277 if (needed != null) { 7278 targetUid = needed.targetUid; 7279 } else { 7280 try { 7281 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7282 } catch (RemoteException ex) { 7283 return null; 7284 } 7285 if (targetUid < 0) { 7286 if (DEBUG_URI_PERMISSION) { 7287 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7288 + " on user " + targetUserId); 7289 } 7290 return null; 7291 } 7292 } 7293 if (data != null) { 7294 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7295 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7296 targetUid); 7297 if (targetUid > 0) { 7298 if (needed == null) { 7299 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7300 } 7301 needed.add(grantUri); 7302 } 7303 } 7304 if (clip != null) { 7305 for (int i=0; i<clip.getItemCount(); i++) { 7306 Uri uri = clip.getItemAt(i).getUri(); 7307 if (uri != null) { 7308 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7309 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7310 targetUid); 7311 if (targetUid > 0) { 7312 if (needed == null) { 7313 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7314 } 7315 needed.add(grantUri); 7316 } 7317 } else { 7318 Intent clipIntent = clip.getItemAt(i).getIntent(); 7319 if (clipIntent != null) { 7320 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7321 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7322 if (newNeeded != null) { 7323 needed = newNeeded; 7324 } 7325 } 7326 } 7327 } 7328 } 7329 7330 return needed; 7331 } 7332 7333 /** 7334 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7335 */ 7336 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7337 UriPermissionOwner owner) { 7338 if (needed != null) { 7339 for (int i=0; i<needed.size(); i++) { 7340 GrantUri grantUri = needed.get(i); 7341 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7342 grantUri, needed.flags, owner); 7343 } 7344 } 7345 } 7346 7347 void grantUriPermissionFromIntentLocked(int callingUid, 7348 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7349 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7350 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7351 if (needed == null) { 7352 return; 7353 } 7354 7355 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7356 } 7357 7358 /** 7359 * @param uri This uri must NOT contain an embedded userId. 7360 * @param userId The userId in which the uri is to be resolved. 7361 */ 7362 @Override 7363 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7364 final int modeFlags, int userId) { 7365 enforceNotIsolatedCaller("grantUriPermission"); 7366 GrantUri grantUri = new GrantUri(userId, uri, false); 7367 synchronized(this) { 7368 final ProcessRecord r = getRecordForAppLocked(caller); 7369 if (r == null) { 7370 throw new SecurityException("Unable to find app for caller " 7371 + caller 7372 + " when granting permission to uri " + grantUri); 7373 } 7374 if (targetPkg == null) { 7375 throw new IllegalArgumentException("null target"); 7376 } 7377 if (grantUri == null) { 7378 throw new IllegalArgumentException("null uri"); 7379 } 7380 7381 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7382 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7383 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7384 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7385 7386 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7387 UserHandle.getUserId(r.uid)); 7388 } 7389 } 7390 7391 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7392 if (perm.modeFlags == 0) { 7393 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7394 perm.targetUid); 7395 if (perms != null) { 7396 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7397 "Removing " + perm.targetUid + " permission to " + perm.uri); 7398 7399 perms.remove(perm.uri); 7400 if (perms.isEmpty()) { 7401 mGrantedUriPermissions.remove(perm.targetUid); 7402 } 7403 } 7404 } 7405 } 7406 7407 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7408 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7409 7410 final IPackageManager pm = AppGlobals.getPackageManager(); 7411 final String authority = grantUri.uri.getAuthority(); 7412 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7413 if (pi == null) { 7414 Slog.w(TAG, "No content provider found for permission revoke: " 7415 + grantUri.toSafeString()); 7416 return; 7417 } 7418 7419 // Does the caller have this permission on the URI? 7420 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7421 // If they don't have direct access to the URI, then revoke any 7422 // ownerless URI permissions that have been granted to them. 7423 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7424 if (perms != null) { 7425 boolean persistChanged = false; 7426 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7427 final UriPermission perm = it.next(); 7428 if (perm.uri.sourceUserId == grantUri.sourceUserId 7429 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7430 if (DEBUG_URI_PERMISSION) 7431 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7432 " permission to " + perm.uri); 7433 persistChanged |= perm.revokeModes( 7434 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7435 if (perm.modeFlags == 0) { 7436 it.remove(); 7437 } 7438 } 7439 } 7440 if (perms.isEmpty()) { 7441 mGrantedUriPermissions.remove(callingUid); 7442 } 7443 if (persistChanged) { 7444 schedulePersistUriGrants(); 7445 } 7446 } 7447 return; 7448 } 7449 7450 boolean persistChanged = false; 7451 7452 // Go through all of the permissions and remove any that match. 7453 int N = mGrantedUriPermissions.size(); 7454 for (int i = 0; i < N; i++) { 7455 final int targetUid = mGrantedUriPermissions.keyAt(i); 7456 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7457 7458 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7459 final UriPermission perm = it.next(); 7460 if (perm.uri.sourceUserId == grantUri.sourceUserId 7461 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7462 if (DEBUG_URI_PERMISSION) 7463 Slog.v(TAG, 7464 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7465 persistChanged |= perm.revokeModes( 7466 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7467 if (perm.modeFlags == 0) { 7468 it.remove(); 7469 } 7470 } 7471 } 7472 7473 if (perms.isEmpty()) { 7474 mGrantedUriPermissions.remove(targetUid); 7475 N--; 7476 i--; 7477 } 7478 } 7479 7480 if (persistChanged) { 7481 schedulePersistUriGrants(); 7482 } 7483 } 7484 7485 /** 7486 * @param uri This uri must NOT contain an embedded userId. 7487 * @param userId The userId in which the uri is to be resolved. 7488 */ 7489 @Override 7490 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7491 int userId) { 7492 enforceNotIsolatedCaller("revokeUriPermission"); 7493 synchronized(this) { 7494 final ProcessRecord r = getRecordForAppLocked(caller); 7495 if (r == null) { 7496 throw new SecurityException("Unable to find app for caller " 7497 + caller 7498 + " when revoking permission to uri " + uri); 7499 } 7500 if (uri == null) { 7501 Slog.w(TAG, "revokeUriPermission: null uri"); 7502 return; 7503 } 7504 7505 if (!Intent.isAccessUriMode(modeFlags)) { 7506 return; 7507 } 7508 7509 final IPackageManager pm = AppGlobals.getPackageManager(); 7510 final String authority = uri.getAuthority(); 7511 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7512 if (pi == null) { 7513 Slog.w(TAG, "No content provider found for permission revoke: " 7514 + uri.toSafeString()); 7515 return; 7516 } 7517 7518 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7519 } 7520 } 7521 7522 /** 7523 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7524 * given package. 7525 * 7526 * @param packageName Package name to match, or {@code null} to apply to all 7527 * packages. 7528 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7529 * to all users. 7530 * @param persistable If persistable grants should be removed. 7531 */ 7532 private void removeUriPermissionsForPackageLocked( 7533 String packageName, int userHandle, boolean persistable) { 7534 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7535 throw new IllegalArgumentException("Must narrow by either package or user"); 7536 } 7537 7538 boolean persistChanged = false; 7539 7540 int N = mGrantedUriPermissions.size(); 7541 for (int i = 0; i < N; i++) { 7542 final int targetUid = mGrantedUriPermissions.keyAt(i); 7543 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7544 7545 // Only inspect grants matching user 7546 if (userHandle == UserHandle.USER_ALL 7547 || userHandle == UserHandle.getUserId(targetUid)) { 7548 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7549 final UriPermission perm = it.next(); 7550 7551 // Only inspect grants matching package 7552 if (packageName == null || perm.sourcePkg.equals(packageName) 7553 || perm.targetPkg.equals(packageName)) { 7554 persistChanged |= perm.revokeModes(persistable 7555 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7556 7557 // Only remove when no modes remain; any persisted grants 7558 // will keep this alive. 7559 if (perm.modeFlags == 0) { 7560 it.remove(); 7561 } 7562 } 7563 } 7564 7565 if (perms.isEmpty()) { 7566 mGrantedUriPermissions.remove(targetUid); 7567 N--; 7568 i--; 7569 } 7570 } 7571 } 7572 7573 if (persistChanged) { 7574 schedulePersistUriGrants(); 7575 } 7576 } 7577 7578 @Override 7579 public IBinder newUriPermissionOwner(String name) { 7580 enforceNotIsolatedCaller("newUriPermissionOwner"); 7581 synchronized(this) { 7582 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7583 return owner.getExternalTokenLocked(); 7584 } 7585 } 7586 7587 /** 7588 * @param uri This uri must NOT contain an embedded userId. 7589 * @param sourceUserId The userId in which the uri is to be resolved. 7590 * @param targetUserId The userId of the app that receives the grant. 7591 */ 7592 @Override 7593 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7594 final int modeFlags, int sourceUserId, int targetUserId) { 7595 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7596 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7597 synchronized(this) { 7598 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7599 if (owner == null) { 7600 throw new IllegalArgumentException("Unknown owner: " + token); 7601 } 7602 if (fromUid != Binder.getCallingUid()) { 7603 if (Binder.getCallingUid() != Process.myUid()) { 7604 // Only system code can grant URI permissions on behalf 7605 // of other users. 7606 throw new SecurityException("nice try"); 7607 } 7608 } 7609 if (targetPkg == null) { 7610 throw new IllegalArgumentException("null target"); 7611 } 7612 if (uri == null) { 7613 throw new IllegalArgumentException("null uri"); 7614 } 7615 7616 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7617 modeFlags, owner, targetUserId); 7618 } 7619 } 7620 7621 /** 7622 * @param uri This uri must NOT contain an embedded userId. 7623 * @param userId The userId in which the uri is to be resolved. 7624 */ 7625 @Override 7626 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7627 synchronized(this) { 7628 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7629 if (owner == null) { 7630 throw new IllegalArgumentException("Unknown owner: " + token); 7631 } 7632 7633 if (uri == null) { 7634 owner.removeUriPermissionsLocked(mode); 7635 } else { 7636 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7637 } 7638 } 7639 } 7640 7641 private void schedulePersistUriGrants() { 7642 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7643 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7644 10 * DateUtils.SECOND_IN_MILLIS); 7645 } 7646 } 7647 7648 private void writeGrantedUriPermissions() { 7649 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7650 7651 // Snapshot permissions so we can persist without lock 7652 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7653 synchronized (this) { 7654 final int size = mGrantedUriPermissions.size(); 7655 for (int i = 0; i < size; i++) { 7656 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7657 for (UriPermission perm : perms.values()) { 7658 if (perm.persistedModeFlags != 0) { 7659 persist.add(perm.snapshot()); 7660 } 7661 } 7662 } 7663 } 7664 7665 FileOutputStream fos = null; 7666 try { 7667 fos = mGrantFile.startWrite(); 7668 7669 XmlSerializer out = new FastXmlSerializer(); 7670 out.setOutput(fos, "utf-8"); 7671 out.startDocument(null, true); 7672 out.startTag(null, TAG_URI_GRANTS); 7673 for (UriPermission.Snapshot perm : persist) { 7674 out.startTag(null, TAG_URI_GRANT); 7675 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7676 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7677 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7678 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7679 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7680 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7681 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7682 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7683 out.endTag(null, TAG_URI_GRANT); 7684 } 7685 out.endTag(null, TAG_URI_GRANTS); 7686 out.endDocument(); 7687 7688 mGrantFile.finishWrite(fos); 7689 } catch (IOException e) { 7690 if (fos != null) { 7691 mGrantFile.failWrite(fos); 7692 } 7693 } 7694 } 7695 7696 private void readGrantedUriPermissionsLocked() { 7697 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7698 7699 final long now = System.currentTimeMillis(); 7700 7701 FileInputStream fis = null; 7702 try { 7703 fis = mGrantFile.openRead(); 7704 final XmlPullParser in = Xml.newPullParser(); 7705 in.setInput(fis, null); 7706 7707 int type; 7708 while ((type = in.next()) != END_DOCUMENT) { 7709 final String tag = in.getName(); 7710 if (type == START_TAG) { 7711 if (TAG_URI_GRANT.equals(tag)) { 7712 final int sourceUserId; 7713 final int targetUserId; 7714 final int userHandle = readIntAttribute(in, 7715 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7716 if (userHandle != UserHandle.USER_NULL) { 7717 // For backwards compatibility. 7718 sourceUserId = userHandle; 7719 targetUserId = userHandle; 7720 } else { 7721 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7722 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7723 } 7724 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7725 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7726 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7727 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7728 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7729 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7730 7731 // Sanity check that provider still belongs to source package 7732 final ProviderInfo pi = getProviderInfoLocked( 7733 uri.getAuthority(), sourceUserId); 7734 if (pi != null && sourcePkg.equals(pi.packageName)) { 7735 int targetUid = -1; 7736 try { 7737 targetUid = AppGlobals.getPackageManager() 7738 .getPackageUid(targetPkg, targetUserId); 7739 } catch (RemoteException e) { 7740 } 7741 if (targetUid != -1) { 7742 final UriPermission perm = findOrCreateUriPermissionLocked( 7743 sourcePkg, targetPkg, targetUid, 7744 new GrantUri(sourceUserId, uri, prefix)); 7745 perm.initPersistedModes(modeFlags, createdTime); 7746 } 7747 } else { 7748 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7749 + " but instead found " + pi); 7750 } 7751 } 7752 } 7753 } 7754 } catch (FileNotFoundException e) { 7755 // Missing grants is okay 7756 } catch (IOException e) { 7757 Slog.wtf(TAG, "Failed reading Uri grants", e); 7758 } catch (XmlPullParserException e) { 7759 Slog.wtf(TAG, "Failed reading Uri grants", e); 7760 } finally { 7761 IoUtils.closeQuietly(fis); 7762 } 7763 } 7764 7765 /** 7766 * @param uri This uri must NOT contain an embedded userId. 7767 * @param userId The userId in which the uri is to be resolved. 7768 */ 7769 @Override 7770 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7771 enforceNotIsolatedCaller("takePersistableUriPermission"); 7772 7773 Preconditions.checkFlagsArgument(modeFlags, 7774 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7775 7776 synchronized (this) { 7777 final int callingUid = Binder.getCallingUid(); 7778 boolean persistChanged = false; 7779 GrantUri grantUri = new GrantUri(userId, uri, false); 7780 7781 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7782 new GrantUri(userId, uri, false)); 7783 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7784 new GrantUri(userId, uri, true)); 7785 7786 final boolean exactValid = (exactPerm != null) 7787 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7788 final boolean prefixValid = (prefixPerm != null) 7789 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7790 7791 if (!(exactValid || prefixValid)) { 7792 throw new SecurityException("No persistable permission grants found for UID " 7793 + callingUid + " and Uri " + grantUri.toSafeString()); 7794 } 7795 7796 if (exactValid) { 7797 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7798 } 7799 if (prefixValid) { 7800 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7801 } 7802 7803 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7804 7805 if (persistChanged) { 7806 schedulePersistUriGrants(); 7807 } 7808 } 7809 } 7810 7811 /** 7812 * @param uri This uri must NOT contain an embedded userId. 7813 * @param userId The userId in which the uri is to be resolved. 7814 */ 7815 @Override 7816 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7817 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7818 7819 Preconditions.checkFlagsArgument(modeFlags, 7820 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7821 7822 synchronized (this) { 7823 final int callingUid = Binder.getCallingUid(); 7824 boolean persistChanged = false; 7825 7826 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7827 new GrantUri(userId, uri, false)); 7828 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7829 new GrantUri(userId, uri, true)); 7830 if (exactPerm == null && prefixPerm == null) { 7831 throw new SecurityException("No permission grants found for UID " + callingUid 7832 + " and Uri " + uri.toSafeString()); 7833 } 7834 7835 if (exactPerm != null) { 7836 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7837 removeUriPermissionIfNeededLocked(exactPerm); 7838 } 7839 if (prefixPerm != null) { 7840 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7841 removeUriPermissionIfNeededLocked(prefixPerm); 7842 } 7843 7844 if (persistChanged) { 7845 schedulePersistUriGrants(); 7846 } 7847 } 7848 } 7849 7850 /** 7851 * Prune any older {@link UriPermission} for the given UID until outstanding 7852 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7853 * 7854 * @return if any mutations occured that require persisting. 7855 */ 7856 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7857 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7858 if (perms == null) return false; 7859 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7860 7861 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7862 for (UriPermission perm : perms.values()) { 7863 if (perm.persistedModeFlags != 0) { 7864 persisted.add(perm); 7865 } 7866 } 7867 7868 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7869 if (trimCount <= 0) return false; 7870 7871 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7872 for (int i = 0; i < trimCount; i++) { 7873 final UriPermission perm = persisted.get(i); 7874 7875 if (DEBUG_URI_PERMISSION) { 7876 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7877 } 7878 7879 perm.releasePersistableModes(~0); 7880 removeUriPermissionIfNeededLocked(perm); 7881 } 7882 7883 return true; 7884 } 7885 7886 @Override 7887 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7888 String packageName, boolean incoming) { 7889 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7890 Preconditions.checkNotNull(packageName, "packageName"); 7891 7892 final int callingUid = Binder.getCallingUid(); 7893 final IPackageManager pm = AppGlobals.getPackageManager(); 7894 try { 7895 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7896 if (packageUid != callingUid) { 7897 throw new SecurityException( 7898 "Package " + packageName + " does not belong to calling UID " + callingUid); 7899 } 7900 } catch (RemoteException e) { 7901 throw new SecurityException("Failed to verify package name ownership"); 7902 } 7903 7904 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7905 synchronized (this) { 7906 if (incoming) { 7907 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7908 callingUid); 7909 if (perms == null) { 7910 Slog.w(TAG, "No permission grants found for " + packageName); 7911 } else { 7912 for (UriPermission perm : perms.values()) { 7913 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7914 result.add(perm.buildPersistedPublicApiObject()); 7915 } 7916 } 7917 } 7918 } else { 7919 final int size = mGrantedUriPermissions.size(); 7920 for (int i = 0; i < size; i++) { 7921 final ArrayMap<GrantUri, UriPermission> perms = 7922 mGrantedUriPermissions.valueAt(i); 7923 for (UriPermission perm : perms.values()) { 7924 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7925 result.add(perm.buildPersistedPublicApiObject()); 7926 } 7927 } 7928 } 7929 } 7930 } 7931 return new ParceledListSlice<android.content.UriPermission>(result); 7932 } 7933 7934 @Override 7935 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7936 synchronized (this) { 7937 ProcessRecord app = 7938 who != null ? getRecordForAppLocked(who) : null; 7939 if (app == null) return; 7940 7941 Message msg = Message.obtain(); 7942 msg.what = WAIT_FOR_DEBUGGER_MSG; 7943 msg.obj = app; 7944 msg.arg1 = waiting ? 1 : 0; 7945 mHandler.sendMessage(msg); 7946 } 7947 } 7948 7949 @Override 7950 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7951 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7952 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7953 outInfo.availMem = Process.getFreeMemory(); 7954 outInfo.totalMem = Process.getTotalMemory(); 7955 outInfo.threshold = homeAppMem; 7956 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7957 outInfo.hiddenAppThreshold = cachedAppMem; 7958 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7959 ProcessList.SERVICE_ADJ); 7960 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7961 ProcessList.VISIBLE_APP_ADJ); 7962 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7963 ProcessList.FOREGROUND_APP_ADJ); 7964 } 7965 7966 // ========================================================= 7967 // TASK MANAGEMENT 7968 // ========================================================= 7969 7970 @Override 7971 public List<IAppTask> getAppTasks(String callingPackage) { 7972 int callingUid = Binder.getCallingUid(); 7973 long ident = Binder.clearCallingIdentity(); 7974 7975 synchronized(this) { 7976 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7977 try { 7978 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7979 7980 final int N = mRecentTasks.size(); 7981 for (int i = 0; i < N; i++) { 7982 TaskRecord tr = mRecentTasks.get(i); 7983 // Skip tasks that do not match the caller. We don't need to verify 7984 // callingPackage, because we are also limiting to callingUid and know 7985 // that will limit to the correct security sandbox. 7986 if (tr.effectiveUid != callingUid) { 7987 continue; 7988 } 7989 Intent intent = tr.getBaseIntent(); 7990 if (intent == null || 7991 !callingPackage.equals(intent.getComponent().getPackageName())) { 7992 continue; 7993 } 7994 ActivityManager.RecentTaskInfo taskInfo = 7995 createRecentTaskInfoFromTaskRecord(tr); 7996 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7997 list.add(taskImpl); 7998 } 7999 } finally { 8000 Binder.restoreCallingIdentity(ident); 8001 } 8002 return list; 8003 } 8004 } 8005 8006 @Override 8007 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8008 final int callingUid = Binder.getCallingUid(); 8009 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8010 8011 synchronized(this) { 8012 if (localLOGV) Slog.v( 8013 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8014 8015 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8016 callingUid); 8017 8018 // TODO: Improve with MRU list from all ActivityStacks. 8019 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8020 } 8021 8022 return list; 8023 } 8024 8025 TaskRecord getMostRecentTask() { 8026 return mRecentTasks.get(0); 8027 } 8028 8029 /** 8030 * Creates a new RecentTaskInfo from a TaskRecord. 8031 */ 8032 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8033 // Update the task description to reflect any changes in the task stack 8034 tr.updateTaskDescription(); 8035 8036 // Compose the recent task info 8037 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8038 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8039 rti.persistentId = tr.taskId; 8040 rti.baseIntent = new Intent(tr.getBaseIntent()); 8041 rti.origActivity = tr.origActivity; 8042 rti.description = tr.lastDescription; 8043 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8044 rti.userId = tr.userId; 8045 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8046 rti.firstActiveTime = tr.firstActiveTime; 8047 rti.lastActiveTime = tr.lastActiveTime; 8048 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8049 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8050 return rti; 8051 } 8052 8053 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8054 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8055 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8056 if (!allowed) { 8057 if (checkPermission(android.Manifest.permission.GET_TASKS, 8058 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8059 // Temporary compatibility: some existing apps on the system image may 8060 // still be requesting the old permission and not switched to the new 8061 // one; if so, we'll still allow them full access. This means we need 8062 // to see if they are holding the old permission and are a system app. 8063 try { 8064 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8065 allowed = true; 8066 Slog.w(TAG, caller + ": caller " + callingUid 8067 + " is using old GET_TASKS but privileged; allowing"); 8068 } 8069 } catch (RemoteException e) { 8070 } 8071 } 8072 } 8073 if (!allowed) { 8074 Slog.w(TAG, caller + ": caller " + callingUid 8075 + " does not hold GET_TASKS; limiting output"); 8076 } 8077 return allowed; 8078 } 8079 8080 @Override 8081 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8082 final int callingUid = Binder.getCallingUid(); 8083 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8084 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8085 8086 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8087 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8088 synchronized (this) { 8089 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8090 callingUid); 8091 final boolean detailed = checkCallingPermission( 8092 android.Manifest.permission.GET_DETAILED_TASKS) 8093 == PackageManager.PERMISSION_GRANTED; 8094 8095 final int N = mRecentTasks.size(); 8096 ArrayList<ActivityManager.RecentTaskInfo> res 8097 = new ArrayList<ActivityManager.RecentTaskInfo>( 8098 maxNum < N ? maxNum : N); 8099 8100 final Set<Integer> includedUsers; 8101 if (includeProfiles) { 8102 includedUsers = getProfileIdsLocked(userId); 8103 } else { 8104 includedUsers = new HashSet<Integer>(); 8105 } 8106 includedUsers.add(Integer.valueOf(userId)); 8107 8108 for (int i=0; i<N && maxNum > 0; i++) { 8109 TaskRecord tr = mRecentTasks.get(i); 8110 // Only add calling user or related users recent tasks 8111 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8112 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8113 continue; 8114 } 8115 8116 // Return the entry if desired by the caller. We always return 8117 // the first entry, because callers always expect this to be the 8118 // foreground app. We may filter others if the caller has 8119 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8120 // we should exclude the entry. 8121 8122 if (i == 0 8123 || withExcluded 8124 || (tr.intent == null) 8125 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8126 == 0)) { 8127 if (!allowed) { 8128 // If the caller doesn't have the GET_TASKS permission, then only 8129 // allow them to see a small subset of tasks -- their own and home. 8130 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8131 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8132 continue; 8133 } 8134 } 8135 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8136 if (tr.stack != null && tr.stack.isHomeStack()) { 8137 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8138 continue; 8139 } 8140 } 8141 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8142 // Don't include auto remove tasks that are finished or finishing. 8143 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8144 + tr); 8145 continue; 8146 } 8147 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8148 && !tr.isAvailable) { 8149 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8150 continue; 8151 } 8152 8153 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8154 if (!detailed) { 8155 rti.baseIntent.replaceExtras((Bundle)null); 8156 } 8157 8158 res.add(rti); 8159 maxNum--; 8160 } 8161 } 8162 return res; 8163 } 8164 } 8165 8166 private TaskRecord recentTaskForIdLocked(int id) { 8167 final int N = mRecentTasks.size(); 8168 for (int i=0; i<N; i++) { 8169 TaskRecord tr = mRecentTasks.get(i); 8170 if (tr.taskId == id) { 8171 return tr; 8172 } 8173 } 8174 return null; 8175 } 8176 8177 @Override 8178 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8179 synchronized (this) { 8180 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8181 "getTaskThumbnail()"); 8182 TaskRecord tr = recentTaskForIdLocked(id); 8183 if (tr != null) { 8184 return tr.getTaskThumbnailLocked(); 8185 } 8186 } 8187 return null; 8188 } 8189 8190 @Override 8191 public int addAppTask(IBinder activityToken, Intent intent, 8192 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8193 final int callingUid = Binder.getCallingUid(); 8194 final long callingIdent = Binder.clearCallingIdentity(); 8195 8196 try { 8197 synchronized (this) { 8198 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8199 if (r == null) { 8200 throw new IllegalArgumentException("Activity does not exist; token=" 8201 + activityToken); 8202 } 8203 ComponentName comp = intent.getComponent(); 8204 if (comp == null) { 8205 throw new IllegalArgumentException("Intent " + intent 8206 + " must specify explicit component"); 8207 } 8208 if (thumbnail.getWidth() != mThumbnailWidth 8209 || thumbnail.getHeight() != mThumbnailHeight) { 8210 throw new IllegalArgumentException("Bad thumbnail size: got " 8211 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8212 + mThumbnailWidth + "x" + mThumbnailHeight); 8213 } 8214 if (intent.getSelector() != null) { 8215 intent.setSelector(null); 8216 } 8217 if (intent.getSourceBounds() != null) { 8218 intent.setSourceBounds(null); 8219 } 8220 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8221 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8222 // The caller has added this as an auto-remove task... that makes no 8223 // sense, so turn off auto-remove. 8224 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8225 } 8226 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8227 // Must be a new task. 8228 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8229 } 8230 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8231 mLastAddedTaskActivity = null; 8232 } 8233 ActivityInfo ainfo = mLastAddedTaskActivity; 8234 if (ainfo == null) { 8235 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8236 comp, 0, UserHandle.getUserId(callingUid)); 8237 if (ainfo.applicationInfo.uid != callingUid) { 8238 throw new SecurityException( 8239 "Can't add task for another application: target uid=" 8240 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8241 } 8242 } 8243 8244 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8245 intent, description); 8246 8247 int trimIdx = trimRecentsForTask(task, false); 8248 if (trimIdx >= 0) { 8249 // If this would have caused a trim, then we'll abort because that 8250 // means it would be added at the end of the list but then just removed. 8251 return -1; 8252 } 8253 8254 final int N = mRecentTasks.size(); 8255 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8256 final TaskRecord tr = mRecentTasks.remove(N - 1); 8257 tr.removedFromRecents(mTaskPersister); 8258 } 8259 8260 task.inRecents = true; 8261 mRecentTasks.add(task); 8262 r.task.stack.addTask(task, false, false); 8263 8264 task.setLastThumbnail(thumbnail); 8265 task.freeLastThumbnail(); 8266 8267 return task.taskId; 8268 } 8269 } finally { 8270 Binder.restoreCallingIdentity(callingIdent); 8271 } 8272 } 8273 8274 @Override 8275 public Point getAppTaskThumbnailSize() { 8276 synchronized (this) { 8277 return new Point(mThumbnailWidth, mThumbnailHeight); 8278 } 8279 } 8280 8281 @Override 8282 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8283 synchronized (this) { 8284 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8285 if (r != null) { 8286 r.setTaskDescription(td); 8287 r.task.updateTaskDescription(); 8288 } 8289 } 8290 } 8291 8292 @Override 8293 public Bitmap getTaskDescriptionIcon(String filename) { 8294 if (!FileUtils.isValidExtFilename(filename) 8295 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8296 throw new IllegalArgumentException("Bad filename: " + filename); 8297 } 8298 return mTaskPersister.getTaskDescriptionIcon(filename); 8299 } 8300 8301 @Override 8302 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8303 throws RemoteException { 8304 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8305 opts.getCustomInPlaceResId() == 0) { 8306 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8307 "with valid animation"); 8308 } 8309 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8310 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8311 opts.getCustomInPlaceResId()); 8312 mWindowManager.executeAppTransition(); 8313 } 8314 8315 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8316 mRecentTasks.remove(tr); 8317 tr.removedFromRecents(mTaskPersister); 8318 ComponentName component = tr.getBaseIntent().getComponent(); 8319 if (component == null) { 8320 Slog.w(TAG, "No component for base intent of task: " + tr); 8321 return; 8322 } 8323 8324 if (!killProcess) { 8325 return; 8326 } 8327 8328 // Determine if the process(es) for this task should be killed. 8329 final String pkg = component.getPackageName(); 8330 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8331 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8332 for (int i = 0; i < pmap.size(); i++) { 8333 8334 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8335 for (int j = 0; j < uids.size(); j++) { 8336 ProcessRecord proc = uids.valueAt(j); 8337 if (proc.userId != tr.userId) { 8338 // Don't kill process for a different user. 8339 continue; 8340 } 8341 if (proc == mHomeProcess) { 8342 // Don't kill the home process along with tasks from the same package. 8343 continue; 8344 } 8345 if (!proc.pkgList.containsKey(pkg)) { 8346 // Don't kill process that is not associated with this task. 8347 continue; 8348 } 8349 8350 for (int k = 0; k < proc.activities.size(); k++) { 8351 TaskRecord otherTask = proc.activities.get(k).task; 8352 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8353 // Don't kill process(es) that has an activity in a different task that is 8354 // also in recents. 8355 return; 8356 } 8357 } 8358 8359 // Add process to kill list. 8360 procsToKill.add(proc); 8361 } 8362 } 8363 8364 // Find any running services associated with this app and stop if needed. 8365 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8366 8367 // Kill the running processes. 8368 for (int i = 0; i < procsToKill.size(); i++) { 8369 ProcessRecord pr = procsToKill.get(i); 8370 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8371 pr.kill("remove task", true); 8372 } else { 8373 pr.waitingToKill = "remove task"; 8374 } 8375 } 8376 } 8377 8378 /** 8379 * Removes the task with the specified task id. 8380 * 8381 * @param taskId Identifier of the task to be removed. 8382 * @param killProcess Kill any process associated with the task if possible. 8383 * @return Returns true if the given task was found and removed. 8384 */ 8385 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8386 TaskRecord tr = recentTaskForIdLocked(taskId); 8387 if (tr != null) { 8388 tr.removeTaskActivitiesLocked(); 8389 cleanUpRemovedTaskLocked(tr, killProcess); 8390 if (tr.isPersistable) { 8391 notifyTaskPersisterLocked(null, true); 8392 } 8393 return true; 8394 } 8395 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8396 return false; 8397 } 8398 8399 @Override 8400 public boolean removeTask(int taskId) { 8401 synchronized (this) { 8402 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8403 "removeTask()"); 8404 long ident = Binder.clearCallingIdentity(); 8405 try { 8406 return removeTaskByIdLocked(taskId, true); 8407 } finally { 8408 Binder.restoreCallingIdentity(ident); 8409 } 8410 } 8411 } 8412 8413 /** 8414 * TODO: Add mController hook 8415 */ 8416 @Override 8417 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8418 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8419 "moveTaskToFront()"); 8420 8421 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8422 synchronized(this) { 8423 moveTaskToFrontLocked(taskId, flags, options); 8424 } 8425 } 8426 8427 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8428 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8429 Binder.getCallingUid(), -1, -1, "Task to front")) { 8430 ActivityOptions.abort(options); 8431 return; 8432 } 8433 final long origId = Binder.clearCallingIdentity(); 8434 try { 8435 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8436 if (task == null) { 8437 return; 8438 } 8439 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8440 mStackSupervisor.showLockTaskToast(); 8441 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8442 return; 8443 } 8444 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8445 if (prev != null && prev.isRecentsActivity()) { 8446 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8447 } 8448 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8449 } finally { 8450 Binder.restoreCallingIdentity(origId); 8451 } 8452 ActivityOptions.abort(options); 8453 } 8454 8455 @Override 8456 public void moveTaskToBack(int taskId) { 8457 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8458 "moveTaskToBack()"); 8459 8460 synchronized(this) { 8461 TaskRecord tr = recentTaskForIdLocked(taskId); 8462 if (tr != null) { 8463 if (tr == mStackSupervisor.mLockTaskModeTask) { 8464 mStackSupervisor.showLockTaskToast(); 8465 return; 8466 } 8467 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8468 ActivityStack stack = tr.stack; 8469 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8470 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8471 Binder.getCallingUid(), -1, -1, "Task to back")) { 8472 return; 8473 } 8474 } 8475 final long origId = Binder.clearCallingIdentity(); 8476 try { 8477 stack.moveTaskToBackLocked(taskId, null); 8478 } finally { 8479 Binder.restoreCallingIdentity(origId); 8480 } 8481 } 8482 } 8483 } 8484 8485 /** 8486 * Moves an activity, and all of the other activities within the same task, to the bottom 8487 * of the history stack. The activity's order within the task is unchanged. 8488 * 8489 * @param token A reference to the activity we wish to move 8490 * @param nonRoot If false then this only works if the activity is the root 8491 * of a task; if true it will work for any activity in a task. 8492 * @return Returns true if the move completed, false if not. 8493 */ 8494 @Override 8495 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8496 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8497 synchronized(this) { 8498 final long origId = Binder.clearCallingIdentity(); 8499 try { 8500 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8501 if (taskId >= 0) { 8502 if ((mStackSupervisor.mLockTaskModeTask != null) 8503 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8504 mStackSupervisor.showLockTaskToast(); 8505 return false; 8506 } 8507 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8508 } 8509 } finally { 8510 Binder.restoreCallingIdentity(origId); 8511 } 8512 } 8513 return false; 8514 } 8515 8516 @Override 8517 public void moveTaskBackwards(int task) { 8518 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8519 "moveTaskBackwards()"); 8520 8521 synchronized(this) { 8522 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8523 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8524 return; 8525 } 8526 final long origId = Binder.clearCallingIdentity(); 8527 moveTaskBackwardsLocked(task); 8528 Binder.restoreCallingIdentity(origId); 8529 } 8530 } 8531 8532 private final void moveTaskBackwardsLocked(int task) { 8533 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8534 } 8535 8536 @Override 8537 public IBinder getHomeActivityToken() throws RemoteException { 8538 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8539 "getHomeActivityToken()"); 8540 synchronized (this) { 8541 return mStackSupervisor.getHomeActivityToken(); 8542 } 8543 } 8544 8545 @Override 8546 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8547 IActivityContainerCallback callback) throws RemoteException { 8548 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8549 "createActivityContainer()"); 8550 synchronized (this) { 8551 if (parentActivityToken == null) { 8552 throw new IllegalArgumentException("parent token must not be null"); 8553 } 8554 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8555 if (r == null) { 8556 return null; 8557 } 8558 if (callback == null) { 8559 throw new IllegalArgumentException("callback must not be null"); 8560 } 8561 return mStackSupervisor.createActivityContainer(r, callback); 8562 } 8563 } 8564 8565 @Override 8566 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8567 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8568 "deleteActivityContainer()"); 8569 synchronized (this) { 8570 mStackSupervisor.deleteActivityContainer(container); 8571 } 8572 } 8573 8574 @Override 8575 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8576 throws RemoteException { 8577 synchronized (this) { 8578 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8579 if (stack != null) { 8580 return stack.mActivityContainer; 8581 } 8582 return null; 8583 } 8584 } 8585 8586 @Override 8587 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8588 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8589 "moveTaskToStack()"); 8590 if (stackId == HOME_STACK_ID) { 8591 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8592 new RuntimeException("here").fillInStackTrace()); 8593 } 8594 synchronized (this) { 8595 long ident = Binder.clearCallingIdentity(); 8596 try { 8597 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8598 + stackId + " toTop=" + toTop); 8599 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8600 } finally { 8601 Binder.restoreCallingIdentity(ident); 8602 } 8603 } 8604 } 8605 8606 @Override 8607 public void resizeStack(int stackBoxId, Rect bounds) { 8608 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8609 "resizeStackBox()"); 8610 long ident = Binder.clearCallingIdentity(); 8611 try { 8612 mWindowManager.resizeStack(stackBoxId, bounds); 8613 } finally { 8614 Binder.restoreCallingIdentity(ident); 8615 } 8616 } 8617 8618 @Override 8619 public List<StackInfo> getAllStackInfos() { 8620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8621 "getAllStackInfos()"); 8622 long ident = Binder.clearCallingIdentity(); 8623 try { 8624 synchronized (this) { 8625 return mStackSupervisor.getAllStackInfosLocked(); 8626 } 8627 } finally { 8628 Binder.restoreCallingIdentity(ident); 8629 } 8630 } 8631 8632 @Override 8633 public StackInfo getStackInfo(int stackId) { 8634 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8635 "getStackInfo()"); 8636 long ident = Binder.clearCallingIdentity(); 8637 try { 8638 synchronized (this) { 8639 return mStackSupervisor.getStackInfoLocked(stackId); 8640 } 8641 } finally { 8642 Binder.restoreCallingIdentity(ident); 8643 } 8644 } 8645 8646 @Override 8647 public boolean isInHomeStack(int taskId) { 8648 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8649 "getStackInfo()"); 8650 long ident = Binder.clearCallingIdentity(); 8651 try { 8652 synchronized (this) { 8653 TaskRecord tr = recentTaskForIdLocked(taskId); 8654 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8655 } 8656 } finally { 8657 Binder.restoreCallingIdentity(ident); 8658 } 8659 } 8660 8661 @Override 8662 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8663 synchronized(this) { 8664 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8665 } 8666 } 8667 8668 private boolean isLockTaskAuthorized(String pkg) { 8669 final DevicePolicyManager dpm = (DevicePolicyManager) 8670 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8671 try { 8672 int uid = mContext.getPackageManager().getPackageUid(pkg, 8673 Binder.getCallingUserHandle().getIdentifier()); 8674 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8675 } catch (NameNotFoundException e) { 8676 return false; 8677 } 8678 } 8679 8680 void startLockTaskMode(TaskRecord task) { 8681 final String pkg; 8682 synchronized (this) { 8683 pkg = task.intent.getComponent().getPackageName(); 8684 } 8685 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8686 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8687 final TaskRecord taskRecord = task; 8688 mHandler.post(new Runnable() { 8689 @Override 8690 public void run() { 8691 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8692 } 8693 }); 8694 return; 8695 } 8696 long ident = Binder.clearCallingIdentity(); 8697 try { 8698 synchronized (this) { 8699 // Since we lost lock on task, make sure it is still there. 8700 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8701 if (task != null) { 8702 if (!isSystemInitiated 8703 && ((mStackSupervisor.getFocusedStack() == null) 8704 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8705 throw new IllegalArgumentException("Invalid task, not in foreground"); 8706 } 8707 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8708 } 8709 } 8710 } finally { 8711 Binder.restoreCallingIdentity(ident); 8712 } 8713 } 8714 8715 @Override 8716 public void startLockTaskMode(int taskId) { 8717 final TaskRecord task; 8718 long ident = Binder.clearCallingIdentity(); 8719 try { 8720 synchronized (this) { 8721 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8722 } 8723 } finally { 8724 Binder.restoreCallingIdentity(ident); 8725 } 8726 if (task != null) { 8727 startLockTaskMode(task); 8728 } 8729 } 8730 8731 @Override 8732 public void startLockTaskMode(IBinder token) { 8733 final TaskRecord task; 8734 long ident = Binder.clearCallingIdentity(); 8735 try { 8736 synchronized (this) { 8737 final ActivityRecord r = ActivityRecord.forToken(token); 8738 if (r == null) { 8739 return; 8740 } 8741 task = r.task; 8742 } 8743 } finally { 8744 Binder.restoreCallingIdentity(ident); 8745 } 8746 if (task != null) { 8747 startLockTaskMode(task); 8748 } 8749 } 8750 8751 @Override 8752 public void startLockTaskModeOnCurrent() throws RemoteException { 8753 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8754 "startLockTaskModeOnCurrent"); 8755 ActivityRecord r = null; 8756 synchronized (this) { 8757 r = mStackSupervisor.topRunningActivityLocked(); 8758 } 8759 startLockTaskMode(r.task); 8760 } 8761 8762 @Override 8763 public void stopLockTaskMode() { 8764 // Verify that the user matches the package of the intent for the TaskRecord 8765 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8766 // and stopLockTaskMode. 8767 final int callingUid = Binder.getCallingUid(); 8768 if (callingUid != Process.SYSTEM_UID) { 8769 try { 8770 String pkg = 8771 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8772 int uid = mContext.getPackageManager().getPackageUid(pkg, 8773 Binder.getCallingUserHandle().getIdentifier()); 8774 if (uid != callingUid) { 8775 throw new SecurityException("Invalid uid, expected " + uid); 8776 } 8777 } catch (NameNotFoundException e) { 8778 Log.d(TAG, "stopLockTaskMode " + e); 8779 return; 8780 } 8781 } 8782 long ident = Binder.clearCallingIdentity(); 8783 try { 8784 Log.d(TAG, "stopLockTaskMode"); 8785 // Stop lock task 8786 synchronized (this) { 8787 mStackSupervisor.setLockTaskModeLocked(null, false); 8788 } 8789 } finally { 8790 Binder.restoreCallingIdentity(ident); 8791 } 8792 } 8793 8794 @Override 8795 public void stopLockTaskModeOnCurrent() throws RemoteException { 8796 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8797 "stopLockTaskModeOnCurrent"); 8798 long ident = Binder.clearCallingIdentity(); 8799 try { 8800 stopLockTaskMode(); 8801 } finally { 8802 Binder.restoreCallingIdentity(ident); 8803 } 8804 } 8805 8806 @Override 8807 public boolean isInLockTaskMode() { 8808 synchronized (this) { 8809 return mStackSupervisor.isInLockTaskMode(); 8810 } 8811 } 8812 8813 // ========================================================= 8814 // CONTENT PROVIDERS 8815 // ========================================================= 8816 8817 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8818 List<ProviderInfo> providers = null; 8819 try { 8820 providers = AppGlobals.getPackageManager(). 8821 queryContentProviders(app.processName, app.uid, 8822 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8823 } catch (RemoteException ex) { 8824 } 8825 if (DEBUG_MU) 8826 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8827 int userId = app.userId; 8828 if (providers != null) { 8829 int N = providers.size(); 8830 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8831 for (int i=0; i<N; i++) { 8832 ProviderInfo cpi = 8833 (ProviderInfo)providers.get(i); 8834 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8835 cpi.name, cpi.flags); 8836 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8837 // This is a singleton provider, but a user besides the 8838 // default user is asking to initialize a process it runs 8839 // in... well, no, it doesn't actually run in this process, 8840 // it runs in the process of the default user. Get rid of it. 8841 providers.remove(i); 8842 N--; 8843 i--; 8844 continue; 8845 } 8846 8847 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8848 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8849 if (cpr == null) { 8850 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8851 mProviderMap.putProviderByClass(comp, cpr); 8852 } 8853 if (DEBUG_MU) 8854 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8855 app.pubProviders.put(cpi.name, cpr); 8856 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8857 // Don't add this if it is a platform component that is marked 8858 // to run in multiple processes, because this is actually 8859 // part of the framework so doesn't make sense to track as a 8860 // separate apk in the process. 8861 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8862 mProcessStats); 8863 } 8864 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8865 } 8866 } 8867 return providers; 8868 } 8869 8870 /** 8871 * Check if {@link ProcessRecord} has a possible chance at accessing the 8872 * given {@link ProviderInfo}. Final permission checking is always done 8873 * in {@link ContentProvider}. 8874 */ 8875 private final String checkContentProviderPermissionLocked( 8876 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8877 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8878 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8879 boolean checkedGrants = false; 8880 if (checkUser) { 8881 // Looking for cross-user grants before enforcing the typical cross-users permissions 8882 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8883 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8884 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8885 return null; 8886 } 8887 checkedGrants = true; 8888 } 8889 userId = handleIncomingUser(callingPid, callingUid, userId, 8890 false, ALLOW_NON_FULL, 8891 "checkContentProviderPermissionLocked " + cpi.authority, null); 8892 if (userId != tmpTargetUserId) { 8893 // When we actually went to determine the final targer user ID, this ended 8894 // up different than our initial check for the authority. This is because 8895 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8896 // SELF. So we need to re-check the grants again. 8897 checkedGrants = false; 8898 } 8899 } 8900 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8901 cpi.applicationInfo.uid, cpi.exported) 8902 == PackageManager.PERMISSION_GRANTED) { 8903 return null; 8904 } 8905 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8906 cpi.applicationInfo.uid, cpi.exported) 8907 == PackageManager.PERMISSION_GRANTED) { 8908 return null; 8909 } 8910 8911 PathPermission[] pps = cpi.pathPermissions; 8912 if (pps != null) { 8913 int i = pps.length; 8914 while (i > 0) { 8915 i--; 8916 PathPermission pp = pps[i]; 8917 String pprperm = pp.getReadPermission(); 8918 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8919 cpi.applicationInfo.uid, cpi.exported) 8920 == PackageManager.PERMISSION_GRANTED) { 8921 return null; 8922 } 8923 String ppwperm = pp.getWritePermission(); 8924 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8925 cpi.applicationInfo.uid, cpi.exported) 8926 == PackageManager.PERMISSION_GRANTED) { 8927 return null; 8928 } 8929 } 8930 } 8931 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8932 return null; 8933 } 8934 8935 String msg; 8936 if (!cpi.exported) { 8937 msg = "Permission Denial: opening provider " + cpi.name 8938 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8939 + ", uid=" + callingUid + ") that is not exported from uid " 8940 + cpi.applicationInfo.uid; 8941 } else { 8942 msg = "Permission Denial: opening provider " + cpi.name 8943 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8944 + ", uid=" + callingUid + ") requires " 8945 + cpi.readPermission + " or " + cpi.writePermission; 8946 } 8947 Slog.w(TAG, msg); 8948 return msg; 8949 } 8950 8951 /** 8952 * Returns if the ContentProvider has granted a uri to callingUid 8953 */ 8954 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8955 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8956 if (perms != null) { 8957 for (int i=perms.size()-1; i>=0; i--) { 8958 GrantUri grantUri = perms.keyAt(i); 8959 if (grantUri.sourceUserId == userId || !checkUser) { 8960 if (matchesProvider(grantUri.uri, cpi)) { 8961 return true; 8962 } 8963 } 8964 } 8965 } 8966 return false; 8967 } 8968 8969 /** 8970 * Returns true if the uri authority is one of the authorities specified in the provider. 8971 */ 8972 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8973 String uriAuth = uri.getAuthority(); 8974 String cpiAuth = cpi.authority; 8975 if (cpiAuth.indexOf(';') == -1) { 8976 return cpiAuth.equals(uriAuth); 8977 } 8978 String[] cpiAuths = cpiAuth.split(";"); 8979 int length = cpiAuths.length; 8980 for (int i = 0; i < length; i++) { 8981 if (cpiAuths[i].equals(uriAuth)) return true; 8982 } 8983 return false; 8984 } 8985 8986 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8987 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8988 if (r != null) { 8989 for (int i=0; i<r.conProviders.size(); i++) { 8990 ContentProviderConnection conn = r.conProviders.get(i); 8991 if (conn.provider == cpr) { 8992 if (DEBUG_PROVIDER) Slog.v(TAG, 8993 "Adding provider requested by " 8994 + r.processName + " from process " 8995 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8996 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8997 if (stable) { 8998 conn.stableCount++; 8999 conn.numStableIncs++; 9000 } else { 9001 conn.unstableCount++; 9002 conn.numUnstableIncs++; 9003 } 9004 return conn; 9005 } 9006 } 9007 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9008 if (stable) { 9009 conn.stableCount = 1; 9010 conn.numStableIncs = 1; 9011 } else { 9012 conn.unstableCount = 1; 9013 conn.numUnstableIncs = 1; 9014 } 9015 cpr.connections.add(conn); 9016 r.conProviders.add(conn); 9017 return conn; 9018 } 9019 cpr.addExternalProcessHandleLocked(externalProcessToken); 9020 return null; 9021 } 9022 9023 boolean decProviderCountLocked(ContentProviderConnection conn, 9024 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9025 if (conn != null) { 9026 cpr = conn.provider; 9027 if (DEBUG_PROVIDER) Slog.v(TAG, 9028 "Removing provider requested by " 9029 + conn.client.processName + " from process " 9030 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9031 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9032 if (stable) { 9033 conn.stableCount--; 9034 } else { 9035 conn.unstableCount--; 9036 } 9037 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9038 cpr.connections.remove(conn); 9039 conn.client.conProviders.remove(conn); 9040 return true; 9041 } 9042 return false; 9043 } 9044 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9045 return false; 9046 } 9047 9048 private void checkTime(long startTime, String where) { 9049 long now = SystemClock.elapsedRealtime(); 9050 if ((now-startTime) > 1000) { 9051 // If we are taking more than a second, log about it. 9052 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9053 } 9054 } 9055 9056 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9057 String name, IBinder token, boolean stable, int userId) { 9058 ContentProviderRecord cpr; 9059 ContentProviderConnection conn = null; 9060 ProviderInfo cpi = null; 9061 9062 synchronized(this) { 9063 long startTime = SystemClock.elapsedRealtime(); 9064 9065 ProcessRecord r = null; 9066 if (caller != null) { 9067 r = getRecordForAppLocked(caller); 9068 if (r == null) { 9069 throw new SecurityException( 9070 "Unable to find app for caller " + caller 9071 + " (pid=" + Binder.getCallingPid() 9072 + ") when getting content provider " + name); 9073 } 9074 } 9075 9076 boolean checkCrossUser = true; 9077 9078 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9079 9080 // First check if this content provider has been published... 9081 cpr = mProviderMap.getProviderByName(name, userId); 9082 // If that didn't work, check if it exists for user 0 and then 9083 // verify that it's a singleton provider before using it. 9084 if (cpr == null && userId != UserHandle.USER_OWNER) { 9085 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9086 if (cpr != null) { 9087 cpi = cpr.info; 9088 if (isSingleton(cpi.processName, cpi.applicationInfo, 9089 cpi.name, cpi.flags) 9090 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9091 userId = UserHandle.USER_OWNER; 9092 checkCrossUser = false; 9093 } else { 9094 cpr = null; 9095 cpi = null; 9096 } 9097 } 9098 } 9099 9100 boolean providerRunning = cpr != null; 9101 if (providerRunning) { 9102 cpi = cpr.info; 9103 String msg; 9104 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9105 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9106 != null) { 9107 throw new SecurityException(msg); 9108 } 9109 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9110 9111 if (r != null && cpr.canRunHere(r)) { 9112 // This provider has been published or is in the process 9113 // of being published... but it is also allowed to run 9114 // in the caller's process, so don't make a connection 9115 // and just let the caller instantiate its own instance. 9116 ContentProviderHolder holder = cpr.newHolder(null); 9117 // don't give caller the provider object, it needs 9118 // to make its own. 9119 holder.provider = null; 9120 return holder; 9121 } 9122 9123 final long origId = Binder.clearCallingIdentity(); 9124 9125 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9126 9127 // In this case the provider instance already exists, so we can 9128 // return it right away. 9129 conn = incProviderCountLocked(r, cpr, token, stable); 9130 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9131 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9132 // If this is a perceptible app accessing the provider, 9133 // make sure to count it as being accessed and thus 9134 // back up on the LRU list. This is good because 9135 // content providers are often expensive to start. 9136 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9137 updateLruProcessLocked(cpr.proc, false, null); 9138 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9139 } 9140 } 9141 9142 if (cpr.proc != null) { 9143 if (false) { 9144 if (cpr.name.flattenToShortString().equals( 9145 "com.android.providers.calendar/.CalendarProvider2")) { 9146 Slog.v(TAG, "****************** KILLING " 9147 + cpr.name.flattenToShortString()); 9148 Process.killProcess(cpr.proc.pid); 9149 } 9150 } 9151 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9152 boolean success = updateOomAdjLocked(cpr.proc); 9153 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9154 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9155 // NOTE: there is still a race here where a signal could be 9156 // pending on the process even though we managed to update its 9157 // adj level. Not sure what to do about this, but at least 9158 // the race is now smaller. 9159 if (!success) { 9160 // Uh oh... it looks like the provider's process 9161 // has been killed on us. We need to wait for a new 9162 // process to be started, and make sure its death 9163 // doesn't kill our process. 9164 Slog.i(TAG, 9165 "Existing provider " + cpr.name.flattenToShortString() 9166 + " is crashing; detaching " + r); 9167 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9168 checkTime(startTime, "getContentProviderImpl: before appDied"); 9169 appDiedLocked(cpr.proc); 9170 checkTime(startTime, "getContentProviderImpl: after appDied"); 9171 if (!lastRef) { 9172 // This wasn't the last ref our process had on 9173 // the provider... we have now been killed, bail. 9174 return null; 9175 } 9176 providerRunning = false; 9177 conn = null; 9178 } 9179 } 9180 9181 Binder.restoreCallingIdentity(origId); 9182 } 9183 9184 boolean singleton; 9185 if (!providerRunning) { 9186 try { 9187 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9188 cpi = AppGlobals.getPackageManager(). 9189 resolveContentProvider(name, 9190 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9191 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9192 } catch (RemoteException ex) { 9193 } 9194 if (cpi == null) { 9195 return null; 9196 } 9197 // If the provider is a singleton AND 9198 // (it's a call within the same user || the provider is a 9199 // privileged app) 9200 // Then allow connecting to the singleton provider 9201 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9202 cpi.name, cpi.flags) 9203 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9204 if (singleton) { 9205 userId = UserHandle.USER_OWNER; 9206 } 9207 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9208 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9209 9210 String msg; 9211 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9212 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9213 != null) { 9214 throw new SecurityException(msg); 9215 } 9216 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9217 9218 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9219 && !cpi.processName.equals("system")) { 9220 // If this content provider does not run in the system 9221 // process, and the system is not yet ready to run other 9222 // processes, then fail fast instead of hanging. 9223 throw new IllegalArgumentException( 9224 "Attempt to launch content provider before system ready"); 9225 } 9226 9227 // Make sure that the user who owns this provider is started. If not, 9228 // we don't want to allow it to run. 9229 if (mStartedUsers.get(userId) == null) { 9230 Slog.w(TAG, "Unable to launch app " 9231 + cpi.applicationInfo.packageName + "/" 9232 + cpi.applicationInfo.uid + " for provider " 9233 + name + ": user " + userId + " is stopped"); 9234 return null; 9235 } 9236 9237 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9238 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9239 cpr = mProviderMap.getProviderByClass(comp, userId); 9240 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9241 final boolean firstClass = cpr == null; 9242 if (firstClass) { 9243 final long ident = Binder.clearCallingIdentity(); 9244 try { 9245 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9246 ApplicationInfo ai = 9247 AppGlobals.getPackageManager(). 9248 getApplicationInfo( 9249 cpi.applicationInfo.packageName, 9250 STOCK_PM_FLAGS, userId); 9251 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9252 if (ai == null) { 9253 Slog.w(TAG, "No package info for content provider " 9254 + cpi.name); 9255 return null; 9256 } 9257 ai = getAppInfoForUser(ai, userId); 9258 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9259 } catch (RemoteException ex) { 9260 // pm is in same process, this will never happen. 9261 } finally { 9262 Binder.restoreCallingIdentity(ident); 9263 } 9264 } 9265 9266 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9267 9268 if (r != null && cpr.canRunHere(r)) { 9269 // If this is a multiprocess provider, then just return its 9270 // info and allow the caller to instantiate it. Only do 9271 // this if the provider is the same user as the caller's 9272 // process, or can run as root (so can be in any process). 9273 return cpr.newHolder(null); 9274 } 9275 9276 if (DEBUG_PROVIDER) { 9277 RuntimeException e = new RuntimeException("here"); 9278 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9279 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9280 } 9281 9282 // This is single process, and our app is now connecting to it. 9283 // See if we are already in the process of launching this 9284 // provider. 9285 final int N = mLaunchingProviders.size(); 9286 int i; 9287 for (i=0; i<N; i++) { 9288 if (mLaunchingProviders.get(i) == cpr) { 9289 break; 9290 } 9291 } 9292 9293 // If the provider is not already being launched, then get it 9294 // started. 9295 if (i >= N) { 9296 final long origId = Binder.clearCallingIdentity(); 9297 9298 try { 9299 // Content provider is now in use, its package can't be stopped. 9300 try { 9301 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9302 AppGlobals.getPackageManager().setPackageStoppedState( 9303 cpr.appInfo.packageName, false, userId); 9304 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9305 } catch (RemoteException e) { 9306 } catch (IllegalArgumentException e) { 9307 Slog.w(TAG, "Failed trying to unstop package " 9308 + cpr.appInfo.packageName + ": " + e); 9309 } 9310 9311 // Use existing process if already started 9312 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9313 ProcessRecord proc = getProcessRecordLocked( 9314 cpi.processName, cpr.appInfo.uid, false); 9315 if (proc != null && proc.thread != null) { 9316 if (DEBUG_PROVIDER) { 9317 Slog.d(TAG, "Installing in existing process " + proc); 9318 } 9319 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9320 proc.pubProviders.put(cpi.name, cpr); 9321 try { 9322 proc.thread.scheduleInstallProvider(cpi); 9323 } catch (RemoteException e) { 9324 } 9325 } else { 9326 checkTime(startTime, "getContentProviderImpl: before start process"); 9327 proc = startProcessLocked(cpi.processName, 9328 cpr.appInfo, false, 0, "content provider", 9329 new ComponentName(cpi.applicationInfo.packageName, 9330 cpi.name), false, false, false); 9331 checkTime(startTime, "getContentProviderImpl: after start process"); 9332 if (proc == null) { 9333 Slog.w(TAG, "Unable to launch app " 9334 + cpi.applicationInfo.packageName + "/" 9335 + cpi.applicationInfo.uid + " for provider " 9336 + name + ": process is bad"); 9337 return null; 9338 } 9339 } 9340 cpr.launchingApp = proc; 9341 mLaunchingProviders.add(cpr); 9342 } finally { 9343 Binder.restoreCallingIdentity(origId); 9344 } 9345 } 9346 9347 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9348 9349 // Make sure the provider is published (the same provider class 9350 // may be published under multiple names). 9351 if (firstClass) { 9352 mProviderMap.putProviderByClass(comp, cpr); 9353 } 9354 9355 mProviderMap.putProviderByName(name, cpr); 9356 conn = incProviderCountLocked(r, cpr, token, stable); 9357 if (conn != null) { 9358 conn.waiting = true; 9359 } 9360 } 9361 checkTime(startTime, "getContentProviderImpl: done!"); 9362 } 9363 9364 // Wait for the provider to be published... 9365 synchronized (cpr) { 9366 while (cpr.provider == null) { 9367 if (cpr.launchingApp == null) { 9368 Slog.w(TAG, "Unable to launch app " 9369 + cpi.applicationInfo.packageName + "/" 9370 + cpi.applicationInfo.uid + " for provider " 9371 + name + ": launching app became null"); 9372 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9373 UserHandle.getUserId(cpi.applicationInfo.uid), 9374 cpi.applicationInfo.packageName, 9375 cpi.applicationInfo.uid, name); 9376 return null; 9377 } 9378 try { 9379 if (DEBUG_MU) { 9380 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9381 + cpr.launchingApp); 9382 } 9383 if (conn != null) { 9384 conn.waiting = true; 9385 } 9386 cpr.wait(); 9387 } catch (InterruptedException ex) { 9388 } finally { 9389 if (conn != null) { 9390 conn.waiting = false; 9391 } 9392 } 9393 } 9394 } 9395 return cpr != null ? cpr.newHolder(conn) : null; 9396 } 9397 9398 @Override 9399 public final ContentProviderHolder getContentProvider( 9400 IApplicationThread caller, String name, int userId, boolean stable) { 9401 enforceNotIsolatedCaller("getContentProvider"); 9402 if (caller == null) { 9403 String msg = "null IApplicationThread when getting content provider " 9404 + name; 9405 Slog.w(TAG, msg); 9406 throw new SecurityException(msg); 9407 } 9408 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9409 // with cross-user grant. 9410 return getContentProviderImpl(caller, name, null, stable, userId); 9411 } 9412 9413 public ContentProviderHolder getContentProviderExternal( 9414 String name, int userId, IBinder token) { 9415 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9416 "Do not have permission in call getContentProviderExternal()"); 9417 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9418 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9419 return getContentProviderExternalUnchecked(name, token, userId); 9420 } 9421 9422 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9423 IBinder token, int userId) { 9424 return getContentProviderImpl(null, name, token, true, userId); 9425 } 9426 9427 /** 9428 * Drop a content provider from a ProcessRecord's bookkeeping 9429 */ 9430 public void removeContentProvider(IBinder connection, boolean stable) { 9431 enforceNotIsolatedCaller("removeContentProvider"); 9432 long ident = Binder.clearCallingIdentity(); 9433 try { 9434 synchronized (this) { 9435 ContentProviderConnection conn; 9436 try { 9437 conn = (ContentProviderConnection)connection; 9438 } catch (ClassCastException e) { 9439 String msg ="removeContentProvider: " + connection 9440 + " not a ContentProviderConnection"; 9441 Slog.w(TAG, msg); 9442 throw new IllegalArgumentException(msg); 9443 } 9444 if (conn == null) { 9445 throw new NullPointerException("connection is null"); 9446 } 9447 if (decProviderCountLocked(conn, null, null, stable)) { 9448 updateOomAdjLocked(); 9449 } 9450 } 9451 } finally { 9452 Binder.restoreCallingIdentity(ident); 9453 } 9454 } 9455 9456 public void removeContentProviderExternal(String name, IBinder token) { 9457 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9458 "Do not have permission in call removeContentProviderExternal()"); 9459 int userId = UserHandle.getCallingUserId(); 9460 long ident = Binder.clearCallingIdentity(); 9461 try { 9462 removeContentProviderExternalUnchecked(name, token, userId); 9463 } finally { 9464 Binder.restoreCallingIdentity(ident); 9465 } 9466 } 9467 9468 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9469 synchronized (this) { 9470 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9471 if(cpr == null) { 9472 //remove from mProvidersByClass 9473 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9474 return; 9475 } 9476 9477 //update content provider record entry info 9478 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9479 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9480 if (localCpr.hasExternalProcessHandles()) { 9481 if (localCpr.removeExternalProcessHandleLocked(token)) { 9482 updateOomAdjLocked(); 9483 } else { 9484 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9485 + " with no external reference for token: " 9486 + token + "."); 9487 } 9488 } else { 9489 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9490 + " with no external references."); 9491 } 9492 } 9493 } 9494 9495 public final void publishContentProviders(IApplicationThread caller, 9496 List<ContentProviderHolder> providers) { 9497 if (providers == null) { 9498 return; 9499 } 9500 9501 enforceNotIsolatedCaller("publishContentProviders"); 9502 synchronized (this) { 9503 final ProcessRecord r = getRecordForAppLocked(caller); 9504 if (DEBUG_MU) 9505 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9506 if (r == null) { 9507 throw new SecurityException( 9508 "Unable to find app for caller " + caller 9509 + " (pid=" + Binder.getCallingPid() 9510 + ") when publishing content providers"); 9511 } 9512 9513 final long origId = Binder.clearCallingIdentity(); 9514 9515 final int N = providers.size(); 9516 for (int i=0; i<N; i++) { 9517 ContentProviderHolder src = providers.get(i); 9518 if (src == null || src.info == null || src.provider == null) { 9519 continue; 9520 } 9521 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9522 if (DEBUG_MU) 9523 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9524 if (dst != null) { 9525 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9526 mProviderMap.putProviderByClass(comp, dst); 9527 String names[] = dst.info.authority.split(";"); 9528 for (int j = 0; j < names.length; j++) { 9529 mProviderMap.putProviderByName(names[j], dst); 9530 } 9531 9532 int NL = mLaunchingProviders.size(); 9533 int j; 9534 for (j=0; j<NL; j++) { 9535 if (mLaunchingProviders.get(j) == dst) { 9536 mLaunchingProviders.remove(j); 9537 j--; 9538 NL--; 9539 } 9540 } 9541 synchronized (dst) { 9542 dst.provider = src.provider; 9543 dst.proc = r; 9544 dst.notifyAll(); 9545 } 9546 updateOomAdjLocked(r); 9547 } 9548 } 9549 9550 Binder.restoreCallingIdentity(origId); 9551 } 9552 } 9553 9554 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9555 ContentProviderConnection conn; 9556 try { 9557 conn = (ContentProviderConnection)connection; 9558 } catch (ClassCastException e) { 9559 String msg ="refContentProvider: " + connection 9560 + " not a ContentProviderConnection"; 9561 Slog.w(TAG, msg); 9562 throw new IllegalArgumentException(msg); 9563 } 9564 if (conn == null) { 9565 throw new NullPointerException("connection is null"); 9566 } 9567 9568 synchronized (this) { 9569 if (stable > 0) { 9570 conn.numStableIncs += stable; 9571 } 9572 stable = conn.stableCount + stable; 9573 if (stable < 0) { 9574 throw new IllegalStateException("stableCount < 0: " + stable); 9575 } 9576 9577 if (unstable > 0) { 9578 conn.numUnstableIncs += unstable; 9579 } 9580 unstable = conn.unstableCount + unstable; 9581 if (unstable < 0) { 9582 throw new IllegalStateException("unstableCount < 0: " + unstable); 9583 } 9584 9585 if ((stable+unstable) <= 0) { 9586 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9587 + stable + " unstable=" + unstable); 9588 } 9589 conn.stableCount = stable; 9590 conn.unstableCount = unstable; 9591 return !conn.dead; 9592 } 9593 } 9594 9595 public void unstableProviderDied(IBinder connection) { 9596 ContentProviderConnection conn; 9597 try { 9598 conn = (ContentProviderConnection)connection; 9599 } catch (ClassCastException e) { 9600 String msg ="refContentProvider: " + connection 9601 + " not a ContentProviderConnection"; 9602 Slog.w(TAG, msg); 9603 throw new IllegalArgumentException(msg); 9604 } 9605 if (conn == null) { 9606 throw new NullPointerException("connection is null"); 9607 } 9608 9609 // Safely retrieve the content provider associated with the connection. 9610 IContentProvider provider; 9611 synchronized (this) { 9612 provider = conn.provider.provider; 9613 } 9614 9615 if (provider == null) { 9616 // Um, yeah, we're way ahead of you. 9617 return; 9618 } 9619 9620 // Make sure the caller is being honest with us. 9621 if (provider.asBinder().pingBinder()) { 9622 // Er, no, still looks good to us. 9623 synchronized (this) { 9624 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9625 + " says " + conn + " died, but we don't agree"); 9626 return; 9627 } 9628 } 9629 9630 // Well look at that! It's dead! 9631 synchronized (this) { 9632 if (conn.provider.provider != provider) { 9633 // But something changed... good enough. 9634 return; 9635 } 9636 9637 ProcessRecord proc = conn.provider.proc; 9638 if (proc == null || proc.thread == null) { 9639 // Seems like the process is already cleaned up. 9640 return; 9641 } 9642 9643 // As far as we're concerned, this is just like receiving a 9644 // death notification... just a bit prematurely. 9645 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9646 + ") early provider death"); 9647 final long ident = Binder.clearCallingIdentity(); 9648 try { 9649 appDiedLocked(proc); 9650 } finally { 9651 Binder.restoreCallingIdentity(ident); 9652 } 9653 } 9654 } 9655 9656 @Override 9657 public void appNotRespondingViaProvider(IBinder connection) { 9658 enforceCallingPermission( 9659 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9660 9661 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9662 if (conn == null) { 9663 Slog.w(TAG, "ContentProviderConnection is null"); 9664 return; 9665 } 9666 9667 final ProcessRecord host = conn.provider.proc; 9668 if (host == null) { 9669 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9670 return; 9671 } 9672 9673 final long token = Binder.clearCallingIdentity(); 9674 try { 9675 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9676 } finally { 9677 Binder.restoreCallingIdentity(token); 9678 } 9679 } 9680 9681 public final void installSystemProviders() { 9682 List<ProviderInfo> providers; 9683 synchronized (this) { 9684 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9685 providers = generateApplicationProvidersLocked(app); 9686 if (providers != null) { 9687 for (int i=providers.size()-1; i>=0; i--) { 9688 ProviderInfo pi = (ProviderInfo)providers.get(i); 9689 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9690 Slog.w(TAG, "Not installing system proc provider " + pi.name 9691 + ": not system .apk"); 9692 providers.remove(i); 9693 } 9694 } 9695 } 9696 } 9697 if (providers != null) { 9698 mSystemThread.installSystemProviders(providers); 9699 } 9700 9701 mCoreSettingsObserver = new CoreSettingsObserver(this); 9702 9703 //mUsageStatsService.monitorPackages(); 9704 } 9705 9706 /** 9707 * Allows apps to retrieve the MIME type of a URI. 9708 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9709 * users, then it does not need permission to access the ContentProvider. 9710 * Either, it needs cross-user uri grants. 9711 * 9712 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9713 * 9714 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9715 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9716 */ 9717 public String getProviderMimeType(Uri uri, int userId) { 9718 enforceNotIsolatedCaller("getProviderMimeType"); 9719 final String name = uri.getAuthority(); 9720 int callingUid = Binder.getCallingUid(); 9721 int callingPid = Binder.getCallingPid(); 9722 long ident = 0; 9723 boolean clearedIdentity = false; 9724 userId = unsafeConvertIncomingUser(userId); 9725 if (canClearIdentity(callingPid, callingUid, userId)) { 9726 clearedIdentity = true; 9727 ident = Binder.clearCallingIdentity(); 9728 } 9729 ContentProviderHolder holder = null; 9730 try { 9731 holder = getContentProviderExternalUnchecked(name, null, userId); 9732 if (holder != null) { 9733 return holder.provider.getType(uri); 9734 } 9735 } catch (RemoteException e) { 9736 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9737 return null; 9738 } finally { 9739 // We need to clear the identity to call removeContentProviderExternalUnchecked 9740 if (!clearedIdentity) { 9741 ident = Binder.clearCallingIdentity(); 9742 } 9743 try { 9744 if (holder != null) { 9745 removeContentProviderExternalUnchecked(name, null, userId); 9746 } 9747 } finally { 9748 Binder.restoreCallingIdentity(ident); 9749 } 9750 } 9751 9752 return null; 9753 } 9754 9755 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9756 if (UserHandle.getUserId(callingUid) == userId) { 9757 return true; 9758 } 9759 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9760 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9761 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9762 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9763 return true; 9764 } 9765 return false; 9766 } 9767 9768 // ========================================================= 9769 // GLOBAL MANAGEMENT 9770 // ========================================================= 9771 9772 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9773 boolean isolated, int isolatedUid) { 9774 String proc = customProcess != null ? customProcess : info.processName; 9775 BatteryStatsImpl.Uid.Proc ps = null; 9776 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9777 int uid = info.uid; 9778 if (isolated) { 9779 if (isolatedUid == 0) { 9780 int userId = UserHandle.getUserId(uid); 9781 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9782 while (true) { 9783 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9784 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9785 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9786 } 9787 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9788 mNextIsolatedProcessUid++; 9789 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9790 // No process for this uid, use it. 9791 break; 9792 } 9793 stepsLeft--; 9794 if (stepsLeft <= 0) { 9795 return null; 9796 } 9797 } 9798 } else { 9799 // Special case for startIsolatedProcess (internal only), where 9800 // the uid of the isolated process is specified by the caller. 9801 uid = isolatedUid; 9802 } 9803 } 9804 return new ProcessRecord(stats, info, proc, uid); 9805 } 9806 9807 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9808 String abiOverride) { 9809 ProcessRecord app; 9810 if (!isolated) { 9811 app = getProcessRecordLocked(info.processName, info.uid, true); 9812 } else { 9813 app = null; 9814 } 9815 9816 if (app == null) { 9817 app = newProcessRecordLocked(info, null, isolated, 0); 9818 mProcessNames.put(info.processName, app.uid, app); 9819 if (isolated) { 9820 mIsolatedProcesses.put(app.uid, app); 9821 } 9822 updateLruProcessLocked(app, false, null); 9823 updateOomAdjLocked(); 9824 } 9825 9826 // This package really, really can not be stopped. 9827 try { 9828 AppGlobals.getPackageManager().setPackageStoppedState( 9829 info.packageName, false, UserHandle.getUserId(app.uid)); 9830 } catch (RemoteException e) { 9831 } catch (IllegalArgumentException e) { 9832 Slog.w(TAG, "Failed trying to unstop package " 9833 + info.packageName + ": " + e); 9834 } 9835 9836 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9837 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9838 app.persistent = true; 9839 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9840 } 9841 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9842 mPersistentStartingProcesses.add(app); 9843 startProcessLocked(app, "added application", app.processName, abiOverride, 9844 null /* entryPoint */, null /* entryPointArgs */); 9845 } 9846 9847 return app; 9848 } 9849 9850 public void unhandledBack() { 9851 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9852 "unhandledBack()"); 9853 9854 synchronized(this) { 9855 final long origId = Binder.clearCallingIdentity(); 9856 try { 9857 getFocusedStack().unhandledBackLocked(); 9858 } finally { 9859 Binder.restoreCallingIdentity(origId); 9860 } 9861 } 9862 } 9863 9864 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9865 enforceNotIsolatedCaller("openContentUri"); 9866 final int userId = UserHandle.getCallingUserId(); 9867 String name = uri.getAuthority(); 9868 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9869 ParcelFileDescriptor pfd = null; 9870 if (cph != null) { 9871 // We record the binder invoker's uid in thread-local storage before 9872 // going to the content provider to open the file. Later, in the code 9873 // that handles all permissions checks, we look for this uid and use 9874 // that rather than the Activity Manager's own uid. The effect is that 9875 // we do the check against the caller's permissions even though it looks 9876 // to the content provider like the Activity Manager itself is making 9877 // the request. 9878 sCallerIdentity.set(new Identity( 9879 Binder.getCallingPid(), Binder.getCallingUid())); 9880 try { 9881 pfd = cph.provider.openFile(null, uri, "r", null); 9882 } catch (FileNotFoundException e) { 9883 // do nothing; pfd will be returned null 9884 } finally { 9885 // Ensure that whatever happens, we clean up the identity state 9886 sCallerIdentity.remove(); 9887 } 9888 9889 // We've got the fd now, so we're done with the provider. 9890 removeContentProviderExternalUnchecked(name, null, userId); 9891 } else { 9892 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9893 } 9894 return pfd; 9895 } 9896 9897 // Actually is sleeping or shutting down or whatever else in the future 9898 // is an inactive state. 9899 public boolean isSleepingOrShuttingDown() { 9900 return isSleeping() || mShuttingDown; 9901 } 9902 9903 public boolean isSleeping() { 9904 return mSleeping; 9905 } 9906 9907 void goingToSleep() { 9908 synchronized(this) { 9909 mWentToSleep = true; 9910 goToSleepIfNeededLocked(); 9911 } 9912 } 9913 9914 void finishRunningVoiceLocked() { 9915 if (mRunningVoice) { 9916 mRunningVoice = false; 9917 goToSleepIfNeededLocked(); 9918 } 9919 } 9920 9921 void goToSleepIfNeededLocked() { 9922 if (mWentToSleep && !mRunningVoice) { 9923 if (!mSleeping) { 9924 mSleeping = true; 9925 mStackSupervisor.goingToSleepLocked(); 9926 9927 // Initialize the wake times of all processes. 9928 checkExcessivePowerUsageLocked(false); 9929 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9930 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9931 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9932 } 9933 } 9934 } 9935 9936 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9937 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9938 // Never persist the home stack. 9939 return; 9940 } 9941 mTaskPersister.wakeup(task, flush); 9942 } 9943 9944 @Override 9945 public boolean shutdown(int timeout) { 9946 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9947 != PackageManager.PERMISSION_GRANTED) { 9948 throw new SecurityException("Requires permission " 9949 + android.Manifest.permission.SHUTDOWN); 9950 } 9951 9952 boolean timedout = false; 9953 9954 synchronized(this) { 9955 mShuttingDown = true; 9956 updateEventDispatchingLocked(); 9957 timedout = mStackSupervisor.shutdownLocked(timeout); 9958 } 9959 9960 mAppOpsService.shutdown(); 9961 if (mUsageStatsService != null) { 9962 mUsageStatsService.prepareShutdown(); 9963 } 9964 mBatteryStatsService.shutdown(); 9965 synchronized (this) { 9966 mProcessStats.shutdownLocked(); 9967 } 9968 notifyTaskPersisterLocked(null, true); 9969 9970 return timedout; 9971 } 9972 9973 public final void activitySlept(IBinder token) { 9974 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9975 9976 final long origId = Binder.clearCallingIdentity(); 9977 9978 synchronized (this) { 9979 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9980 if (r != null) { 9981 mStackSupervisor.activitySleptLocked(r); 9982 } 9983 } 9984 9985 Binder.restoreCallingIdentity(origId); 9986 } 9987 9988 private String lockScreenShownToString() { 9989 switch (mLockScreenShown) { 9990 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 9991 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 9992 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 9993 default: return "Unknown=" + mLockScreenShown; 9994 } 9995 } 9996 9997 void logLockScreen(String msg) { 9998 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9999 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10000 mWentToSleep + " mSleeping=" + mSleeping); 10001 } 10002 10003 void comeOutOfSleepIfNeededLocked() { 10004 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10005 if (mSleeping) { 10006 mSleeping = false; 10007 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10008 } 10009 } 10010 } 10011 10012 void wakingUp() { 10013 synchronized(this) { 10014 mWentToSleep = false; 10015 comeOutOfSleepIfNeededLocked(); 10016 } 10017 } 10018 10019 void startRunningVoiceLocked() { 10020 if (!mRunningVoice) { 10021 mRunningVoice = true; 10022 comeOutOfSleepIfNeededLocked(); 10023 } 10024 } 10025 10026 private void updateEventDispatchingLocked() { 10027 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10028 } 10029 10030 public void setLockScreenShown(boolean shown) { 10031 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10032 != PackageManager.PERMISSION_GRANTED) { 10033 throw new SecurityException("Requires permission " 10034 + android.Manifest.permission.DEVICE_POWER); 10035 } 10036 10037 synchronized(this) { 10038 long ident = Binder.clearCallingIdentity(); 10039 try { 10040 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10041 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10042 comeOutOfSleepIfNeededLocked(); 10043 } finally { 10044 Binder.restoreCallingIdentity(ident); 10045 } 10046 } 10047 } 10048 10049 @Override 10050 public void stopAppSwitches() { 10051 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10052 != PackageManager.PERMISSION_GRANTED) { 10053 throw new SecurityException("Requires permission " 10054 + android.Manifest.permission.STOP_APP_SWITCHES); 10055 } 10056 10057 synchronized(this) { 10058 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10059 + APP_SWITCH_DELAY_TIME; 10060 mDidAppSwitch = false; 10061 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10062 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10063 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10064 } 10065 } 10066 10067 public void resumeAppSwitches() { 10068 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10069 != PackageManager.PERMISSION_GRANTED) { 10070 throw new SecurityException("Requires permission " 10071 + android.Manifest.permission.STOP_APP_SWITCHES); 10072 } 10073 10074 synchronized(this) { 10075 // Note that we don't execute any pending app switches... we will 10076 // let those wait until either the timeout, or the next start 10077 // activity request. 10078 mAppSwitchesAllowedTime = 0; 10079 } 10080 } 10081 10082 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10083 int callingPid, int callingUid, String name) { 10084 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10085 return true; 10086 } 10087 10088 int perm = checkComponentPermission( 10089 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10090 sourceUid, -1, true); 10091 if (perm == PackageManager.PERMISSION_GRANTED) { 10092 return true; 10093 } 10094 10095 // If the actual IPC caller is different from the logical source, then 10096 // also see if they are allowed to control app switches. 10097 if (callingUid != -1 && callingUid != sourceUid) { 10098 perm = checkComponentPermission( 10099 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10100 callingUid, -1, true); 10101 if (perm == PackageManager.PERMISSION_GRANTED) { 10102 return true; 10103 } 10104 } 10105 10106 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10107 return false; 10108 } 10109 10110 public void setDebugApp(String packageName, boolean waitForDebugger, 10111 boolean persistent) { 10112 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10113 "setDebugApp()"); 10114 10115 long ident = Binder.clearCallingIdentity(); 10116 try { 10117 // Note that this is not really thread safe if there are multiple 10118 // callers into it at the same time, but that's not a situation we 10119 // care about. 10120 if (persistent) { 10121 final ContentResolver resolver = mContext.getContentResolver(); 10122 Settings.Global.putString( 10123 resolver, Settings.Global.DEBUG_APP, 10124 packageName); 10125 Settings.Global.putInt( 10126 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10127 waitForDebugger ? 1 : 0); 10128 } 10129 10130 synchronized (this) { 10131 if (!persistent) { 10132 mOrigDebugApp = mDebugApp; 10133 mOrigWaitForDebugger = mWaitForDebugger; 10134 } 10135 mDebugApp = packageName; 10136 mWaitForDebugger = waitForDebugger; 10137 mDebugTransient = !persistent; 10138 if (packageName != null) { 10139 forceStopPackageLocked(packageName, -1, false, false, true, true, 10140 false, UserHandle.USER_ALL, "set debug app"); 10141 } 10142 } 10143 } finally { 10144 Binder.restoreCallingIdentity(ident); 10145 } 10146 } 10147 10148 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10149 synchronized (this) { 10150 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10151 if (!isDebuggable) { 10152 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10153 throw new SecurityException("Process not debuggable: " + app.packageName); 10154 } 10155 } 10156 10157 mOpenGlTraceApp = processName; 10158 } 10159 } 10160 10161 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10162 synchronized (this) { 10163 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10164 if (!isDebuggable) { 10165 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10166 throw new SecurityException("Process not debuggable: " + app.packageName); 10167 } 10168 } 10169 mProfileApp = processName; 10170 mProfileFile = profilerInfo.profileFile; 10171 if (mProfileFd != null) { 10172 try { 10173 mProfileFd.close(); 10174 } catch (IOException e) { 10175 } 10176 mProfileFd = null; 10177 } 10178 mProfileFd = profilerInfo.profileFd; 10179 mSamplingInterval = profilerInfo.samplingInterval; 10180 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10181 mProfileType = 0; 10182 } 10183 } 10184 10185 @Override 10186 public void setAlwaysFinish(boolean enabled) { 10187 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10188 "setAlwaysFinish()"); 10189 10190 Settings.Global.putInt( 10191 mContext.getContentResolver(), 10192 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10193 10194 synchronized (this) { 10195 mAlwaysFinishActivities = enabled; 10196 } 10197 } 10198 10199 @Override 10200 public void setActivityController(IActivityController controller) { 10201 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10202 "setActivityController()"); 10203 synchronized (this) { 10204 mController = controller; 10205 Watchdog.getInstance().setActivityController(controller); 10206 } 10207 } 10208 10209 @Override 10210 public void setUserIsMonkey(boolean userIsMonkey) { 10211 synchronized (this) { 10212 synchronized (mPidsSelfLocked) { 10213 final int callingPid = Binder.getCallingPid(); 10214 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10215 if (precessRecord == null) { 10216 throw new SecurityException("Unknown process: " + callingPid); 10217 } 10218 if (precessRecord.instrumentationUiAutomationConnection == null) { 10219 throw new SecurityException("Only an instrumentation process " 10220 + "with a UiAutomation can call setUserIsMonkey"); 10221 } 10222 } 10223 mUserIsMonkey = userIsMonkey; 10224 } 10225 } 10226 10227 @Override 10228 public boolean isUserAMonkey() { 10229 synchronized (this) { 10230 // If there is a controller also implies the user is a monkey. 10231 return (mUserIsMonkey || mController != null); 10232 } 10233 } 10234 10235 public void requestBugReport() { 10236 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10237 SystemProperties.set("ctl.start", "bugreport"); 10238 } 10239 10240 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10241 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10242 } 10243 10244 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10245 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10246 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10247 } 10248 return KEY_DISPATCHING_TIMEOUT; 10249 } 10250 10251 @Override 10252 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10253 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10254 != PackageManager.PERMISSION_GRANTED) { 10255 throw new SecurityException("Requires permission " 10256 + android.Manifest.permission.FILTER_EVENTS); 10257 } 10258 ProcessRecord proc; 10259 long timeout; 10260 synchronized (this) { 10261 synchronized (mPidsSelfLocked) { 10262 proc = mPidsSelfLocked.get(pid); 10263 } 10264 timeout = getInputDispatchingTimeoutLocked(proc); 10265 } 10266 10267 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10268 return -1; 10269 } 10270 10271 return timeout; 10272 } 10273 10274 /** 10275 * Handle input dispatching timeouts. 10276 * Returns whether input dispatching should be aborted or not. 10277 */ 10278 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10279 final ActivityRecord activity, final ActivityRecord parent, 10280 final boolean aboveSystem, String reason) { 10281 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10282 != PackageManager.PERMISSION_GRANTED) { 10283 throw new SecurityException("Requires permission " 10284 + android.Manifest.permission.FILTER_EVENTS); 10285 } 10286 10287 final String annotation; 10288 if (reason == null) { 10289 annotation = "Input dispatching timed out"; 10290 } else { 10291 annotation = "Input dispatching timed out (" + reason + ")"; 10292 } 10293 10294 if (proc != null) { 10295 synchronized (this) { 10296 if (proc.debugging) { 10297 return false; 10298 } 10299 10300 if (mDidDexOpt) { 10301 // Give more time since we were dexopting. 10302 mDidDexOpt = false; 10303 return false; 10304 } 10305 10306 if (proc.instrumentationClass != null) { 10307 Bundle info = new Bundle(); 10308 info.putString("shortMsg", "keyDispatchingTimedOut"); 10309 info.putString("longMsg", annotation); 10310 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10311 return true; 10312 } 10313 } 10314 mHandler.post(new Runnable() { 10315 @Override 10316 public void run() { 10317 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10318 } 10319 }); 10320 } 10321 10322 return true; 10323 } 10324 10325 public Bundle getAssistContextExtras(int requestType) { 10326 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10327 UserHandle.getCallingUserId()); 10328 if (pae == null) { 10329 return null; 10330 } 10331 synchronized (pae) { 10332 while (!pae.haveResult) { 10333 try { 10334 pae.wait(); 10335 } catch (InterruptedException e) { 10336 } 10337 } 10338 if (pae.result != null) { 10339 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10340 } 10341 } 10342 synchronized (this) { 10343 mPendingAssistExtras.remove(pae); 10344 mHandler.removeCallbacks(pae); 10345 } 10346 return pae.extras; 10347 } 10348 10349 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10350 int userHandle) { 10351 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10352 "getAssistContextExtras()"); 10353 PendingAssistExtras pae; 10354 Bundle extras = new Bundle(); 10355 synchronized (this) { 10356 ActivityRecord activity = getFocusedStack().mResumedActivity; 10357 if (activity == null) { 10358 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10359 return null; 10360 } 10361 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10362 if (activity.app == null || activity.app.thread == null) { 10363 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10364 return null; 10365 } 10366 if (activity.app.pid == Binder.getCallingPid()) { 10367 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10368 return null; 10369 } 10370 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10371 try { 10372 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10373 requestType); 10374 mPendingAssistExtras.add(pae); 10375 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10376 } catch (RemoteException e) { 10377 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10378 return null; 10379 } 10380 return pae; 10381 } 10382 } 10383 10384 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10385 PendingAssistExtras pae = (PendingAssistExtras)token; 10386 synchronized (pae) { 10387 pae.result = extras; 10388 pae.haveResult = true; 10389 pae.notifyAll(); 10390 if (pae.intent == null) { 10391 // Caller is just waiting for the result. 10392 return; 10393 } 10394 } 10395 10396 // We are now ready to launch the assist activity. 10397 synchronized (this) { 10398 boolean exists = mPendingAssistExtras.remove(pae); 10399 mHandler.removeCallbacks(pae); 10400 if (!exists) { 10401 // Timed out. 10402 return; 10403 } 10404 } 10405 pae.intent.replaceExtras(extras); 10406 if (pae.hint != null) { 10407 pae.intent.putExtra(pae.hint, true); 10408 } 10409 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10410 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10411 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10412 closeSystemDialogs("assist"); 10413 try { 10414 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10415 } catch (ActivityNotFoundException e) { 10416 Slog.w(TAG, "No activity to handle assist action.", e); 10417 } 10418 } 10419 10420 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10421 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10422 } 10423 10424 public void registerProcessObserver(IProcessObserver observer) { 10425 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10426 "registerProcessObserver()"); 10427 synchronized (this) { 10428 mProcessObservers.register(observer); 10429 } 10430 } 10431 10432 @Override 10433 public void unregisterProcessObserver(IProcessObserver observer) { 10434 synchronized (this) { 10435 mProcessObservers.unregister(observer); 10436 } 10437 } 10438 10439 @Override 10440 public boolean convertFromTranslucent(IBinder token) { 10441 final long origId = Binder.clearCallingIdentity(); 10442 try { 10443 synchronized (this) { 10444 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10445 if (r == null) { 10446 return false; 10447 } 10448 final boolean translucentChanged = r.changeWindowTranslucency(true); 10449 if (translucentChanged) { 10450 r.task.stack.releaseBackgroundResources(); 10451 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10452 } 10453 mWindowManager.setAppFullscreen(token, true); 10454 return translucentChanged; 10455 } 10456 } finally { 10457 Binder.restoreCallingIdentity(origId); 10458 } 10459 } 10460 10461 @Override 10462 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10463 final long origId = Binder.clearCallingIdentity(); 10464 try { 10465 synchronized (this) { 10466 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10467 if (r == null) { 10468 return false; 10469 } 10470 int index = r.task.mActivities.lastIndexOf(r); 10471 if (index > 0) { 10472 ActivityRecord under = r.task.mActivities.get(index - 1); 10473 under.returningOptions = options; 10474 } 10475 final boolean translucentChanged = r.changeWindowTranslucency(false); 10476 if (translucentChanged) { 10477 r.task.stack.convertToTranslucent(r); 10478 } 10479 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10480 mWindowManager.setAppFullscreen(token, false); 10481 return translucentChanged; 10482 } 10483 } finally { 10484 Binder.restoreCallingIdentity(origId); 10485 } 10486 } 10487 10488 @Override 10489 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10490 final long origId = Binder.clearCallingIdentity(); 10491 try { 10492 synchronized (this) { 10493 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10494 if (r != null) { 10495 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10496 } 10497 } 10498 return false; 10499 } finally { 10500 Binder.restoreCallingIdentity(origId); 10501 } 10502 } 10503 10504 @Override 10505 public boolean isBackgroundVisibleBehind(IBinder token) { 10506 final long origId = Binder.clearCallingIdentity(); 10507 try { 10508 synchronized (this) { 10509 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10510 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10511 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10512 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10513 return visible; 10514 } 10515 } finally { 10516 Binder.restoreCallingIdentity(origId); 10517 } 10518 } 10519 10520 @Override 10521 public ActivityOptions getActivityOptions(IBinder token) { 10522 final long origId = Binder.clearCallingIdentity(); 10523 try { 10524 synchronized (this) { 10525 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10526 if (r != null) { 10527 final ActivityOptions activityOptions = r.pendingOptions; 10528 r.pendingOptions = null; 10529 return activityOptions; 10530 } 10531 return null; 10532 } 10533 } finally { 10534 Binder.restoreCallingIdentity(origId); 10535 } 10536 } 10537 10538 @Override 10539 public void setImmersive(IBinder token, boolean immersive) { 10540 synchronized(this) { 10541 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10542 if (r == null) { 10543 throw new IllegalArgumentException(); 10544 } 10545 r.immersive = immersive; 10546 10547 // update associated state if we're frontmost 10548 if (r == mFocusedActivity) { 10549 if (DEBUG_IMMERSIVE) { 10550 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10551 } 10552 applyUpdateLockStateLocked(r); 10553 } 10554 } 10555 } 10556 10557 @Override 10558 public boolean isImmersive(IBinder token) { 10559 synchronized (this) { 10560 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10561 if (r == null) { 10562 throw new IllegalArgumentException(); 10563 } 10564 return r.immersive; 10565 } 10566 } 10567 10568 public boolean isTopActivityImmersive() { 10569 enforceNotIsolatedCaller("startActivity"); 10570 synchronized (this) { 10571 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10572 return (r != null) ? r.immersive : false; 10573 } 10574 } 10575 10576 @Override 10577 public boolean isTopOfTask(IBinder token) { 10578 synchronized (this) { 10579 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10580 if (r == null) { 10581 throw new IllegalArgumentException(); 10582 } 10583 return r.task.getTopActivity() == r; 10584 } 10585 } 10586 10587 public final void enterSafeMode() { 10588 synchronized(this) { 10589 // It only makes sense to do this before the system is ready 10590 // and started launching other packages. 10591 if (!mSystemReady) { 10592 try { 10593 AppGlobals.getPackageManager().enterSafeMode(); 10594 } catch (RemoteException e) { 10595 } 10596 } 10597 10598 mSafeMode = true; 10599 } 10600 } 10601 10602 public final void showSafeModeOverlay() { 10603 View v = LayoutInflater.from(mContext).inflate( 10604 com.android.internal.R.layout.safe_mode, null); 10605 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10606 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10607 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10608 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10609 lp.gravity = Gravity.BOTTOM | Gravity.START; 10610 lp.format = v.getBackground().getOpacity(); 10611 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10612 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10613 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10614 ((WindowManager)mContext.getSystemService( 10615 Context.WINDOW_SERVICE)).addView(v, lp); 10616 } 10617 10618 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10619 if (!(sender instanceof PendingIntentRecord)) { 10620 return; 10621 } 10622 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10623 synchronized (stats) { 10624 if (mBatteryStatsService.isOnBattery()) { 10625 mBatteryStatsService.enforceCallingPermission(); 10626 PendingIntentRecord rec = (PendingIntentRecord)sender; 10627 int MY_UID = Binder.getCallingUid(); 10628 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10629 BatteryStatsImpl.Uid.Pkg pkg = 10630 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10631 sourcePkg != null ? sourcePkg : rec.key.packageName); 10632 pkg.incWakeupsLocked(); 10633 } 10634 } 10635 } 10636 10637 public boolean killPids(int[] pids, String pReason, boolean secure) { 10638 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10639 throw new SecurityException("killPids only available to the system"); 10640 } 10641 String reason = (pReason == null) ? "Unknown" : pReason; 10642 // XXX Note: don't acquire main activity lock here, because the window 10643 // manager calls in with its locks held. 10644 10645 boolean killed = false; 10646 synchronized (mPidsSelfLocked) { 10647 int[] types = new int[pids.length]; 10648 int worstType = 0; 10649 for (int i=0; i<pids.length; i++) { 10650 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10651 if (proc != null) { 10652 int type = proc.setAdj; 10653 types[i] = type; 10654 if (type > worstType) { 10655 worstType = type; 10656 } 10657 } 10658 } 10659 10660 // If the worst oom_adj is somewhere in the cached proc LRU range, 10661 // then constrain it so we will kill all cached procs. 10662 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10663 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10664 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10665 } 10666 10667 // If this is not a secure call, don't let it kill processes that 10668 // are important. 10669 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10670 worstType = ProcessList.SERVICE_ADJ; 10671 } 10672 10673 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10674 for (int i=0; i<pids.length; i++) { 10675 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10676 if (proc == null) { 10677 continue; 10678 } 10679 int adj = proc.setAdj; 10680 if (adj >= worstType && !proc.killedByAm) { 10681 proc.kill(reason, true); 10682 killed = true; 10683 } 10684 } 10685 } 10686 return killed; 10687 } 10688 10689 @Override 10690 public void killUid(int uid, String reason) { 10691 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10692 throw new SecurityException("killUid only available to the system"); 10693 } 10694 synchronized (this) { 10695 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10696 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10697 reason != null ? reason : "kill uid"); 10698 } 10699 } 10700 10701 @Override 10702 public boolean killProcessesBelowForeground(String reason) { 10703 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10704 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10705 } 10706 10707 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10708 } 10709 10710 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10711 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10712 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10713 } 10714 10715 boolean killed = false; 10716 synchronized (mPidsSelfLocked) { 10717 final int size = mPidsSelfLocked.size(); 10718 for (int i = 0; i < size; i++) { 10719 final int pid = mPidsSelfLocked.keyAt(i); 10720 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10721 if (proc == null) continue; 10722 10723 final int adj = proc.setAdj; 10724 if (adj > belowAdj && !proc.killedByAm) { 10725 proc.kill(reason, true); 10726 killed = true; 10727 } 10728 } 10729 } 10730 return killed; 10731 } 10732 10733 @Override 10734 public void hang(final IBinder who, boolean allowRestart) { 10735 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10736 != PackageManager.PERMISSION_GRANTED) { 10737 throw new SecurityException("Requires permission " 10738 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10739 } 10740 10741 final IBinder.DeathRecipient death = new DeathRecipient() { 10742 @Override 10743 public void binderDied() { 10744 synchronized (this) { 10745 notifyAll(); 10746 } 10747 } 10748 }; 10749 10750 try { 10751 who.linkToDeath(death, 0); 10752 } catch (RemoteException e) { 10753 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10754 return; 10755 } 10756 10757 synchronized (this) { 10758 Watchdog.getInstance().setAllowRestart(allowRestart); 10759 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10760 synchronized (death) { 10761 while (who.isBinderAlive()) { 10762 try { 10763 death.wait(); 10764 } catch (InterruptedException e) { 10765 } 10766 } 10767 } 10768 Watchdog.getInstance().setAllowRestart(true); 10769 } 10770 } 10771 10772 @Override 10773 public void restart() { 10774 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10775 != PackageManager.PERMISSION_GRANTED) { 10776 throw new SecurityException("Requires permission " 10777 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10778 } 10779 10780 Log.i(TAG, "Sending shutdown broadcast..."); 10781 10782 BroadcastReceiver br = new BroadcastReceiver() { 10783 @Override public void onReceive(Context context, Intent intent) { 10784 // Now the broadcast is done, finish up the low-level shutdown. 10785 Log.i(TAG, "Shutting down activity manager..."); 10786 shutdown(10000); 10787 Log.i(TAG, "Shutdown complete, restarting!"); 10788 Process.killProcess(Process.myPid()); 10789 System.exit(10); 10790 } 10791 }; 10792 10793 // First send the high-level shut down broadcast. 10794 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10795 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10796 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10797 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10798 mContext.sendOrderedBroadcastAsUser(intent, 10799 UserHandle.ALL, null, br, mHandler, 0, null, null); 10800 */ 10801 br.onReceive(mContext, intent); 10802 } 10803 10804 private long getLowRamTimeSinceIdle(long now) { 10805 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10806 } 10807 10808 @Override 10809 public void performIdleMaintenance() { 10810 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10811 != PackageManager.PERMISSION_GRANTED) { 10812 throw new SecurityException("Requires permission " 10813 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10814 } 10815 10816 synchronized (this) { 10817 final long now = SystemClock.uptimeMillis(); 10818 final long timeSinceLastIdle = now - mLastIdleTime; 10819 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10820 mLastIdleTime = now; 10821 mLowRamTimeSinceLastIdle = 0; 10822 if (mLowRamStartTime != 0) { 10823 mLowRamStartTime = now; 10824 } 10825 10826 StringBuilder sb = new StringBuilder(128); 10827 sb.append("Idle maintenance over "); 10828 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10829 sb.append(" low RAM for "); 10830 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10831 Slog.i(TAG, sb.toString()); 10832 10833 // If at least 1/3 of our time since the last idle period has been spent 10834 // with RAM low, then we want to kill processes. 10835 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10836 10837 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10838 ProcessRecord proc = mLruProcesses.get(i); 10839 if (proc.notCachedSinceIdle) { 10840 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10841 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10842 if (doKilling && proc.initialIdlePss != 0 10843 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10844 proc.kill("idle maint (pss " + proc.lastPss 10845 + " from " + proc.initialIdlePss + ")", true); 10846 } 10847 } 10848 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10849 proc.notCachedSinceIdle = true; 10850 proc.initialIdlePss = 0; 10851 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10852 isSleeping(), now); 10853 } 10854 } 10855 10856 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10857 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10858 } 10859 } 10860 10861 private void retrieveSettings() { 10862 final ContentResolver resolver = mContext.getContentResolver(); 10863 String debugApp = Settings.Global.getString( 10864 resolver, Settings.Global.DEBUG_APP); 10865 boolean waitForDebugger = Settings.Global.getInt( 10866 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10867 boolean alwaysFinishActivities = Settings.Global.getInt( 10868 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10869 boolean forceRtl = Settings.Global.getInt( 10870 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10871 // Transfer any global setting for forcing RTL layout, into a System Property 10872 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10873 10874 Configuration configuration = new Configuration(); 10875 Settings.System.getConfiguration(resolver, configuration); 10876 if (forceRtl) { 10877 // This will take care of setting the correct layout direction flags 10878 configuration.setLayoutDirection(configuration.locale); 10879 } 10880 10881 synchronized (this) { 10882 mDebugApp = mOrigDebugApp = debugApp; 10883 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10884 mAlwaysFinishActivities = alwaysFinishActivities; 10885 // This happens before any activities are started, so we can 10886 // change mConfiguration in-place. 10887 updateConfigurationLocked(configuration, null, false, true); 10888 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10889 } 10890 } 10891 10892 /** Loads resources after the current configuration has been set. */ 10893 private void loadResourcesOnSystemReady() { 10894 final Resources res = mContext.getResources(); 10895 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10896 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10897 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10898 } 10899 10900 public boolean testIsSystemReady() { 10901 // no need to synchronize(this) just to read & return the value 10902 return mSystemReady; 10903 } 10904 10905 private static File getCalledPreBootReceiversFile() { 10906 File dataDir = Environment.getDataDirectory(); 10907 File systemDir = new File(dataDir, "system"); 10908 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10909 return fname; 10910 } 10911 10912 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10913 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10914 File file = getCalledPreBootReceiversFile(); 10915 FileInputStream fis = null; 10916 try { 10917 fis = new FileInputStream(file); 10918 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10919 int fvers = dis.readInt(); 10920 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10921 String vers = dis.readUTF(); 10922 String codename = dis.readUTF(); 10923 String build = dis.readUTF(); 10924 if (android.os.Build.VERSION.RELEASE.equals(vers) 10925 && android.os.Build.VERSION.CODENAME.equals(codename) 10926 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10927 int num = dis.readInt(); 10928 while (num > 0) { 10929 num--; 10930 String pkg = dis.readUTF(); 10931 String cls = dis.readUTF(); 10932 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10933 } 10934 } 10935 } 10936 } catch (FileNotFoundException e) { 10937 } catch (IOException e) { 10938 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10939 } finally { 10940 if (fis != null) { 10941 try { 10942 fis.close(); 10943 } catch (IOException e) { 10944 } 10945 } 10946 } 10947 return lastDoneReceivers; 10948 } 10949 10950 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10951 File file = getCalledPreBootReceiversFile(); 10952 FileOutputStream fos = null; 10953 DataOutputStream dos = null; 10954 try { 10955 fos = new FileOutputStream(file); 10956 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10957 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10958 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10959 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10960 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10961 dos.writeInt(list.size()); 10962 for (int i=0; i<list.size(); i++) { 10963 dos.writeUTF(list.get(i).getPackageName()); 10964 dos.writeUTF(list.get(i).getClassName()); 10965 } 10966 } catch (IOException e) { 10967 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10968 file.delete(); 10969 } finally { 10970 FileUtils.sync(fos); 10971 if (dos != null) { 10972 try { 10973 dos.close(); 10974 } catch (IOException e) { 10975 // TODO Auto-generated catch block 10976 e.printStackTrace(); 10977 } 10978 } 10979 } 10980 } 10981 10982 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10983 ArrayList<ComponentName> doneReceivers, int userId) { 10984 boolean waitingUpdate = false; 10985 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10986 List<ResolveInfo> ris = null; 10987 try { 10988 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10989 intent, null, 0, userId); 10990 } catch (RemoteException e) { 10991 } 10992 if (ris != null) { 10993 for (int i=ris.size()-1; i>=0; i--) { 10994 if ((ris.get(i).activityInfo.applicationInfo.flags 10995 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10996 ris.remove(i); 10997 } 10998 } 10999 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11000 11001 // For User 0, load the version number. When delivering to a new user, deliver 11002 // to all receivers. 11003 if (userId == UserHandle.USER_OWNER) { 11004 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11005 for (int i=0; i<ris.size(); i++) { 11006 ActivityInfo ai = ris.get(i).activityInfo; 11007 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11008 if (lastDoneReceivers.contains(comp)) { 11009 // We already did the pre boot receiver for this app with the current 11010 // platform version, so don't do it again... 11011 ris.remove(i); 11012 i--; 11013 // ...however, do keep it as one that has been done, so we don't 11014 // forget about it when rewriting the file of last done receivers. 11015 doneReceivers.add(comp); 11016 } 11017 } 11018 } 11019 11020 // If primary user, send broadcast to all available users, else just to userId 11021 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11022 : new int[] { userId }; 11023 for (int i = 0; i < ris.size(); i++) { 11024 ActivityInfo ai = ris.get(i).activityInfo; 11025 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11026 doneReceivers.add(comp); 11027 intent.setComponent(comp); 11028 for (int j=0; j<users.length; j++) { 11029 IIntentReceiver finisher = null; 11030 // On last receiver and user, set up a completion callback 11031 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11032 finisher = new IIntentReceiver.Stub() { 11033 public void performReceive(Intent intent, int resultCode, 11034 String data, Bundle extras, boolean ordered, 11035 boolean sticky, int sendingUser) { 11036 // The raw IIntentReceiver interface is called 11037 // with the AM lock held, so redispatch to 11038 // execute our code without the lock. 11039 mHandler.post(onFinishCallback); 11040 } 11041 }; 11042 } 11043 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11044 + " for user " + users[j]); 11045 broadcastIntentLocked(null, null, intent, null, finisher, 11046 0, null, null, null, AppOpsManager.OP_NONE, 11047 true, false, MY_PID, Process.SYSTEM_UID, 11048 users[j]); 11049 if (finisher != null) { 11050 waitingUpdate = true; 11051 } 11052 } 11053 } 11054 } 11055 11056 return waitingUpdate; 11057 } 11058 11059 public void systemReady(final Runnable goingCallback) { 11060 synchronized(this) { 11061 if (mSystemReady) { 11062 // If we're done calling all the receivers, run the next "boot phase" passed in 11063 // by the SystemServer 11064 if (goingCallback != null) { 11065 goingCallback.run(); 11066 } 11067 return; 11068 } 11069 11070 // Make sure we have the current profile info, since it is needed for 11071 // security checks. 11072 updateCurrentProfileIdsLocked(); 11073 11074 if (mRecentTasks == null) { 11075 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11076 if (!mRecentTasks.isEmpty()) { 11077 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11078 } 11079 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11080 mTaskPersister.startPersisting(); 11081 } 11082 11083 // Check to see if there are any update receivers to run. 11084 if (!mDidUpdate) { 11085 if (mWaitingUpdate) { 11086 return; 11087 } 11088 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11089 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11090 public void run() { 11091 synchronized (ActivityManagerService.this) { 11092 mDidUpdate = true; 11093 } 11094 writeLastDonePreBootReceivers(doneReceivers); 11095 showBootMessage(mContext.getText( 11096 R.string.android_upgrading_complete), 11097 false); 11098 systemReady(goingCallback); 11099 } 11100 }, doneReceivers, UserHandle.USER_OWNER); 11101 11102 if (mWaitingUpdate) { 11103 return; 11104 } 11105 mDidUpdate = true; 11106 } 11107 11108 mAppOpsService.systemReady(); 11109 mSystemReady = true; 11110 } 11111 11112 ArrayList<ProcessRecord> procsToKill = null; 11113 synchronized(mPidsSelfLocked) { 11114 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11115 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11116 if (!isAllowedWhileBooting(proc.info)){ 11117 if (procsToKill == null) { 11118 procsToKill = new ArrayList<ProcessRecord>(); 11119 } 11120 procsToKill.add(proc); 11121 } 11122 } 11123 } 11124 11125 synchronized(this) { 11126 if (procsToKill != null) { 11127 for (int i=procsToKill.size()-1; i>=0; i--) { 11128 ProcessRecord proc = procsToKill.get(i); 11129 Slog.i(TAG, "Removing system update proc: " + proc); 11130 removeProcessLocked(proc, true, false, "system update done"); 11131 } 11132 } 11133 11134 // Now that we have cleaned up any update processes, we 11135 // are ready to start launching real processes and know that 11136 // we won't trample on them any more. 11137 mProcessesReady = true; 11138 } 11139 11140 Slog.i(TAG, "System now ready"); 11141 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11142 SystemClock.uptimeMillis()); 11143 11144 synchronized(this) { 11145 // Make sure we have no pre-ready processes sitting around. 11146 11147 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11148 ResolveInfo ri = mContext.getPackageManager() 11149 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11150 STOCK_PM_FLAGS); 11151 CharSequence errorMsg = null; 11152 if (ri != null) { 11153 ActivityInfo ai = ri.activityInfo; 11154 ApplicationInfo app = ai.applicationInfo; 11155 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11156 mTopAction = Intent.ACTION_FACTORY_TEST; 11157 mTopData = null; 11158 mTopComponent = new ComponentName(app.packageName, 11159 ai.name); 11160 } else { 11161 errorMsg = mContext.getResources().getText( 11162 com.android.internal.R.string.factorytest_not_system); 11163 } 11164 } else { 11165 errorMsg = mContext.getResources().getText( 11166 com.android.internal.R.string.factorytest_no_action); 11167 } 11168 if (errorMsg != null) { 11169 mTopAction = null; 11170 mTopData = null; 11171 mTopComponent = null; 11172 Message msg = Message.obtain(); 11173 msg.what = SHOW_FACTORY_ERROR_MSG; 11174 msg.getData().putCharSequence("msg", errorMsg); 11175 mHandler.sendMessage(msg); 11176 } 11177 } 11178 } 11179 11180 retrieveSettings(); 11181 loadResourcesOnSystemReady(); 11182 11183 synchronized (this) { 11184 readGrantedUriPermissionsLocked(); 11185 } 11186 11187 if (goingCallback != null) goingCallback.run(); 11188 11189 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11190 Integer.toString(mCurrentUserId), mCurrentUserId); 11191 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11192 Integer.toString(mCurrentUserId), mCurrentUserId); 11193 mSystemServiceManager.startUser(mCurrentUserId); 11194 11195 synchronized (this) { 11196 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11197 try { 11198 List apps = AppGlobals.getPackageManager(). 11199 getPersistentApplications(STOCK_PM_FLAGS); 11200 if (apps != null) { 11201 int N = apps.size(); 11202 int i; 11203 for (i=0; i<N; i++) { 11204 ApplicationInfo info 11205 = (ApplicationInfo)apps.get(i); 11206 if (info != null && 11207 !info.packageName.equals("android")) { 11208 addAppLocked(info, false, null /* ABI override */); 11209 } 11210 } 11211 } 11212 } catch (RemoteException ex) { 11213 // pm is in same process, this will never happen. 11214 } 11215 } 11216 11217 // Start up initial activity. 11218 mBooting = true; 11219 startHomeActivityLocked(mCurrentUserId); 11220 11221 try { 11222 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11223 Message msg = Message.obtain(); 11224 msg.what = SHOW_UID_ERROR_MSG; 11225 mHandler.sendMessage(msg); 11226 } 11227 } catch (RemoteException e) { 11228 } 11229 11230 long ident = Binder.clearCallingIdentity(); 11231 try { 11232 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11233 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11234 | Intent.FLAG_RECEIVER_FOREGROUND); 11235 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11236 broadcastIntentLocked(null, null, intent, 11237 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11238 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11239 intent = new Intent(Intent.ACTION_USER_STARTING); 11240 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11241 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11242 broadcastIntentLocked(null, null, intent, 11243 null, new IIntentReceiver.Stub() { 11244 @Override 11245 public void performReceive(Intent intent, int resultCode, String data, 11246 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11247 throws RemoteException { 11248 } 11249 }, 0, null, null, 11250 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11251 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11252 } catch (Throwable t) { 11253 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11254 } finally { 11255 Binder.restoreCallingIdentity(ident); 11256 } 11257 mStackSupervisor.resumeTopActivitiesLocked(); 11258 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11259 } 11260 } 11261 11262 private boolean makeAppCrashingLocked(ProcessRecord app, 11263 String shortMsg, String longMsg, String stackTrace) { 11264 app.crashing = true; 11265 app.crashingReport = generateProcessError(app, 11266 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11267 startAppProblemLocked(app); 11268 app.stopFreezingAllLocked(); 11269 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11270 } 11271 11272 private void makeAppNotRespondingLocked(ProcessRecord app, 11273 String activity, String shortMsg, String longMsg) { 11274 app.notResponding = true; 11275 app.notRespondingReport = generateProcessError(app, 11276 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11277 activity, shortMsg, longMsg, null); 11278 startAppProblemLocked(app); 11279 app.stopFreezingAllLocked(); 11280 } 11281 11282 /** 11283 * Generate a process error record, suitable for attachment to a ProcessRecord. 11284 * 11285 * @param app The ProcessRecord in which the error occurred. 11286 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11287 * ActivityManager.AppErrorStateInfo 11288 * @param activity The activity associated with the crash, if known. 11289 * @param shortMsg Short message describing the crash. 11290 * @param longMsg Long message describing the crash. 11291 * @param stackTrace Full crash stack trace, may be null. 11292 * 11293 * @return Returns a fully-formed AppErrorStateInfo record. 11294 */ 11295 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11296 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11297 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11298 11299 report.condition = condition; 11300 report.processName = app.processName; 11301 report.pid = app.pid; 11302 report.uid = app.info.uid; 11303 report.tag = activity; 11304 report.shortMsg = shortMsg; 11305 report.longMsg = longMsg; 11306 report.stackTrace = stackTrace; 11307 11308 return report; 11309 } 11310 11311 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11312 synchronized (this) { 11313 app.crashing = false; 11314 app.crashingReport = null; 11315 app.notResponding = false; 11316 app.notRespondingReport = null; 11317 if (app.anrDialog == fromDialog) { 11318 app.anrDialog = null; 11319 } 11320 if (app.waitDialog == fromDialog) { 11321 app.waitDialog = null; 11322 } 11323 if (app.pid > 0 && app.pid != MY_PID) { 11324 handleAppCrashLocked(app, null, null, null); 11325 app.kill("user request after error", true); 11326 } 11327 } 11328 } 11329 11330 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11331 String stackTrace) { 11332 long now = SystemClock.uptimeMillis(); 11333 11334 Long crashTime; 11335 if (!app.isolated) { 11336 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11337 } else { 11338 crashTime = null; 11339 } 11340 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11341 // This process loses! 11342 Slog.w(TAG, "Process " + app.info.processName 11343 + " has crashed too many times: killing!"); 11344 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11345 app.userId, app.info.processName, app.uid); 11346 mStackSupervisor.handleAppCrashLocked(app); 11347 if (!app.persistent) { 11348 // We don't want to start this process again until the user 11349 // explicitly does so... but for persistent process, we really 11350 // need to keep it running. If a persistent process is actually 11351 // repeatedly crashing, then badness for everyone. 11352 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11353 app.info.processName); 11354 if (!app.isolated) { 11355 // XXX We don't have a way to mark isolated processes 11356 // as bad, since they don't have a peristent identity. 11357 mBadProcesses.put(app.info.processName, app.uid, 11358 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11359 mProcessCrashTimes.remove(app.info.processName, app.uid); 11360 } 11361 app.bad = true; 11362 app.removed = true; 11363 // Don't let services in this process be restarted and potentially 11364 // annoy the user repeatedly. Unless it is persistent, since those 11365 // processes run critical code. 11366 removeProcessLocked(app, false, false, "crash"); 11367 mStackSupervisor.resumeTopActivitiesLocked(); 11368 return false; 11369 } 11370 mStackSupervisor.resumeTopActivitiesLocked(); 11371 } else { 11372 mStackSupervisor.finishTopRunningActivityLocked(app); 11373 } 11374 11375 // Bump up the crash count of any services currently running in the proc. 11376 for (int i=app.services.size()-1; i>=0; i--) { 11377 // Any services running in the application need to be placed 11378 // back in the pending list. 11379 ServiceRecord sr = app.services.valueAt(i); 11380 sr.crashCount++; 11381 } 11382 11383 // If the crashing process is what we consider to be the "home process" and it has been 11384 // replaced by a third-party app, clear the package preferred activities from packages 11385 // with a home activity running in the process to prevent a repeatedly crashing app 11386 // from blocking the user to manually clear the list. 11387 final ArrayList<ActivityRecord> activities = app.activities; 11388 if (app == mHomeProcess && activities.size() > 0 11389 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11390 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11391 final ActivityRecord r = activities.get(activityNdx); 11392 if (r.isHomeActivity()) { 11393 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11394 try { 11395 ActivityThread.getPackageManager() 11396 .clearPackagePreferredActivities(r.packageName); 11397 } catch (RemoteException c) { 11398 // pm is in same process, this will never happen. 11399 } 11400 } 11401 } 11402 } 11403 11404 if (!app.isolated) { 11405 // XXX Can't keep track of crash times for isolated processes, 11406 // because they don't have a perisistent identity. 11407 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11408 } 11409 11410 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11411 return true; 11412 } 11413 11414 void startAppProblemLocked(ProcessRecord app) { 11415 // If this app is not running under the current user, then we 11416 // can't give it a report button because that would require 11417 // launching the report UI under a different user. 11418 app.errorReportReceiver = null; 11419 11420 for (int userId : mCurrentProfileIds) { 11421 if (app.userId == userId) { 11422 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11423 mContext, app.info.packageName, app.info.flags); 11424 } 11425 } 11426 skipCurrentReceiverLocked(app); 11427 } 11428 11429 void skipCurrentReceiverLocked(ProcessRecord app) { 11430 for (BroadcastQueue queue : mBroadcastQueues) { 11431 queue.skipCurrentReceiverLocked(app); 11432 } 11433 } 11434 11435 /** 11436 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11437 * The application process will exit immediately after this call returns. 11438 * @param app object of the crashing app, null for the system server 11439 * @param crashInfo describing the exception 11440 */ 11441 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11442 ProcessRecord r = findAppProcess(app, "Crash"); 11443 final String processName = app == null ? "system_server" 11444 : (r == null ? "unknown" : r.processName); 11445 11446 handleApplicationCrashInner("crash", r, processName, crashInfo); 11447 } 11448 11449 /* Native crash reporting uses this inner version because it needs to be somewhat 11450 * decoupled from the AM-managed cleanup lifecycle 11451 */ 11452 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11453 ApplicationErrorReport.CrashInfo crashInfo) { 11454 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11455 UserHandle.getUserId(Binder.getCallingUid()), processName, 11456 r == null ? -1 : r.info.flags, 11457 crashInfo.exceptionClassName, 11458 crashInfo.exceptionMessage, 11459 crashInfo.throwFileName, 11460 crashInfo.throwLineNumber); 11461 11462 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11463 11464 crashApplication(r, crashInfo); 11465 } 11466 11467 public void handleApplicationStrictModeViolation( 11468 IBinder app, 11469 int violationMask, 11470 StrictMode.ViolationInfo info) { 11471 ProcessRecord r = findAppProcess(app, "StrictMode"); 11472 if (r == null) { 11473 return; 11474 } 11475 11476 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11477 Integer stackFingerprint = info.hashCode(); 11478 boolean logIt = true; 11479 synchronized (mAlreadyLoggedViolatedStacks) { 11480 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11481 logIt = false; 11482 // TODO: sub-sample into EventLog for these, with 11483 // the info.durationMillis? Then we'd get 11484 // the relative pain numbers, without logging all 11485 // the stack traces repeatedly. We'd want to do 11486 // likewise in the client code, which also does 11487 // dup suppression, before the Binder call. 11488 } else { 11489 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11490 mAlreadyLoggedViolatedStacks.clear(); 11491 } 11492 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11493 } 11494 } 11495 if (logIt) { 11496 logStrictModeViolationToDropBox(r, info); 11497 } 11498 } 11499 11500 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11501 AppErrorResult result = new AppErrorResult(); 11502 synchronized (this) { 11503 final long origId = Binder.clearCallingIdentity(); 11504 11505 Message msg = Message.obtain(); 11506 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11507 HashMap<String, Object> data = new HashMap<String, Object>(); 11508 data.put("result", result); 11509 data.put("app", r); 11510 data.put("violationMask", violationMask); 11511 data.put("info", info); 11512 msg.obj = data; 11513 mHandler.sendMessage(msg); 11514 11515 Binder.restoreCallingIdentity(origId); 11516 } 11517 int res = result.get(); 11518 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11519 } 11520 } 11521 11522 // Depending on the policy in effect, there could be a bunch of 11523 // these in quick succession so we try to batch these together to 11524 // minimize disk writes, number of dropbox entries, and maximize 11525 // compression, by having more fewer, larger records. 11526 private void logStrictModeViolationToDropBox( 11527 ProcessRecord process, 11528 StrictMode.ViolationInfo info) { 11529 if (info == null) { 11530 return; 11531 } 11532 final boolean isSystemApp = process == null || 11533 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11534 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11535 final String processName = process == null ? "unknown" : process.processName; 11536 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11537 final DropBoxManager dbox = (DropBoxManager) 11538 mContext.getSystemService(Context.DROPBOX_SERVICE); 11539 11540 // Exit early if the dropbox isn't configured to accept this report type. 11541 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11542 11543 boolean bufferWasEmpty; 11544 boolean needsFlush; 11545 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11546 synchronized (sb) { 11547 bufferWasEmpty = sb.length() == 0; 11548 appendDropBoxProcessHeaders(process, processName, sb); 11549 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11550 sb.append("System-App: ").append(isSystemApp).append("\n"); 11551 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11552 if (info.violationNumThisLoop != 0) { 11553 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11554 } 11555 if (info.numAnimationsRunning != 0) { 11556 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11557 } 11558 if (info.broadcastIntentAction != null) { 11559 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11560 } 11561 if (info.durationMillis != -1) { 11562 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11563 } 11564 if (info.numInstances != -1) { 11565 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11566 } 11567 if (info.tags != null) { 11568 for (String tag : info.tags) { 11569 sb.append("Span-Tag: ").append(tag).append("\n"); 11570 } 11571 } 11572 sb.append("\n"); 11573 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11574 sb.append(info.crashInfo.stackTrace); 11575 } 11576 sb.append("\n"); 11577 11578 // Only buffer up to ~64k. Various logging bits truncate 11579 // things at 128k. 11580 needsFlush = (sb.length() > 64 * 1024); 11581 } 11582 11583 // Flush immediately if the buffer's grown too large, or this 11584 // is a non-system app. Non-system apps are isolated with a 11585 // different tag & policy and not batched. 11586 // 11587 // Batching is useful during internal testing with 11588 // StrictMode settings turned up high. Without batching, 11589 // thousands of separate files could be created on boot. 11590 if (!isSystemApp || needsFlush) { 11591 new Thread("Error dump: " + dropboxTag) { 11592 @Override 11593 public void run() { 11594 String report; 11595 synchronized (sb) { 11596 report = sb.toString(); 11597 sb.delete(0, sb.length()); 11598 sb.trimToSize(); 11599 } 11600 if (report.length() != 0) { 11601 dbox.addText(dropboxTag, report); 11602 } 11603 } 11604 }.start(); 11605 return; 11606 } 11607 11608 // System app batching: 11609 if (!bufferWasEmpty) { 11610 // An existing dropbox-writing thread is outstanding, so 11611 // we don't need to start it up. The existing thread will 11612 // catch the buffer appends we just did. 11613 return; 11614 } 11615 11616 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11617 // (After this point, we shouldn't access AMS internal data structures.) 11618 new Thread("Error dump: " + dropboxTag) { 11619 @Override 11620 public void run() { 11621 // 5 second sleep to let stacks arrive and be batched together 11622 try { 11623 Thread.sleep(5000); // 5 seconds 11624 } catch (InterruptedException e) {} 11625 11626 String errorReport; 11627 synchronized (mStrictModeBuffer) { 11628 errorReport = mStrictModeBuffer.toString(); 11629 if (errorReport.length() == 0) { 11630 return; 11631 } 11632 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11633 mStrictModeBuffer.trimToSize(); 11634 } 11635 dbox.addText(dropboxTag, errorReport); 11636 } 11637 }.start(); 11638 } 11639 11640 /** 11641 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11642 * @param app object of the crashing app, null for the system server 11643 * @param tag reported by the caller 11644 * @param system whether this wtf is coming from the system 11645 * @param crashInfo describing the context of the error 11646 * @return true if the process should exit immediately (WTF is fatal) 11647 */ 11648 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11649 final ApplicationErrorReport.CrashInfo crashInfo) { 11650 final int callingUid = Binder.getCallingUid(); 11651 final int callingPid = Binder.getCallingPid(); 11652 11653 if (system) { 11654 // If this is coming from the system, we could very well have low-level 11655 // system locks held, so we want to do this all asynchronously. And we 11656 // never want this to become fatal, so there is that too. 11657 mHandler.post(new Runnable() { 11658 @Override public void run() { 11659 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11660 } 11661 }); 11662 return false; 11663 } 11664 11665 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11666 crashInfo); 11667 11668 if (r != null && r.pid != Process.myPid() && 11669 Settings.Global.getInt(mContext.getContentResolver(), 11670 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11671 crashApplication(r, crashInfo); 11672 return true; 11673 } else { 11674 return false; 11675 } 11676 } 11677 11678 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11679 final ApplicationErrorReport.CrashInfo crashInfo) { 11680 final ProcessRecord r = findAppProcess(app, "WTF"); 11681 final String processName = app == null ? "system_server" 11682 : (r == null ? "unknown" : r.processName); 11683 11684 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11685 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11686 11687 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11688 11689 return r; 11690 } 11691 11692 /** 11693 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11694 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11695 */ 11696 private ProcessRecord findAppProcess(IBinder app, String reason) { 11697 if (app == null) { 11698 return null; 11699 } 11700 11701 synchronized (this) { 11702 final int NP = mProcessNames.getMap().size(); 11703 for (int ip=0; ip<NP; ip++) { 11704 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11705 final int NA = apps.size(); 11706 for (int ia=0; ia<NA; ia++) { 11707 ProcessRecord p = apps.valueAt(ia); 11708 if (p.thread != null && p.thread.asBinder() == app) { 11709 return p; 11710 } 11711 } 11712 } 11713 11714 Slog.w(TAG, "Can't find mystery application for " + reason 11715 + " from pid=" + Binder.getCallingPid() 11716 + " uid=" + Binder.getCallingUid() + ": " + app); 11717 return null; 11718 } 11719 } 11720 11721 /** 11722 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11723 * to append various headers to the dropbox log text. 11724 */ 11725 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11726 StringBuilder sb) { 11727 // Watchdog thread ends up invoking this function (with 11728 // a null ProcessRecord) to add the stack file to dropbox. 11729 // Do not acquire a lock on this (am) in such cases, as it 11730 // could cause a potential deadlock, if and when watchdog 11731 // is invoked due to unavailability of lock on am and it 11732 // would prevent watchdog from killing system_server. 11733 if (process == null) { 11734 sb.append("Process: ").append(processName).append("\n"); 11735 return; 11736 } 11737 // Note: ProcessRecord 'process' is guarded by the service 11738 // instance. (notably process.pkgList, which could otherwise change 11739 // concurrently during execution of this method) 11740 synchronized (this) { 11741 sb.append("Process: ").append(processName).append("\n"); 11742 int flags = process.info.flags; 11743 IPackageManager pm = AppGlobals.getPackageManager(); 11744 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11745 for (int ip=0; ip<process.pkgList.size(); ip++) { 11746 String pkg = process.pkgList.keyAt(ip); 11747 sb.append("Package: ").append(pkg); 11748 try { 11749 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11750 if (pi != null) { 11751 sb.append(" v").append(pi.versionCode); 11752 if (pi.versionName != null) { 11753 sb.append(" (").append(pi.versionName).append(")"); 11754 } 11755 } 11756 } catch (RemoteException e) { 11757 Slog.e(TAG, "Error getting package info: " + pkg, e); 11758 } 11759 sb.append("\n"); 11760 } 11761 } 11762 } 11763 11764 private static String processClass(ProcessRecord process) { 11765 if (process == null || process.pid == MY_PID) { 11766 return "system_server"; 11767 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11768 return "system_app"; 11769 } else { 11770 return "data_app"; 11771 } 11772 } 11773 11774 /** 11775 * Write a description of an error (crash, WTF, ANR) to the drop box. 11776 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11777 * @param process which caused the error, null means the system server 11778 * @param activity which triggered the error, null if unknown 11779 * @param parent activity related to the error, null if unknown 11780 * @param subject line related to the error, null if absent 11781 * @param report in long form describing the error, null if absent 11782 * @param logFile to include in the report, null if none 11783 * @param crashInfo giving an application stack trace, null if absent 11784 */ 11785 public void addErrorToDropBox(String eventType, 11786 ProcessRecord process, String processName, ActivityRecord activity, 11787 ActivityRecord parent, String subject, 11788 final String report, final File logFile, 11789 final ApplicationErrorReport.CrashInfo crashInfo) { 11790 // NOTE -- this must never acquire the ActivityManagerService lock, 11791 // otherwise the watchdog may be prevented from resetting the system. 11792 11793 final String dropboxTag = processClass(process) + "_" + eventType; 11794 final DropBoxManager dbox = (DropBoxManager) 11795 mContext.getSystemService(Context.DROPBOX_SERVICE); 11796 11797 // Exit early if the dropbox isn't configured to accept this report type. 11798 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11799 11800 final StringBuilder sb = new StringBuilder(1024); 11801 appendDropBoxProcessHeaders(process, processName, sb); 11802 if (activity != null) { 11803 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11804 } 11805 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11806 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11807 } 11808 if (parent != null && parent != activity) { 11809 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11810 } 11811 if (subject != null) { 11812 sb.append("Subject: ").append(subject).append("\n"); 11813 } 11814 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11815 if (Debug.isDebuggerConnected()) { 11816 sb.append("Debugger: Connected\n"); 11817 } 11818 sb.append("\n"); 11819 11820 // Do the rest in a worker thread to avoid blocking the caller on I/O 11821 // (After this point, we shouldn't access AMS internal data structures.) 11822 Thread worker = new Thread("Error dump: " + dropboxTag) { 11823 @Override 11824 public void run() { 11825 if (report != null) { 11826 sb.append(report); 11827 } 11828 if (logFile != null) { 11829 try { 11830 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11831 "\n\n[[TRUNCATED]]")); 11832 } catch (IOException e) { 11833 Slog.e(TAG, "Error reading " + logFile, e); 11834 } 11835 } 11836 if (crashInfo != null && crashInfo.stackTrace != null) { 11837 sb.append(crashInfo.stackTrace); 11838 } 11839 11840 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11841 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11842 if (lines > 0) { 11843 sb.append("\n"); 11844 11845 // Merge several logcat streams, and take the last N lines 11846 InputStreamReader input = null; 11847 try { 11848 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11849 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11850 "-b", "crash", 11851 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11852 11853 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11854 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11855 input = new InputStreamReader(logcat.getInputStream()); 11856 11857 int num; 11858 char[] buf = new char[8192]; 11859 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11860 } catch (IOException e) { 11861 Slog.e(TAG, "Error running logcat", e); 11862 } finally { 11863 if (input != null) try { input.close(); } catch (IOException e) {} 11864 } 11865 } 11866 11867 dbox.addText(dropboxTag, sb.toString()); 11868 } 11869 }; 11870 11871 if (process == null) { 11872 // If process is null, we are being called from some internal code 11873 // and may be about to die -- run this synchronously. 11874 worker.run(); 11875 } else { 11876 worker.start(); 11877 } 11878 } 11879 11880 /** 11881 * Bring up the "unexpected error" dialog box for a crashing app. 11882 * Deal with edge cases (intercepts from instrumented applications, 11883 * ActivityController, error intent receivers, that sort of thing). 11884 * @param r the application crashing 11885 * @param crashInfo describing the failure 11886 */ 11887 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11888 long timeMillis = System.currentTimeMillis(); 11889 String shortMsg = crashInfo.exceptionClassName; 11890 String longMsg = crashInfo.exceptionMessage; 11891 String stackTrace = crashInfo.stackTrace; 11892 if (shortMsg != null && longMsg != null) { 11893 longMsg = shortMsg + ": " + longMsg; 11894 } else if (shortMsg != null) { 11895 longMsg = shortMsg; 11896 } 11897 11898 AppErrorResult result = new AppErrorResult(); 11899 synchronized (this) { 11900 if (mController != null) { 11901 try { 11902 String name = r != null ? r.processName : null; 11903 int pid = r != null ? r.pid : Binder.getCallingPid(); 11904 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11905 if (!mController.appCrashed(name, pid, 11906 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11907 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11908 && "Native crash".equals(crashInfo.exceptionClassName)) { 11909 Slog.w(TAG, "Skip killing native crashed app " + name 11910 + "(" + pid + ") during testing"); 11911 } else { 11912 Slog.w(TAG, "Force-killing crashed app " + name 11913 + " at watcher's request"); 11914 if (r != null) { 11915 r.kill("crash", true); 11916 } else { 11917 // Huh. 11918 Process.killProcess(pid); 11919 Process.killProcessGroup(uid, pid); 11920 } 11921 } 11922 return; 11923 } 11924 } catch (RemoteException e) { 11925 mController = null; 11926 Watchdog.getInstance().setActivityController(null); 11927 } 11928 } 11929 11930 final long origId = Binder.clearCallingIdentity(); 11931 11932 // If this process is running instrumentation, finish it. 11933 if (r != null && r.instrumentationClass != null) { 11934 Slog.w(TAG, "Error in app " + r.processName 11935 + " running instrumentation " + r.instrumentationClass + ":"); 11936 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11937 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11938 Bundle info = new Bundle(); 11939 info.putString("shortMsg", shortMsg); 11940 info.putString("longMsg", longMsg); 11941 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11942 Binder.restoreCallingIdentity(origId); 11943 return; 11944 } 11945 11946 // If we can't identify the process or it's already exceeded its crash quota, 11947 // quit right away without showing a crash dialog. 11948 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11949 Binder.restoreCallingIdentity(origId); 11950 return; 11951 } 11952 11953 Message msg = Message.obtain(); 11954 msg.what = SHOW_ERROR_MSG; 11955 HashMap data = new HashMap(); 11956 data.put("result", result); 11957 data.put("app", r); 11958 msg.obj = data; 11959 mHandler.sendMessage(msg); 11960 11961 Binder.restoreCallingIdentity(origId); 11962 } 11963 11964 int res = result.get(); 11965 11966 Intent appErrorIntent = null; 11967 synchronized (this) { 11968 if (r != null && !r.isolated) { 11969 // XXX Can't keep track of crash time for isolated processes, 11970 // since they don't have a persistent identity. 11971 mProcessCrashTimes.put(r.info.processName, r.uid, 11972 SystemClock.uptimeMillis()); 11973 } 11974 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11975 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11976 } 11977 } 11978 11979 if (appErrorIntent != null) { 11980 try { 11981 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11982 } catch (ActivityNotFoundException e) { 11983 Slog.w(TAG, "bug report receiver dissappeared", e); 11984 } 11985 } 11986 } 11987 11988 Intent createAppErrorIntentLocked(ProcessRecord r, 11989 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11990 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11991 if (report == null) { 11992 return null; 11993 } 11994 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11995 result.setComponent(r.errorReportReceiver); 11996 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11997 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11998 return result; 11999 } 12000 12001 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12002 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12003 if (r.errorReportReceiver == null) { 12004 return null; 12005 } 12006 12007 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12008 return null; 12009 } 12010 12011 ApplicationErrorReport report = new ApplicationErrorReport(); 12012 report.packageName = r.info.packageName; 12013 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12014 report.processName = r.processName; 12015 report.time = timeMillis; 12016 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12017 12018 if (r.crashing || r.forceCrashReport) { 12019 report.type = ApplicationErrorReport.TYPE_CRASH; 12020 report.crashInfo = crashInfo; 12021 } else if (r.notResponding) { 12022 report.type = ApplicationErrorReport.TYPE_ANR; 12023 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12024 12025 report.anrInfo.activity = r.notRespondingReport.tag; 12026 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12027 report.anrInfo.info = r.notRespondingReport.longMsg; 12028 } 12029 12030 return report; 12031 } 12032 12033 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12034 enforceNotIsolatedCaller("getProcessesInErrorState"); 12035 // assume our apps are happy - lazy create the list 12036 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12037 12038 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12039 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12040 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12041 12042 synchronized (this) { 12043 12044 // iterate across all processes 12045 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12046 ProcessRecord app = mLruProcesses.get(i); 12047 if (!allUsers && app.userId != userId) { 12048 continue; 12049 } 12050 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12051 // This one's in trouble, so we'll generate a report for it 12052 // crashes are higher priority (in case there's a crash *and* an anr) 12053 ActivityManager.ProcessErrorStateInfo report = null; 12054 if (app.crashing) { 12055 report = app.crashingReport; 12056 } else if (app.notResponding) { 12057 report = app.notRespondingReport; 12058 } 12059 12060 if (report != null) { 12061 if (errList == null) { 12062 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12063 } 12064 errList.add(report); 12065 } else { 12066 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12067 " crashing = " + app.crashing + 12068 " notResponding = " + app.notResponding); 12069 } 12070 } 12071 } 12072 } 12073 12074 return errList; 12075 } 12076 12077 static int procStateToImportance(int procState, int memAdj, 12078 ActivityManager.RunningAppProcessInfo currApp) { 12079 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12080 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12081 currApp.lru = memAdj; 12082 } else { 12083 currApp.lru = 0; 12084 } 12085 return imp; 12086 } 12087 12088 private void fillInProcMemInfo(ProcessRecord app, 12089 ActivityManager.RunningAppProcessInfo outInfo) { 12090 outInfo.pid = app.pid; 12091 outInfo.uid = app.info.uid; 12092 if (mHeavyWeightProcess == app) { 12093 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12094 } 12095 if (app.persistent) { 12096 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12097 } 12098 if (app.activities.size() > 0) { 12099 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12100 } 12101 outInfo.lastTrimLevel = app.trimMemoryLevel; 12102 int adj = app.curAdj; 12103 int procState = app.curProcState; 12104 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12105 outInfo.importanceReasonCode = app.adjTypeCode; 12106 outInfo.processState = app.curProcState; 12107 } 12108 12109 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12110 enforceNotIsolatedCaller("getRunningAppProcesses"); 12111 // Lazy instantiation of list 12112 List<ActivityManager.RunningAppProcessInfo> runList = null; 12113 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12114 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12115 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12116 synchronized (this) { 12117 // Iterate across all processes 12118 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12119 ProcessRecord app = mLruProcesses.get(i); 12120 if (!allUsers && app.userId != userId) { 12121 continue; 12122 } 12123 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12124 // Generate process state info for running application 12125 ActivityManager.RunningAppProcessInfo currApp = 12126 new ActivityManager.RunningAppProcessInfo(app.processName, 12127 app.pid, app.getPackageList()); 12128 fillInProcMemInfo(app, currApp); 12129 if (app.adjSource instanceof ProcessRecord) { 12130 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12131 currApp.importanceReasonImportance = 12132 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12133 app.adjSourceProcState); 12134 } else if (app.adjSource instanceof ActivityRecord) { 12135 ActivityRecord r = (ActivityRecord)app.adjSource; 12136 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12137 } 12138 if (app.adjTarget instanceof ComponentName) { 12139 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12140 } 12141 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12142 // + " lru=" + currApp.lru); 12143 if (runList == null) { 12144 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12145 } 12146 runList.add(currApp); 12147 } 12148 } 12149 } 12150 return runList; 12151 } 12152 12153 public List<ApplicationInfo> getRunningExternalApplications() { 12154 enforceNotIsolatedCaller("getRunningExternalApplications"); 12155 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12156 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12157 if (runningApps != null && runningApps.size() > 0) { 12158 Set<String> extList = new HashSet<String>(); 12159 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12160 if (app.pkgList != null) { 12161 for (String pkg : app.pkgList) { 12162 extList.add(pkg); 12163 } 12164 } 12165 } 12166 IPackageManager pm = AppGlobals.getPackageManager(); 12167 for (String pkg : extList) { 12168 try { 12169 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12170 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12171 retList.add(info); 12172 } 12173 } catch (RemoteException e) { 12174 } 12175 } 12176 } 12177 return retList; 12178 } 12179 12180 @Override 12181 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12182 enforceNotIsolatedCaller("getMyMemoryState"); 12183 synchronized (this) { 12184 ProcessRecord proc; 12185 synchronized (mPidsSelfLocked) { 12186 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12187 } 12188 fillInProcMemInfo(proc, outInfo); 12189 } 12190 } 12191 12192 @Override 12193 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12194 if (checkCallingPermission(android.Manifest.permission.DUMP) 12195 != PackageManager.PERMISSION_GRANTED) { 12196 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12197 + Binder.getCallingPid() 12198 + ", uid=" + Binder.getCallingUid() 12199 + " without permission " 12200 + android.Manifest.permission.DUMP); 12201 return; 12202 } 12203 12204 boolean dumpAll = false; 12205 boolean dumpClient = false; 12206 String dumpPackage = null; 12207 12208 int opti = 0; 12209 while (opti < args.length) { 12210 String opt = args[opti]; 12211 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12212 break; 12213 } 12214 opti++; 12215 if ("-a".equals(opt)) { 12216 dumpAll = true; 12217 } else if ("-c".equals(opt)) { 12218 dumpClient = true; 12219 } else if ("-h".equals(opt)) { 12220 pw.println("Activity manager dump options:"); 12221 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12222 pw.println(" cmd may be one of:"); 12223 pw.println(" a[ctivities]: activity stack state"); 12224 pw.println(" r[recents]: recent activities state"); 12225 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12226 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12227 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12228 pw.println(" o[om]: out of memory management"); 12229 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12230 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12231 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12232 pw.println(" service [COMP_SPEC]: service client-side state"); 12233 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12234 pw.println(" all: dump all activities"); 12235 pw.println(" top: dump the top activity"); 12236 pw.println(" write: write all pending state to storage"); 12237 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12238 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12239 pw.println(" a partial substring in a component name, a"); 12240 pw.println(" hex object identifier."); 12241 pw.println(" -a: include all available server state."); 12242 pw.println(" -c: include client state."); 12243 return; 12244 } else { 12245 pw.println("Unknown argument: " + opt + "; use -h for help"); 12246 } 12247 } 12248 12249 long origId = Binder.clearCallingIdentity(); 12250 boolean more = false; 12251 // Is the caller requesting to dump a particular piece of data? 12252 if (opti < args.length) { 12253 String cmd = args[opti]; 12254 opti++; 12255 if ("activities".equals(cmd) || "a".equals(cmd)) { 12256 synchronized (this) { 12257 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12258 } 12259 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12260 synchronized (this) { 12261 dumpRecentsLocked(fd, pw, args, opti, true, null); 12262 } 12263 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12264 String[] newArgs; 12265 String name; 12266 if (opti >= args.length) { 12267 name = null; 12268 newArgs = EMPTY_STRING_ARRAY; 12269 } else { 12270 name = args[opti]; 12271 opti++; 12272 newArgs = new String[args.length - opti]; 12273 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12274 args.length - opti); 12275 } 12276 synchronized (this) { 12277 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12278 } 12279 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12280 String[] newArgs; 12281 String name; 12282 if (opti >= args.length) { 12283 name = null; 12284 newArgs = EMPTY_STRING_ARRAY; 12285 } else { 12286 name = args[opti]; 12287 opti++; 12288 newArgs = new String[args.length - opti]; 12289 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12290 args.length - opti); 12291 } 12292 synchronized (this) { 12293 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12294 } 12295 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12296 String[] newArgs; 12297 String name; 12298 if (opti >= args.length) { 12299 name = null; 12300 newArgs = EMPTY_STRING_ARRAY; 12301 } else { 12302 name = args[opti]; 12303 opti++; 12304 newArgs = new String[args.length - opti]; 12305 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12306 args.length - opti); 12307 } 12308 synchronized (this) { 12309 dumpProcessesLocked(fd, pw, args, opti, true, name); 12310 } 12311 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12312 synchronized (this) { 12313 dumpOomLocked(fd, pw, args, opti, true); 12314 } 12315 } else if ("provider".equals(cmd)) { 12316 String[] newArgs; 12317 String name; 12318 if (opti >= args.length) { 12319 name = null; 12320 newArgs = EMPTY_STRING_ARRAY; 12321 } else { 12322 name = args[opti]; 12323 opti++; 12324 newArgs = new String[args.length - opti]; 12325 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12326 } 12327 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12328 pw.println("No providers match: " + name); 12329 pw.println("Use -h for help."); 12330 } 12331 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12332 synchronized (this) { 12333 dumpProvidersLocked(fd, pw, args, opti, true, null); 12334 } 12335 } else if ("service".equals(cmd)) { 12336 String[] newArgs; 12337 String name; 12338 if (opti >= args.length) { 12339 name = null; 12340 newArgs = EMPTY_STRING_ARRAY; 12341 } else { 12342 name = args[opti]; 12343 opti++; 12344 newArgs = new String[args.length - opti]; 12345 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12346 args.length - opti); 12347 } 12348 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12349 pw.println("No services match: " + name); 12350 pw.println("Use -h for help."); 12351 } 12352 } else if ("package".equals(cmd)) { 12353 String[] newArgs; 12354 if (opti >= args.length) { 12355 pw.println("package: no package name specified"); 12356 pw.println("Use -h for help."); 12357 } else { 12358 dumpPackage = args[opti]; 12359 opti++; 12360 newArgs = new String[args.length - opti]; 12361 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12362 args.length - opti); 12363 args = newArgs; 12364 opti = 0; 12365 more = true; 12366 } 12367 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12368 synchronized (this) { 12369 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12370 } 12371 } else if ("write".equals(cmd)) { 12372 mTaskPersister.flush(); 12373 pw.println("All tasks persisted."); 12374 return; 12375 } else { 12376 // Dumping a single activity? 12377 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12378 pw.println("Bad activity command, or no activities match: " + cmd); 12379 pw.println("Use -h for help."); 12380 } 12381 } 12382 if (!more) { 12383 Binder.restoreCallingIdentity(origId); 12384 return; 12385 } 12386 } 12387 12388 // No piece of data specified, dump everything. 12389 synchronized (this) { 12390 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12391 pw.println(); 12392 if (dumpAll) { 12393 pw.println("-------------------------------------------------------------------------------"); 12394 } 12395 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12396 pw.println(); 12397 if (dumpAll) { 12398 pw.println("-------------------------------------------------------------------------------"); 12399 } 12400 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12401 pw.println(); 12402 if (dumpAll) { 12403 pw.println("-------------------------------------------------------------------------------"); 12404 } 12405 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12406 pw.println(); 12407 if (dumpAll) { 12408 pw.println("-------------------------------------------------------------------------------"); 12409 } 12410 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12411 pw.println(); 12412 if (dumpAll) { 12413 pw.println("-------------------------------------------------------------------------------"); 12414 } 12415 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12416 pw.println(); 12417 if (dumpAll) { 12418 pw.println("-------------------------------------------------------------------------------"); 12419 } 12420 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12421 } 12422 Binder.restoreCallingIdentity(origId); 12423 } 12424 12425 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12426 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12427 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12428 12429 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12430 dumpPackage); 12431 boolean needSep = printedAnything; 12432 12433 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12434 dumpPackage, needSep, " mFocusedActivity: "); 12435 if (printed) { 12436 printedAnything = true; 12437 needSep = false; 12438 } 12439 12440 if (dumpPackage == null) { 12441 if (needSep) { 12442 pw.println(); 12443 } 12444 needSep = true; 12445 printedAnything = true; 12446 mStackSupervisor.dump(pw, " "); 12447 } 12448 12449 if (!printedAnything) { 12450 pw.println(" (nothing)"); 12451 } 12452 } 12453 12454 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12455 int opti, boolean dumpAll, String dumpPackage) { 12456 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12457 12458 boolean printedAnything = false; 12459 12460 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12461 boolean printedHeader = false; 12462 12463 final int N = mRecentTasks.size(); 12464 for (int i=0; i<N; i++) { 12465 TaskRecord tr = mRecentTasks.get(i); 12466 if (dumpPackage != null) { 12467 if (tr.realActivity == null || 12468 !dumpPackage.equals(tr.realActivity)) { 12469 continue; 12470 } 12471 } 12472 if (!printedHeader) { 12473 pw.println(" Recent tasks:"); 12474 printedHeader = true; 12475 printedAnything = true; 12476 } 12477 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12478 pw.println(tr); 12479 if (dumpAll) { 12480 mRecentTasks.get(i).dump(pw, " "); 12481 } 12482 } 12483 } 12484 12485 if (!printedAnything) { 12486 pw.println(" (nothing)"); 12487 } 12488 } 12489 12490 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12491 int opti, boolean dumpAll, String dumpPackage) { 12492 boolean needSep = false; 12493 boolean printedAnything = false; 12494 int numPers = 0; 12495 12496 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12497 12498 if (dumpAll) { 12499 final int NP = mProcessNames.getMap().size(); 12500 for (int ip=0; ip<NP; ip++) { 12501 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12502 final int NA = procs.size(); 12503 for (int ia=0; ia<NA; ia++) { 12504 ProcessRecord r = procs.valueAt(ia); 12505 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12506 continue; 12507 } 12508 if (!needSep) { 12509 pw.println(" All known processes:"); 12510 needSep = true; 12511 printedAnything = true; 12512 } 12513 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12514 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12515 pw.print(" "); pw.println(r); 12516 r.dump(pw, " "); 12517 if (r.persistent) { 12518 numPers++; 12519 } 12520 } 12521 } 12522 } 12523 12524 if (mIsolatedProcesses.size() > 0) { 12525 boolean printed = false; 12526 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12527 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12528 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12529 continue; 12530 } 12531 if (!printed) { 12532 if (needSep) { 12533 pw.println(); 12534 } 12535 pw.println(" Isolated process list (sorted by uid):"); 12536 printedAnything = true; 12537 printed = true; 12538 needSep = true; 12539 } 12540 pw.println(String.format("%sIsolated #%2d: %s", 12541 " ", i, r.toString())); 12542 } 12543 } 12544 12545 if (mLruProcesses.size() > 0) { 12546 if (needSep) { 12547 pw.println(); 12548 } 12549 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12550 pw.print(" total, non-act at "); 12551 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12552 pw.print(", non-svc at "); 12553 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12554 pw.println("):"); 12555 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12556 needSep = true; 12557 printedAnything = true; 12558 } 12559 12560 if (dumpAll || dumpPackage != null) { 12561 synchronized (mPidsSelfLocked) { 12562 boolean printed = false; 12563 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12564 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12565 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12566 continue; 12567 } 12568 if (!printed) { 12569 if (needSep) pw.println(); 12570 needSep = true; 12571 pw.println(" PID mappings:"); 12572 printed = true; 12573 printedAnything = true; 12574 } 12575 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12576 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12577 } 12578 } 12579 } 12580 12581 if (mForegroundProcesses.size() > 0) { 12582 synchronized (mPidsSelfLocked) { 12583 boolean printed = false; 12584 for (int i=0; i<mForegroundProcesses.size(); i++) { 12585 ProcessRecord r = mPidsSelfLocked.get( 12586 mForegroundProcesses.valueAt(i).pid); 12587 if (dumpPackage != null && (r == null 12588 || !r.pkgList.containsKey(dumpPackage))) { 12589 continue; 12590 } 12591 if (!printed) { 12592 if (needSep) pw.println(); 12593 needSep = true; 12594 pw.println(" Foreground Processes:"); 12595 printed = true; 12596 printedAnything = true; 12597 } 12598 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12599 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12600 } 12601 } 12602 } 12603 12604 if (mPersistentStartingProcesses.size() > 0) { 12605 if (needSep) pw.println(); 12606 needSep = true; 12607 printedAnything = true; 12608 pw.println(" Persisent processes that are starting:"); 12609 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12610 "Starting Norm", "Restarting PERS", dumpPackage); 12611 } 12612 12613 if (mRemovedProcesses.size() > 0) { 12614 if (needSep) pw.println(); 12615 needSep = true; 12616 printedAnything = true; 12617 pw.println(" Processes that are being removed:"); 12618 dumpProcessList(pw, this, mRemovedProcesses, " ", 12619 "Removed Norm", "Removed PERS", dumpPackage); 12620 } 12621 12622 if (mProcessesOnHold.size() > 0) { 12623 if (needSep) pw.println(); 12624 needSep = true; 12625 printedAnything = true; 12626 pw.println(" Processes that are on old until the system is ready:"); 12627 dumpProcessList(pw, this, mProcessesOnHold, " ", 12628 "OnHold Norm", "OnHold PERS", dumpPackage); 12629 } 12630 12631 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12632 12633 if (mProcessCrashTimes.getMap().size() > 0) { 12634 boolean printed = false; 12635 long now = SystemClock.uptimeMillis(); 12636 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12637 final int NP = pmap.size(); 12638 for (int ip=0; ip<NP; ip++) { 12639 String pname = pmap.keyAt(ip); 12640 SparseArray<Long> uids = pmap.valueAt(ip); 12641 final int N = uids.size(); 12642 for (int i=0; i<N; i++) { 12643 int puid = uids.keyAt(i); 12644 ProcessRecord r = mProcessNames.get(pname, puid); 12645 if (dumpPackage != null && (r == null 12646 || !r.pkgList.containsKey(dumpPackage))) { 12647 continue; 12648 } 12649 if (!printed) { 12650 if (needSep) pw.println(); 12651 needSep = true; 12652 pw.println(" Time since processes crashed:"); 12653 printed = true; 12654 printedAnything = true; 12655 } 12656 pw.print(" Process "); pw.print(pname); 12657 pw.print(" uid "); pw.print(puid); 12658 pw.print(": last crashed "); 12659 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12660 pw.println(" ago"); 12661 } 12662 } 12663 } 12664 12665 if (mBadProcesses.getMap().size() > 0) { 12666 boolean printed = false; 12667 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12668 final int NP = pmap.size(); 12669 for (int ip=0; ip<NP; ip++) { 12670 String pname = pmap.keyAt(ip); 12671 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12672 final int N = uids.size(); 12673 for (int i=0; i<N; i++) { 12674 int puid = uids.keyAt(i); 12675 ProcessRecord r = mProcessNames.get(pname, puid); 12676 if (dumpPackage != null && (r == null 12677 || !r.pkgList.containsKey(dumpPackage))) { 12678 continue; 12679 } 12680 if (!printed) { 12681 if (needSep) pw.println(); 12682 needSep = true; 12683 pw.println(" Bad processes:"); 12684 printedAnything = true; 12685 } 12686 BadProcessInfo info = uids.valueAt(i); 12687 pw.print(" Bad process "); pw.print(pname); 12688 pw.print(" uid "); pw.print(puid); 12689 pw.print(": crashed at time "); pw.println(info.time); 12690 if (info.shortMsg != null) { 12691 pw.print(" Short msg: "); pw.println(info.shortMsg); 12692 } 12693 if (info.longMsg != null) { 12694 pw.print(" Long msg: "); pw.println(info.longMsg); 12695 } 12696 if (info.stack != null) { 12697 pw.println(" Stack:"); 12698 int lastPos = 0; 12699 for (int pos=0; pos<info.stack.length(); pos++) { 12700 if (info.stack.charAt(pos) == '\n') { 12701 pw.print(" "); 12702 pw.write(info.stack, lastPos, pos-lastPos); 12703 pw.println(); 12704 lastPos = pos+1; 12705 } 12706 } 12707 if (lastPos < info.stack.length()) { 12708 pw.print(" "); 12709 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12710 pw.println(); 12711 } 12712 } 12713 } 12714 } 12715 } 12716 12717 if (dumpPackage == null) { 12718 pw.println(); 12719 needSep = false; 12720 pw.println(" mStartedUsers:"); 12721 for (int i=0; i<mStartedUsers.size(); i++) { 12722 UserStartedState uss = mStartedUsers.valueAt(i); 12723 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12724 pw.print(": "); uss.dump("", pw); 12725 } 12726 pw.print(" mStartedUserArray: ["); 12727 for (int i=0; i<mStartedUserArray.length; i++) { 12728 if (i > 0) pw.print(", "); 12729 pw.print(mStartedUserArray[i]); 12730 } 12731 pw.println("]"); 12732 pw.print(" mUserLru: ["); 12733 for (int i=0; i<mUserLru.size(); i++) { 12734 if (i > 0) pw.print(", "); 12735 pw.print(mUserLru.get(i)); 12736 } 12737 pw.println("]"); 12738 if (dumpAll) { 12739 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12740 } 12741 synchronized (mUserProfileGroupIdsSelfLocked) { 12742 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12743 pw.println(" mUserProfileGroupIds:"); 12744 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12745 pw.print(" User #"); 12746 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12747 pw.print(" -> profile #"); 12748 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12749 } 12750 } 12751 } 12752 } 12753 if (mHomeProcess != null && (dumpPackage == null 12754 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12755 if (needSep) { 12756 pw.println(); 12757 needSep = false; 12758 } 12759 pw.println(" mHomeProcess: " + mHomeProcess); 12760 } 12761 if (mPreviousProcess != null && (dumpPackage == null 12762 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12763 if (needSep) { 12764 pw.println(); 12765 needSep = false; 12766 } 12767 pw.println(" mPreviousProcess: " + mPreviousProcess); 12768 } 12769 if (dumpAll) { 12770 StringBuilder sb = new StringBuilder(128); 12771 sb.append(" mPreviousProcessVisibleTime: "); 12772 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12773 pw.println(sb); 12774 } 12775 if (mHeavyWeightProcess != null && (dumpPackage == null 12776 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12777 if (needSep) { 12778 pw.println(); 12779 needSep = false; 12780 } 12781 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12782 } 12783 if (dumpPackage == null) { 12784 pw.println(" mConfiguration: " + mConfiguration); 12785 } 12786 if (dumpAll) { 12787 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12788 if (mCompatModePackages.getPackages().size() > 0) { 12789 boolean printed = false; 12790 for (Map.Entry<String, Integer> entry 12791 : mCompatModePackages.getPackages().entrySet()) { 12792 String pkg = entry.getKey(); 12793 int mode = entry.getValue(); 12794 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12795 continue; 12796 } 12797 if (!printed) { 12798 pw.println(" mScreenCompatPackages:"); 12799 printed = true; 12800 } 12801 pw.print(" "); pw.print(pkg); pw.print(": "); 12802 pw.print(mode); pw.println(); 12803 } 12804 } 12805 } 12806 if (dumpPackage == null) { 12807 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12808 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12809 + " mLockScreenShown " + lockScreenShownToString()); 12810 } 12811 if (mShuttingDown || mRunningVoice) { 12812 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12813 } 12814 } 12815 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12816 || mOrigWaitForDebugger) { 12817 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12818 || dumpPackage.equals(mOrigDebugApp)) { 12819 if (needSep) { 12820 pw.println(); 12821 needSep = false; 12822 } 12823 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12824 + " mDebugTransient=" + mDebugTransient 12825 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12826 } 12827 } 12828 if (mOpenGlTraceApp != null) { 12829 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12830 if (needSep) { 12831 pw.println(); 12832 needSep = false; 12833 } 12834 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12835 } 12836 } 12837 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12838 || mProfileFd != null) { 12839 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12840 if (needSep) { 12841 pw.println(); 12842 needSep = false; 12843 } 12844 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12845 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12846 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12847 + mAutoStopProfiler); 12848 pw.println(" mProfileType=" + mProfileType); 12849 } 12850 } 12851 if (dumpPackage == null) { 12852 if (mAlwaysFinishActivities || mController != null) { 12853 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12854 + " mController=" + mController); 12855 } 12856 if (dumpAll) { 12857 pw.println(" Total persistent processes: " + numPers); 12858 pw.println(" mProcessesReady=" + mProcessesReady 12859 + " mSystemReady=" + mSystemReady 12860 + " mBooted=" + mBooted 12861 + " mFactoryTest=" + mFactoryTest); 12862 pw.println(" mBooting=" + mBooting 12863 + " mCallFinishBooting=" + mCallFinishBooting 12864 + " mBootAnimationComplete=" + mBootAnimationComplete); 12865 pw.print(" mLastPowerCheckRealtime="); 12866 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12867 pw.println(""); 12868 pw.print(" mLastPowerCheckUptime="); 12869 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12870 pw.println(""); 12871 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12872 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12873 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12874 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12875 + " (" + mLruProcesses.size() + " total)" 12876 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12877 + " mNumServiceProcs=" + mNumServiceProcs 12878 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12879 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12880 + " mLastMemoryLevel" + mLastMemoryLevel 12881 + " mLastNumProcesses" + mLastNumProcesses); 12882 long now = SystemClock.uptimeMillis(); 12883 pw.print(" mLastIdleTime="); 12884 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12885 pw.print(" mLowRamSinceLastIdle="); 12886 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12887 pw.println(); 12888 } 12889 } 12890 12891 if (!printedAnything) { 12892 pw.println(" (nothing)"); 12893 } 12894 } 12895 12896 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12897 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12898 if (mProcessesToGc.size() > 0) { 12899 boolean printed = false; 12900 long now = SystemClock.uptimeMillis(); 12901 for (int i=0; i<mProcessesToGc.size(); i++) { 12902 ProcessRecord proc = mProcessesToGc.get(i); 12903 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12904 continue; 12905 } 12906 if (!printed) { 12907 if (needSep) pw.println(); 12908 needSep = true; 12909 pw.println(" Processes that are waiting to GC:"); 12910 printed = true; 12911 } 12912 pw.print(" Process "); pw.println(proc); 12913 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12914 pw.print(", last gced="); 12915 pw.print(now-proc.lastRequestedGc); 12916 pw.print(" ms ago, last lowMem="); 12917 pw.print(now-proc.lastLowMemory); 12918 pw.println(" ms ago"); 12919 12920 } 12921 } 12922 return needSep; 12923 } 12924 12925 void printOomLevel(PrintWriter pw, String name, int adj) { 12926 pw.print(" "); 12927 if (adj >= 0) { 12928 pw.print(' '); 12929 if (adj < 10) pw.print(' '); 12930 } else { 12931 if (adj > -10) pw.print(' '); 12932 } 12933 pw.print(adj); 12934 pw.print(": "); 12935 pw.print(name); 12936 pw.print(" ("); 12937 pw.print(mProcessList.getMemLevel(adj)/1024); 12938 pw.println(" kB)"); 12939 } 12940 12941 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12942 int opti, boolean dumpAll) { 12943 boolean needSep = false; 12944 12945 if (mLruProcesses.size() > 0) { 12946 if (needSep) pw.println(); 12947 needSep = true; 12948 pw.println(" OOM levels:"); 12949 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12950 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12951 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12952 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12953 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12954 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12955 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12956 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12957 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12958 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12959 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12960 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12961 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12962 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12963 12964 if (needSep) pw.println(); 12965 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12966 pw.print(" total, non-act at "); 12967 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12968 pw.print(", non-svc at "); 12969 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12970 pw.println("):"); 12971 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12972 needSep = true; 12973 } 12974 12975 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12976 12977 pw.println(); 12978 pw.println(" mHomeProcess: " + mHomeProcess); 12979 pw.println(" mPreviousProcess: " + mPreviousProcess); 12980 if (mHeavyWeightProcess != null) { 12981 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12982 } 12983 12984 return true; 12985 } 12986 12987 /** 12988 * There are three ways to call this: 12989 * - no provider specified: dump all the providers 12990 * - a flattened component name that matched an existing provider was specified as the 12991 * first arg: dump that one provider 12992 * - the first arg isn't the flattened component name of an existing provider: 12993 * dump all providers whose component contains the first arg as a substring 12994 */ 12995 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12996 int opti, boolean dumpAll) { 12997 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12998 } 12999 13000 static class ItemMatcher { 13001 ArrayList<ComponentName> components; 13002 ArrayList<String> strings; 13003 ArrayList<Integer> objects; 13004 boolean all; 13005 13006 ItemMatcher() { 13007 all = true; 13008 } 13009 13010 void build(String name) { 13011 ComponentName componentName = ComponentName.unflattenFromString(name); 13012 if (componentName != null) { 13013 if (components == null) { 13014 components = new ArrayList<ComponentName>(); 13015 } 13016 components.add(componentName); 13017 all = false; 13018 } else { 13019 int objectId = 0; 13020 // Not a '/' separated full component name; maybe an object ID? 13021 try { 13022 objectId = Integer.parseInt(name, 16); 13023 if (objects == null) { 13024 objects = new ArrayList<Integer>(); 13025 } 13026 objects.add(objectId); 13027 all = false; 13028 } catch (RuntimeException e) { 13029 // Not an integer; just do string match. 13030 if (strings == null) { 13031 strings = new ArrayList<String>(); 13032 } 13033 strings.add(name); 13034 all = false; 13035 } 13036 } 13037 } 13038 13039 int build(String[] args, int opti) { 13040 for (; opti<args.length; opti++) { 13041 String name = args[opti]; 13042 if ("--".equals(name)) { 13043 return opti+1; 13044 } 13045 build(name); 13046 } 13047 return opti; 13048 } 13049 13050 boolean match(Object object, ComponentName comp) { 13051 if (all) { 13052 return true; 13053 } 13054 if (components != null) { 13055 for (int i=0; i<components.size(); i++) { 13056 if (components.get(i).equals(comp)) { 13057 return true; 13058 } 13059 } 13060 } 13061 if (objects != null) { 13062 for (int i=0; i<objects.size(); i++) { 13063 if (System.identityHashCode(object) == objects.get(i)) { 13064 return true; 13065 } 13066 } 13067 } 13068 if (strings != null) { 13069 String flat = comp.flattenToString(); 13070 for (int i=0; i<strings.size(); i++) { 13071 if (flat.contains(strings.get(i))) { 13072 return true; 13073 } 13074 } 13075 } 13076 return false; 13077 } 13078 } 13079 13080 /** 13081 * There are three things that cmd can be: 13082 * - a flattened component name that matches an existing activity 13083 * - the cmd arg isn't the flattened component name of an existing activity: 13084 * dump all activity whose component contains the cmd as a substring 13085 * - A hex number of the ActivityRecord object instance. 13086 */ 13087 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13088 int opti, boolean dumpAll) { 13089 ArrayList<ActivityRecord> activities; 13090 13091 synchronized (this) { 13092 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13093 } 13094 13095 if (activities.size() <= 0) { 13096 return false; 13097 } 13098 13099 String[] newArgs = new String[args.length - opti]; 13100 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13101 13102 TaskRecord lastTask = null; 13103 boolean needSep = false; 13104 for (int i=activities.size()-1; i>=0; i--) { 13105 ActivityRecord r = activities.get(i); 13106 if (needSep) { 13107 pw.println(); 13108 } 13109 needSep = true; 13110 synchronized (this) { 13111 if (lastTask != r.task) { 13112 lastTask = r.task; 13113 pw.print("TASK "); pw.print(lastTask.affinity); 13114 pw.print(" id="); pw.println(lastTask.taskId); 13115 if (dumpAll) { 13116 lastTask.dump(pw, " "); 13117 } 13118 } 13119 } 13120 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13121 } 13122 return true; 13123 } 13124 13125 /** 13126 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13127 * there is a thread associated with the activity. 13128 */ 13129 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13130 final ActivityRecord r, String[] args, boolean dumpAll) { 13131 String innerPrefix = prefix + " "; 13132 synchronized (this) { 13133 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13134 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13135 pw.print(" pid="); 13136 if (r.app != null) pw.println(r.app.pid); 13137 else pw.println("(not running)"); 13138 if (dumpAll) { 13139 r.dump(pw, innerPrefix); 13140 } 13141 } 13142 if (r.app != null && r.app.thread != null) { 13143 // flush anything that is already in the PrintWriter since the thread is going 13144 // to write to the file descriptor directly 13145 pw.flush(); 13146 try { 13147 TransferPipe tp = new TransferPipe(); 13148 try { 13149 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13150 r.appToken, innerPrefix, args); 13151 tp.go(fd); 13152 } finally { 13153 tp.kill(); 13154 } 13155 } catch (IOException e) { 13156 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13157 } catch (RemoteException e) { 13158 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13159 } 13160 } 13161 } 13162 13163 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13164 int opti, boolean dumpAll, String dumpPackage) { 13165 boolean needSep = false; 13166 boolean onlyHistory = false; 13167 boolean printedAnything = false; 13168 13169 if ("history".equals(dumpPackage)) { 13170 if (opti < args.length && "-s".equals(args[opti])) { 13171 dumpAll = false; 13172 } 13173 onlyHistory = true; 13174 dumpPackage = null; 13175 } 13176 13177 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13178 if (!onlyHistory && dumpAll) { 13179 if (mRegisteredReceivers.size() > 0) { 13180 boolean printed = false; 13181 Iterator it = mRegisteredReceivers.values().iterator(); 13182 while (it.hasNext()) { 13183 ReceiverList r = (ReceiverList)it.next(); 13184 if (dumpPackage != null && (r.app == null || 13185 !dumpPackage.equals(r.app.info.packageName))) { 13186 continue; 13187 } 13188 if (!printed) { 13189 pw.println(" Registered Receivers:"); 13190 needSep = true; 13191 printed = true; 13192 printedAnything = true; 13193 } 13194 pw.print(" * "); pw.println(r); 13195 r.dump(pw, " "); 13196 } 13197 } 13198 13199 if (mReceiverResolver.dump(pw, needSep ? 13200 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13201 " ", dumpPackage, false)) { 13202 needSep = true; 13203 printedAnything = true; 13204 } 13205 } 13206 13207 for (BroadcastQueue q : mBroadcastQueues) { 13208 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13209 printedAnything |= needSep; 13210 } 13211 13212 needSep = true; 13213 13214 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13215 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13216 if (needSep) { 13217 pw.println(); 13218 } 13219 needSep = true; 13220 printedAnything = true; 13221 pw.print(" Sticky broadcasts for user "); 13222 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13223 StringBuilder sb = new StringBuilder(128); 13224 for (Map.Entry<String, ArrayList<Intent>> ent 13225 : mStickyBroadcasts.valueAt(user).entrySet()) { 13226 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13227 if (dumpAll) { 13228 pw.println(":"); 13229 ArrayList<Intent> intents = ent.getValue(); 13230 final int N = intents.size(); 13231 for (int i=0; i<N; i++) { 13232 sb.setLength(0); 13233 sb.append(" Intent: "); 13234 intents.get(i).toShortString(sb, false, true, false, false); 13235 pw.println(sb.toString()); 13236 Bundle bundle = intents.get(i).getExtras(); 13237 if (bundle != null) { 13238 pw.print(" "); 13239 pw.println(bundle.toString()); 13240 } 13241 } 13242 } else { 13243 pw.println(""); 13244 } 13245 } 13246 } 13247 } 13248 13249 if (!onlyHistory && dumpAll) { 13250 pw.println(); 13251 for (BroadcastQueue queue : mBroadcastQueues) { 13252 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13253 + queue.mBroadcastsScheduled); 13254 } 13255 pw.println(" mHandler:"); 13256 mHandler.dump(new PrintWriterPrinter(pw), " "); 13257 needSep = true; 13258 printedAnything = true; 13259 } 13260 13261 if (!printedAnything) { 13262 pw.println(" (nothing)"); 13263 } 13264 } 13265 13266 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13267 int opti, boolean dumpAll, String dumpPackage) { 13268 boolean needSep; 13269 boolean printedAnything = false; 13270 13271 ItemMatcher matcher = new ItemMatcher(); 13272 matcher.build(args, opti); 13273 13274 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13275 13276 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13277 printedAnything |= needSep; 13278 13279 if (mLaunchingProviders.size() > 0) { 13280 boolean printed = false; 13281 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13282 ContentProviderRecord r = mLaunchingProviders.get(i); 13283 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13284 continue; 13285 } 13286 if (!printed) { 13287 if (needSep) pw.println(); 13288 needSep = true; 13289 pw.println(" Launching content providers:"); 13290 printed = true; 13291 printedAnything = true; 13292 } 13293 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13294 pw.println(r); 13295 } 13296 } 13297 13298 if (mGrantedUriPermissions.size() > 0) { 13299 boolean printed = false; 13300 int dumpUid = -2; 13301 if (dumpPackage != null) { 13302 try { 13303 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13304 } catch (NameNotFoundException e) { 13305 dumpUid = -1; 13306 } 13307 } 13308 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13309 int uid = mGrantedUriPermissions.keyAt(i); 13310 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13311 continue; 13312 } 13313 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13314 if (!printed) { 13315 if (needSep) pw.println(); 13316 needSep = true; 13317 pw.println(" Granted Uri Permissions:"); 13318 printed = true; 13319 printedAnything = true; 13320 } 13321 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13322 for (UriPermission perm : perms.values()) { 13323 pw.print(" "); pw.println(perm); 13324 if (dumpAll) { 13325 perm.dump(pw, " "); 13326 } 13327 } 13328 } 13329 } 13330 13331 if (!printedAnything) { 13332 pw.println(" (nothing)"); 13333 } 13334 } 13335 13336 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13337 int opti, boolean dumpAll, String dumpPackage) { 13338 boolean printed = false; 13339 13340 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13341 13342 if (mIntentSenderRecords.size() > 0) { 13343 Iterator<WeakReference<PendingIntentRecord>> it 13344 = mIntentSenderRecords.values().iterator(); 13345 while (it.hasNext()) { 13346 WeakReference<PendingIntentRecord> ref = it.next(); 13347 PendingIntentRecord rec = ref != null ? ref.get(): null; 13348 if (dumpPackage != null && (rec == null 13349 || !dumpPackage.equals(rec.key.packageName))) { 13350 continue; 13351 } 13352 printed = true; 13353 if (rec != null) { 13354 pw.print(" * "); pw.println(rec); 13355 if (dumpAll) { 13356 rec.dump(pw, " "); 13357 } 13358 } else { 13359 pw.print(" * "); pw.println(ref); 13360 } 13361 } 13362 } 13363 13364 if (!printed) { 13365 pw.println(" (nothing)"); 13366 } 13367 } 13368 13369 private static final int dumpProcessList(PrintWriter pw, 13370 ActivityManagerService service, List list, 13371 String prefix, String normalLabel, String persistentLabel, 13372 String dumpPackage) { 13373 int numPers = 0; 13374 final int N = list.size()-1; 13375 for (int i=N; i>=0; i--) { 13376 ProcessRecord r = (ProcessRecord)list.get(i); 13377 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13378 continue; 13379 } 13380 pw.println(String.format("%s%s #%2d: %s", 13381 prefix, (r.persistent ? persistentLabel : normalLabel), 13382 i, r.toString())); 13383 if (r.persistent) { 13384 numPers++; 13385 } 13386 } 13387 return numPers; 13388 } 13389 13390 private static final boolean dumpProcessOomList(PrintWriter pw, 13391 ActivityManagerService service, List<ProcessRecord> origList, 13392 String prefix, String normalLabel, String persistentLabel, 13393 boolean inclDetails, String dumpPackage) { 13394 13395 ArrayList<Pair<ProcessRecord, Integer>> list 13396 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13397 for (int i=0; i<origList.size(); i++) { 13398 ProcessRecord r = origList.get(i); 13399 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13400 continue; 13401 } 13402 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13403 } 13404 13405 if (list.size() <= 0) { 13406 return false; 13407 } 13408 13409 Comparator<Pair<ProcessRecord, Integer>> comparator 13410 = new Comparator<Pair<ProcessRecord, Integer>>() { 13411 @Override 13412 public int compare(Pair<ProcessRecord, Integer> object1, 13413 Pair<ProcessRecord, Integer> object2) { 13414 if (object1.first.setAdj != object2.first.setAdj) { 13415 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13416 } 13417 if (object1.second.intValue() != object2.second.intValue()) { 13418 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13419 } 13420 return 0; 13421 } 13422 }; 13423 13424 Collections.sort(list, comparator); 13425 13426 final long curRealtime = SystemClock.elapsedRealtime(); 13427 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13428 final long curUptime = SystemClock.uptimeMillis(); 13429 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13430 13431 for (int i=list.size()-1; i>=0; i--) { 13432 ProcessRecord r = list.get(i).first; 13433 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13434 char schedGroup; 13435 switch (r.setSchedGroup) { 13436 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13437 schedGroup = 'B'; 13438 break; 13439 case Process.THREAD_GROUP_DEFAULT: 13440 schedGroup = 'F'; 13441 break; 13442 default: 13443 schedGroup = '?'; 13444 break; 13445 } 13446 char foreground; 13447 if (r.foregroundActivities) { 13448 foreground = 'A'; 13449 } else if (r.foregroundServices) { 13450 foreground = 'S'; 13451 } else { 13452 foreground = ' '; 13453 } 13454 String procState = ProcessList.makeProcStateString(r.curProcState); 13455 pw.print(prefix); 13456 pw.print(r.persistent ? persistentLabel : normalLabel); 13457 pw.print(" #"); 13458 int num = (origList.size()-1)-list.get(i).second; 13459 if (num < 10) pw.print(' '); 13460 pw.print(num); 13461 pw.print(": "); 13462 pw.print(oomAdj); 13463 pw.print(' '); 13464 pw.print(schedGroup); 13465 pw.print('/'); 13466 pw.print(foreground); 13467 pw.print('/'); 13468 pw.print(procState); 13469 pw.print(" trm:"); 13470 if (r.trimMemoryLevel < 10) pw.print(' '); 13471 pw.print(r.trimMemoryLevel); 13472 pw.print(' '); 13473 pw.print(r.toShortString()); 13474 pw.print(" ("); 13475 pw.print(r.adjType); 13476 pw.println(')'); 13477 if (r.adjSource != null || r.adjTarget != null) { 13478 pw.print(prefix); 13479 pw.print(" "); 13480 if (r.adjTarget instanceof ComponentName) { 13481 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13482 } else if (r.adjTarget != null) { 13483 pw.print(r.adjTarget.toString()); 13484 } else { 13485 pw.print("{null}"); 13486 } 13487 pw.print("<="); 13488 if (r.adjSource instanceof ProcessRecord) { 13489 pw.print("Proc{"); 13490 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13491 pw.println("}"); 13492 } else if (r.adjSource != null) { 13493 pw.println(r.adjSource.toString()); 13494 } else { 13495 pw.println("{null}"); 13496 } 13497 } 13498 if (inclDetails) { 13499 pw.print(prefix); 13500 pw.print(" "); 13501 pw.print("oom: max="); pw.print(r.maxAdj); 13502 pw.print(" curRaw="); pw.print(r.curRawAdj); 13503 pw.print(" setRaw="); pw.print(r.setRawAdj); 13504 pw.print(" cur="); pw.print(r.curAdj); 13505 pw.print(" set="); pw.println(r.setAdj); 13506 pw.print(prefix); 13507 pw.print(" "); 13508 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13509 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13510 pw.print(" lastPss="); pw.print(r.lastPss); 13511 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13512 pw.print(prefix); 13513 pw.print(" "); 13514 pw.print("cached="); pw.print(r.cached); 13515 pw.print(" empty="); pw.print(r.empty); 13516 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13517 13518 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13519 if (r.lastWakeTime != 0) { 13520 long wtime; 13521 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13522 synchronized (stats) { 13523 wtime = stats.getProcessWakeTime(r.info.uid, 13524 r.pid, curRealtime); 13525 } 13526 long timeUsed = wtime - r.lastWakeTime; 13527 pw.print(prefix); 13528 pw.print(" "); 13529 pw.print("keep awake over "); 13530 TimeUtils.formatDuration(realtimeSince, pw); 13531 pw.print(" used "); 13532 TimeUtils.formatDuration(timeUsed, pw); 13533 pw.print(" ("); 13534 pw.print((timeUsed*100)/realtimeSince); 13535 pw.println("%)"); 13536 } 13537 if (r.lastCpuTime != 0) { 13538 long timeUsed = r.curCpuTime - r.lastCpuTime; 13539 pw.print(prefix); 13540 pw.print(" "); 13541 pw.print("run cpu over "); 13542 TimeUtils.formatDuration(uptimeSince, pw); 13543 pw.print(" used "); 13544 TimeUtils.formatDuration(timeUsed, pw); 13545 pw.print(" ("); 13546 pw.print((timeUsed*100)/uptimeSince); 13547 pw.println("%)"); 13548 } 13549 } 13550 } 13551 } 13552 return true; 13553 } 13554 13555 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13556 String[] args) { 13557 ArrayList<ProcessRecord> procs; 13558 synchronized (this) { 13559 if (args != null && args.length > start 13560 && args[start].charAt(0) != '-') { 13561 procs = new ArrayList<ProcessRecord>(); 13562 int pid = -1; 13563 try { 13564 pid = Integer.parseInt(args[start]); 13565 } catch (NumberFormatException e) { 13566 } 13567 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13568 ProcessRecord proc = mLruProcesses.get(i); 13569 if (proc.pid == pid) { 13570 procs.add(proc); 13571 } else if (allPkgs && proc.pkgList != null 13572 && proc.pkgList.containsKey(args[start])) { 13573 procs.add(proc); 13574 } else if (proc.processName.equals(args[start])) { 13575 procs.add(proc); 13576 } 13577 } 13578 if (procs.size() <= 0) { 13579 return null; 13580 } 13581 } else { 13582 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13583 } 13584 } 13585 return procs; 13586 } 13587 13588 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13589 PrintWriter pw, String[] args) { 13590 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13591 if (procs == null) { 13592 pw.println("No process found for: " + args[0]); 13593 return; 13594 } 13595 13596 long uptime = SystemClock.uptimeMillis(); 13597 long realtime = SystemClock.elapsedRealtime(); 13598 pw.println("Applications Graphics Acceleration Info:"); 13599 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13600 13601 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13602 ProcessRecord r = procs.get(i); 13603 if (r.thread != null) { 13604 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13605 pw.flush(); 13606 try { 13607 TransferPipe tp = new TransferPipe(); 13608 try { 13609 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13610 tp.go(fd); 13611 } finally { 13612 tp.kill(); 13613 } 13614 } catch (IOException e) { 13615 pw.println("Failure while dumping the app: " + r); 13616 pw.flush(); 13617 } catch (RemoteException e) { 13618 pw.println("Got a RemoteException while dumping the app " + r); 13619 pw.flush(); 13620 } 13621 } 13622 } 13623 } 13624 13625 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13626 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13627 if (procs == null) { 13628 pw.println("No process found for: " + args[0]); 13629 return; 13630 } 13631 13632 pw.println("Applications Database Info:"); 13633 13634 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13635 ProcessRecord r = procs.get(i); 13636 if (r.thread != null) { 13637 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13638 pw.flush(); 13639 try { 13640 TransferPipe tp = new TransferPipe(); 13641 try { 13642 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13643 tp.go(fd); 13644 } finally { 13645 tp.kill(); 13646 } 13647 } catch (IOException e) { 13648 pw.println("Failure while dumping the app: " + r); 13649 pw.flush(); 13650 } catch (RemoteException e) { 13651 pw.println("Got a RemoteException while dumping the app " + r); 13652 pw.flush(); 13653 } 13654 } 13655 } 13656 } 13657 13658 final static class MemItem { 13659 final boolean isProc; 13660 final String label; 13661 final String shortLabel; 13662 final long pss; 13663 final int id; 13664 final boolean hasActivities; 13665 ArrayList<MemItem> subitems; 13666 13667 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13668 boolean _hasActivities) { 13669 isProc = true; 13670 label = _label; 13671 shortLabel = _shortLabel; 13672 pss = _pss; 13673 id = _id; 13674 hasActivities = _hasActivities; 13675 } 13676 13677 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13678 isProc = false; 13679 label = _label; 13680 shortLabel = _shortLabel; 13681 pss = _pss; 13682 id = _id; 13683 hasActivities = false; 13684 } 13685 } 13686 13687 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13688 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13689 if (sort && !isCompact) { 13690 Collections.sort(items, new Comparator<MemItem>() { 13691 @Override 13692 public int compare(MemItem lhs, MemItem rhs) { 13693 if (lhs.pss < rhs.pss) { 13694 return 1; 13695 } else if (lhs.pss > rhs.pss) { 13696 return -1; 13697 } 13698 return 0; 13699 } 13700 }); 13701 } 13702 13703 for (int i=0; i<items.size(); i++) { 13704 MemItem mi = items.get(i); 13705 if (!isCompact) { 13706 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13707 } else if (mi.isProc) { 13708 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13709 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13710 pw.println(mi.hasActivities ? ",a" : ",e"); 13711 } else { 13712 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13713 pw.println(mi.pss); 13714 } 13715 if (mi.subitems != null) { 13716 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13717 true, isCompact); 13718 } 13719 } 13720 } 13721 13722 // These are in KB. 13723 static final long[] DUMP_MEM_BUCKETS = new long[] { 13724 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13725 120*1024, 160*1024, 200*1024, 13726 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13727 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13728 }; 13729 13730 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13731 boolean stackLike) { 13732 int start = label.lastIndexOf('.'); 13733 if (start >= 0) start++; 13734 else start = 0; 13735 int end = label.length(); 13736 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13737 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13738 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13739 out.append(bucket); 13740 out.append(stackLike ? "MB." : "MB "); 13741 out.append(label, start, end); 13742 return; 13743 } 13744 } 13745 out.append(memKB/1024); 13746 out.append(stackLike ? "MB." : "MB "); 13747 out.append(label, start, end); 13748 } 13749 13750 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13751 ProcessList.NATIVE_ADJ, 13752 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13753 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13754 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13755 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13756 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13757 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13758 }; 13759 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13760 "Native", 13761 "System", "Persistent", "Persistent Service", "Foreground", 13762 "Visible", "Perceptible", 13763 "Heavy Weight", "Backup", 13764 "A Services", "Home", 13765 "Previous", "B Services", "Cached" 13766 }; 13767 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13768 "native", 13769 "sys", "pers", "persvc", "fore", 13770 "vis", "percept", 13771 "heavy", "backup", 13772 "servicea", "home", 13773 "prev", "serviceb", "cached" 13774 }; 13775 13776 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13777 long realtime, boolean isCheckinRequest, boolean isCompact) { 13778 if (isCheckinRequest || isCompact) { 13779 // short checkin version 13780 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13781 } else { 13782 pw.println("Applications Memory Usage (kB):"); 13783 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13784 } 13785 } 13786 13787 private static final int KSM_SHARED = 0; 13788 private static final int KSM_SHARING = 1; 13789 private static final int KSM_UNSHARED = 2; 13790 private static final int KSM_VOLATILE = 3; 13791 13792 private final long[] getKsmInfo() { 13793 long[] longOut = new long[4]; 13794 final int[] SINGLE_LONG_FORMAT = new int[] { 13795 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13796 }; 13797 long[] longTmp = new long[1]; 13798 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13799 SINGLE_LONG_FORMAT, null, longTmp, null); 13800 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13801 longTmp[0] = 0; 13802 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13803 SINGLE_LONG_FORMAT, null, longTmp, null); 13804 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13805 longTmp[0] = 0; 13806 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13807 SINGLE_LONG_FORMAT, null, longTmp, null); 13808 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13809 longTmp[0] = 0; 13810 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13811 SINGLE_LONG_FORMAT, null, longTmp, null); 13812 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13813 return longOut; 13814 } 13815 13816 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13817 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13818 boolean dumpDetails = false; 13819 boolean dumpFullDetails = false; 13820 boolean dumpDalvik = false; 13821 boolean oomOnly = false; 13822 boolean isCompact = false; 13823 boolean localOnly = false; 13824 boolean packages = false; 13825 13826 int opti = 0; 13827 while (opti < args.length) { 13828 String opt = args[opti]; 13829 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13830 break; 13831 } 13832 opti++; 13833 if ("-a".equals(opt)) { 13834 dumpDetails = true; 13835 dumpFullDetails = true; 13836 dumpDalvik = true; 13837 } else if ("-d".equals(opt)) { 13838 dumpDalvik = true; 13839 } else if ("-c".equals(opt)) { 13840 isCompact = true; 13841 } else if ("--oom".equals(opt)) { 13842 oomOnly = true; 13843 } else if ("--local".equals(opt)) { 13844 localOnly = true; 13845 } else if ("--package".equals(opt)) { 13846 packages = true; 13847 } else if ("-h".equals(opt)) { 13848 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13849 pw.println(" -a: include all available information for each process."); 13850 pw.println(" -d: include dalvik details when dumping process details."); 13851 pw.println(" -c: dump in a compact machine-parseable representation."); 13852 pw.println(" --oom: only show processes organized by oom adj."); 13853 pw.println(" --local: only collect details locally, don't call process."); 13854 pw.println(" --package: interpret process arg as package, dumping all"); 13855 pw.println(" processes that have loaded that package."); 13856 pw.println("If [process] is specified it can be the name or "); 13857 pw.println("pid of a specific process to dump."); 13858 return; 13859 } else { 13860 pw.println("Unknown argument: " + opt + "; use -h for help"); 13861 } 13862 } 13863 13864 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13865 long uptime = SystemClock.uptimeMillis(); 13866 long realtime = SystemClock.elapsedRealtime(); 13867 final long[] tmpLong = new long[1]; 13868 13869 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13870 if (procs == null) { 13871 // No Java processes. Maybe they want to print a native process. 13872 if (args != null && args.length > opti 13873 && args[opti].charAt(0) != '-') { 13874 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13875 = new ArrayList<ProcessCpuTracker.Stats>(); 13876 updateCpuStatsNow(); 13877 int findPid = -1; 13878 try { 13879 findPid = Integer.parseInt(args[opti]); 13880 } catch (NumberFormatException e) { 13881 } 13882 synchronized (mProcessCpuTracker) { 13883 final int N = mProcessCpuTracker.countStats(); 13884 for (int i=0; i<N; i++) { 13885 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13886 if (st.pid == findPid || (st.baseName != null 13887 && st.baseName.equals(args[opti]))) { 13888 nativeProcs.add(st); 13889 } 13890 } 13891 } 13892 if (nativeProcs.size() > 0) { 13893 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13894 isCompact); 13895 Debug.MemoryInfo mi = null; 13896 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13897 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13898 final int pid = r.pid; 13899 if (!isCheckinRequest && dumpDetails) { 13900 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13901 } 13902 if (mi == null) { 13903 mi = new Debug.MemoryInfo(); 13904 } 13905 if (dumpDetails || (!brief && !oomOnly)) { 13906 Debug.getMemoryInfo(pid, mi); 13907 } else { 13908 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13909 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13910 } 13911 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13912 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13913 if (isCheckinRequest) { 13914 pw.println(); 13915 } 13916 } 13917 return; 13918 } 13919 } 13920 pw.println("No process found for: " + args[opti]); 13921 return; 13922 } 13923 13924 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13925 dumpDetails = true; 13926 } 13927 13928 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13929 13930 String[] innerArgs = new String[args.length-opti]; 13931 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13932 13933 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13934 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13935 long nativePss=0, dalvikPss=0, otherPss=0; 13936 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13937 13938 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13939 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13940 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13941 13942 long totalPss = 0; 13943 long cachedPss = 0; 13944 13945 Debug.MemoryInfo mi = null; 13946 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13947 final ProcessRecord r = procs.get(i); 13948 final IApplicationThread thread; 13949 final int pid; 13950 final int oomAdj; 13951 final boolean hasActivities; 13952 synchronized (this) { 13953 thread = r.thread; 13954 pid = r.pid; 13955 oomAdj = r.getSetAdjWithServices(); 13956 hasActivities = r.activities.size() > 0; 13957 } 13958 if (thread != null) { 13959 if (!isCheckinRequest && dumpDetails) { 13960 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13961 } 13962 if (mi == null) { 13963 mi = new Debug.MemoryInfo(); 13964 } 13965 if (dumpDetails || (!brief && !oomOnly)) { 13966 Debug.getMemoryInfo(pid, mi); 13967 } else { 13968 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13969 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13970 } 13971 if (dumpDetails) { 13972 if (localOnly) { 13973 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13974 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13975 if (isCheckinRequest) { 13976 pw.println(); 13977 } 13978 } else { 13979 try { 13980 pw.flush(); 13981 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13982 dumpDalvik, innerArgs); 13983 } catch (RemoteException e) { 13984 if (!isCheckinRequest) { 13985 pw.println("Got RemoteException!"); 13986 pw.flush(); 13987 } 13988 } 13989 } 13990 } 13991 13992 final long myTotalPss = mi.getTotalPss(); 13993 final long myTotalUss = mi.getTotalUss(); 13994 13995 synchronized (this) { 13996 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13997 // Record this for posterity if the process has been stable. 13998 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13999 } 14000 } 14001 14002 if (!isCheckinRequest && mi != null) { 14003 totalPss += myTotalPss; 14004 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14005 (hasActivities ? " / activities)" : ")"), 14006 r.processName, myTotalPss, pid, hasActivities); 14007 procMems.add(pssItem); 14008 procMemsMap.put(pid, pssItem); 14009 14010 nativePss += mi.nativePss; 14011 dalvikPss += mi.dalvikPss; 14012 otherPss += mi.otherPss; 14013 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14014 long mem = mi.getOtherPss(j); 14015 miscPss[j] += mem; 14016 otherPss -= mem; 14017 } 14018 14019 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14020 cachedPss += myTotalPss; 14021 } 14022 14023 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14024 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14025 || oomIndex == (oomPss.length-1)) { 14026 oomPss[oomIndex] += myTotalPss; 14027 if (oomProcs[oomIndex] == null) { 14028 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14029 } 14030 oomProcs[oomIndex].add(pssItem); 14031 break; 14032 } 14033 } 14034 } 14035 } 14036 } 14037 14038 long nativeProcTotalPss = 0; 14039 14040 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14041 // If we are showing aggregations, also look for native processes to 14042 // include so that our aggregations are more accurate. 14043 updateCpuStatsNow(); 14044 synchronized (mProcessCpuTracker) { 14045 final int N = mProcessCpuTracker.countStats(); 14046 for (int i=0; i<N; i++) { 14047 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14048 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14049 if (mi == null) { 14050 mi = new Debug.MemoryInfo(); 14051 } 14052 if (!brief && !oomOnly) { 14053 Debug.getMemoryInfo(st.pid, mi); 14054 } else { 14055 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14056 mi.nativePrivateDirty = (int)tmpLong[0]; 14057 } 14058 14059 final long myTotalPss = mi.getTotalPss(); 14060 totalPss += myTotalPss; 14061 nativeProcTotalPss += myTotalPss; 14062 14063 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14064 st.name, myTotalPss, st.pid, false); 14065 procMems.add(pssItem); 14066 14067 nativePss += mi.nativePss; 14068 dalvikPss += mi.dalvikPss; 14069 otherPss += mi.otherPss; 14070 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14071 long mem = mi.getOtherPss(j); 14072 miscPss[j] += mem; 14073 otherPss -= mem; 14074 } 14075 oomPss[0] += myTotalPss; 14076 if (oomProcs[0] == null) { 14077 oomProcs[0] = new ArrayList<MemItem>(); 14078 } 14079 oomProcs[0].add(pssItem); 14080 } 14081 } 14082 } 14083 14084 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14085 14086 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14087 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14088 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14089 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14090 String label = Debug.MemoryInfo.getOtherLabel(j); 14091 catMems.add(new MemItem(label, label, miscPss[j], j)); 14092 } 14093 14094 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14095 for (int j=0; j<oomPss.length; j++) { 14096 if (oomPss[j] != 0) { 14097 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14098 : DUMP_MEM_OOM_LABEL[j]; 14099 MemItem item = new MemItem(label, label, oomPss[j], 14100 DUMP_MEM_OOM_ADJ[j]); 14101 item.subitems = oomProcs[j]; 14102 oomMems.add(item); 14103 } 14104 } 14105 14106 if (!brief && !oomOnly && !isCompact) { 14107 pw.println(); 14108 pw.println("Total PSS by process:"); 14109 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14110 pw.println(); 14111 } 14112 if (!isCompact) { 14113 pw.println("Total PSS by OOM adjustment:"); 14114 } 14115 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14116 if (!brief && !oomOnly) { 14117 PrintWriter out = categoryPw != null ? categoryPw : pw; 14118 if (!isCompact) { 14119 out.println(); 14120 out.println("Total PSS by category:"); 14121 } 14122 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14123 } 14124 if (!isCompact) { 14125 pw.println(); 14126 } 14127 MemInfoReader memInfo = new MemInfoReader(); 14128 memInfo.readMemInfo(); 14129 if (nativeProcTotalPss > 0) { 14130 synchronized (this) { 14131 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14132 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14133 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14134 } 14135 } 14136 if (!brief) { 14137 if (!isCompact) { 14138 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14139 pw.print(" kB (status "); 14140 switch (mLastMemoryLevel) { 14141 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14142 pw.println("normal)"); 14143 break; 14144 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14145 pw.println("moderate)"); 14146 break; 14147 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14148 pw.println("low)"); 14149 break; 14150 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14151 pw.println("critical)"); 14152 break; 14153 default: 14154 pw.print(mLastMemoryLevel); 14155 pw.println(")"); 14156 break; 14157 } 14158 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14159 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14160 pw.print(cachedPss); pw.print(" cached pss + "); 14161 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14162 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14163 } else { 14164 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14165 pw.print(cachedPss + memInfo.getCachedSizeKb() 14166 + memInfo.getFreeSizeKb()); pw.print(","); 14167 pw.println(totalPss - cachedPss); 14168 } 14169 } 14170 if (!isCompact) { 14171 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14172 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14173 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14174 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14175 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14176 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14177 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14178 } 14179 if (!brief) { 14180 if (memInfo.getZramTotalSizeKb() != 0) { 14181 if (!isCompact) { 14182 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14183 pw.print(" kB physical used for "); 14184 pw.print(memInfo.getSwapTotalSizeKb() 14185 - memInfo.getSwapFreeSizeKb()); 14186 pw.print(" kB in swap ("); 14187 pw.print(memInfo.getSwapTotalSizeKb()); 14188 pw.println(" kB total swap)"); 14189 } else { 14190 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14191 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14192 pw.println(memInfo.getSwapFreeSizeKb()); 14193 } 14194 } 14195 final long[] ksm = getKsmInfo(); 14196 if (!isCompact) { 14197 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14198 || ksm[KSM_VOLATILE] != 0) { 14199 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14200 pw.print(" kB saved from shared "); 14201 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14202 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14203 pw.print(" kB unshared; "); 14204 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14205 } 14206 pw.print(" Tuning: "); 14207 pw.print(ActivityManager.staticGetMemoryClass()); 14208 pw.print(" (large "); 14209 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14210 pw.print("), oom "); 14211 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14212 pw.print(" kB"); 14213 pw.print(", restore limit "); 14214 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14215 pw.print(" kB"); 14216 if (ActivityManager.isLowRamDeviceStatic()) { 14217 pw.print(" (low-ram)"); 14218 } 14219 if (ActivityManager.isHighEndGfx()) { 14220 pw.print(" (high-end-gfx)"); 14221 } 14222 pw.println(); 14223 } else { 14224 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14225 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14226 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14227 pw.print("tuning,"); 14228 pw.print(ActivityManager.staticGetMemoryClass()); 14229 pw.print(','); 14230 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14231 pw.print(','); 14232 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14233 if (ActivityManager.isLowRamDeviceStatic()) { 14234 pw.print(",low-ram"); 14235 } 14236 if (ActivityManager.isHighEndGfx()) { 14237 pw.print(",high-end-gfx"); 14238 } 14239 pw.println(); 14240 } 14241 } 14242 } 14243 } 14244 14245 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14246 String name) { 14247 sb.append(" "); 14248 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14249 sb.append(' '); 14250 sb.append(ProcessList.makeProcStateString(procState)); 14251 sb.append(' '); 14252 ProcessList.appendRamKb(sb, pss); 14253 sb.append(" kB: "); 14254 sb.append(name); 14255 } 14256 14257 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14258 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14259 sb.append(" ("); 14260 sb.append(mi.pid); 14261 sb.append(") "); 14262 sb.append(mi.adjType); 14263 sb.append('\n'); 14264 if (mi.adjReason != null) { 14265 sb.append(" "); 14266 sb.append(mi.adjReason); 14267 sb.append('\n'); 14268 } 14269 } 14270 14271 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14272 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14273 for (int i=0, N=memInfos.size(); i<N; i++) { 14274 ProcessMemInfo mi = memInfos.get(i); 14275 infoMap.put(mi.pid, mi); 14276 } 14277 updateCpuStatsNow(); 14278 synchronized (mProcessCpuTracker) { 14279 final int N = mProcessCpuTracker.countStats(); 14280 for (int i=0; i<N; i++) { 14281 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14282 if (st.vsize > 0) { 14283 long pss = Debug.getPss(st.pid, null); 14284 if (pss > 0) { 14285 if (infoMap.indexOfKey(st.pid) < 0) { 14286 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14287 ProcessList.NATIVE_ADJ, -1, "native", null); 14288 mi.pss = pss; 14289 memInfos.add(mi); 14290 } 14291 } 14292 } 14293 } 14294 } 14295 14296 long totalPss = 0; 14297 for (int i=0, N=memInfos.size(); i<N; i++) { 14298 ProcessMemInfo mi = memInfos.get(i); 14299 if (mi.pss == 0) { 14300 mi.pss = Debug.getPss(mi.pid, null); 14301 } 14302 totalPss += mi.pss; 14303 } 14304 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14305 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14306 if (lhs.oomAdj != rhs.oomAdj) { 14307 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14308 } 14309 if (lhs.pss != rhs.pss) { 14310 return lhs.pss < rhs.pss ? 1 : -1; 14311 } 14312 return 0; 14313 } 14314 }); 14315 14316 StringBuilder tag = new StringBuilder(128); 14317 StringBuilder stack = new StringBuilder(128); 14318 tag.append("Low on memory -- "); 14319 appendMemBucket(tag, totalPss, "total", false); 14320 appendMemBucket(stack, totalPss, "total", true); 14321 14322 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14323 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14324 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14325 14326 boolean firstLine = true; 14327 int lastOomAdj = Integer.MIN_VALUE; 14328 long extraNativeRam = 0; 14329 long cachedPss = 0; 14330 for (int i=0, N=memInfos.size(); i<N; i++) { 14331 ProcessMemInfo mi = memInfos.get(i); 14332 14333 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14334 cachedPss += mi.pss; 14335 } 14336 14337 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14338 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14339 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14340 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14341 if (lastOomAdj != mi.oomAdj) { 14342 lastOomAdj = mi.oomAdj; 14343 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14344 tag.append(" / "); 14345 } 14346 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14347 if (firstLine) { 14348 stack.append(":"); 14349 firstLine = false; 14350 } 14351 stack.append("\n\t at "); 14352 } else { 14353 stack.append("$"); 14354 } 14355 } else { 14356 tag.append(" "); 14357 stack.append("$"); 14358 } 14359 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14360 appendMemBucket(tag, mi.pss, mi.name, false); 14361 } 14362 appendMemBucket(stack, mi.pss, mi.name, true); 14363 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14364 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14365 stack.append("("); 14366 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14367 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14368 stack.append(DUMP_MEM_OOM_LABEL[k]); 14369 stack.append(":"); 14370 stack.append(DUMP_MEM_OOM_ADJ[k]); 14371 } 14372 } 14373 stack.append(")"); 14374 } 14375 } 14376 14377 appendMemInfo(fullNativeBuilder, mi); 14378 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14379 // The short form only has native processes that are >= 1MB. 14380 if (mi.pss >= 1000) { 14381 appendMemInfo(shortNativeBuilder, mi); 14382 } else { 14383 extraNativeRam += mi.pss; 14384 } 14385 } else { 14386 // Short form has all other details, but if we have collected RAM 14387 // from smaller native processes let's dump a summary of that. 14388 if (extraNativeRam > 0) { 14389 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14390 -1, extraNativeRam, "(Other native)"); 14391 shortNativeBuilder.append('\n'); 14392 extraNativeRam = 0; 14393 } 14394 appendMemInfo(fullJavaBuilder, mi); 14395 } 14396 } 14397 14398 fullJavaBuilder.append(" "); 14399 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14400 fullJavaBuilder.append(" kB: TOTAL\n"); 14401 14402 MemInfoReader memInfo = new MemInfoReader(); 14403 memInfo.readMemInfo(); 14404 final long[] infos = memInfo.getRawInfo(); 14405 14406 StringBuilder memInfoBuilder = new StringBuilder(1024); 14407 Debug.getMemInfo(infos); 14408 memInfoBuilder.append(" MemInfo: "); 14409 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14410 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14411 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14412 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14413 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14414 memInfoBuilder.append(" "); 14415 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14416 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14417 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14418 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14419 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14420 memInfoBuilder.append(" ZRAM: "); 14421 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14422 memInfoBuilder.append(" kB RAM, "); 14423 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14424 memInfoBuilder.append(" kB swap total, "); 14425 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14426 memInfoBuilder.append(" kB swap free\n"); 14427 } 14428 final long[] ksm = getKsmInfo(); 14429 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14430 || ksm[KSM_VOLATILE] != 0) { 14431 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14432 memInfoBuilder.append(" kB saved from shared "); 14433 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14434 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14435 memInfoBuilder.append(" kB unshared; "); 14436 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14437 } 14438 memInfoBuilder.append(" Free RAM: "); 14439 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14440 + memInfo.getFreeSizeKb()); 14441 memInfoBuilder.append(" kB\n"); 14442 memInfoBuilder.append(" Used RAM: "); 14443 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14444 memInfoBuilder.append(" kB\n"); 14445 memInfoBuilder.append(" Lost RAM: "); 14446 memInfoBuilder.append(memInfo.getTotalSizeKb() 14447 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14448 - memInfo.getKernelUsedSizeKb()); 14449 memInfoBuilder.append(" kB\n"); 14450 Slog.i(TAG, "Low on memory:"); 14451 Slog.i(TAG, shortNativeBuilder.toString()); 14452 Slog.i(TAG, fullJavaBuilder.toString()); 14453 Slog.i(TAG, memInfoBuilder.toString()); 14454 14455 StringBuilder dropBuilder = new StringBuilder(1024); 14456 /* 14457 StringWriter oomSw = new StringWriter(); 14458 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14459 StringWriter catSw = new StringWriter(); 14460 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14461 String[] emptyArgs = new String[] { }; 14462 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14463 oomPw.flush(); 14464 String oomString = oomSw.toString(); 14465 */ 14466 dropBuilder.append("Low on memory:"); 14467 dropBuilder.append(stack); 14468 dropBuilder.append('\n'); 14469 dropBuilder.append(fullNativeBuilder); 14470 dropBuilder.append(fullJavaBuilder); 14471 dropBuilder.append('\n'); 14472 dropBuilder.append(memInfoBuilder); 14473 dropBuilder.append('\n'); 14474 /* 14475 dropBuilder.append(oomString); 14476 dropBuilder.append('\n'); 14477 */ 14478 StringWriter catSw = new StringWriter(); 14479 synchronized (ActivityManagerService.this) { 14480 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14481 String[] emptyArgs = new String[] { }; 14482 catPw.println(); 14483 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14484 catPw.println(); 14485 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14486 false, false, null); 14487 catPw.println(); 14488 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14489 catPw.flush(); 14490 } 14491 dropBuilder.append(catSw.toString()); 14492 addErrorToDropBox("lowmem", null, "system_server", null, 14493 null, tag.toString(), dropBuilder.toString(), null, null); 14494 //Slog.i(TAG, "Sent to dropbox:"); 14495 //Slog.i(TAG, dropBuilder.toString()); 14496 synchronized (ActivityManagerService.this) { 14497 long now = SystemClock.uptimeMillis(); 14498 if (mLastMemUsageReportTime < now) { 14499 mLastMemUsageReportTime = now; 14500 } 14501 } 14502 } 14503 14504 /** 14505 * Searches array of arguments for the specified string 14506 * @param args array of argument strings 14507 * @param value value to search for 14508 * @return true if the value is contained in the array 14509 */ 14510 private static boolean scanArgs(String[] args, String value) { 14511 if (args != null) { 14512 for (String arg : args) { 14513 if (value.equals(arg)) { 14514 return true; 14515 } 14516 } 14517 } 14518 return false; 14519 } 14520 14521 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14522 ContentProviderRecord cpr, boolean always) { 14523 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14524 14525 if (!inLaunching || always) { 14526 synchronized (cpr) { 14527 cpr.launchingApp = null; 14528 cpr.notifyAll(); 14529 } 14530 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14531 String names[] = cpr.info.authority.split(";"); 14532 for (int j = 0; j < names.length; j++) { 14533 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14534 } 14535 } 14536 14537 for (int i=0; i<cpr.connections.size(); i++) { 14538 ContentProviderConnection conn = cpr.connections.get(i); 14539 if (conn.waiting) { 14540 // If this connection is waiting for the provider, then we don't 14541 // need to mess with its process unless we are always removing 14542 // or for some reason the provider is not currently launching. 14543 if (inLaunching && !always) { 14544 continue; 14545 } 14546 } 14547 ProcessRecord capp = conn.client; 14548 conn.dead = true; 14549 if (conn.stableCount > 0) { 14550 if (!capp.persistent && capp.thread != null 14551 && capp.pid != 0 14552 && capp.pid != MY_PID) { 14553 capp.kill("depends on provider " 14554 + cpr.name.flattenToShortString() 14555 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14556 } 14557 } else if (capp.thread != null && conn.provider.provider != null) { 14558 try { 14559 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14560 } catch (RemoteException e) { 14561 } 14562 // In the protocol here, we don't expect the client to correctly 14563 // clean up this connection, we'll just remove it. 14564 cpr.connections.remove(i); 14565 conn.client.conProviders.remove(conn); 14566 } 14567 } 14568 14569 if (inLaunching && always) { 14570 mLaunchingProviders.remove(cpr); 14571 } 14572 return inLaunching; 14573 } 14574 14575 /** 14576 * Main code for cleaning up a process when it has gone away. This is 14577 * called both as a result of the process dying, or directly when stopping 14578 * a process when running in single process mode. 14579 * 14580 * @return Returns true if the given process has been restarted, so the 14581 * app that was passed in must remain on the process lists. 14582 */ 14583 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14584 boolean restarting, boolean allowRestart, int index) { 14585 if (index >= 0) { 14586 removeLruProcessLocked(app); 14587 ProcessList.remove(app.pid); 14588 } 14589 14590 mProcessesToGc.remove(app); 14591 mPendingPssProcesses.remove(app); 14592 14593 // Dismiss any open dialogs. 14594 if (app.crashDialog != null && !app.forceCrashReport) { 14595 app.crashDialog.dismiss(); 14596 app.crashDialog = null; 14597 } 14598 if (app.anrDialog != null) { 14599 app.anrDialog.dismiss(); 14600 app.anrDialog = null; 14601 } 14602 if (app.waitDialog != null) { 14603 app.waitDialog.dismiss(); 14604 app.waitDialog = null; 14605 } 14606 14607 app.crashing = false; 14608 app.notResponding = false; 14609 14610 app.resetPackageList(mProcessStats); 14611 app.unlinkDeathRecipient(); 14612 app.makeInactive(mProcessStats); 14613 app.waitingToKill = null; 14614 app.forcingToForeground = null; 14615 updateProcessForegroundLocked(app, false, false); 14616 app.foregroundActivities = false; 14617 app.hasShownUi = false; 14618 app.treatLikeActivity = false; 14619 app.hasAboveClient = false; 14620 app.hasClientActivities = false; 14621 14622 mServices.killServicesLocked(app, allowRestart); 14623 14624 boolean restart = false; 14625 14626 // Remove published content providers. 14627 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14628 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14629 final boolean always = app.bad || !allowRestart; 14630 if (removeDyingProviderLocked(app, cpr, always) || always) { 14631 // We left the provider in the launching list, need to 14632 // restart it. 14633 restart = true; 14634 } 14635 14636 cpr.provider = null; 14637 cpr.proc = null; 14638 } 14639 app.pubProviders.clear(); 14640 14641 // Take care of any launching providers waiting for this process. 14642 if (checkAppInLaunchingProvidersLocked(app, false)) { 14643 restart = true; 14644 } 14645 14646 // Unregister from connected content providers. 14647 if (!app.conProviders.isEmpty()) { 14648 for (int i=0; i<app.conProviders.size(); i++) { 14649 ContentProviderConnection conn = app.conProviders.get(i); 14650 conn.provider.connections.remove(conn); 14651 } 14652 app.conProviders.clear(); 14653 } 14654 14655 // At this point there may be remaining entries in mLaunchingProviders 14656 // where we were the only one waiting, so they are no longer of use. 14657 // Look for these and clean up if found. 14658 // XXX Commented out for now. Trying to figure out a way to reproduce 14659 // the actual situation to identify what is actually going on. 14660 if (false) { 14661 for (int i=0; i<mLaunchingProviders.size(); i++) { 14662 ContentProviderRecord cpr = (ContentProviderRecord) 14663 mLaunchingProviders.get(i); 14664 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14665 synchronized (cpr) { 14666 cpr.launchingApp = null; 14667 cpr.notifyAll(); 14668 } 14669 } 14670 } 14671 } 14672 14673 skipCurrentReceiverLocked(app); 14674 14675 // Unregister any receivers. 14676 for (int i=app.receivers.size()-1; i>=0; i--) { 14677 removeReceiverLocked(app.receivers.valueAt(i)); 14678 } 14679 app.receivers.clear(); 14680 14681 // If the app is undergoing backup, tell the backup manager about it 14682 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14683 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14684 + mBackupTarget.appInfo + " died during backup"); 14685 try { 14686 IBackupManager bm = IBackupManager.Stub.asInterface( 14687 ServiceManager.getService(Context.BACKUP_SERVICE)); 14688 bm.agentDisconnected(app.info.packageName); 14689 } catch (RemoteException e) { 14690 // can't happen; backup manager is local 14691 } 14692 } 14693 14694 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14695 ProcessChangeItem item = mPendingProcessChanges.get(i); 14696 if (item.pid == app.pid) { 14697 mPendingProcessChanges.remove(i); 14698 mAvailProcessChanges.add(item); 14699 } 14700 } 14701 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14702 14703 // If the caller is restarting this app, then leave it in its 14704 // current lists and let the caller take care of it. 14705 if (restarting) { 14706 return false; 14707 } 14708 14709 if (!app.persistent || app.isolated) { 14710 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14711 "Removing non-persistent process during cleanup: " + app); 14712 mProcessNames.remove(app.processName, app.uid); 14713 mIsolatedProcesses.remove(app.uid); 14714 if (mHeavyWeightProcess == app) { 14715 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14716 mHeavyWeightProcess.userId, 0)); 14717 mHeavyWeightProcess = null; 14718 } 14719 } else if (!app.removed) { 14720 // This app is persistent, so we need to keep its record around. 14721 // If it is not already on the pending app list, add it there 14722 // and start a new process for it. 14723 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14724 mPersistentStartingProcesses.add(app); 14725 restart = true; 14726 } 14727 } 14728 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14729 "Clean-up removing on hold: " + app); 14730 mProcessesOnHold.remove(app); 14731 14732 if (app == mHomeProcess) { 14733 mHomeProcess = null; 14734 } 14735 if (app == mPreviousProcess) { 14736 mPreviousProcess = null; 14737 } 14738 14739 if (restart && !app.isolated) { 14740 // We have components that still need to be running in the 14741 // process, so re-launch it. 14742 if (index < 0) { 14743 ProcessList.remove(app.pid); 14744 } 14745 mProcessNames.put(app.processName, app.uid, app); 14746 startProcessLocked(app, "restart", app.processName); 14747 return true; 14748 } else if (app.pid > 0 && app.pid != MY_PID) { 14749 // Goodbye! 14750 boolean removed; 14751 synchronized (mPidsSelfLocked) { 14752 mPidsSelfLocked.remove(app.pid); 14753 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14754 } 14755 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14756 if (app.isolated) { 14757 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14758 } 14759 app.setPid(0); 14760 } 14761 return false; 14762 } 14763 14764 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14765 // Look through the content providers we are waiting to have launched, 14766 // and if any run in this process then either schedule a restart of 14767 // the process or kill the client waiting for it if this process has 14768 // gone bad. 14769 int NL = mLaunchingProviders.size(); 14770 boolean restart = false; 14771 for (int i=0; i<NL; i++) { 14772 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14773 if (cpr.launchingApp == app) { 14774 if (!alwaysBad && !app.bad) { 14775 restart = true; 14776 } else { 14777 removeDyingProviderLocked(app, cpr, true); 14778 // cpr should have been removed from mLaunchingProviders 14779 NL = mLaunchingProviders.size(); 14780 i--; 14781 } 14782 } 14783 } 14784 return restart; 14785 } 14786 14787 // ========================================================= 14788 // SERVICES 14789 // ========================================================= 14790 14791 @Override 14792 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14793 int flags) { 14794 enforceNotIsolatedCaller("getServices"); 14795 synchronized (this) { 14796 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14797 } 14798 } 14799 14800 @Override 14801 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14802 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14803 synchronized (this) { 14804 return mServices.getRunningServiceControlPanelLocked(name); 14805 } 14806 } 14807 14808 @Override 14809 public ComponentName startService(IApplicationThread caller, Intent service, 14810 String resolvedType, int userId) { 14811 enforceNotIsolatedCaller("startService"); 14812 // Refuse possible leaked file descriptors 14813 if (service != null && service.hasFileDescriptors() == true) { 14814 throw new IllegalArgumentException("File descriptors passed in Intent"); 14815 } 14816 14817 if (DEBUG_SERVICE) 14818 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14819 synchronized(this) { 14820 final int callingPid = Binder.getCallingPid(); 14821 final int callingUid = Binder.getCallingUid(); 14822 final long origId = Binder.clearCallingIdentity(); 14823 ComponentName res = mServices.startServiceLocked(caller, service, 14824 resolvedType, callingPid, callingUid, userId); 14825 Binder.restoreCallingIdentity(origId); 14826 return res; 14827 } 14828 } 14829 14830 ComponentName startServiceInPackage(int uid, 14831 Intent service, String resolvedType, int userId) { 14832 synchronized(this) { 14833 if (DEBUG_SERVICE) 14834 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14835 final long origId = Binder.clearCallingIdentity(); 14836 ComponentName res = mServices.startServiceLocked(null, service, 14837 resolvedType, -1, uid, userId); 14838 Binder.restoreCallingIdentity(origId); 14839 return res; 14840 } 14841 } 14842 14843 @Override 14844 public int stopService(IApplicationThread caller, Intent service, 14845 String resolvedType, int userId) { 14846 enforceNotIsolatedCaller("stopService"); 14847 // Refuse possible leaked file descriptors 14848 if (service != null && service.hasFileDescriptors() == true) { 14849 throw new IllegalArgumentException("File descriptors passed in Intent"); 14850 } 14851 14852 synchronized(this) { 14853 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14854 } 14855 } 14856 14857 @Override 14858 public IBinder peekService(Intent service, String resolvedType) { 14859 enforceNotIsolatedCaller("peekService"); 14860 // Refuse possible leaked file descriptors 14861 if (service != null && service.hasFileDescriptors() == true) { 14862 throw new IllegalArgumentException("File descriptors passed in Intent"); 14863 } 14864 synchronized(this) { 14865 return mServices.peekServiceLocked(service, resolvedType); 14866 } 14867 } 14868 14869 @Override 14870 public boolean stopServiceToken(ComponentName className, IBinder token, 14871 int startId) { 14872 synchronized(this) { 14873 return mServices.stopServiceTokenLocked(className, token, startId); 14874 } 14875 } 14876 14877 @Override 14878 public void setServiceForeground(ComponentName className, IBinder token, 14879 int id, Notification notification, boolean removeNotification) { 14880 synchronized(this) { 14881 mServices.setServiceForegroundLocked(className, token, id, notification, 14882 removeNotification); 14883 } 14884 } 14885 14886 @Override 14887 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14888 boolean requireFull, String name, String callerPackage) { 14889 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14890 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14891 } 14892 14893 int unsafeConvertIncomingUser(int userId) { 14894 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14895 ? mCurrentUserId : userId; 14896 } 14897 14898 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14899 int allowMode, String name, String callerPackage) { 14900 final int callingUserId = UserHandle.getUserId(callingUid); 14901 if (callingUserId == userId) { 14902 return userId; 14903 } 14904 14905 // Note that we may be accessing mCurrentUserId outside of a lock... 14906 // shouldn't be a big deal, if this is being called outside 14907 // of a locked context there is intrinsically a race with 14908 // the value the caller will receive and someone else changing it. 14909 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14910 // we will switch to the calling user if access to the current user fails. 14911 int targetUserId = unsafeConvertIncomingUser(userId); 14912 14913 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14914 final boolean allow; 14915 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14916 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14917 // If the caller has this permission, they always pass go. And collect $200. 14918 allow = true; 14919 } else if (allowMode == ALLOW_FULL_ONLY) { 14920 // We require full access, sucks to be you. 14921 allow = false; 14922 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14923 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14924 // If the caller does not have either permission, they are always doomed. 14925 allow = false; 14926 } else if (allowMode == ALLOW_NON_FULL) { 14927 // We are blanket allowing non-full access, you lucky caller! 14928 allow = true; 14929 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14930 // We may or may not allow this depending on whether the two users are 14931 // in the same profile. 14932 synchronized (mUserProfileGroupIdsSelfLocked) { 14933 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14934 UserInfo.NO_PROFILE_GROUP_ID); 14935 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14936 UserInfo.NO_PROFILE_GROUP_ID); 14937 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14938 && callingProfile == targetProfile; 14939 } 14940 } else { 14941 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14942 } 14943 if (!allow) { 14944 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14945 // In this case, they would like to just execute as their 14946 // owner user instead of failing. 14947 targetUserId = callingUserId; 14948 } else { 14949 StringBuilder builder = new StringBuilder(128); 14950 builder.append("Permission Denial: "); 14951 builder.append(name); 14952 if (callerPackage != null) { 14953 builder.append(" from "); 14954 builder.append(callerPackage); 14955 } 14956 builder.append(" asks to run as user "); 14957 builder.append(userId); 14958 builder.append(" but is calling from user "); 14959 builder.append(UserHandle.getUserId(callingUid)); 14960 builder.append("; this requires "); 14961 builder.append(INTERACT_ACROSS_USERS_FULL); 14962 if (allowMode != ALLOW_FULL_ONLY) { 14963 builder.append(" or "); 14964 builder.append(INTERACT_ACROSS_USERS); 14965 } 14966 String msg = builder.toString(); 14967 Slog.w(TAG, msg); 14968 throw new SecurityException(msg); 14969 } 14970 } 14971 } 14972 if (!allowAll && targetUserId < 0) { 14973 throw new IllegalArgumentException( 14974 "Call does not support special user #" + targetUserId); 14975 } 14976 // Check shell permission 14977 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14978 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14979 targetUserId)) { 14980 throw new SecurityException("Shell does not have permission to access user " 14981 + targetUserId + "\n " + Debug.getCallers(3)); 14982 } 14983 } 14984 return targetUserId; 14985 } 14986 14987 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14988 String className, int flags) { 14989 boolean result = false; 14990 // For apps that don't have pre-defined UIDs, check for permission 14991 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14992 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14993 if (ActivityManager.checkUidPermission( 14994 INTERACT_ACROSS_USERS, 14995 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14996 ComponentName comp = new ComponentName(aInfo.packageName, className); 14997 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14998 + " requests FLAG_SINGLE_USER, but app does not hold " 14999 + INTERACT_ACROSS_USERS; 15000 Slog.w(TAG, msg); 15001 throw new SecurityException(msg); 15002 } 15003 // Permission passed 15004 result = true; 15005 } 15006 } else if ("system".equals(componentProcessName)) { 15007 result = true; 15008 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15009 // Phone app and persistent apps are allowed to export singleuser providers. 15010 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15011 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15012 } 15013 if (DEBUG_MU) { 15014 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15015 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15016 } 15017 return result; 15018 } 15019 15020 /** 15021 * Checks to see if the caller is in the same app as the singleton 15022 * component, or the component is in a special app. It allows special apps 15023 * to export singleton components but prevents exporting singleton 15024 * components for regular apps. 15025 */ 15026 boolean isValidSingletonCall(int callingUid, int componentUid) { 15027 int componentAppId = UserHandle.getAppId(componentUid); 15028 return UserHandle.isSameApp(callingUid, componentUid) 15029 || componentAppId == Process.SYSTEM_UID 15030 || componentAppId == Process.PHONE_UID 15031 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15032 == PackageManager.PERMISSION_GRANTED; 15033 } 15034 15035 public int bindService(IApplicationThread caller, IBinder token, 15036 Intent service, String resolvedType, 15037 IServiceConnection connection, int flags, int userId) { 15038 enforceNotIsolatedCaller("bindService"); 15039 15040 // Refuse possible leaked file descriptors 15041 if (service != null && service.hasFileDescriptors() == true) { 15042 throw new IllegalArgumentException("File descriptors passed in Intent"); 15043 } 15044 15045 synchronized(this) { 15046 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15047 connection, flags, userId); 15048 } 15049 } 15050 15051 public boolean unbindService(IServiceConnection connection) { 15052 synchronized (this) { 15053 return mServices.unbindServiceLocked(connection); 15054 } 15055 } 15056 15057 public void publishService(IBinder token, Intent intent, IBinder service) { 15058 // Refuse possible leaked file descriptors 15059 if (intent != null && intent.hasFileDescriptors() == true) { 15060 throw new IllegalArgumentException("File descriptors passed in Intent"); 15061 } 15062 15063 synchronized(this) { 15064 if (!(token instanceof ServiceRecord)) { 15065 throw new IllegalArgumentException("Invalid service token"); 15066 } 15067 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15068 } 15069 } 15070 15071 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15072 // Refuse possible leaked file descriptors 15073 if (intent != null && intent.hasFileDescriptors() == true) { 15074 throw new IllegalArgumentException("File descriptors passed in Intent"); 15075 } 15076 15077 synchronized(this) { 15078 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15079 } 15080 } 15081 15082 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15083 synchronized(this) { 15084 if (!(token instanceof ServiceRecord)) { 15085 throw new IllegalArgumentException("Invalid service token"); 15086 } 15087 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15088 } 15089 } 15090 15091 // ========================================================= 15092 // BACKUP AND RESTORE 15093 // ========================================================= 15094 15095 // Cause the target app to be launched if necessary and its backup agent 15096 // instantiated. The backup agent will invoke backupAgentCreated() on the 15097 // activity manager to announce its creation. 15098 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15099 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15100 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15101 15102 synchronized(this) { 15103 // !!! TODO: currently no check here that we're already bound 15104 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15105 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15106 synchronized (stats) { 15107 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15108 } 15109 15110 // Backup agent is now in use, its package can't be stopped. 15111 try { 15112 AppGlobals.getPackageManager().setPackageStoppedState( 15113 app.packageName, false, UserHandle.getUserId(app.uid)); 15114 } catch (RemoteException e) { 15115 } catch (IllegalArgumentException e) { 15116 Slog.w(TAG, "Failed trying to unstop package " 15117 + app.packageName + ": " + e); 15118 } 15119 15120 BackupRecord r = new BackupRecord(ss, app, backupMode); 15121 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15122 ? new ComponentName(app.packageName, app.backupAgentName) 15123 : new ComponentName("android", "FullBackupAgent"); 15124 // startProcessLocked() returns existing proc's record if it's already running 15125 ProcessRecord proc = startProcessLocked(app.processName, app, 15126 false, 0, "backup", hostingName, false, false, false); 15127 if (proc == null) { 15128 Slog.e(TAG, "Unable to start backup agent process " + r); 15129 return false; 15130 } 15131 15132 r.app = proc; 15133 mBackupTarget = r; 15134 mBackupAppName = app.packageName; 15135 15136 // Try not to kill the process during backup 15137 updateOomAdjLocked(proc); 15138 15139 // If the process is already attached, schedule the creation of the backup agent now. 15140 // If it is not yet live, this will be done when it attaches to the framework. 15141 if (proc.thread != null) { 15142 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15143 try { 15144 proc.thread.scheduleCreateBackupAgent(app, 15145 compatibilityInfoForPackageLocked(app), backupMode); 15146 } catch (RemoteException e) { 15147 // Will time out on the backup manager side 15148 } 15149 } else { 15150 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15151 } 15152 // Invariants: at this point, the target app process exists and the application 15153 // is either already running or in the process of coming up. mBackupTarget and 15154 // mBackupAppName describe the app, so that when it binds back to the AM we 15155 // know that it's scheduled for a backup-agent operation. 15156 } 15157 15158 return true; 15159 } 15160 15161 @Override 15162 public void clearPendingBackup() { 15163 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15164 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15165 15166 synchronized (this) { 15167 mBackupTarget = null; 15168 mBackupAppName = null; 15169 } 15170 } 15171 15172 // A backup agent has just come up 15173 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15174 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15175 + " = " + agent); 15176 15177 synchronized(this) { 15178 if (!agentPackageName.equals(mBackupAppName)) { 15179 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15180 return; 15181 } 15182 } 15183 15184 long oldIdent = Binder.clearCallingIdentity(); 15185 try { 15186 IBackupManager bm = IBackupManager.Stub.asInterface( 15187 ServiceManager.getService(Context.BACKUP_SERVICE)); 15188 bm.agentConnected(agentPackageName, agent); 15189 } catch (RemoteException e) { 15190 // can't happen; the backup manager service is local 15191 } catch (Exception e) { 15192 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15193 e.printStackTrace(); 15194 } finally { 15195 Binder.restoreCallingIdentity(oldIdent); 15196 } 15197 } 15198 15199 // done with this agent 15200 public void unbindBackupAgent(ApplicationInfo appInfo) { 15201 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15202 if (appInfo == null) { 15203 Slog.w(TAG, "unbind backup agent for null app"); 15204 return; 15205 } 15206 15207 synchronized(this) { 15208 try { 15209 if (mBackupAppName == null) { 15210 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15211 return; 15212 } 15213 15214 if (!mBackupAppName.equals(appInfo.packageName)) { 15215 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15216 return; 15217 } 15218 15219 // Not backing this app up any more; reset its OOM adjustment 15220 final ProcessRecord proc = mBackupTarget.app; 15221 updateOomAdjLocked(proc); 15222 15223 // If the app crashed during backup, 'thread' will be null here 15224 if (proc.thread != null) { 15225 try { 15226 proc.thread.scheduleDestroyBackupAgent(appInfo, 15227 compatibilityInfoForPackageLocked(appInfo)); 15228 } catch (Exception e) { 15229 Slog.e(TAG, "Exception when unbinding backup agent:"); 15230 e.printStackTrace(); 15231 } 15232 } 15233 } finally { 15234 mBackupTarget = null; 15235 mBackupAppName = null; 15236 } 15237 } 15238 } 15239 // ========================================================= 15240 // BROADCASTS 15241 // ========================================================= 15242 15243 private final List getStickiesLocked(String action, IntentFilter filter, 15244 List cur, int userId) { 15245 final ContentResolver resolver = mContext.getContentResolver(); 15246 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15247 if (stickies == null) { 15248 return cur; 15249 } 15250 final ArrayList<Intent> list = stickies.get(action); 15251 if (list == null) { 15252 return cur; 15253 } 15254 int N = list.size(); 15255 for (int i=0; i<N; i++) { 15256 Intent intent = list.get(i); 15257 if (filter.match(resolver, intent, true, TAG) >= 0) { 15258 if (cur == null) { 15259 cur = new ArrayList<Intent>(); 15260 } 15261 cur.add(intent); 15262 } 15263 } 15264 return cur; 15265 } 15266 15267 boolean isPendingBroadcastProcessLocked(int pid) { 15268 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15269 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15270 } 15271 15272 void skipPendingBroadcastLocked(int pid) { 15273 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15274 for (BroadcastQueue queue : mBroadcastQueues) { 15275 queue.skipPendingBroadcastLocked(pid); 15276 } 15277 } 15278 15279 // The app just attached; send any pending broadcasts that it should receive 15280 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15281 boolean didSomething = false; 15282 for (BroadcastQueue queue : mBroadcastQueues) { 15283 didSomething |= queue.sendPendingBroadcastsLocked(app); 15284 } 15285 return didSomething; 15286 } 15287 15288 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15289 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15290 enforceNotIsolatedCaller("registerReceiver"); 15291 int callingUid; 15292 int callingPid; 15293 synchronized(this) { 15294 ProcessRecord callerApp = null; 15295 if (caller != null) { 15296 callerApp = getRecordForAppLocked(caller); 15297 if (callerApp == null) { 15298 throw new SecurityException( 15299 "Unable to find app for caller " + caller 15300 + " (pid=" + Binder.getCallingPid() 15301 + ") when registering receiver " + receiver); 15302 } 15303 if (callerApp.info.uid != Process.SYSTEM_UID && 15304 !callerApp.pkgList.containsKey(callerPackage) && 15305 !"android".equals(callerPackage)) { 15306 throw new SecurityException("Given caller package " + callerPackage 15307 + " is not running in process " + callerApp); 15308 } 15309 callingUid = callerApp.info.uid; 15310 callingPid = callerApp.pid; 15311 } else { 15312 callerPackage = null; 15313 callingUid = Binder.getCallingUid(); 15314 callingPid = Binder.getCallingPid(); 15315 } 15316 15317 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15318 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15319 15320 List allSticky = null; 15321 15322 // Look for any matching sticky broadcasts... 15323 Iterator actions = filter.actionsIterator(); 15324 if (actions != null) { 15325 while (actions.hasNext()) { 15326 String action = (String)actions.next(); 15327 allSticky = getStickiesLocked(action, filter, allSticky, 15328 UserHandle.USER_ALL); 15329 allSticky = getStickiesLocked(action, filter, allSticky, 15330 UserHandle.getUserId(callingUid)); 15331 } 15332 } else { 15333 allSticky = getStickiesLocked(null, filter, allSticky, 15334 UserHandle.USER_ALL); 15335 allSticky = getStickiesLocked(null, filter, allSticky, 15336 UserHandle.getUserId(callingUid)); 15337 } 15338 15339 // The first sticky in the list is returned directly back to 15340 // the client. 15341 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15342 15343 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15344 + ": " + sticky); 15345 15346 if (receiver == null) { 15347 return sticky; 15348 } 15349 15350 ReceiverList rl 15351 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15352 if (rl == null) { 15353 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15354 userId, receiver); 15355 if (rl.app != null) { 15356 rl.app.receivers.add(rl); 15357 } else { 15358 try { 15359 receiver.asBinder().linkToDeath(rl, 0); 15360 } catch (RemoteException e) { 15361 return sticky; 15362 } 15363 rl.linkedToDeath = true; 15364 } 15365 mRegisteredReceivers.put(receiver.asBinder(), rl); 15366 } else if (rl.uid != callingUid) { 15367 throw new IllegalArgumentException( 15368 "Receiver requested to register for uid " + callingUid 15369 + " was previously registered for uid " + rl.uid); 15370 } else if (rl.pid != callingPid) { 15371 throw new IllegalArgumentException( 15372 "Receiver requested to register for pid " + callingPid 15373 + " was previously registered for pid " + rl.pid); 15374 } else if (rl.userId != userId) { 15375 throw new IllegalArgumentException( 15376 "Receiver requested to register for user " + userId 15377 + " was previously registered for user " + rl.userId); 15378 } 15379 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15380 permission, callingUid, userId); 15381 rl.add(bf); 15382 if (!bf.debugCheck()) { 15383 Slog.w(TAG, "==> For Dynamic broadast"); 15384 } 15385 mReceiverResolver.addFilter(bf); 15386 15387 // Enqueue broadcasts for all existing stickies that match 15388 // this filter. 15389 if (allSticky != null) { 15390 ArrayList receivers = new ArrayList(); 15391 receivers.add(bf); 15392 15393 int N = allSticky.size(); 15394 for (int i=0; i<N; i++) { 15395 Intent intent = (Intent)allSticky.get(i); 15396 BroadcastQueue queue = broadcastQueueForIntent(intent); 15397 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15398 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15399 null, null, false, true, true, -1); 15400 queue.enqueueParallelBroadcastLocked(r); 15401 queue.scheduleBroadcastsLocked(); 15402 } 15403 } 15404 15405 return sticky; 15406 } 15407 } 15408 15409 public void unregisterReceiver(IIntentReceiver receiver) { 15410 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15411 15412 final long origId = Binder.clearCallingIdentity(); 15413 try { 15414 boolean doTrim = false; 15415 15416 synchronized(this) { 15417 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15418 if (rl != null) { 15419 if (rl.curBroadcast != null) { 15420 BroadcastRecord r = rl.curBroadcast; 15421 final boolean doNext = finishReceiverLocked( 15422 receiver.asBinder(), r.resultCode, r.resultData, 15423 r.resultExtras, r.resultAbort); 15424 if (doNext) { 15425 doTrim = true; 15426 r.queue.processNextBroadcast(false); 15427 } 15428 } 15429 15430 if (rl.app != null) { 15431 rl.app.receivers.remove(rl); 15432 } 15433 removeReceiverLocked(rl); 15434 if (rl.linkedToDeath) { 15435 rl.linkedToDeath = false; 15436 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15437 } 15438 } 15439 } 15440 15441 // If we actually concluded any broadcasts, we might now be able 15442 // to trim the recipients' apps from our working set 15443 if (doTrim) { 15444 trimApplications(); 15445 return; 15446 } 15447 15448 } finally { 15449 Binder.restoreCallingIdentity(origId); 15450 } 15451 } 15452 15453 void removeReceiverLocked(ReceiverList rl) { 15454 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15455 int N = rl.size(); 15456 for (int i=0; i<N; i++) { 15457 mReceiverResolver.removeFilter(rl.get(i)); 15458 } 15459 } 15460 15461 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15462 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15463 ProcessRecord r = mLruProcesses.get(i); 15464 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15465 try { 15466 r.thread.dispatchPackageBroadcast(cmd, packages); 15467 } catch (RemoteException ex) { 15468 } 15469 } 15470 } 15471 } 15472 15473 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15474 int callingUid, int[] users) { 15475 List<ResolveInfo> receivers = null; 15476 try { 15477 HashSet<ComponentName> singleUserReceivers = null; 15478 boolean scannedFirstReceivers = false; 15479 for (int user : users) { 15480 // Skip users that have Shell restrictions 15481 if (callingUid == Process.SHELL_UID 15482 && getUserManagerLocked().hasUserRestriction( 15483 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15484 continue; 15485 } 15486 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15487 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15488 if (user != 0 && newReceivers != null) { 15489 // If this is not the primary user, we need to check for 15490 // any receivers that should be filtered out. 15491 for (int i=0; i<newReceivers.size(); i++) { 15492 ResolveInfo ri = newReceivers.get(i); 15493 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15494 newReceivers.remove(i); 15495 i--; 15496 } 15497 } 15498 } 15499 if (newReceivers != null && newReceivers.size() == 0) { 15500 newReceivers = null; 15501 } 15502 if (receivers == null) { 15503 receivers = newReceivers; 15504 } else if (newReceivers != null) { 15505 // We need to concatenate the additional receivers 15506 // found with what we have do far. This would be easy, 15507 // but we also need to de-dup any receivers that are 15508 // singleUser. 15509 if (!scannedFirstReceivers) { 15510 // Collect any single user receivers we had already retrieved. 15511 scannedFirstReceivers = true; 15512 for (int i=0; i<receivers.size(); i++) { 15513 ResolveInfo ri = receivers.get(i); 15514 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15515 ComponentName cn = new ComponentName( 15516 ri.activityInfo.packageName, ri.activityInfo.name); 15517 if (singleUserReceivers == null) { 15518 singleUserReceivers = new HashSet<ComponentName>(); 15519 } 15520 singleUserReceivers.add(cn); 15521 } 15522 } 15523 } 15524 // Add the new results to the existing results, tracking 15525 // and de-dupping single user receivers. 15526 for (int i=0; i<newReceivers.size(); i++) { 15527 ResolveInfo ri = newReceivers.get(i); 15528 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15529 ComponentName cn = new ComponentName( 15530 ri.activityInfo.packageName, ri.activityInfo.name); 15531 if (singleUserReceivers == null) { 15532 singleUserReceivers = new HashSet<ComponentName>(); 15533 } 15534 if (!singleUserReceivers.contains(cn)) { 15535 singleUserReceivers.add(cn); 15536 receivers.add(ri); 15537 } 15538 } else { 15539 receivers.add(ri); 15540 } 15541 } 15542 } 15543 } 15544 } catch (RemoteException ex) { 15545 // pm is in same process, this will never happen. 15546 } 15547 return receivers; 15548 } 15549 15550 private final int broadcastIntentLocked(ProcessRecord callerApp, 15551 String callerPackage, Intent intent, String resolvedType, 15552 IIntentReceiver resultTo, int resultCode, String resultData, 15553 Bundle map, String requiredPermission, int appOp, 15554 boolean ordered, boolean sticky, int callingPid, int callingUid, 15555 int userId) { 15556 intent = new Intent(intent); 15557 15558 // By default broadcasts do not go to stopped apps. 15559 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15560 15561 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15562 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15563 + " ordered=" + ordered + " userid=" + userId); 15564 if ((resultTo != null) && !ordered) { 15565 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15566 } 15567 15568 userId = handleIncomingUser(callingPid, callingUid, userId, 15569 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15570 15571 // Make sure that the user who is receiving this broadcast is started. 15572 // If not, we will just skip it. 15573 15574 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15575 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15576 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15577 Slog.w(TAG, "Skipping broadcast of " + intent 15578 + ": user " + userId + " is stopped"); 15579 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15580 } 15581 } 15582 15583 /* 15584 * Prevent non-system code (defined here to be non-persistent 15585 * processes) from sending protected broadcasts. 15586 */ 15587 int callingAppId = UserHandle.getAppId(callingUid); 15588 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15589 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15590 || callingAppId == Process.NFC_UID || callingUid == 0) { 15591 // Always okay. 15592 } else if (callerApp == null || !callerApp.persistent) { 15593 try { 15594 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15595 intent.getAction())) { 15596 String msg = "Permission Denial: not allowed to send broadcast " 15597 + intent.getAction() + " from pid=" 15598 + callingPid + ", uid=" + callingUid; 15599 Slog.w(TAG, msg); 15600 throw new SecurityException(msg); 15601 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15602 // Special case for compatibility: we don't want apps to send this, 15603 // but historically it has not been protected and apps may be using it 15604 // to poke their own app widget. So, instead of making it protected, 15605 // just limit it to the caller. 15606 if (callerApp == null) { 15607 String msg = "Permission Denial: not allowed to send broadcast " 15608 + intent.getAction() + " from unknown caller."; 15609 Slog.w(TAG, msg); 15610 throw new SecurityException(msg); 15611 } else if (intent.getComponent() != null) { 15612 // They are good enough to send to an explicit component... verify 15613 // it is being sent to the calling app. 15614 if (!intent.getComponent().getPackageName().equals( 15615 callerApp.info.packageName)) { 15616 String msg = "Permission Denial: not allowed to send broadcast " 15617 + intent.getAction() + " to " 15618 + intent.getComponent().getPackageName() + " from " 15619 + callerApp.info.packageName; 15620 Slog.w(TAG, msg); 15621 throw new SecurityException(msg); 15622 } 15623 } else { 15624 // Limit broadcast to their own package. 15625 intent.setPackage(callerApp.info.packageName); 15626 } 15627 } 15628 } catch (RemoteException e) { 15629 Slog.w(TAG, "Remote exception", e); 15630 return ActivityManager.BROADCAST_SUCCESS; 15631 } 15632 } 15633 15634 // Handle special intents: if this broadcast is from the package 15635 // manager about a package being removed, we need to remove all of 15636 // its activities from the history stack. 15637 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15638 intent.getAction()); 15639 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15640 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15641 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15642 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15643 || uidRemoved) { 15644 if (checkComponentPermission( 15645 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15646 callingPid, callingUid, -1, true) 15647 == PackageManager.PERMISSION_GRANTED) { 15648 if (uidRemoved) { 15649 final Bundle intentExtras = intent.getExtras(); 15650 final int uid = intentExtras != null 15651 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15652 if (uid >= 0) { 15653 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15654 synchronized (bs) { 15655 bs.removeUidStatsLocked(uid); 15656 } 15657 mAppOpsService.uidRemoved(uid); 15658 } 15659 } else { 15660 // If resources are unavailable just force stop all 15661 // those packages and flush the attribute cache as well. 15662 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15663 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15664 if (list != null && (list.length > 0)) { 15665 for (String pkg : list) { 15666 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15667 "storage unmount"); 15668 } 15669 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15670 sendPackageBroadcastLocked( 15671 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15672 } 15673 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15674 intent.getAction())) { 15675 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15676 } else { 15677 Uri data = intent.getData(); 15678 String ssp; 15679 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15680 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15681 intent.getAction()); 15682 boolean fullUninstall = removed && 15683 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15684 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15685 forceStopPackageLocked(ssp, UserHandle.getAppId( 15686 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15687 false, fullUninstall, userId, 15688 removed ? "pkg removed" : "pkg changed"); 15689 } 15690 if (removed) { 15691 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15692 new String[] {ssp}, userId); 15693 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15694 mAppOpsService.packageRemoved( 15695 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15696 15697 // Remove all permissions granted from/to this package 15698 removeUriPermissionsForPackageLocked(ssp, userId, true); 15699 } 15700 } 15701 } 15702 } 15703 } 15704 } else { 15705 String msg = "Permission Denial: " + intent.getAction() 15706 + " broadcast from " + callerPackage + " (pid=" + callingPid 15707 + ", uid=" + callingUid + ")" 15708 + " requires " 15709 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15710 Slog.w(TAG, msg); 15711 throw new SecurityException(msg); 15712 } 15713 15714 // Special case for adding a package: by default turn on compatibility 15715 // mode. 15716 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15717 Uri data = intent.getData(); 15718 String ssp; 15719 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15720 mCompatModePackages.handlePackageAddedLocked(ssp, 15721 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15722 } 15723 } 15724 15725 /* 15726 * If this is the time zone changed action, queue up a message that will reset the timezone 15727 * of all currently running processes. This message will get queued up before the broadcast 15728 * happens. 15729 */ 15730 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15731 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15732 } 15733 15734 /* 15735 * If the user set the time, let all running processes know. 15736 */ 15737 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15738 final int is24Hour = intent.getBooleanExtra( 15739 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15740 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15741 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15742 synchronized (stats) { 15743 stats.noteCurrentTimeChangedLocked(); 15744 } 15745 } 15746 15747 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15748 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15749 } 15750 15751 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15752 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15753 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15754 } 15755 15756 // Add to the sticky list if requested. 15757 if (sticky) { 15758 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15759 callingPid, callingUid) 15760 != PackageManager.PERMISSION_GRANTED) { 15761 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15762 + callingPid + ", uid=" + callingUid 15763 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15764 Slog.w(TAG, msg); 15765 throw new SecurityException(msg); 15766 } 15767 if (requiredPermission != null) { 15768 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15769 + " and enforce permission " + requiredPermission); 15770 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15771 } 15772 if (intent.getComponent() != null) { 15773 throw new SecurityException( 15774 "Sticky broadcasts can't target a specific component"); 15775 } 15776 // We use userId directly here, since the "all" target is maintained 15777 // as a separate set of sticky broadcasts. 15778 if (userId != UserHandle.USER_ALL) { 15779 // But first, if this is not a broadcast to all users, then 15780 // make sure it doesn't conflict with an existing broadcast to 15781 // all users. 15782 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15783 UserHandle.USER_ALL); 15784 if (stickies != null) { 15785 ArrayList<Intent> list = stickies.get(intent.getAction()); 15786 if (list != null) { 15787 int N = list.size(); 15788 int i; 15789 for (i=0; i<N; i++) { 15790 if (intent.filterEquals(list.get(i))) { 15791 throw new IllegalArgumentException( 15792 "Sticky broadcast " + intent + " for user " 15793 + userId + " conflicts with existing global broadcast"); 15794 } 15795 } 15796 } 15797 } 15798 } 15799 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15800 if (stickies == null) { 15801 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15802 mStickyBroadcasts.put(userId, stickies); 15803 } 15804 ArrayList<Intent> list = stickies.get(intent.getAction()); 15805 if (list == null) { 15806 list = new ArrayList<Intent>(); 15807 stickies.put(intent.getAction(), list); 15808 } 15809 int N = list.size(); 15810 int i; 15811 for (i=0; i<N; i++) { 15812 if (intent.filterEquals(list.get(i))) { 15813 // This sticky already exists, replace it. 15814 list.set(i, new Intent(intent)); 15815 break; 15816 } 15817 } 15818 if (i >= N) { 15819 list.add(new Intent(intent)); 15820 } 15821 } 15822 15823 int[] users; 15824 if (userId == UserHandle.USER_ALL) { 15825 // Caller wants broadcast to go to all started users. 15826 users = mStartedUserArray; 15827 } else { 15828 // Caller wants broadcast to go to one specific user. 15829 users = new int[] {userId}; 15830 } 15831 15832 // Figure out who all will receive this broadcast. 15833 List receivers = null; 15834 List<BroadcastFilter> registeredReceivers = null; 15835 // Need to resolve the intent to interested receivers... 15836 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15837 == 0) { 15838 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15839 } 15840 if (intent.getComponent() == null) { 15841 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15842 // Query one target user at a time, excluding shell-restricted users 15843 UserManagerService ums = getUserManagerLocked(); 15844 for (int i = 0; i < users.length; i++) { 15845 if (ums.hasUserRestriction( 15846 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15847 continue; 15848 } 15849 List<BroadcastFilter> registeredReceiversForUser = 15850 mReceiverResolver.queryIntent(intent, 15851 resolvedType, false, users[i]); 15852 if (registeredReceivers == null) { 15853 registeredReceivers = registeredReceiversForUser; 15854 } else if (registeredReceiversForUser != null) { 15855 registeredReceivers.addAll(registeredReceiversForUser); 15856 } 15857 } 15858 } else { 15859 registeredReceivers = mReceiverResolver.queryIntent(intent, 15860 resolvedType, false, userId); 15861 } 15862 } 15863 15864 final boolean replacePending = 15865 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15866 15867 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15868 + " replacePending=" + replacePending); 15869 15870 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15871 if (!ordered && NR > 0) { 15872 // If we are not serializing this broadcast, then send the 15873 // registered receivers separately so they don't wait for the 15874 // components to be launched. 15875 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15876 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15877 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15878 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15879 ordered, sticky, false, userId); 15880 if (DEBUG_BROADCAST) Slog.v( 15881 TAG, "Enqueueing parallel broadcast " + r); 15882 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15883 if (!replaced) { 15884 queue.enqueueParallelBroadcastLocked(r); 15885 queue.scheduleBroadcastsLocked(); 15886 } 15887 registeredReceivers = null; 15888 NR = 0; 15889 } 15890 15891 // Merge into one list. 15892 int ir = 0; 15893 if (receivers != null) { 15894 // A special case for PACKAGE_ADDED: do not allow the package 15895 // being added to see this broadcast. This prevents them from 15896 // using this as a back door to get run as soon as they are 15897 // installed. Maybe in the future we want to have a special install 15898 // broadcast or such for apps, but we'd like to deliberately make 15899 // this decision. 15900 String skipPackages[] = null; 15901 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15902 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15903 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15904 Uri data = intent.getData(); 15905 if (data != null) { 15906 String pkgName = data.getSchemeSpecificPart(); 15907 if (pkgName != null) { 15908 skipPackages = new String[] { pkgName }; 15909 } 15910 } 15911 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15912 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15913 } 15914 if (skipPackages != null && (skipPackages.length > 0)) { 15915 for (String skipPackage : skipPackages) { 15916 if (skipPackage != null) { 15917 int NT = receivers.size(); 15918 for (int it=0; it<NT; it++) { 15919 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15920 if (curt.activityInfo.packageName.equals(skipPackage)) { 15921 receivers.remove(it); 15922 it--; 15923 NT--; 15924 } 15925 } 15926 } 15927 } 15928 } 15929 15930 int NT = receivers != null ? receivers.size() : 0; 15931 int it = 0; 15932 ResolveInfo curt = null; 15933 BroadcastFilter curr = null; 15934 while (it < NT && ir < NR) { 15935 if (curt == null) { 15936 curt = (ResolveInfo)receivers.get(it); 15937 } 15938 if (curr == null) { 15939 curr = registeredReceivers.get(ir); 15940 } 15941 if (curr.getPriority() >= curt.priority) { 15942 // Insert this broadcast record into the final list. 15943 receivers.add(it, curr); 15944 ir++; 15945 curr = null; 15946 it++; 15947 NT++; 15948 } else { 15949 // Skip to the next ResolveInfo in the final list. 15950 it++; 15951 curt = null; 15952 } 15953 } 15954 } 15955 while (ir < NR) { 15956 if (receivers == null) { 15957 receivers = new ArrayList(); 15958 } 15959 receivers.add(registeredReceivers.get(ir)); 15960 ir++; 15961 } 15962 15963 if ((receivers != null && receivers.size() > 0) 15964 || resultTo != null) { 15965 BroadcastQueue queue = broadcastQueueForIntent(intent); 15966 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15967 callerPackage, callingPid, callingUid, resolvedType, 15968 requiredPermission, appOp, receivers, resultTo, resultCode, 15969 resultData, map, ordered, sticky, false, userId); 15970 if (DEBUG_BROADCAST) Slog.v( 15971 TAG, "Enqueueing ordered broadcast " + r 15972 + ": prev had " + queue.mOrderedBroadcasts.size()); 15973 if (DEBUG_BROADCAST) { 15974 int seq = r.intent.getIntExtra("seq", -1); 15975 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15976 } 15977 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15978 if (!replaced) { 15979 queue.enqueueOrderedBroadcastLocked(r); 15980 queue.scheduleBroadcastsLocked(); 15981 } 15982 } 15983 15984 return ActivityManager.BROADCAST_SUCCESS; 15985 } 15986 15987 final Intent verifyBroadcastLocked(Intent intent) { 15988 // Refuse possible leaked file descriptors 15989 if (intent != null && intent.hasFileDescriptors() == true) { 15990 throw new IllegalArgumentException("File descriptors passed in Intent"); 15991 } 15992 15993 int flags = intent.getFlags(); 15994 15995 if (!mProcessesReady) { 15996 // if the caller really truly claims to know what they're doing, go 15997 // ahead and allow the broadcast without launching any receivers 15998 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15999 intent = new Intent(intent); 16000 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16001 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16002 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16003 + " before boot completion"); 16004 throw new IllegalStateException("Cannot broadcast before boot completed"); 16005 } 16006 } 16007 16008 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16009 throw new IllegalArgumentException( 16010 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16011 } 16012 16013 return intent; 16014 } 16015 16016 public final int broadcastIntent(IApplicationThread caller, 16017 Intent intent, String resolvedType, IIntentReceiver resultTo, 16018 int resultCode, String resultData, Bundle map, 16019 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16020 enforceNotIsolatedCaller("broadcastIntent"); 16021 synchronized(this) { 16022 intent = verifyBroadcastLocked(intent); 16023 16024 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16025 final int callingPid = Binder.getCallingPid(); 16026 final int callingUid = Binder.getCallingUid(); 16027 final long origId = Binder.clearCallingIdentity(); 16028 int res = broadcastIntentLocked(callerApp, 16029 callerApp != null ? callerApp.info.packageName : null, 16030 intent, resolvedType, resultTo, 16031 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16032 callingPid, callingUid, userId); 16033 Binder.restoreCallingIdentity(origId); 16034 return res; 16035 } 16036 } 16037 16038 int broadcastIntentInPackage(String packageName, int uid, 16039 Intent intent, String resolvedType, IIntentReceiver resultTo, 16040 int resultCode, String resultData, Bundle map, 16041 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16042 synchronized(this) { 16043 intent = verifyBroadcastLocked(intent); 16044 16045 final long origId = Binder.clearCallingIdentity(); 16046 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16047 resultTo, resultCode, resultData, map, requiredPermission, 16048 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16049 Binder.restoreCallingIdentity(origId); 16050 return res; 16051 } 16052 } 16053 16054 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16055 // Refuse possible leaked file descriptors 16056 if (intent != null && intent.hasFileDescriptors() == true) { 16057 throw new IllegalArgumentException("File descriptors passed in Intent"); 16058 } 16059 16060 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16061 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16062 16063 synchronized(this) { 16064 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16065 != PackageManager.PERMISSION_GRANTED) { 16066 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16067 + Binder.getCallingPid() 16068 + ", uid=" + Binder.getCallingUid() 16069 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16070 Slog.w(TAG, msg); 16071 throw new SecurityException(msg); 16072 } 16073 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16074 if (stickies != null) { 16075 ArrayList<Intent> list = stickies.get(intent.getAction()); 16076 if (list != null) { 16077 int N = list.size(); 16078 int i; 16079 for (i=0; i<N; i++) { 16080 if (intent.filterEquals(list.get(i))) { 16081 list.remove(i); 16082 break; 16083 } 16084 } 16085 if (list.size() <= 0) { 16086 stickies.remove(intent.getAction()); 16087 } 16088 } 16089 if (stickies.size() <= 0) { 16090 mStickyBroadcasts.remove(userId); 16091 } 16092 } 16093 } 16094 } 16095 16096 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16097 String resultData, Bundle resultExtras, boolean resultAbort) { 16098 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16099 if (r == null) { 16100 Slog.w(TAG, "finishReceiver called but not found on queue"); 16101 return false; 16102 } 16103 16104 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16105 } 16106 16107 void backgroundServicesFinishedLocked(int userId) { 16108 for (BroadcastQueue queue : mBroadcastQueues) { 16109 queue.backgroundServicesFinishedLocked(userId); 16110 } 16111 } 16112 16113 public void finishReceiver(IBinder who, int resultCode, String resultData, 16114 Bundle resultExtras, boolean resultAbort) { 16115 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16116 16117 // Refuse possible leaked file descriptors 16118 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16119 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16120 } 16121 16122 final long origId = Binder.clearCallingIdentity(); 16123 try { 16124 boolean doNext = false; 16125 BroadcastRecord r; 16126 16127 synchronized(this) { 16128 r = broadcastRecordForReceiverLocked(who); 16129 if (r != null) { 16130 doNext = r.queue.finishReceiverLocked(r, resultCode, 16131 resultData, resultExtras, resultAbort, true); 16132 } 16133 } 16134 16135 if (doNext) { 16136 r.queue.processNextBroadcast(false); 16137 } 16138 trimApplications(); 16139 } finally { 16140 Binder.restoreCallingIdentity(origId); 16141 } 16142 } 16143 16144 // ========================================================= 16145 // INSTRUMENTATION 16146 // ========================================================= 16147 16148 public boolean startInstrumentation(ComponentName className, 16149 String profileFile, int flags, Bundle arguments, 16150 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16151 int userId, String abiOverride) { 16152 enforceNotIsolatedCaller("startInstrumentation"); 16153 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16154 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16155 // Refuse possible leaked file descriptors 16156 if (arguments != null && arguments.hasFileDescriptors()) { 16157 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16158 } 16159 16160 synchronized(this) { 16161 InstrumentationInfo ii = null; 16162 ApplicationInfo ai = null; 16163 try { 16164 ii = mContext.getPackageManager().getInstrumentationInfo( 16165 className, STOCK_PM_FLAGS); 16166 ai = AppGlobals.getPackageManager().getApplicationInfo( 16167 ii.targetPackage, STOCK_PM_FLAGS, userId); 16168 } catch (PackageManager.NameNotFoundException e) { 16169 } catch (RemoteException e) { 16170 } 16171 if (ii == null) { 16172 reportStartInstrumentationFailure(watcher, className, 16173 "Unable to find instrumentation info for: " + className); 16174 return false; 16175 } 16176 if (ai == null) { 16177 reportStartInstrumentationFailure(watcher, className, 16178 "Unable to find instrumentation target package: " + ii.targetPackage); 16179 return false; 16180 } 16181 16182 int match = mContext.getPackageManager().checkSignatures( 16183 ii.targetPackage, ii.packageName); 16184 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16185 String msg = "Permission Denial: starting instrumentation " 16186 + className + " from pid=" 16187 + Binder.getCallingPid() 16188 + ", uid=" + Binder.getCallingPid() 16189 + " not allowed because package " + ii.packageName 16190 + " does not have a signature matching the target " 16191 + ii.targetPackage; 16192 reportStartInstrumentationFailure(watcher, className, msg); 16193 throw new SecurityException(msg); 16194 } 16195 16196 final long origId = Binder.clearCallingIdentity(); 16197 // Instrumentation can kill and relaunch even persistent processes 16198 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16199 "start instr"); 16200 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16201 app.instrumentationClass = className; 16202 app.instrumentationInfo = ai; 16203 app.instrumentationProfileFile = profileFile; 16204 app.instrumentationArguments = arguments; 16205 app.instrumentationWatcher = watcher; 16206 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16207 app.instrumentationResultClass = className; 16208 Binder.restoreCallingIdentity(origId); 16209 } 16210 16211 return true; 16212 } 16213 16214 /** 16215 * Report errors that occur while attempting to start Instrumentation. Always writes the 16216 * error to the logs, but if somebody is watching, send the report there too. This enables 16217 * the "am" command to report errors with more information. 16218 * 16219 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16220 * @param cn The component name of the instrumentation. 16221 * @param report The error report. 16222 */ 16223 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16224 ComponentName cn, String report) { 16225 Slog.w(TAG, report); 16226 try { 16227 if (watcher != null) { 16228 Bundle results = new Bundle(); 16229 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16230 results.putString("Error", report); 16231 watcher.instrumentationStatus(cn, -1, results); 16232 } 16233 } catch (RemoteException e) { 16234 Slog.w(TAG, e); 16235 } 16236 } 16237 16238 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16239 if (app.instrumentationWatcher != null) { 16240 try { 16241 // NOTE: IInstrumentationWatcher *must* be oneway here 16242 app.instrumentationWatcher.instrumentationFinished( 16243 app.instrumentationClass, 16244 resultCode, 16245 results); 16246 } catch (RemoteException e) { 16247 } 16248 } 16249 if (app.instrumentationUiAutomationConnection != null) { 16250 try { 16251 app.instrumentationUiAutomationConnection.shutdown(); 16252 } catch (RemoteException re) { 16253 /* ignore */ 16254 } 16255 // Only a UiAutomation can set this flag and now that 16256 // it is finished we make sure it is reset to its default. 16257 mUserIsMonkey = false; 16258 } 16259 app.instrumentationWatcher = null; 16260 app.instrumentationUiAutomationConnection = null; 16261 app.instrumentationClass = null; 16262 app.instrumentationInfo = null; 16263 app.instrumentationProfileFile = null; 16264 app.instrumentationArguments = null; 16265 16266 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16267 "finished inst"); 16268 } 16269 16270 public void finishInstrumentation(IApplicationThread target, 16271 int resultCode, Bundle results) { 16272 int userId = UserHandle.getCallingUserId(); 16273 // Refuse possible leaked file descriptors 16274 if (results != null && results.hasFileDescriptors()) { 16275 throw new IllegalArgumentException("File descriptors passed in Intent"); 16276 } 16277 16278 synchronized(this) { 16279 ProcessRecord app = getRecordForAppLocked(target); 16280 if (app == null) { 16281 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16282 return; 16283 } 16284 final long origId = Binder.clearCallingIdentity(); 16285 finishInstrumentationLocked(app, resultCode, results); 16286 Binder.restoreCallingIdentity(origId); 16287 } 16288 } 16289 16290 // ========================================================= 16291 // CONFIGURATION 16292 // ========================================================= 16293 16294 public ConfigurationInfo getDeviceConfigurationInfo() { 16295 ConfigurationInfo config = new ConfigurationInfo(); 16296 synchronized (this) { 16297 config.reqTouchScreen = mConfiguration.touchscreen; 16298 config.reqKeyboardType = mConfiguration.keyboard; 16299 config.reqNavigation = mConfiguration.navigation; 16300 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16301 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16302 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16303 } 16304 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16305 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16306 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16307 } 16308 config.reqGlEsVersion = GL_ES_VERSION; 16309 } 16310 return config; 16311 } 16312 16313 ActivityStack getFocusedStack() { 16314 return mStackSupervisor.getFocusedStack(); 16315 } 16316 16317 public Configuration getConfiguration() { 16318 Configuration ci; 16319 synchronized(this) { 16320 ci = new Configuration(mConfiguration); 16321 } 16322 return ci; 16323 } 16324 16325 public void updatePersistentConfiguration(Configuration values) { 16326 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16327 "updateConfiguration()"); 16328 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16329 "updateConfiguration()"); 16330 if (values == null) { 16331 throw new NullPointerException("Configuration must not be null"); 16332 } 16333 16334 synchronized(this) { 16335 final long origId = Binder.clearCallingIdentity(); 16336 updateConfigurationLocked(values, null, true, false); 16337 Binder.restoreCallingIdentity(origId); 16338 } 16339 } 16340 16341 public void updateConfiguration(Configuration values) { 16342 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16343 "updateConfiguration()"); 16344 16345 synchronized(this) { 16346 if (values == null && mWindowManager != null) { 16347 // sentinel: fetch the current configuration from the window manager 16348 values = mWindowManager.computeNewConfiguration(); 16349 } 16350 16351 if (mWindowManager != null) { 16352 mProcessList.applyDisplaySize(mWindowManager); 16353 } 16354 16355 final long origId = Binder.clearCallingIdentity(); 16356 if (values != null) { 16357 Settings.System.clearConfiguration(values); 16358 } 16359 updateConfigurationLocked(values, null, false, false); 16360 Binder.restoreCallingIdentity(origId); 16361 } 16362 } 16363 16364 /** 16365 * Do either or both things: (1) change the current configuration, and (2) 16366 * make sure the given activity is running with the (now) current 16367 * configuration. Returns true if the activity has been left running, or 16368 * false if <var>starting</var> is being destroyed to match the new 16369 * configuration. 16370 * @param persistent TODO 16371 */ 16372 boolean updateConfigurationLocked(Configuration values, 16373 ActivityRecord starting, boolean persistent, boolean initLocale) { 16374 int changes = 0; 16375 16376 if (values != null) { 16377 Configuration newConfig = new Configuration(mConfiguration); 16378 changes = newConfig.updateFrom(values); 16379 if (changes != 0) { 16380 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16381 Slog.i(TAG, "Updating configuration to: " + values); 16382 } 16383 16384 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16385 16386 if (values.locale != null && !initLocale) { 16387 saveLocaleLocked(values.locale, 16388 !values.locale.equals(mConfiguration.locale), 16389 values.userSetLocale); 16390 } 16391 16392 mConfigurationSeq++; 16393 if (mConfigurationSeq <= 0) { 16394 mConfigurationSeq = 1; 16395 } 16396 newConfig.seq = mConfigurationSeq; 16397 mConfiguration = newConfig; 16398 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16399 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16400 //mUsageStatsService.noteStartConfig(newConfig); 16401 16402 final Configuration configCopy = new Configuration(mConfiguration); 16403 16404 // TODO: If our config changes, should we auto dismiss any currently 16405 // showing dialogs? 16406 mShowDialogs = shouldShowDialogs(newConfig); 16407 16408 AttributeCache ac = AttributeCache.instance(); 16409 if (ac != null) { 16410 ac.updateConfiguration(configCopy); 16411 } 16412 16413 // Make sure all resources in our process are updated 16414 // right now, so that anyone who is going to retrieve 16415 // resource values after we return will be sure to get 16416 // the new ones. This is especially important during 16417 // boot, where the first config change needs to guarantee 16418 // all resources have that config before following boot 16419 // code is executed. 16420 mSystemThread.applyConfigurationToResources(configCopy); 16421 16422 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16423 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16424 msg.obj = new Configuration(configCopy); 16425 mHandler.sendMessage(msg); 16426 } 16427 16428 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16429 ProcessRecord app = mLruProcesses.get(i); 16430 try { 16431 if (app.thread != null) { 16432 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16433 + app.processName + " new config " + mConfiguration); 16434 app.thread.scheduleConfigurationChanged(configCopy); 16435 } 16436 } catch (Exception e) { 16437 } 16438 } 16439 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16440 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16441 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16442 | Intent.FLAG_RECEIVER_FOREGROUND); 16443 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16444 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16445 Process.SYSTEM_UID, UserHandle.USER_ALL); 16446 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16447 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16448 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16449 broadcastIntentLocked(null, null, intent, 16450 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16451 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16452 } 16453 } 16454 } 16455 16456 boolean kept = true; 16457 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16458 // mainStack is null during startup. 16459 if (mainStack != null) { 16460 if (changes != 0 && starting == null) { 16461 // If the configuration changed, and the caller is not already 16462 // in the process of starting an activity, then find the top 16463 // activity to check if its configuration needs to change. 16464 starting = mainStack.topRunningActivityLocked(null); 16465 } 16466 16467 if (starting != null) { 16468 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16469 // And we need to make sure at this point that all other activities 16470 // are made visible with the correct configuration. 16471 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16472 } 16473 } 16474 16475 if (values != null && mWindowManager != null) { 16476 mWindowManager.setNewConfiguration(mConfiguration); 16477 } 16478 16479 return kept; 16480 } 16481 16482 /** 16483 * Decide based on the configuration whether we should shouw the ANR, 16484 * crash, etc dialogs. The idea is that if there is no affordnace to 16485 * press the on-screen buttons, we shouldn't show the dialog. 16486 * 16487 * A thought: SystemUI might also want to get told about this, the Power 16488 * dialog / global actions also might want different behaviors. 16489 */ 16490 private static final boolean shouldShowDialogs(Configuration config) { 16491 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16492 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16493 } 16494 16495 /** 16496 * Save the locale. You must be inside a synchronized (this) block. 16497 */ 16498 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16499 if(isDiff) { 16500 SystemProperties.set("user.language", l.getLanguage()); 16501 SystemProperties.set("user.region", l.getCountry()); 16502 } 16503 16504 if(isPersist) { 16505 SystemProperties.set("persist.sys.language", l.getLanguage()); 16506 SystemProperties.set("persist.sys.country", l.getCountry()); 16507 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16508 16509 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16510 } 16511 } 16512 16513 @Override 16514 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16515 synchronized (this) { 16516 ActivityRecord srec = ActivityRecord.forToken(token); 16517 if (srec.task != null && srec.task.stack != null) { 16518 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16519 } 16520 } 16521 return false; 16522 } 16523 16524 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16525 Intent resultData) { 16526 16527 synchronized (this) { 16528 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16529 if (stack != null) { 16530 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16531 } 16532 return false; 16533 } 16534 } 16535 16536 public int getLaunchedFromUid(IBinder activityToken) { 16537 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16538 if (srec == null) { 16539 return -1; 16540 } 16541 return srec.launchedFromUid; 16542 } 16543 16544 public String getLaunchedFromPackage(IBinder activityToken) { 16545 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16546 if (srec == null) { 16547 return null; 16548 } 16549 return srec.launchedFromPackage; 16550 } 16551 16552 // ========================================================= 16553 // LIFETIME MANAGEMENT 16554 // ========================================================= 16555 16556 // Returns which broadcast queue the app is the current [or imminent] receiver 16557 // on, or 'null' if the app is not an active broadcast recipient. 16558 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16559 BroadcastRecord r = app.curReceiver; 16560 if (r != null) { 16561 return r.queue; 16562 } 16563 16564 // It's not the current receiver, but it might be starting up to become one 16565 synchronized (this) { 16566 for (BroadcastQueue queue : mBroadcastQueues) { 16567 r = queue.mPendingBroadcast; 16568 if (r != null && r.curApp == app) { 16569 // found it; report which queue it's in 16570 return queue; 16571 } 16572 } 16573 } 16574 16575 return null; 16576 } 16577 16578 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16579 boolean doingAll, long now) { 16580 if (mAdjSeq == app.adjSeq) { 16581 // This adjustment has already been computed. 16582 return app.curRawAdj; 16583 } 16584 16585 if (app.thread == null) { 16586 app.adjSeq = mAdjSeq; 16587 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16588 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16589 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16590 } 16591 16592 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16593 app.adjSource = null; 16594 app.adjTarget = null; 16595 app.empty = false; 16596 app.cached = false; 16597 16598 final int activitiesSize = app.activities.size(); 16599 16600 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16601 // The max adjustment doesn't allow this app to be anything 16602 // below foreground, so it is not worth doing work for it. 16603 app.adjType = "fixed"; 16604 app.adjSeq = mAdjSeq; 16605 app.curRawAdj = app.maxAdj; 16606 app.foregroundActivities = false; 16607 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16608 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16609 // System processes can do UI, and when they do we want to have 16610 // them trim their memory after the user leaves the UI. To 16611 // facilitate this, here we need to determine whether or not it 16612 // is currently showing UI. 16613 app.systemNoUi = true; 16614 if (app == TOP_APP) { 16615 app.systemNoUi = false; 16616 } else if (activitiesSize > 0) { 16617 for (int j = 0; j < activitiesSize; j++) { 16618 final ActivityRecord r = app.activities.get(j); 16619 if (r.visible) { 16620 app.systemNoUi = false; 16621 } 16622 } 16623 } 16624 if (!app.systemNoUi) { 16625 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16626 } 16627 return (app.curAdj=app.maxAdj); 16628 } 16629 16630 app.systemNoUi = false; 16631 16632 // Determine the importance of the process, starting with most 16633 // important to least, and assign an appropriate OOM adjustment. 16634 int adj; 16635 int schedGroup; 16636 int procState; 16637 boolean foregroundActivities = false; 16638 BroadcastQueue queue; 16639 if (app == TOP_APP) { 16640 // The last app on the list is the foreground app. 16641 adj = ProcessList.FOREGROUND_APP_ADJ; 16642 schedGroup = Process.THREAD_GROUP_DEFAULT; 16643 app.adjType = "top-activity"; 16644 foregroundActivities = true; 16645 procState = ActivityManager.PROCESS_STATE_TOP; 16646 } else if (app.instrumentationClass != null) { 16647 // Don't want to kill running instrumentation. 16648 adj = ProcessList.FOREGROUND_APP_ADJ; 16649 schedGroup = Process.THREAD_GROUP_DEFAULT; 16650 app.adjType = "instrumentation"; 16651 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16652 } else if ((queue = isReceivingBroadcast(app)) != null) { 16653 // An app that is currently receiving a broadcast also 16654 // counts as being in the foreground for OOM killer purposes. 16655 // It's placed in a sched group based on the nature of the 16656 // broadcast as reflected by which queue it's active in. 16657 adj = ProcessList.FOREGROUND_APP_ADJ; 16658 schedGroup = (queue == mFgBroadcastQueue) 16659 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16660 app.adjType = "broadcast"; 16661 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16662 } else if (app.executingServices.size() > 0) { 16663 // An app that is currently executing a service callback also 16664 // counts as being in the foreground. 16665 adj = ProcessList.FOREGROUND_APP_ADJ; 16666 schedGroup = app.execServicesFg ? 16667 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16668 app.adjType = "exec-service"; 16669 procState = ActivityManager.PROCESS_STATE_SERVICE; 16670 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16671 } else { 16672 // As far as we know the process is empty. We may change our mind later. 16673 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16674 // At this point we don't actually know the adjustment. Use the cached adj 16675 // value that the caller wants us to. 16676 adj = cachedAdj; 16677 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16678 app.cached = true; 16679 app.empty = true; 16680 app.adjType = "cch-empty"; 16681 } 16682 16683 // Examine all activities if not already foreground. 16684 if (!foregroundActivities && activitiesSize > 0) { 16685 for (int j = 0; j < activitiesSize; j++) { 16686 final ActivityRecord r = app.activities.get(j); 16687 if (r.app != app) { 16688 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16689 + app + "?!?"); 16690 continue; 16691 } 16692 if (r.visible) { 16693 // App has a visible activity; only upgrade adjustment. 16694 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16695 adj = ProcessList.VISIBLE_APP_ADJ; 16696 app.adjType = "visible"; 16697 } 16698 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16699 procState = ActivityManager.PROCESS_STATE_TOP; 16700 } 16701 schedGroup = Process.THREAD_GROUP_DEFAULT; 16702 app.cached = false; 16703 app.empty = false; 16704 foregroundActivities = true; 16705 break; 16706 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16707 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16708 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16709 app.adjType = "pausing"; 16710 } 16711 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16712 procState = ActivityManager.PROCESS_STATE_TOP; 16713 } 16714 schedGroup = Process.THREAD_GROUP_DEFAULT; 16715 app.cached = false; 16716 app.empty = false; 16717 foregroundActivities = true; 16718 } else if (r.state == ActivityState.STOPPING) { 16719 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16720 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16721 app.adjType = "stopping"; 16722 } 16723 // For the process state, we will at this point consider the 16724 // process to be cached. It will be cached either as an activity 16725 // or empty depending on whether the activity is finishing. We do 16726 // this so that we can treat the process as cached for purposes of 16727 // memory trimming (determing current memory level, trim command to 16728 // send to process) since there can be an arbitrary number of stopping 16729 // processes and they should soon all go into the cached state. 16730 if (!r.finishing) { 16731 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16732 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16733 } 16734 } 16735 app.cached = false; 16736 app.empty = false; 16737 foregroundActivities = true; 16738 } else { 16739 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16740 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16741 app.adjType = "cch-act"; 16742 } 16743 } 16744 } 16745 } 16746 16747 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16748 if (app.foregroundServices) { 16749 // The user is aware of this app, so make it visible. 16750 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16751 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16752 app.cached = false; 16753 app.adjType = "fg-service"; 16754 schedGroup = Process.THREAD_GROUP_DEFAULT; 16755 } else if (app.forcingToForeground != null) { 16756 // The user is aware of this app, so make it visible. 16757 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16758 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16759 app.cached = false; 16760 app.adjType = "force-fg"; 16761 app.adjSource = app.forcingToForeground; 16762 schedGroup = Process.THREAD_GROUP_DEFAULT; 16763 } 16764 } 16765 16766 if (app == mHeavyWeightProcess) { 16767 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16768 // We don't want to kill the current heavy-weight process. 16769 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16770 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16771 app.cached = false; 16772 app.adjType = "heavy"; 16773 } 16774 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16775 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16776 } 16777 } 16778 16779 if (app == mHomeProcess) { 16780 if (adj > ProcessList.HOME_APP_ADJ) { 16781 // This process is hosting what we currently consider to be the 16782 // home app, so we don't want to let it go into the background. 16783 adj = ProcessList.HOME_APP_ADJ; 16784 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16785 app.cached = false; 16786 app.adjType = "home"; 16787 } 16788 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16789 procState = ActivityManager.PROCESS_STATE_HOME; 16790 } 16791 } 16792 16793 if (app == mPreviousProcess && app.activities.size() > 0) { 16794 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16795 // This was the previous process that showed UI to the user. 16796 // We want to try to keep it around more aggressively, to give 16797 // a good experience around switching between two apps. 16798 adj = ProcessList.PREVIOUS_APP_ADJ; 16799 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16800 app.cached = false; 16801 app.adjType = "previous"; 16802 } 16803 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16804 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16805 } 16806 } 16807 16808 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16809 + " reason=" + app.adjType); 16810 16811 // By default, we use the computed adjustment. It may be changed if 16812 // there are applications dependent on our services or providers, but 16813 // this gives us a baseline and makes sure we don't get into an 16814 // infinite recursion. 16815 app.adjSeq = mAdjSeq; 16816 app.curRawAdj = adj; 16817 app.hasStartedServices = false; 16818 16819 if (mBackupTarget != null && app == mBackupTarget.app) { 16820 // If possible we want to avoid killing apps while they're being backed up 16821 if (adj > ProcessList.BACKUP_APP_ADJ) { 16822 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16823 adj = ProcessList.BACKUP_APP_ADJ; 16824 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16825 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16826 } 16827 app.adjType = "backup"; 16828 app.cached = false; 16829 } 16830 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16831 procState = ActivityManager.PROCESS_STATE_BACKUP; 16832 } 16833 } 16834 16835 boolean mayBeTop = false; 16836 16837 for (int is = app.services.size()-1; 16838 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16839 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16840 || procState > ActivityManager.PROCESS_STATE_TOP); 16841 is--) { 16842 ServiceRecord s = app.services.valueAt(is); 16843 if (s.startRequested) { 16844 app.hasStartedServices = true; 16845 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16846 procState = ActivityManager.PROCESS_STATE_SERVICE; 16847 } 16848 if (app.hasShownUi && app != mHomeProcess) { 16849 // If this process has shown some UI, let it immediately 16850 // go to the LRU list because it may be pretty heavy with 16851 // UI stuff. We'll tag it with a label just to help 16852 // debug and understand what is going on. 16853 if (adj > ProcessList.SERVICE_ADJ) { 16854 app.adjType = "cch-started-ui-services"; 16855 } 16856 } else { 16857 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16858 // This service has seen some activity within 16859 // recent memory, so we will keep its process ahead 16860 // of the background processes. 16861 if (adj > ProcessList.SERVICE_ADJ) { 16862 adj = ProcessList.SERVICE_ADJ; 16863 app.adjType = "started-services"; 16864 app.cached = false; 16865 } 16866 } 16867 // If we have let the service slide into the background 16868 // state, still have some text describing what it is doing 16869 // even though the service no longer has an impact. 16870 if (adj > ProcessList.SERVICE_ADJ) { 16871 app.adjType = "cch-started-services"; 16872 } 16873 } 16874 } 16875 for (int conni = s.connections.size()-1; 16876 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16877 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16878 || procState > ActivityManager.PROCESS_STATE_TOP); 16879 conni--) { 16880 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16881 for (int i = 0; 16882 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16883 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16884 || procState > ActivityManager.PROCESS_STATE_TOP); 16885 i++) { 16886 // XXX should compute this based on the max of 16887 // all connected clients. 16888 ConnectionRecord cr = clist.get(i); 16889 if (cr.binding.client == app) { 16890 // Binding to ourself is not interesting. 16891 continue; 16892 } 16893 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16894 ProcessRecord client = cr.binding.client; 16895 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16896 TOP_APP, doingAll, now); 16897 int clientProcState = client.curProcState; 16898 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16899 // If the other app is cached for any reason, for purposes here 16900 // we are going to consider it empty. The specific cached state 16901 // doesn't propagate except under certain conditions. 16902 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16903 } 16904 String adjType = null; 16905 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16906 // Not doing bind OOM management, so treat 16907 // this guy more like a started service. 16908 if (app.hasShownUi && app != mHomeProcess) { 16909 // If this process has shown some UI, let it immediately 16910 // go to the LRU list because it may be pretty heavy with 16911 // UI stuff. We'll tag it with a label just to help 16912 // debug and understand what is going on. 16913 if (adj > clientAdj) { 16914 adjType = "cch-bound-ui-services"; 16915 } 16916 app.cached = false; 16917 clientAdj = adj; 16918 clientProcState = procState; 16919 } else { 16920 if (now >= (s.lastActivity 16921 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16922 // This service has not seen activity within 16923 // recent memory, so allow it to drop to the 16924 // LRU list if there is no other reason to keep 16925 // it around. We'll also tag it with a label just 16926 // to help debug and undertand what is going on. 16927 if (adj > clientAdj) { 16928 adjType = "cch-bound-services"; 16929 } 16930 clientAdj = adj; 16931 } 16932 } 16933 } 16934 if (adj > clientAdj) { 16935 // If this process has recently shown UI, and 16936 // the process that is binding to it is less 16937 // important than being visible, then we don't 16938 // care about the binding as much as we care 16939 // about letting this process get into the LRU 16940 // list to be killed and restarted if needed for 16941 // memory. 16942 if (app.hasShownUi && app != mHomeProcess 16943 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16944 adjType = "cch-bound-ui-services"; 16945 } else { 16946 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16947 |Context.BIND_IMPORTANT)) != 0) { 16948 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16949 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16950 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16951 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16952 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16953 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16954 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16955 adj = clientAdj; 16956 } else { 16957 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16958 adj = ProcessList.VISIBLE_APP_ADJ; 16959 } 16960 } 16961 if (!client.cached) { 16962 app.cached = false; 16963 } 16964 adjType = "service"; 16965 } 16966 } 16967 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16968 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16969 schedGroup = Process.THREAD_GROUP_DEFAULT; 16970 } 16971 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16972 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16973 // Special handling of clients who are in the top state. 16974 // We *may* want to consider this process to be in the 16975 // top state as well, but only if there is not another 16976 // reason for it to be running. Being on the top is a 16977 // special state, meaning you are specifically running 16978 // for the current top app. If the process is already 16979 // running in the background for some other reason, it 16980 // is more important to continue considering it to be 16981 // in the background state. 16982 mayBeTop = true; 16983 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16984 } else { 16985 // Special handling for above-top states (persistent 16986 // processes). These should not bring the current process 16987 // into the top state, since they are not on top. Instead 16988 // give them the best state after that. 16989 clientProcState = 16990 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16991 } 16992 } 16993 } else { 16994 if (clientProcState < 16995 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16996 clientProcState = 16997 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16998 } 16999 } 17000 if (procState > clientProcState) { 17001 procState = clientProcState; 17002 } 17003 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17004 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17005 app.pendingUiClean = true; 17006 } 17007 if (adjType != null) { 17008 app.adjType = adjType; 17009 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17010 .REASON_SERVICE_IN_USE; 17011 app.adjSource = cr.binding.client; 17012 app.adjSourceProcState = clientProcState; 17013 app.adjTarget = s.name; 17014 } 17015 } 17016 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17017 app.treatLikeActivity = true; 17018 } 17019 final ActivityRecord a = cr.activity; 17020 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17021 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17022 (a.visible || a.state == ActivityState.RESUMED 17023 || a.state == ActivityState.PAUSING)) { 17024 adj = ProcessList.FOREGROUND_APP_ADJ; 17025 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17026 schedGroup = Process.THREAD_GROUP_DEFAULT; 17027 } 17028 app.cached = false; 17029 app.adjType = "service"; 17030 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17031 .REASON_SERVICE_IN_USE; 17032 app.adjSource = a; 17033 app.adjSourceProcState = procState; 17034 app.adjTarget = s.name; 17035 } 17036 } 17037 } 17038 } 17039 } 17040 17041 for (int provi = app.pubProviders.size()-1; 17042 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17043 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17044 || procState > ActivityManager.PROCESS_STATE_TOP); 17045 provi--) { 17046 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17047 for (int i = cpr.connections.size()-1; 17048 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17049 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17050 || procState > ActivityManager.PROCESS_STATE_TOP); 17051 i--) { 17052 ContentProviderConnection conn = cpr.connections.get(i); 17053 ProcessRecord client = conn.client; 17054 if (client == app) { 17055 // Being our own client is not interesting. 17056 continue; 17057 } 17058 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17059 int clientProcState = client.curProcState; 17060 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17061 // If the other app is cached for any reason, for purposes here 17062 // we are going to consider it empty. 17063 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17064 } 17065 if (adj > clientAdj) { 17066 if (app.hasShownUi && app != mHomeProcess 17067 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17068 app.adjType = "cch-ui-provider"; 17069 } else { 17070 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17071 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17072 app.adjType = "provider"; 17073 } 17074 app.cached &= client.cached; 17075 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17076 .REASON_PROVIDER_IN_USE; 17077 app.adjSource = client; 17078 app.adjSourceProcState = clientProcState; 17079 app.adjTarget = cpr.name; 17080 } 17081 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17082 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17083 // Special handling of clients who are in the top state. 17084 // We *may* want to consider this process to be in the 17085 // top state as well, but only if there is not another 17086 // reason for it to be running. Being on the top is a 17087 // special state, meaning you are specifically running 17088 // for the current top app. If the process is already 17089 // running in the background for some other reason, it 17090 // is more important to continue considering it to be 17091 // in the background state. 17092 mayBeTop = true; 17093 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17094 } else { 17095 // Special handling for above-top states (persistent 17096 // processes). These should not bring the current process 17097 // into the top state, since they are not on top. Instead 17098 // give them the best state after that. 17099 clientProcState = 17100 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17101 } 17102 } 17103 if (procState > clientProcState) { 17104 procState = clientProcState; 17105 } 17106 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17107 schedGroup = Process.THREAD_GROUP_DEFAULT; 17108 } 17109 } 17110 // If the provider has external (non-framework) process 17111 // dependencies, ensure that its adjustment is at least 17112 // FOREGROUND_APP_ADJ. 17113 if (cpr.hasExternalProcessHandles()) { 17114 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17115 adj = ProcessList.FOREGROUND_APP_ADJ; 17116 schedGroup = Process.THREAD_GROUP_DEFAULT; 17117 app.cached = false; 17118 app.adjType = "provider"; 17119 app.adjTarget = cpr.name; 17120 } 17121 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17122 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17123 } 17124 } 17125 } 17126 17127 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17128 // A client of one of our services or providers is in the top state. We 17129 // *may* want to be in the top state, but not if we are already running in 17130 // the background for some other reason. For the decision here, we are going 17131 // to pick out a few specific states that we want to remain in when a client 17132 // is top (states that tend to be longer-term) and otherwise allow it to go 17133 // to the top state. 17134 switch (procState) { 17135 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17136 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17137 case ActivityManager.PROCESS_STATE_SERVICE: 17138 // These all are longer-term states, so pull them up to the top 17139 // of the background states, but not all the way to the top state. 17140 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17141 break; 17142 default: 17143 // Otherwise, top is a better choice, so take it. 17144 procState = ActivityManager.PROCESS_STATE_TOP; 17145 break; 17146 } 17147 } 17148 17149 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17150 if (app.hasClientActivities) { 17151 // This is a cached process, but with client activities. Mark it so. 17152 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17153 app.adjType = "cch-client-act"; 17154 } else if (app.treatLikeActivity) { 17155 // This is a cached process, but somebody wants us to treat it like it has 17156 // an activity, okay! 17157 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17158 app.adjType = "cch-as-act"; 17159 } 17160 } 17161 17162 if (adj == ProcessList.SERVICE_ADJ) { 17163 if (doingAll) { 17164 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17165 mNewNumServiceProcs++; 17166 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17167 if (!app.serviceb) { 17168 // This service isn't far enough down on the LRU list to 17169 // normally be a B service, but if we are low on RAM and it 17170 // is large we want to force it down since we would prefer to 17171 // keep launcher over it. 17172 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17173 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17174 app.serviceHighRam = true; 17175 app.serviceb = true; 17176 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17177 } else { 17178 mNewNumAServiceProcs++; 17179 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17180 } 17181 } else { 17182 app.serviceHighRam = false; 17183 } 17184 } 17185 if (app.serviceb) { 17186 adj = ProcessList.SERVICE_B_ADJ; 17187 } 17188 } 17189 17190 app.curRawAdj = adj; 17191 17192 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17193 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17194 if (adj > app.maxAdj) { 17195 adj = app.maxAdj; 17196 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17197 schedGroup = Process.THREAD_GROUP_DEFAULT; 17198 } 17199 } 17200 17201 // Do final modification to adj. Everything we do between here and applying 17202 // the final setAdj must be done in this function, because we will also use 17203 // it when computing the final cached adj later. Note that we don't need to 17204 // worry about this for max adj above, since max adj will always be used to 17205 // keep it out of the cached vaues. 17206 app.curAdj = app.modifyRawOomAdj(adj); 17207 app.curSchedGroup = schedGroup; 17208 app.curProcState = procState; 17209 app.foregroundActivities = foregroundActivities; 17210 17211 return app.curRawAdj; 17212 } 17213 17214 /** 17215 * Schedule PSS collection of a process. 17216 */ 17217 void requestPssLocked(ProcessRecord proc, int procState) { 17218 if (mPendingPssProcesses.contains(proc)) { 17219 return; 17220 } 17221 if (mPendingPssProcesses.size() == 0) { 17222 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17223 } 17224 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17225 proc.pssProcState = procState; 17226 mPendingPssProcesses.add(proc); 17227 } 17228 17229 /** 17230 * Schedule PSS collection of all processes. 17231 */ 17232 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17233 if (!always) { 17234 if (now < (mLastFullPssTime + 17235 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17236 return; 17237 } 17238 } 17239 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17240 mLastFullPssTime = now; 17241 mFullPssPending = true; 17242 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17243 mPendingPssProcesses.clear(); 17244 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17245 ProcessRecord app = mLruProcesses.get(i); 17246 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17247 app.pssProcState = app.setProcState; 17248 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17249 isSleeping(), now); 17250 mPendingPssProcesses.add(app); 17251 } 17252 } 17253 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17254 } 17255 17256 /** 17257 * Ask a given process to GC right now. 17258 */ 17259 final void performAppGcLocked(ProcessRecord app) { 17260 try { 17261 app.lastRequestedGc = SystemClock.uptimeMillis(); 17262 if (app.thread != null) { 17263 if (app.reportLowMemory) { 17264 app.reportLowMemory = false; 17265 app.thread.scheduleLowMemory(); 17266 } else { 17267 app.thread.processInBackground(); 17268 } 17269 } 17270 } catch (Exception e) { 17271 // whatever. 17272 } 17273 } 17274 17275 /** 17276 * Returns true if things are idle enough to perform GCs. 17277 */ 17278 private final boolean canGcNowLocked() { 17279 boolean processingBroadcasts = false; 17280 for (BroadcastQueue q : mBroadcastQueues) { 17281 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17282 processingBroadcasts = true; 17283 } 17284 } 17285 return !processingBroadcasts 17286 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17287 } 17288 17289 /** 17290 * Perform GCs on all processes that are waiting for it, but only 17291 * if things are idle. 17292 */ 17293 final void performAppGcsLocked() { 17294 final int N = mProcessesToGc.size(); 17295 if (N <= 0) { 17296 return; 17297 } 17298 if (canGcNowLocked()) { 17299 while (mProcessesToGc.size() > 0) { 17300 ProcessRecord proc = mProcessesToGc.remove(0); 17301 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17302 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17303 <= SystemClock.uptimeMillis()) { 17304 // To avoid spamming the system, we will GC processes one 17305 // at a time, waiting a few seconds between each. 17306 performAppGcLocked(proc); 17307 scheduleAppGcsLocked(); 17308 return; 17309 } else { 17310 // It hasn't been long enough since we last GCed this 17311 // process... put it in the list to wait for its time. 17312 addProcessToGcListLocked(proc); 17313 break; 17314 } 17315 } 17316 } 17317 17318 scheduleAppGcsLocked(); 17319 } 17320 } 17321 17322 /** 17323 * If all looks good, perform GCs on all processes waiting for them. 17324 */ 17325 final void performAppGcsIfAppropriateLocked() { 17326 if (canGcNowLocked()) { 17327 performAppGcsLocked(); 17328 return; 17329 } 17330 // Still not idle, wait some more. 17331 scheduleAppGcsLocked(); 17332 } 17333 17334 /** 17335 * Schedule the execution of all pending app GCs. 17336 */ 17337 final void scheduleAppGcsLocked() { 17338 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17339 17340 if (mProcessesToGc.size() > 0) { 17341 // Schedule a GC for the time to the next process. 17342 ProcessRecord proc = mProcessesToGc.get(0); 17343 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17344 17345 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17346 long now = SystemClock.uptimeMillis(); 17347 if (when < (now+GC_TIMEOUT)) { 17348 when = now + GC_TIMEOUT; 17349 } 17350 mHandler.sendMessageAtTime(msg, when); 17351 } 17352 } 17353 17354 /** 17355 * Add a process to the array of processes waiting to be GCed. Keeps the 17356 * list in sorted order by the last GC time. The process can't already be 17357 * on the list. 17358 */ 17359 final void addProcessToGcListLocked(ProcessRecord proc) { 17360 boolean added = false; 17361 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17362 if (mProcessesToGc.get(i).lastRequestedGc < 17363 proc.lastRequestedGc) { 17364 added = true; 17365 mProcessesToGc.add(i+1, proc); 17366 break; 17367 } 17368 } 17369 if (!added) { 17370 mProcessesToGc.add(0, proc); 17371 } 17372 } 17373 17374 /** 17375 * Set up to ask a process to GC itself. This will either do it 17376 * immediately, or put it on the list of processes to gc the next 17377 * time things are idle. 17378 */ 17379 final void scheduleAppGcLocked(ProcessRecord app) { 17380 long now = SystemClock.uptimeMillis(); 17381 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17382 return; 17383 } 17384 if (!mProcessesToGc.contains(app)) { 17385 addProcessToGcListLocked(app); 17386 scheduleAppGcsLocked(); 17387 } 17388 } 17389 17390 final void checkExcessivePowerUsageLocked(boolean doKills) { 17391 updateCpuStatsNow(); 17392 17393 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17394 boolean doWakeKills = doKills; 17395 boolean doCpuKills = doKills; 17396 if (mLastPowerCheckRealtime == 0) { 17397 doWakeKills = false; 17398 } 17399 if (mLastPowerCheckUptime == 0) { 17400 doCpuKills = false; 17401 } 17402 if (stats.isScreenOn()) { 17403 doWakeKills = false; 17404 } 17405 final long curRealtime = SystemClock.elapsedRealtime(); 17406 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17407 final long curUptime = SystemClock.uptimeMillis(); 17408 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17409 mLastPowerCheckRealtime = curRealtime; 17410 mLastPowerCheckUptime = curUptime; 17411 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17412 doWakeKills = false; 17413 } 17414 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17415 doCpuKills = false; 17416 } 17417 int i = mLruProcesses.size(); 17418 while (i > 0) { 17419 i--; 17420 ProcessRecord app = mLruProcesses.get(i); 17421 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17422 long wtime; 17423 synchronized (stats) { 17424 wtime = stats.getProcessWakeTime(app.info.uid, 17425 app.pid, curRealtime); 17426 } 17427 long wtimeUsed = wtime - app.lastWakeTime; 17428 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17429 if (DEBUG_POWER) { 17430 StringBuilder sb = new StringBuilder(128); 17431 sb.append("Wake for "); 17432 app.toShortString(sb); 17433 sb.append(": over "); 17434 TimeUtils.formatDuration(realtimeSince, sb); 17435 sb.append(" used "); 17436 TimeUtils.formatDuration(wtimeUsed, sb); 17437 sb.append(" ("); 17438 sb.append((wtimeUsed*100)/realtimeSince); 17439 sb.append("%)"); 17440 Slog.i(TAG, sb.toString()); 17441 sb.setLength(0); 17442 sb.append("CPU for "); 17443 app.toShortString(sb); 17444 sb.append(": over "); 17445 TimeUtils.formatDuration(uptimeSince, sb); 17446 sb.append(" used "); 17447 TimeUtils.formatDuration(cputimeUsed, sb); 17448 sb.append(" ("); 17449 sb.append((cputimeUsed*100)/uptimeSince); 17450 sb.append("%)"); 17451 Slog.i(TAG, sb.toString()); 17452 } 17453 // If a process has held a wake lock for more 17454 // than 50% of the time during this period, 17455 // that sounds bad. Kill! 17456 if (doWakeKills && realtimeSince > 0 17457 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17458 synchronized (stats) { 17459 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17460 realtimeSince, wtimeUsed); 17461 } 17462 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17463 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17464 } else if (doCpuKills && uptimeSince > 0 17465 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17466 synchronized (stats) { 17467 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17468 uptimeSince, cputimeUsed); 17469 } 17470 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17471 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17472 } else { 17473 app.lastWakeTime = wtime; 17474 app.lastCpuTime = app.curCpuTime; 17475 } 17476 } 17477 } 17478 } 17479 17480 private final boolean applyOomAdjLocked(ProcessRecord app, 17481 ProcessRecord TOP_APP, boolean doingAll, long now) { 17482 boolean success = true; 17483 17484 if (app.curRawAdj != app.setRawAdj) { 17485 app.setRawAdj = app.curRawAdj; 17486 } 17487 17488 int changes = 0; 17489 17490 if (app.curAdj != app.setAdj) { 17491 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17492 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17493 TAG, "Set " + app.pid + " " + app.processName + 17494 " adj " + app.curAdj + ": " + app.adjType); 17495 app.setAdj = app.curAdj; 17496 } 17497 17498 if (app.setSchedGroup != app.curSchedGroup) { 17499 app.setSchedGroup = app.curSchedGroup; 17500 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17501 "Setting process group of " + app.processName 17502 + " to " + app.curSchedGroup); 17503 if (app.waitingToKill != null && 17504 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17505 app.kill(app.waitingToKill, true); 17506 success = false; 17507 } else { 17508 if (true) { 17509 long oldId = Binder.clearCallingIdentity(); 17510 try { 17511 Process.setProcessGroup(app.pid, app.curSchedGroup); 17512 } catch (Exception e) { 17513 Slog.w(TAG, "Failed setting process group of " + app.pid 17514 + " to " + app.curSchedGroup); 17515 e.printStackTrace(); 17516 } finally { 17517 Binder.restoreCallingIdentity(oldId); 17518 } 17519 } else { 17520 if (app.thread != null) { 17521 try { 17522 app.thread.setSchedulingGroup(app.curSchedGroup); 17523 } catch (RemoteException e) { 17524 } 17525 } 17526 } 17527 Process.setSwappiness(app.pid, 17528 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17529 } 17530 } 17531 if (app.repForegroundActivities != app.foregroundActivities) { 17532 app.repForegroundActivities = app.foregroundActivities; 17533 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17534 } 17535 if (app.repProcState != app.curProcState) { 17536 app.repProcState = app.curProcState; 17537 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17538 if (app.thread != null) { 17539 try { 17540 if (false) { 17541 //RuntimeException h = new RuntimeException("here"); 17542 Slog.i(TAG, "Sending new process state " + app.repProcState 17543 + " to " + app /*, h*/); 17544 } 17545 app.thread.setProcessState(app.repProcState); 17546 } catch (RemoteException e) { 17547 } 17548 } 17549 } 17550 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17551 app.setProcState)) { 17552 app.lastStateTime = now; 17553 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17554 isSleeping(), now); 17555 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17556 + ProcessList.makeProcStateString(app.setProcState) + " to " 17557 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17558 + (app.nextPssTime-now) + ": " + app); 17559 } else { 17560 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17561 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17562 requestPssLocked(app, app.setProcState); 17563 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17564 isSleeping(), now); 17565 } else if (false && DEBUG_PSS) { 17566 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17567 } 17568 } 17569 if (app.setProcState != app.curProcState) { 17570 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17571 "Proc state change of " + app.processName 17572 + " to " + app.curProcState); 17573 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17574 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17575 if (setImportant && !curImportant) { 17576 // This app is no longer something we consider important enough to allow to 17577 // use arbitrary amounts of battery power. Note 17578 // its current wake lock time to later know to kill it if 17579 // it is not behaving well. 17580 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17581 synchronized (stats) { 17582 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17583 app.pid, SystemClock.elapsedRealtime()); 17584 } 17585 app.lastCpuTime = app.curCpuTime; 17586 17587 } 17588 app.setProcState = app.curProcState; 17589 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17590 app.notCachedSinceIdle = false; 17591 } 17592 if (!doingAll) { 17593 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17594 } else { 17595 app.procStateChanged = true; 17596 } 17597 } 17598 17599 if (changes != 0) { 17600 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17601 int i = mPendingProcessChanges.size()-1; 17602 ProcessChangeItem item = null; 17603 while (i >= 0) { 17604 item = mPendingProcessChanges.get(i); 17605 if (item.pid == app.pid) { 17606 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17607 break; 17608 } 17609 i--; 17610 } 17611 if (i < 0) { 17612 // No existing item in pending changes; need a new one. 17613 final int NA = mAvailProcessChanges.size(); 17614 if (NA > 0) { 17615 item = mAvailProcessChanges.remove(NA-1); 17616 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17617 } else { 17618 item = new ProcessChangeItem(); 17619 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17620 } 17621 item.changes = 0; 17622 item.pid = app.pid; 17623 item.uid = app.info.uid; 17624 if (mPendingProcessChanges.size() == 0) { 17625 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17626 "*** Enqueueing dispatch processes changed!"); 17627 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17628 } 17629 mPendingProcessChanges.add(item); 17630 } 17631 item.changes |= changes; 17632 item.processState = app.repProcState; 17633 item.foregroundActivities = app.repForegroundActivities; 17634 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17635 + Integer.toHexString(System.identityHashCode(item)) 17636 + " " + app.toShortString() + ": changes=" + item.changes 17637 + " procState=" + item.processState 17638 + " foreground=" + item.foregroundActivities 17639 + " type=" + app.adjType + " source=" + app.adjSource 17640 + " target=" + app.adjTarget); 17641 } 17642 17643 return success; 17644 } 17645 17646 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17647 if (proc.thread != null) { 17648 if (proc.baseProcessTracker != null) { 17649 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17650 } 17651 if (proc.repProcState >= 0) { 17652 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17653 proc.repProcState); 17654 } 17655 } 17656 } 17657 17658 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17659 ProcessRecord TOP_APP, boolean doingAll, long now) { 17660 if (app.thread == null) { 17661 return false; 17662 } 17663 17664 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17665 17666 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17667 } 17668 17669 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17670 boolean oomAdj) { 17671 if (isForeground != proc.foregroundServices) { 17672 proc.foregroundServices = isForeground; 17673 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17674 proc.info.uid); 17675 if (isForeground) { 17676 if (curProcs == null) { 17677 curProcs = new ArrayList<ProcessRecord>(); 17678 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17679 } 17680 if (!curProcs.contains(proc)) { 17681 curProcs.add(proc); 17682 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17683 proc.info.packageName, proc.info.uid); 17684 } 17685 } else { 17686 if (curProcs != null) { 17687 if (curProcs.remove(proc)) { 17688 mBatteryStatsService.noteEvent( 17689 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17690 proc.info.packageName, proc.info.uid); 17691 if (curProcs.size() <= 0) { 17692 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17693 } 17694 } 17695 } 17696 } 17697 if (oomAdj) { 17698 updateOomAdjLocked(); 17699 } 17700 } 17701 } 17702 17703 private final ActivityRecord resumedAppLocked() { 17704 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17705 String pkg; 17706 int uid; 17707 if (act != null) { 17708 pkg = act.packageName; 17709 uid = act.info.applicationInfo.uid; 17710 } else { 17711 pkg = null; 17712 uid = -1; 17713 } 17714 // Has the UID or resumed package name changed? 17715 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17716 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17717 if (mCurResumedPackage != null) { 17718 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17719 mCurResumedPackage, mCurResumedUid); 17720 } 17721 mCurResumedPackage = pkg; 17722 mCurResumedUid = uid; 17723 if (mCurResumedPackage != null) { 17724 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17725 mCurResumedPackage, mCurResumedUid); 17726 } 17727 } 17728 return act; 17729 } 17730 17731 final boolean updateOomAdjLocked(ProcessRecord app) { 17732 final ActivityRecord TOP_ACT = resumedAppLocked(); 17733 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17734 final boolean wasCached = app.cached; 17735 17736 mAdjSeq++; 17737 17738 // This is the desired cached adjusment we want to tell it to use. 17739 // If our app is currently cached, we know it, and that is it. Otherwise, 17740 // we don't know it yet, and it needs to now be cached we will then 17741 // need to do a complete oom adj. 17742 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17743 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17744 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17745 SystemClock.uptimeMillis()); 17746 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17747 // Changed to/from cached state, so apps after it in the LRU 17748 // list may also be changed. 17749 updateOomAdjLocked(); 17750 } 17751 return success; 17752 } 17753 17754 final void updateOomAdjLocked() { 17755 final ActivityRecord TOP_ACT = resumedAppLocked(); 17756 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17757 final long now = SystemClock.uptimeMillis(); 17758 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17759 final int N = mLruProcesses.size(); 17760 17761 if (false) { 17762 RuntimeException e = new RuntimeException(); 17763 e.fillInStackTrace(); 17764 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17765 } 17766 17767 mAdjSeq++; 17768 mNewNumServiceProcs = 0; 17769 mNewNumAServiceProcs = 0; 17770 17771 final int emptyProcessLimit; 17772 final int cachedProcessLimit; 17773 if (mProcessLimit <= 0) { 17774 emptyProcessLimit = cachedProcessLimit = 0; 17775 } else if (mProcessLimit == 1) { 17776 emptyProcessLimit = 1; 17777 cachedProcessLimit = 0; 17778 } else { 17779 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17780 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17781 } 17782 17783 // Let's determine how many processes we have running vs. 17784 // how many slots we have for background processes; we may want 17785 // to put multiple processes in a slot of there are enough of 17786 // them. 17787 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17788 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17789 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17790 if (numEmptyProcs > cachedProcessLimit) { 17791 // If there are more empty processes than our limit on cached 17792 // processes, then use the cached process limit for the factor. 17793 // This ensures that the really old empty processes get pushed 17794 // down to the bottom, so if we are running low on memory we will 17795 // have a better chance at keeping around more cached processes 17796 // instead of a gazillion empty processes. 17797 numEmptyProcs = cachedProcessLimit; 17798 } 17799 int emptyFactor = numEmptyProcs/numSlots; 17800 if (emptyFactor < 1) emptyFactor = 1; 17801 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17802 if (cachedFactor < 1) cachedFactor = 1; 17803 int stepCached = 0; 17804 int stepEmpty = 0; 17805 int numCached = 0; 17806 int numEmpty = 0; 17807 int numTrimming = 0; 17808 17809 mNumNonCachedProcs = 0; 17810 mNumCachedHiddenProcs = 0; 17811 17812 // First update the OOM adjustment for each of the 17813 // application processes based on their current state. 17814 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17815 int nextCachedAdj = curCachedAdj+1; 17816 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17817 int nextEmptyAdj = curEmptyAdj+2; 17818 for (int i=N-1; i>=0; i--) { 17819 ProcessRecord app = mLruProcesses.get(i); 17820 if (!app.killedByAm && app.thread != null) { 17821 app.procStateChanged = false; 17822 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17823 17824 // If we haven't yet assigned the final cached adj 17825 // to the process, do that now. 17826 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17827 switch (app.curProcState) { 17828 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17829 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17830 // This process is a cached process holding activities... 17831 // assign it the next cached value for that type, and then 17832 // step that cached level. 17833 app.curRawAdj = curCachedAdj; 17834 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17835 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17836 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17837 + ")"); 17838 if (curCachedAdj != nextCachedAdj) { 17839 stepCached++; 17840 if (stepCached >= cachedFactor) { 17841 stepCached = 0; 17842 curCachedAdj = nextCachedAdj; 17843 nextCachedAdj += 2; 17844 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17845 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17846 } 17847 } 17848 } 17849 break; 17850 default: 17851 // For everything else, assign next empty cached process 17852 // level and bump that up. Note that this means that 17853 // long-running services that have dropped down to the 17854 // cached level will be treated as empty (since their process 17855 // state is still as a service), which is what we want. 17856 app.curRawAdj = curEmptyAdj; 17857 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17858 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17859 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17860 + ")"); 17861 if (curEmptyAdj != nextEmptyAdj) { 17862 stepEmpty++; 17863 if (stepEmpty >= emptyFactor) { 17864 stepEmpty = 0; 17865 curEmptyAdj = nextEmptyAdj; 17866 nextEmptyAdj += 2; 17867 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17868 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17869 } 17870 } 17871 } 17872 break; 17873 } 17874 } 17875 17876 applyOomAdjLocked(app, TOP_APP, true, now); 17877 17878 // Count the number of process types. 17879 switch (app.curProcState) { 17880 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17881 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17882 mNumCachedHiddenProcs++; 17883 numCached++; 17884 if (numCached > cachedProcessLimit) { 17885 app.kill("cached #" + numCached, true); 17886 } 17887 break; 17888 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17889 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17890 && app.lastActivityTime < oldTime) { 17891 app.kill("empty for " 17892 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17893 / 1000) + "s", true); 17894 } else { 17895 numEmpty++; 17896 if (numEmpty > emptyProcessLimit) { 17897 app.kill("empty #" + numEmpty, true); 17898 } 17899 } 17900 break; 17901 default: 17902 mNumNonCachedProcs++; 17903 break; 17904 } 17905 17906 if (app.isolated && app.services.size() <= 0) { 17907 // If this is an isolated process, and there are no 17908 // services running in it, then the process is no longer 17909 // needed. We agressively kill these because we can by 17910 // definition not re-use the same process again, and it is 17911 // good to avoid having whatever code was running in them 17912 // left sitting around after no longer needed. 17913 app.kill("isolated not needed", true); 17914 } 17915 17916 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17917 && !app.killedByAm) { 17918 numTrimming++; 17919 } 17920 } 17921 } 17922 17923 mNumServiceProcs = mNewNumServiceProcs; 17924 17925 // Now determine the memory trimming level of background processes. 17926 // Unfortunately we need to start at the back of the list to do this 17927 // properly. We only do this if the number of background apps we 17928 // are managing to keep around is less than half the maximum we desire; 17929 // if we are keeping a good number around, we'll let them use whatever 17930 // memory they want. 17931 final int numCachedAndEmpty = numCached + numEmpty; 17932 int memFactor; 17933 if (numCached <= ProcessList.TRIM_CACHED_APPS 17934 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17935 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17936 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17937 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17938 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17939 } else { 17940 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17941 } 17942 } else { 17943 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17944 } 17945 // We always allow the memory level to go up (better). We only allow it to go 17946 // down if we are in a state where that is allowed, *and* the total number of processes 17947 // has gone down since last time. 17948 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17949 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17950 + " last=" + mLastNumProcesses); 17951 if (memFactor > mLastMemoryLevel) { 17952 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17953 memFactor = mLastMemoryLevel; 17954 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17955 } 17956 } 17957 mLastMemoryLevel = memFactor; 17958 mLastNumProcesses = mLruProcesses.size(); 17959 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17960 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17961 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17962 if (mLowRamStartTime == 0) { 17963 mLowRamStartTime = now; 17964 } 17965 int step = 0; 17966 int fgTrimLevel; 17967 switch (memFactor) { 17968 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17969 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17970 break; 17971 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17972 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17973 break; 17974 default: 17975 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17976 break; 17977 } 17978 int factor = numTrimming/3; 17979 int minFactor = 2; 17980 if (mHomeProcess != null) minFactor++; 17981 if (mPreviousProcess != null) minFactor++; 17982 if (factor < minFactor) factor = minFactor; 17983 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17984 for (int i=N-1; i>=0; i--) { 17985 ProcessRecord app = mLruProcesses.get(i); 17986 if (allChanged || app.procStateChanged) { 17987 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17988 app.procStateChanged = false; 17989 } 17990 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17991 && !app.killedByAm) { 17992 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17993 try { 17994 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17995 "Trimming memory of " + app.processName 17996 + " to " + curLevel); 17997 app.thread.scheduleTrimMemory(curLevel); 17998 } catch (RemoteException e) { 17999 } 18000 if (false) { 18001 // For now we won't do this; our memory trimming seems 18002 // to be good enough at this point that destroying 18003 // activities causes more harm than good. 18004 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18005 && app != mHomeProcess && app != mPreviousProcess) { 18006 // Need to do this on its own message because the stack may not 18007 // be in a consistent state at this point. 18008 // For these apps we will also finish their activities 18009 // to help them free memory. 18010 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18011 } 18012 } 18013 } 18014 app.trimMemoryLevel = curLevel; 18015 step++; 18016 if (step >= factor) { 18017 step = 0; 18018 switch (curLevel) { 18019 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18020 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18021 break; 18022 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18023 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18024 break; 18025 } 18026 } 18027 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18028 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18029 && app.thread != null) { 18030 try { 18031 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18032 "Trimming memory of heavy-weight " + app.processName 18033 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18034 app.thread.scheduleTrimMemory( 18035 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18036 } catch (RemoteException e) { 18037 } 18038 } 18039 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18040 } else { 18041 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18042 || app.systemNoUi) && app.pendingUiClean) { 18043 // If this application is now in the background and it 18044 // had done UI, then give it the special trim level to 18045 // have it free UI resources. 18046 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18047 if (app.trimMemoryLevel < level && app.thread != null) { 18048 try { 18049 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18050 "Trimming memory of bg-ui " + app.processName 18051 + " to " + level); 18052 app.thread.scheduleTrimMemory(level); 18053 } catch (RemoteException e) { 18054 } 18055 } 18056 app.pendingUiClean = false; 18057 } 18058 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18059 try { 18060 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18061 "Trimming memory of fg " + app.processName 18062 + " to " + fgTrimLevel); 18063 app.thread.scheduleTrimMemory(fgTrimLevel); 18064 } catch (RemoteException e) { 18065 } 18066 } 18067 app.trimMemoryLevel = fgTrimLevel; 18068 } 18069 } 18070 } else { 18071 if (mLowRamStartTime != 0) { 18072 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18073 mLowRamStartTime = 0; 18074 } 18075 for (int i=N-1; i>=0; i--) { 18076 ProcessRecord app = mLruProcesses.get(i); 18077 if (allChanged || app.procStateChanged) { 18078 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18079 app.procStateChanged = false; 18080 } 18081 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18082 || app.systemNoUi) && app.pendingUiClean) { 18083 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18084 && app.thread != null) { 18085 try { 18086 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18087 "Trimming memory of ui hidden " + app.processName 18088 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18089 app.thread.scheduleTrimMemory( 18090 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18091 } catch (RemoteException e) { 18092 } 18093 } 18094 app.pendingUiClean = false; 18095 } 18096 app.trimMemoryLevel = 0; 18097 } 18098 } 18099 18100 if (mAlwaysFinishActivities) { 18101 // Need to do this on its own message because the stack may not 18102 // be in a consistent state at this point. 18103 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18104 } 18105 18106 if (allChanged) { 18107 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18108 } 18109 18110 if (mProcessStats.shouldWriteNowLocked(now)) { 18111 mHandler.post(new Runnable() { 18112 @Override public void run() { 18113 synchronized (ActivityManagerService.this) { 18114 mProcessStats.writeStateAsyncLocked(); 18115 } 18116 } 18117 }); 18118 } 18119 18120 if (DEBUG_OOM_ADJ) { 18121 if (false) { 18122 RuntimeException here = new RuntimeException("here"); 18123 here.fillInStackTrace(); 18124 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18125 } else { 18126 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18127 } 18128 } 18129 } 18130 18131 final void trimApplications() { 18132 synchronized (this) { 18133 int i; 18134 18135 // First remove any unused application processes whose package 18136 // has been removed. 18137 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18138 final ProcessRecord app = mRemovedProcesses.get(i); 18139 if (app.activities.size() == 0 18140 && app.curReceiver == null && app.services.size() == 0) { 18141 Slog.i( 18142 TAG, "Exiting empty application process " 18143 + app.processName + " (" 18144 + (app.thread != null ? app.thread.asBinder() : null) 18145 + ")\n"); 18146 if (app.pid > 0 && app.pid != MY_PID) { 18147 app.kill("empty", false); 18148 } else { 18149 try { 18150 app.thread.scheduleExit(); 18151 } catch (Exception e) { 18152 // Ignore exceptions. 18153 } 18154 } 18155 cleanUpApplicationRecordLocked(app, false, true, -1); 18156 mRemovedProcesses.remove(i); 18157 18158 if (app.persistent) { 18159 addAppLocked(app.info, false, null /* ABI override */); 18160 } 18161 } 18162 } 18163 18164 // Now update the oom adj for all processes. 18165 updateOomAdjLocked(); 18166 } 18167 } 18168 18169 /** This method sends the specified signal to each of the persistent apps */ 18170 public void signalPersistentProcesses(int sig) throws RemoteException { 18171 if (sig != Process.SIGNAL_USR1) { 18172 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18173 } 18174 18175 synchronized (this) { 18176 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18177 != PackageManager.PERMISSION_GRANTED) { 18178 throw new SecurityException("Requires permission " 18179 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18180 } 18181 18182 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18183 ProcessRecord r = mLruProcesses.get(i); 18184 if (r.thread != null && r.persistent) { 18185 Process.sendSignal(r.pid, sig); 18186 } 18187 } 18188 } 18189 } 18190 18191 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18192 if (proc == null || proc == mProfileProc) { 18193 proc = mProfileProc; 18194 profileType = mProfileType; 18195 clearProfilerLocked(); 18196 } 18197 if (proc == null) { 18198 return; 18199 } 18200 try { 18201 proc.thread.profilerControl(false, null, profileType); 18202 } catch (RemoteException e) { 18203 throw new IllegalStateException("Process disappeared"); 18204 } 18205 } 18206 18207 private void clearProfilerLocked() { 18208 if (mProfileFd != null) { 18209 try { 18210 mProfileFd.close(); 18211 } catch (IOException e) { 18212 } 18213 } 18214 mProfileApp = null; 18215 mProfileProc = null; 18216 mProfileFile = null; 18217 mProfileType = 0; 18218 mAutoStopProfiler = false; 18219 mSamplingInterval = 0; 18220 } 18221 18222 public boolean profileControl(String process, int userId, boolean start, 18223 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18224 18225 try { 18226 synchronized (this) { 18227 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18228 // its own permission. 18229 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18230 != PackageManager.PERMISSION_GRANTED) { 18231 throw new SecurityException("Requires permission " 18232 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18233 } 18234 18235 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18236 throw new IllegalArgumentException("null profile info or fd"); 18237 } 18238 18239 ProcessRecord proc = null; 18240 if (process != null) { 18241 proc = findProcessLocked(process, userId, "profileControl"); 18242 } 18243 18244 if (start && (proc == null || proc.thread == null)) { 18245 throw new IllegalArgumentException("Unknown process: " + process); 18246 } 18247 18248 if (start) { 18249 stopProfilerLocked(null, 0); 18250 setProfileApp(proc.info, proc.processName, profilerInfo); 18251 mProfileProc = proc; 18252 mProfileType = profileType; 18253 ParcelFileDescriptor fd = profilerInfo.profileFd; 18254 try { 18255 fd = fd.dup(); 18256 } catch (IOException e) { 18257 fd = null; 18258 } 18259 profilerInfo.profileFd = fd; 18260 proc.thread.profilerControl(start, profilerInfo, profileType); 18261 fd = null; 18262 mProfileFd = null; 18263 } else { 18264 stopProfilerLocked(proc, profileType); 18265 if (profilerInfo != null && profilerInfo.profileFd != null) { 18266 try { 18267 profilerInfo.profileFd.close(); 18268 } catch (IOException e) { 18269 } 18270 } 18271 } 18272 18273 return true; 18274 } 18275 } catch (RemoteException e) { 18276 throw new IllegalStateException("Process disappeared"); 18277 } finally { 18278 if (profilerInfo != null && profilerInfo.profileFd != null) { 18279 try { 18280 profilerInfo.profileFd.close(); 18281 } catch (IOException e) { 18282 } 18283 } 18284 } 18285 } 18286 18287 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18288 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18289 userId, true, ALLOW_FULL_ONLY, callName, null); 18290 ProcessRecord proc = null; 18291 try { 18292 int pid = Integer.parseInt(process); 18293 synchronized (mPidsSelfLocked) { 18294 proc = mPidsSelfLocked.get(pid); 18295 } 18296 } catch (NumberFormatException e) { 18297 } 18298 18299 if (proc == null) { 18300 ArrayMap<String, SparseArray<ProcessRecord>> all 18301 = mProcessNames.getMap(); 18302 SparseArray<ProcessRecord> procs = all.get(process); 18303 if (procs != null && procs.size() > 0) { 18304 proc = procs.valueAt(0); 18305 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18306 for (int i=1; i<procs.size(); i++) { 18307 ProcessRecord thisProc = procs.valueAt(i); 18308 if (thisProc.userId == userId) { 18309 proc = thisProc; 18310 break; 18311 } 18312 } 18313 } 18314 } 18315 } 18316 18317 return proc; 18318 } 18319 18320 public boolean dumpHeap(String process, int userId, boolean managed, 18321 String path, ParcelFileDescriptor fd) throws RemoteException { 18322 18323 try { 18324 synchronized (this) { 18325 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18326 // its own permission (same as profileControl). 18327 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18328 != PackageManager.PERMISSION_GRANTED) { 18329 throw new SecurityException("Requires permission " 18330 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18331 } 18332 18333 if (fd == null) { 18334 throw new IllegalArgumentException("null fd"); 18335 } 18336 18337 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18338 if (proc == null || proc.thread == null) { 18339 throw new IllegalArgumentException("Unknown process: " + process); 18340 } 18341 18342 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18343 if (!isDebuggable) { 18344 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18345 throw new SecurityException("Process not debuggable: " + proc); 18346 } 18347 } 18348 18349 proc.thread.dumpHeap(managed, path, fd); 18350 fd = null; 18351 return true; 18352 } 18353 } catch (RemoteException e) { 18354 throw new IllegalStateException("Process disappeared"); 18355 } finally { 18356 if (fd != null) { 18357 try { 18358 fd.close(); 18359 } catch (IOException e) { 18360 } 18361 } 18362 } 18363 } 18364 18365 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18366 public void monitor() { 18367 synchronized (this) { } 18368 } 18369 18370 void onCoreSettingsChange(Bundle settings) { 18371 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18372 ProcessRecord processRecord = mLruProcesses.get(i); 18373 try { 18374 if (processRecord.thread != null) { 18375 processRecord.thread.setCoreSettings(settings); 18376 } 18377 } catch (RemoteException re) { 18378 /* ignore */ 18379 } 18380 } 18381 } 18382 18383 // Multi-user methods 18384 18385 /** 18386 * Start user, if its not already running, but don't bring it to foreground. 18387 */ 18388 @Override 18389 public boolean startUserInBackground(final int userId) { 18390 return startUser(userId, /* foreground */ false); 18391 } 18392 18393 /** 18394 * Start user, if its not already running, and bring it to foreground. 18395 */ 18396 boolean startUserInForeground(final int userId, Dialog dlg) { 18397 boolean result = startUser(userId, /* foreground */ true); 18398 dlg.dismiss(); 18399 return result; 18400 } 18401 18402 /** 18403 * Refreshes the list of users related to the current user when either a 18404 * user switch happens or when a new related user is started in the 18405 * background. 18406 */ 18407 private void updateCurrentProfileIdsLocked() { 18408 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18409 mCurrentUserId, false /* enabledOnly */); 18410 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18411 for (int i = 0; i < currentProfileIds.length; i++) { 18412 currentProfileIds[i] = profiles.get(i).id; 18413 } 18414 mCurrentProfileIds = currentProfileIds; 18415 18416 synchronized (mUserProfileGroupIdsSelfLocked) { 18417 mUserProfileGroupIdsSelfLocked.clear(); 18418 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18419 for (int i = 0; i < users.size(); i++) { 18420 UserInfo user = users.get(i); 18421 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18422 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18423 } 18424 } 18425 } 18426 } 18427 18428 private Set getProfileIdsLocked(int userId) { 18429 Set userIds = new HashSet<Integer>(); 18430 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18431 userId, false /* enabledOnly */); 18432 for (UserInfo user : profiles) { 18433 userIds.add(Integer.valueOf(user.id)); 18434 } 18435 return userIds; 18436 } 18437 18438 @Override 18439 public boolean switchUser(final int userId) { 18440 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18441 String userName; 18442 synchronized (this) { 18443 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18444 if (userInfo == null) { 18445 Slog.w(TAG, "No user info for user #" + userId); 18446 return false; 18447 } 18448 if (userInfo.isManagedProfile()) { 18449 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18450 return false; 18451 } 18452 userName = userInfo.name; 18453 mTargetUserId = userId; 18454 } 18455 mHandler.removeMessages(START_USER_SWITCH_MSG); 18456 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18457 return true; 18458 } 18459 18460 private void showUserSwitchDialog(int userId, String userName) { 18461 // The dialog will show and then initiate the user switch by calling startUserInForeground 18462 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18463 true /* above system */); 18464 d.show(); 18465 } 18466 18467 private boolean startUser(final int userId, final boolean foreground) { 18468 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18469 != PackageManager.PERMISSION_GRANTED) { 18470 String msg = "Permission Denial: switchUser() from pid=" 18471 + Binder.getCallingPid() 18472 + ", uid=" + Binder.getCallingUid() 18473 + " requires " + INTERACT_ACROSS_USERS_FULL; 18474 Slog.w(TAG, msg); 18475 throw new SecurityException(msg); 18476 } 18477 18478 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18479 18480 final long ident = Binder.clearCallingIdentity(); 18481 try { 18482 synchronized (this) { 18483 final int oldUserId = mCurrentUserId; 18484 if (oldUserId == userId) { 18485 return true; 18486 } 18487 18488 mStackSupervisor.setLockTaskModeLocked(null, false); 18489 18490 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18491 if (userInfo == null) { 18492 Slog.w(TAG, "No user info for user #" + userId); 18493 return false; 18494 } 18495 if (foreground && userInfo.isManagedProfile()) { 18496 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18497 return false; 18498 } 18499 18500 if (foreground) { 18501 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18502 R.anim.screen_user_enter); 18503 } 18504 18505 boolean needStart = false; 18506 18507 // If the user we are switching to is not currently started, then 18508 // we need to start it now. 18509 if (mStartedUsers.get(userId) == null) { 18510 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18511 updateStartedUserArrayLocked(); 18512 needStart = true; 18513 } 18514 18515 final Integer userIdInt = Integer.valueOf(userId); 18516 mUserLru.remove(userIdInt); 18517 mUserLru.add(userIdInt); 18518 18519 if (foreground) { 18520 mCurrentUserId = userId; 18521 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18522 updateCurrentProfileIdsLocked(); 18523 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18524 // Once the internal notion of the active user has switched, we lock the device 18525 // with the option to show the user switcher on the keyguard. 18526 mWindowManager.lockNow(null); 18527 } else { 18528 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18529 updateCurrentProfileIdsLocked(); 18530 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18531 mUserLru.remove(currentUserIdInt); 18532 mUserLru.add(currentUserIdInt); 18533 } 18534 18535 final UserStartedState uss = mStartedUsers.get(userId); 18536 18537 // Make sure user is in the started state. If it is currently 18538 // stopping, we need to knock that off. 18539 if (uss.mState == UserStartedState.STATE_STOPPING) { 18540 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18541 // so we can just fairly silently bring the user back from 18542 // the almost-dead. 18543 uss.mState = UserStartedState.STATE_RUNNING; 18544 updateStartedUserArrayLocked(); 18545 needStart = true; 18546 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18547 // This means ACTION_SHUTDOWN has been sent, so we will 18548 // need to treat this as a new boot of the user. 18549 uss.mState = UserStartedState.STATE_BOOTING; 18550 updateStartedUserArrayLocked(); 18551 needStart = true; 18552 } 18553 18554 if (uss.mState == UserStartedState.STATE_BOOTING) { 18555 // Booting up a new user, need to tell system services about it. 18556 // Note that this is on the same handler as scheduling of broadcasts, 18557 // which is important because it needs to go first. 18558 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18559 } 18560 18561 if (foreground) { 18562 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18563 oldUserId)); 18564 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18565 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18566 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18567 oldUserId, userId, uss)); 18568 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18569 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18570 } 18571 18572 if (needStart) { 18573 // Send USER_STARTED broadcast 18574 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18575 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18576 | Intent.FLAG_RECEIVER_FOREGROUND); 18577 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18578 broadcastIntentLocked(null, null, intent, 18579 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18580 false, false, MY_PID, Process.SYSTEM_UID, userId); 18581 } 18582 18583 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18584 if (userId != UserHandle.USER_OWNER) { 18585 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18586 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18587 broadcastIntentLocked(null, null, intent, null, 18588 new IIntentReceiver.Stub() { 18589 public void performReceive(Intent intent, int resultCode, 18590 String data, Bundle extras, boolean ordered, 18591 boolean sticky, int sendingUser) { 18592 onUserInitialized(uss, foreground, oldUserId, userId); 18593 } 18594 }, 0, null, null, null, AppOpsManager.OP_NONE, 18595 true, false, MY_PID, Process.SYSTEM_UID, 18596 userId); 18597 uss.initializing = true; 18598 } else { 18599 getUserManagerLocked().makeInitialized(userInfo.id); 18600 } 18601 } 18602 18603 if (foreground) { 18604 if (!uss.initializing) { 18605 moveUserToForeground(uss, oldUserId, userId); 18606 } 18607 } else { 18608 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18609 } 18610 18611 if (needStart) { 18612 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18613 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18614 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18615 broadcastIntentLocked(null, null, intent, 18616 null, new IIntentReceiver.Stub() { 18617 @Override 18618 public void performReceive(Intent intent, int resultCode, String data, 18619 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18620 throws RemoteException { 18621 } 18622 }, 0, null, null, 18623 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18624 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18625 } 18626 } 18627 } finally { 18628 Binder.restoreCallingIdentity(ident); 18629 } 18630 18631 return true; 18632 } 18633 18634 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18635 long ident = Binder.clearCallingIdentity(); 18636 try { 18637 Intent intent; 18638 if (oldUserId >= 0) { 18639 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18640 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18641 int count = profiles.size(); 18642 for (int i = 0; i < count; i++) { 18643 int profileUserId = profiles.get(i).id; 18644 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18645 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18646 | Intent.FLAG_RECEIVER_FOREGROUND); 18647 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18648 broadcastIntentLocked(null, null, intent, 18649 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18650 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18651 } 18652 } 18653 if (newUserId >= 0) { 18654 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18655 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18656 int count = profiles.size(); 18657 for (int i = 0; i < count; i++) { 18658 int profileUserId = profiles.get(i).id; 18659 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18660 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18661 | Intent.FLAG_RECEIVER_FOREGROUND); 18662 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18663 broadcastIntentLocked(null, null, intent, 18664 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18665 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18666 } 18667 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18668 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18669 | Intent.FLAG_RECEIVER_FOREGROUND); 18670 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18671 broadcastIntentLocked(null, null, intent, 18672 null, null, 0, null, null, 18673 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18674 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18675 } 18676 } finally { 18677 Binder.restoreCallingIdentity(ident); 18678 } 18679 } 18680 18681 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18682 final int newUserId) { 18683 final int N = mUserSwitchObservers.beginBroadcast(); 18684 if (N > 0) { 18685 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18686 int mCount = 0; 18687 @Override 18688 public void sendResult(Bundle data) throws RemoteException { 18689 synchronized (ActivityManagerService.this) { 18690 if (mCurUserSwitchCallback == this) { 18691 mCount++; 18692 if (mCount == N) { 18693 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18694 } 18695 } 18696 } 18697 } 18698 }; 18699 synchronized (this) { 18700 uss.switching = true; 18701 mCurUserSwitchCallback = callback; 18702 } 18703 for (int i=0; i<N; i++) { 18704 try { 18705 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18706 newUserId, callback); 18707 } catch (RemoteException e) { 18708 } 18709 } 18710 } else { 18711 synchronized (this) { 18712 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18713 } 18714 } 18715 mUserSwitchObservers.finishBroadcast(); 18716 } 18717 18718 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18719 synchronized (this) { 18720 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18721 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18722 } 18723 } 18724 18725 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18726 mCurUserSwitchCallback = null; 18727 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18728 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18729 oldUserId, newUserId, uss)); 18730 } 18731 18732 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18733 synchronized (this) { 18734 if (foreground) { 18735 moveUserToForeground(uss, oldUserId, newUserId); 18736 } 18737 } 18738 18739 completeSwitchAndInitalize(uss, newUserId, true, false); 18740 } 18741 18742 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18743 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18744 if (homeInFront) { 18745 startHomeActivityLocked(newUserId); 18746 } else { 18747 mStackSupervisor.resumeTopActivitiesLocked(); 18748 } 18749 EventLogTags.writeAmSwitchUser(newUserId); 18750 getUserManagerLocked().userForeground(newUserId); 18751 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18752 } 18753 18754 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18755 completeSwitchAndInitalize(uss, newUserId, false, true); 18756 } 18757 18758 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18759 boolean clearInitializing, boolean clearSwitching) { 18760 boolean unfrozen = false; 18761 synchronized (this) { 18762 if (clearInitializing) { 18763 uss.initializing = false; 18764 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18765 } 18766 if (clearSwitching) { 18767 uss.switching = false; 18768 } 18769 if (!uss.switching && !uss.initializing) { 18770 mWindowManager.stopFreezingScreen(); 18771 unfrozen = true; 18772 } 18773 } 18774 if (unfrozen) { 18775 final int N = mUserSwitchObservers.beginBroadcast(); 18776 for (int i=0; i<N; i++) { 18777 try { 18778 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18779 } catch (RemoteException e) { 18780 } 18781 } 18782 mUserSwitchObservers.finishBroadcast(); 18783 } 18784 } 18785 18786 void scheduleStartProfilesLocked() { 18787 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18788 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18789 DateUtils.SECOND_IN_MILLIS); 18790 } 18791 } 18792 18793 void startProfilesLocked() { 18794 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18795 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18796 mCurrentUserId, false /* enabledOnly */); 18797 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18798 for (UserInfo user : profiles) { 18799 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18800 && user.id != mCurrentUserId) { 18801 toStart.add(user); 18802 } 18803 } 18804 final int n = toStart.size(); 18805 int i = 0; 18806 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18807 startUserInBackground(toStart.get(i).id); 18808 } 18809 if (i < n) { 18810 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18811 } 18812 } 18813 18814 void finishUserBoot(UserStartedState uss) { 18815 synchronized (this) { 18816 if (uss.mState == UserStartedState.STATE_BOOTING 18817 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18818 uss.mState = UserStartedState.STATE_RUNNING; 18819 final int userId = uss.mHandle.getIdentifier(); 18820 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18821 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18822 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18823 broadcastIntentLocked(null, null, intent, 18824 null, null, 0, null, null, 18825 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18826 true, false, MY_PID, Process.SYSTEM_UID, userId); 18827 } 18828 } 18829 } 18830 18831 void finishUserSwitch(UserStartedState uss) { 18832 synchronized (this) { 18833 finishUserBoot(uss); 18834 18835 startProfilesLocked(); 18836 18837 int num = mUserLru.size(); 18838 int i = 0; 18839 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18840 Integer oldUserId = mUserLru.get(i); 18841 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18842 if (oldUss == null) { 18843 // Shouldn't happen, but be sane if it does. 18844 mUserLru.remove(i); 18845 num--; 18846 continue; 18847 } 18848 if (oldUss.mState == UserStartedState.STATE_STOPPING 18849 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18850 // This user is already stopping, doesn't count. 18851 num--; 18852 i++; 18853 continue; 18854 } 18855 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18856 // Owner and current can't be stopped, but count as running. 18857 i++; 18858 continue; 18859 } 18860 // This is a user to be stopped. 18861 stopUserLocked(oldUserId, null); 18862 num--; 18863 i++; 18864 } 18865 } 18866 } 18867 18868 @Override 18869 public int stopUser(final int userId, final IStopUserCallback callback) { 18870 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18871 != PackageManager.PERMISSION_GRANTED) { 18872 String msg = "Permission Denial: switchUser() from pid=" 18873 + Binder.getCallingPid() 18874 + ", uid=" + Binder.getCallingUid() 18875 + " requires " + INTERACT_ACROSS_USERS_FULL; 18876 Slog.w(TAG, msg); 18877 throw new SecurityException(msg); 18878 } 18879 if (userId <= 0) { 18880 throw new IllegalArgumentException("Can't stop primary user " + userId); 18881 } 18882 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18883 synchronized (this) { 18884 return stopUserLocked(userId, callback); 18885 } 18886 } 18887 18888 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18889 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18890 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18891 return ActivityManager.USER_OP_IS_CURRENT; 18892 } 18893 18894 final UserStartedState uss = mStartedUsers.get(userId); 18895 if (uss == null) { 18896 // User is not started, nothing to do... but we do need to 18897 // callback if requested. 18898 if (callback != null) { 18899 mHandler.post(new Runnable() { 18900 @Override 18901 public void run() { 18902 try { 18903 callback.userStopped(userId); 18904 } catch (RemoteException e) { 18905 } 18906 } 18907 }); 18908 } 18909 return ActivityManager.USER_OP_SUCCESS; 18910 } 18911 18912 if (callback != null) { 18913 uss.mStopCallbacks.add(callback); 18914 } 18915 18916 if (uss.mState != UserStartedState.STATE_STOPPING 18917 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18918 uss.mState = UserStartedState.STATE_STOPPING; 18919 updateStartedUserArrayLocked(); 18920 18921 long ident = Binder.clearCallingIdentity(); 18922 try { 18923 // We are going to broadcast ACTION_USER_STOPPING and then 18924 // once that is done send a final ACTION_SHUTDOWN and then 18925 // stop the user. 18926 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18927 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18928 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18929 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18930 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18931 // This is the result receiver for the final shutdown broadcast. 18932 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18933 @Override 18934 public void performReceive(Intent intent, int resultCode, String data, 18935 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18936 finishUserStop(uss); 18937 } 18938 }; 18939 // This is the result receiver for the initial stopping broadcast. 18940 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18941 @Override 18942 public void performReceive(Intent intent, int resultCode, String data, 18943 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18944 // On to the next. 18945 synchronized (ActivityManagerService.this) { 18946 if (uss.mState != UserStartedState.STATE_STOPPING) { 18947 // Whoops, we are being started back up. Abort, abort! 18948 return; 18949 } 18950 uss.mState = UserStartedState.STATE_SHUTDOWN; 18951 } 18952 mBatteryStatsService.noteEvent( 18953 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18954 Integer.toString(userId), userId); 18955 mSystemServiceManager.stopUser(userId); 18956 broadcastIntentLocked(null, null, shutdownIntent, 18957 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18958 true, false, MY_PID, Process.SYSTEM_UID, userId); 18959 } 18960 }; 18961 // Kick things off. 18962 broadcastIntentLocked(null, null, stoppingIntent, 18963 null, stoppingReceiver, 0, null, null, 18964 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18965 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18966 } finally { 18967 Binder.restoreCallingIdentity(ident); 18968 } 18969 } 18970 18971 return ActivityManager.USER_OP_SUCCESS; 18972 } 18973 18974 void finishUserStop(UserStartedState uss) { 18975 final int userId = uss.mHandle.getIdentifier(); 18976 boolean stopped; 18977 ArrayList<IStopUserCallback> callbacks; 18978 synchronized (this) { 18979 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18980 if (mStartedUsers.get(userId) != uss) { 18981 stopped = false; 18982 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18983 stopped = false; 18984 } else { 18985 stopped = true; 18986 // User can no longer run. 18987 mStartedUsers.remove(userId); 18988 mUserLru.remove(Integer.valueOf(userId)); 18989 updateStartedUserArrayLocked(); 18990 18991 // Clean up all state and processes associated with the user. 18992 // Kill all the processes for the user. 18993 forceStopUserLocked(userId, "finish user"); 18994 } 18995 18996 // Explicitly remove the old information in mRecentTasks. 18997 removeRecentTasksForUserLocked(userId); 18998 } 18999 19000 for (int i=0; i<callbacks.size(); i++) { 19001 try { 19002 if (stopped) callbacks.get(i).userStopped(userId); 19003 else callbacks.get(i).userStopAborted(userId); 19004 } catch (RemoteException e) { 19005 } 19006 } 19007 19008 if (stopped) { 19009 mSystemServiceManager.cleanupUser(userId); 19010 synchronized (this) { 19011 mStackSupervisor.removeUserLocked(userId); 19012 } 19013 } 19014 } 19015 19016 @Override 19017 public UserInfo getCurrentUser() { 19018 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19019 != PackageManager.PERMISSION_GRANTED) && ( 19020 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19021 != PackageManager.PERMISSION_GRANTED)) { 19022 String msg = "Permission Denial: getCurrentUser() from pid=" 19023 + Binder.getCallingPid() 19024 + ", uid=" + Binder.getCallingUid() 19025 + " requires " + INTERACT_ACROSS_USERS; 19026 Slog.w(TAG, msg); 19027 throw new SecurityException(msg); 19028 } 19029 synchronized (this) { 19030 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19031 return getUserManagerLocked().getUserInfo(userId); 19032 } 19033 } 19034 19035 int getCurrentUserIdLocked() { 19036 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19037 } 19038 19039 @Override 19040 public boolean isUserRunning(int userId, boolean orStopped) { 19041 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19042 != PackageManager.PERMISSION_GRANTED) { 19043 String msg = "Permission Denial: isUserRunning() from pid=" 19044 + Binder.getCallingPid() 19045 + ", uid=" + Binder.getCallingUid() 19046 + " requires " + INTERACT_ACROSS_USERS; 19047 Slog.w(TAG, msg); 19048 throw new SecurityException(msg); 19049 } 19050 synchronized (this) { 19051 return isUserRunningLocked(userId, orStopped); 19052 } 19053 } 19054 19055 boolean isUserRunningLocked(int userId, boolean orStopped) { 19056 UserStartedState state = mStartedUsers.get(userId); 19057 if (state == null) { 19058 return false; 19059 } 19060 if (orStopped) { 19061 return true; 19062 } 19063 return state.mState != UserStartedState.STATE_STOPPING 19064 && state.mState != UserStartedState.STATE_SHUTDOWN; 19065 } 19066 19067 @Override 19068 public int[] getRunningUserIds() { 19069 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19070 != PackageManager.PERMISSION_GRANTED) { 19071 String msg = "Permission Denial: isUserRunning() from pid=" 19072 + Binder.getCallingPid() 19073 + ", uid=" + Binder.getCallingUid() 19074 + " requires " + INTERACT_ACROSS_USERS; 19075 Slog.w(TAG, msg); 19076 throw new SecurityException(msg); 19077 } 19078 synchronized (this) { 19079 return mStartedUserArray; 19080 } 19081 } 19082 19083 private void updateStartedUserArrayLocked() { 19084 int num = 0; 19085 for (int i=0; i<mStartedUsers.size(); i++) { 19086 UserStartedState uss = mStartedUsers.valueAt(i); 19087 // This list does not include stopping users. 19088 if (uss.mState != UserStartedState.STATE_STOPPING 19089 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19090 num++; 19091 } 19092 } 19093 mStartedUserArray = new int[num]; 19094 num = 0; 19095 for (int i=0; i<mStartedUsers.size(); i++) { 19096 UserStartedState uss = mStartedUsers.valueAt(i); 19097 if (uss.mState != UserStartedState.STATE_STOPPING 19098 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19099 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19100 num++; 19101 } 19102 } 19103 } 19104 19105 @Override 19106 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19107 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19108 != PackageManager.PERMISSION_GRANTED) { 19109 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19110 + Binder.getCallingPid() 19111 + ", uid=" + Binder.getCallingUid() 19112 + " requires " + INTERACT_ACROSS_USERS_FULL; 19113 Slog.w(TAG, msg); 19114 throw new SecurityException(msg); 19115 } 19116 19117 mUserSwitchObservers.register(observer); 19118 } 19119 19120 @Override 19121 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19122 mUserSwitchObservers.unregister(observer); 19123 } 19124 19125 private boolean userExists(int userId) { 19126 if (userId == 0) { 19127 return true; 19128 } 19129 UserManagerService ums = getUserManagerLocked(); 19130 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19131 } 19132 19133 int[] getUsersLocked() { 19134 UserManagerService ums = getUserManagerLocked(); 19135 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19136 } 19137 19138 UserManagerService getUserManagerLocked() { 19139 if (mUserManager == null) { 19140 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19141 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19142 } 19143 return mUserManager; 19144 } 19145 19146 private int applyUserId(int uid, int userId) { 19147 return UserHandle.getUid(userId, uid); 19148 } 19149 19150 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19151 if (info == null) return null; 19152 ApplicationInfo newInfo = new ApplicationInfo(info); 19153 newInfo.uid = applyUserId(info.uid, userId); 19154 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19155 + info.packageName; 19156 return newInfo; 19157 } 19158 19159 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19160 if (aInfo == null 19161 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19162 return aInfo; 19163 } 19164 19165 ActivityInfo info = new ActivityInfo(aInfo); 19166 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19167 return info; 19168 } 19169 19170 private final class LocalService extends ActivityManagerInternal { 19171 @Override 19172 public void goingToSleep() { 19173 ActivityManagerService.this.goingToSleep(); 19174 } 19175 19176 @Override 19177 public void wakingUp() { 19178 ActivityManagerService.this.wakingUp(); 19179 } 19180 19181 @Override 19182 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19183 String processName, String abiOverride, int uid, Runnable crashHandler) { 19184 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19185 processName, abiOverride, uid, crashHandler); 19186 } 19187 } 19188 19189 /** 19190 * An implementation of IAppTask, that allows an app to manage its own tasks via 19191 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19192 * only the process that calls getAppTasks() can call the AppTask methods. 19193 */ 19194 class AppTaskImpl extends IAppTask.Stub { 19195 private int mTaskId; 19196 private int mCallingUid; 19197 19198 public AppTaskImpl(int taskId, int callingUid) { 19199 mTaskId = taskId; 19200 mCallingUid = callingUid; 19201 } 19202 19203 private void checkCaller() { 19204 if (mCallingUid != Binder.getCallingUid()) { 19205 throw new SecurityException("Caller " + mCallingUid 19206 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19207 } 19208 } 19209 19210 @Override 19211 public void finishAndRemoveTask() { 19212 checkCaller(); 19213 19214 synchronized (ActivityManagerService.this) { 19215 long origId = Binder.clearCallingIdentity(); 19216 try { 19217 if (!removeTaskByIdLocked(mTaskId, false)) { 19218 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19219 } 19220 } finally { 19221 Binder.restoreCallingIdentity(origId); 19222 } 19223 } 19224 } 19225 19226 @Override 19227 public ActivityManager.RecentTaskInfo getTaskInfo() { 19228 checkCaller(); 19229 19230 synchronized (ActivityManagerService.this) { 19231 long origId = Binder.clearCallingIdentity(); 19232 try { 19233 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19234 if (tr == null) { 19235 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19236 } 19237 return createRecentTaskInfoFromTaskRecord(tr); 19238 } finally { 19239 Binder.restoreCallingIdentity(origId); 19240 } 19241 } 19242 } 19243 19244 @Override 19245 public void moveToFront() { 19246 checkCaller(); 19247 19248 final TaskRecord tr; 19249 synchronized (ActivityManagerService.this) { 19250 tr = recentTaskForIdLocked(mTaskId); 19251 if (tr == null) { 19252 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19253 } 19254 if (tr.getRootActivity() != null) { 19255 moveTaskToFrontLocked(tr.taskId, 0, null); 19256 return; 19257 } 19258 } 19259 19260 startActivityFromRecentsInner(tr.taskId, null); 19261 } 19262 19263 @Override 19264 public int startActivity(IBinder whoThread, String callingPackage, 19265 Intent intent, String resolvedType, Bundle options) { 19266 checkCaller(); 19267 19268 int callingUser = UserHandle.getCallingUserId(); 19269 TaskRecord tr; 19270 IApplicationThread appThread; 19271 synchronized (ActivityManagerService.this) { 19272 tr = recentTaskForIdLocked(mTaskId); 19273 if (tr == null) { 19274 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19275 } 19276 appThread = ApplicationThreadNative.asInterface(whoThread); 19277 if (appThread == null) { 19278 throw new IllegalArgumentException("Bad app thread " + appThread); 19279 } 19280 } 19281 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19282 resolvedType, null, null, null, null, 0, 0, null, null, 19283 null, options, callingUser, null, tr); 19284 } 19285 19286 @Override 19287 public void setExcludeFromRecents(boolean exclude) { 19288 checkCaller(); 19289 19290 synchronized (ActivityManagerService.this) { 19291 long origId = Binder.clearCallingIdentity(); 19292 try { 19293 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19294 if (tr == null) { 19295 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19296 } 19297 Intent intent = tr.getBaseIntent(); 19298 if (exclude) { 19299 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19300 } else { 19301 intent.setFlags(intent.getFlags() 19302 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19303 } 19304 } finally { 19305 Binder.restoreCallingIdentity(origId); 19306 } 19307 } 19308 } 19309 } 19310} 19311