ActivityManagerService.java revision a11bb7427171418681428754051d5ee4dce851ee
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 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8302 mRecentTasks.remove(tr); 8303 tr.removedFromRecents(mTaskPersister); 8304 ComponentName component = tr.getBaseIntent().getComponent(); 8305 if (component == null) { 8306 Slog.w(TAG, "No component for base intent of task: " + tr); 8307 return; 8308 } 8309 8310 if (!killProcess) { 8311 return; 8312 } 8313 8314 // Determine if the process(es) for this task should be killed. 8315 final String pkg = component.getPackageName(); 8316 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8317 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8318 for (int i = 0; i < pmap.size(); i++) { 8319 8320 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8321 for (int j = 0; j < uids.size(); j++) { 8322 ProcessRecord proc = uids.valueAt(j); 8323 if (proc.userId != tr.userId) { 8324 // Don't kill process for a different user. 8325 continue; 8326 } 8327 if (proc == mHomeProcess) { 8328 // Don't kill the home process along with tasks from the same package. 8329 continue; 8330 } 8331 if (!proc.pkgList.containsKey(pkg)) { 8332 // Don't kill process that is not associated with this task. 8333 continue; 8334 } 8335 8336 for (int k = 0; k < proc.activities.size(); k++) { 8337 TaskRecord otherTask = proc.activities.get(k).task; 8338 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8339 // Don't kill process(es) that has an activity in a different task that is 8340 // also in recents. 8341 return; 8342 } 8343 } 8344 8345 // Add process to kill list. 8346 procsToKill.add(proc); 8347 } 8348 } 8349 8350 // Find any running services associated with this app and stop if needed. 8351 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8352 8353 // Kill the running processes. 8354 for (int i = 0; i < procsToKill.size(); i++) { 8355 ProcessRecord pr = procsToKill.get(i); 8356 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8357 pr.kill("remove task", true); 8358 } else { 8359 pr.waitingToKill = "remove task"; 8360 } 8361 } 8362 } 8363 8364 /** 8365 * Removes the task with the specified task id. 8366 * 8367 * @param taskId Identifier of the task to be removed. 8368 * @param killProcess Kill any process associated with the task if possible. 8369 * @return Returns true if the given task was found and removed. 8370 */ 8371 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8372 TaskRecord tr = recentTaskForIdLocked(taskId); 8373 if (tr != null) { 8374 tr.removeTaskActivitiesLocked(); 8375 cleanUpRemovedTaskLocked(tr, killProcess); 8376 if (tr.isPersistable) { 8377 notifyTaskPersisterLocked(null, true); 8378 } 8379 return true; 8380 } 8381 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8382 return false; 8383 } 8384 8385 @Override 8386 public boolean removeTask(int taskId) { 8387 synchronized (this) { 8388 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8389 "removeTask()"); 8390 long ident = Binder.clearCallingIdentity(); 8391 try { 8392 return removeTaskByIdLocked(taskId, true); 8393 } finally { 8394 Binder.restoreCallingIdentity(ident); 8395 } 8396 } 8397 } 8398 8399 /** 8400 * TODO: Add mController hook 8401 */ 8402 @Override 8403 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8404 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8405 "moveTaskToFront()"); 8406 8407 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8408 synchronized(this) { 8409 moveTaskToFrontLocked(taskId, flags, options); 8410 } 8411 } 8412 8413 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8414 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8415 Binder.getCallingUid(), -1, -1, "Task to front")) { 8416 ActivityOptions.abort(options); 8417 return; 8418 } 8419 final long origId = Binder.clearCallingIdentity(); 8420 try { 8421 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8422 if (task == null) { 8423 return; 8424 } 8425 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8426 mStackSupervisor.showLockTaskToast(); 8427 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8428 return; 8429 } 8430 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8431 if (prev != null && prev.isRecentsActivity()) { 8432 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8433 } 8434 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8435 } finally { 8436 Binder.restoreCallingIdentity(origId); 8437 } 8438 ActivityOptions.abort(options); 8439 } 8440 8441 @Override 8442 public void moveTaskToBack(int taskId) { 8443 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8444 "moveTaskToBack()"); 8445 8446 synchronized(this) { 8447 TaskRecord tr = recentTaskForIdLocked(taskId); 8448 if (tr != null) { 8449 if (tr == mStackSupervisor.mLockTaskModeTask) { 8450 mStackSupervisor.showLockTaskToast(); 8451 return; 8452 } 8453 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8454 ActivityStack stack = tr.stack; 8455 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8456 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8457 Binder.getCallingUid(), -1, -1, "Task to back")) { 8458 return; 8459 } 8460 } 8461 final long origId = Binder.clearCallingIdentity(); 8462 try { 8463 stack.moveTaskToBackLocked(taskId, null); 8464 } finally { 8465 Binder.restoreCallingIdentity(origId); 8466 } 8467 } 8468 } 8469 } 8470 8471 /** 8472 * Moves an activity, and all of the other activities within the same task, to the bottom 8473 * of the history stack. The activity's order within the task is unchanged. 8474 * 8475 * @param token A reference to the activity we wish to move 8476 * @param nonRoot If false then this only works if the activity is the root 8477 * of a task; if true it will work for any activity in a task. 8478 * @return Returns true if the move completed, false if not. 8479 */ 8480 @Override 8481 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8482 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8483 synchronized(this) { 8484 final long origId = Binder.clearCallingIdentity(); 8485 try { 8486 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8487 if (taskId >= 0) { 8488 if ((mStackSupervisor.mLockTaskModeTask != null) 8489 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8490 mStackSupervisor.showLockTaskToast(); 8491 return false; 8492 } 8493 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8494 } 8495 } finally { 8496 Binder.restoreCallingIdentity(origId); 8497 } 8498 } 8499 return false; 8500 } 8501 8502 @Override 8503 public void moveTaskBackwards(int task) { 8504 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8505 "moveTaskBackwards()"); 8506 8507 synchronized(this) { 8508 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8509 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8510 return; 8511 } 8512 final long origId = Binder.clearCallingIdentity(); 8513 moveTaskBackwardsLocked(task); 8514 Binder.restoreCallingIdentity(origId); 8515 } 8516 } 8517 8518 private final void moveTaskBackwardsLocked(int task) { 8519 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8520 } 8521 8522 @Override 8523 public IBinder getHomeActivityToken() throws RemoteException { 8524 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8525 "getHomeActivityToken()"); 8526 synchronized (this) { 8527 return mStackSupervisor.getHomeActivityToken(); 8528 } 8529 } 8530 8531 @Override 8532 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8533 IActivityContainerCallback callback) throws RemoteException { 8534 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8535 "createActivityContainer()"); 8536 synchronized (this) { 8537 if (parentActivityToken == null) { 8538 throw new IllegalArgumentException("parent token must not be null"); 8539 } 8540 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8541 if (r == null) { 8542 return null; 8543 } 8544 if (callback == null) { 8545 throw new IllegalArgumentException("callback must not be null"); 8546 } 8547 return mStackSupervisor.createActivityContainer(r, callback); 8548 } 8549 } 8550 8551 @Override 8552 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8553 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8554 "deleteActivityContainer()"); 8555 synchronized (this) { 8556 mStackSupervisor.deleteActivityContainer(container); 8557 } 8558 } 8559 8560 @Override 8561 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8562 throws RemoteException { 8563 synchronized (this) { 8564 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8565 if (stack != null) { 8566 return stack.mActivityContainer; 8567 } 8568 return null; 8569 } 8570 } 8571 8572 @Override 8573 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8574 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8575 "moveTaskToStack()"); 8576 if (stackId == HOME_STACK_ID) { 8577 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8578 new RuntimeException("here").fillInStackTrace()); 8579 } 8580 synchronized (this) { 8581 long ident = Binder.clearCallingIdentity(); 8582 try { 8583 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8584 + stackId + " toTop=" + toTop); 8585 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8586 } finally { 8587 Binder.restoreCallingIdentity(ident); 8588 } 8589 } 8590 } 8591 8592 @Override 8593 public void resizeStack(int stackBoxId, Rect bounds) { 8594 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8595 "resizeStackBox()"); 8596 long ident = Binder.clearCallingIdentity(); 8597 try { 8598 mWindowManager.resizeStack(stackBoxId, bounds); 8599 } finally { 8600 Binder.restoreCallingIdentity(ident); 8601 } 8602 } 8603 8604 @Override 8605 public List<StackInfo> getAllStackInfos() { 8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8607 "getAllStackInfos()"); 8608 long ident = Binder.clearCallingIdentity(); 8609 try { 8610 synchronized (this) { 8611 return mStackSupervisor.getAllStackInfosLocked(); 8612 } 8613 } finally { 8614 Binder.restoreCallingIdentity(ident); 8615 } 8616 } 8617 8618 @Override 8619 public StackInfo getStackInfo(int stackId) { 8620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8621 "getStackInfo()"); 8622 long ident = Binder.clearCallingIdentity(); 8623 try { 8624 synchronized (this) { 8625 return mStackSupervisor.getStackInfoLocked(stackId); 8626 } 8627 } finally { 8628 Binder.restoreCallingIdentity(ident); 8629 } 8630 } 8631 8632 @Override 8633 public boolean isInHomeStack(int taskId) { 8634 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8635 "getStackInfo()"); 8636 long ident = Binder.clearCallingIdentity(); 8637 try { 8638 synchronized (this) { 8639 TaskRecord tr = recentTaskForIdLocked(taskId); 8640 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8641 } 8642 } finally { 8643 Binder.restoreCallingIdentity(ident); 8644 } 8645 } 8646 8647 @Override 8648 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8649 synchronized(this) { 8650 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8651 } 8652 } 8653 8654 private boolean isLockTaskAuthorized(String pkg) { 8655 final DevicePolicyManager dpm = (DevicePolicyManager) 8656 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8657 try { 8658 int uid = mContext.getPackageManager().getPackageUid(pkg, 8659 Binder.getCallingUserHandle().getIdentifier()); 8660 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8661 } catch (NameNotFoundException e) { 8662 return false; 8663 } 8664 } 8665 8666 void startLockTaskMode(TaskRecord task) { 8667 final String pkg; 8668 synchronized (this) { 8669 pkg = task.intent.getComponent().getPackageName(); 8670 } 8671 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8672 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8673 final TaskRecord taskRecord = task; 8674 mHandler.post(new Runnable() { 8675 @Override 8676 public void run() { 8677 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8678 } 8679 }); 8680 return; 8681 } 8682 long ident = Binder.clearCallingIdentity(); 8683 try { 8684 synchronized (this) { 8685 // Since we lost lock on task, make sure it is still there. 8686 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8687 if (task != null) { 8688 if (!isSystemInitiated 8689 && ((mStackSupervisor.getFocusedStack() == null) 8690 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8691 throw new IllegalArgumentException("Invalid task, not in foreground"); 8692 } 8693 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8694 } 8695 } 8696 } finally { 8697 Binder.restoreCallingIdentity(ident); 8698 } 8699 } 8700 8701 @Override 8702 public void startLockTaskMode(int taskId) { 8703 final TaskRecord task; 8704 long ident = Binder.clearCallingIdentity(); 8705 try { 8706 synchronized (this) { 8707 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 if (task != null) { 8713 startLockTaskMode(task); 8714 } 8715 } 8716 8717 @Override 8718 public void startLockTaskMode(IBinder token) { 8719 final TaskRecord task; 8720 long ident = Binder.clearCallingIdentity(); 8721 try { 8722 synchronized (this) { 8723 final ActivityRecord r = ActivityRecord.forToken(token); 8724 if (r == null) { 8725 return; 8726 } 8727 task = r.task; 8728 } 8729 } finally { 8730 Binder.restoreCallingIdentity(ident); 8731 } 8732 if (task != null) { 8733 startLockTaskMode(task); 8734 } 8735 } 8736 8737 @Override 8738 public void startLockTaskModeOnCurrent() throws RemoteException { 8739 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8740 "startLockTaskModeOnCurrent"); 8741 ActivityRecord r = null; 8742 synchronized (this) { 8743 r = mStackSupervisor.topRunningActivityLocked(); 8744 } 8745 startLockTaskMode(r.task); 8746 } 8747 8748 @Override 8749 public void stopLockTaskMode() { 8750 // Verify that the user matches the package of the intent for the TaskRecord 8751 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8752 // and stopLockTaskMode. 8753 final int callingUid = Binder.getCallingUid(); 8754 if (callingUid != Process.SYSTEM_UID) { 8755 try { 8756 String pkg = 8757 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8758 int uid = mContext.getPackageManager().getPackageUid(pkg, 8759 Binder.getCallingUserHandle().getIdentifier()); 8760 if (uid != callingUid) { 8761 throw new SecurityException("Invalid uid, expected " + uid); 8762 } 8763 } catch (NameNotFoundException e) { 8764 Log.d(TAG, "stopLockTaskMode " + e); 8765 return; 8766 } 8767 } 8768 long ident = Binder.clearCallingIdentity(); 8769 try { 8770 Log.d(TAG, "stopLockTaskMode"); 8771 // Stop lock task 8772 synchronized (this) { 8773 mStackSupervisor.setLockTaskModeLocked(null, false); 8774 } 8775 } finally { 8776 Binder.restoreCallingIdentity(ident); 8777 } 8778 } 8779 8780 @Override 8781 public void stopLockTaskModeOnCurrent() throws RemoteException { 8782 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8783 "stopLockTaskModeOnCurrent"); 8784 long ident = Binder.clearCallingIdentity(); 8785 try { 8786 stopLockTaskMode(); 8787 } finally { 8788 Binder.restoreCallingIdentity(ident); 8789 } 8790 } 8791 8792 @Override 8793 public boolean isInLockTaskMode() { 8794 synchronized (this) { 8795 return mStackSupervisor.isInLockTaskMode(); 8796 } 8797 } 8798 8799 // ========================================================= 8800 // CONTENT PROVIDERS 8801 // ========================================================= 8802 8803 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8804 List<ProviderInfo> providers = null; 8805 try { 8806 providers = AppGlobals.getPackageManager(). 8807 queryContentProviders(app.processName, app.uid, 8808 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8809 } catch (RemoteException ex) { 8810 } 8811 if (DEBUG_MU) 8812 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8813 int userId = app.userId; 8814 if (providers != null) { 8815 int N = providers.size(); 8816 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8817 for (int i=0; i<N; i++) { 8818 ProviderInfo cpi = 8819 (ProviderInfo)providers.get(i); 8820 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8821 cpi.name, cpi.flags); 8822 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8823 // This is a singleton provider, but a user besides the 8824 // default user is asking to initialize a process it runs 8825 // in... well, no, it doesn't actually run in this process, 8826 // it runs in the process of the default user. Get rid of it. 8827 providers.remove(i); 8828 N--; 8829 i--; 8830 continue; 8831 } 8832 8833 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8834 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8835 if (cpr == null) { 8836 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8837 mProviderMap.putProviderByClass(comp, cpr); 8838 } 8839 if (DEBUG_MU) 8840 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8841 app.pubProviders.put(cpi.name, cpr); 8842 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8843 // Don't add this if it is a platform component that is marked 8844 // to run in multiple processes, because this is actually 8845 // part of the framework so doesn't make sense to track as a 8846 // separate apk in the process. 8847 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8848 mProcessStats); 8849 } 8850 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8851 } 8852 } 8853 return providers; 8854 } 8855 8856 /** 8857 * Check if {@link ProcessRecord} has a possible chance at accessing the 8858 * given {@link ProviderInfo}. Final permission checking is always done 8859 * in {@link ContentProvider}. 8860 */ 8861 private final String checkContentProviderPermissionLocked( 8862 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8863 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8864 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8865 boolean checkedGrants = false; 8866 if (checkUser) { 8867 // Looking for cross-user grants before enforcing the typical cross-users permissions 8868 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8869 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8870 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8871 return null; 8872 } 8873 checkedGrants = true; 8874 } 8875 userId = handleIncomingUser(callingPid, callingUid, userId, 8876 false, ALLOW_NON_FULL, 8877 "checkContentProviderPermissionLocked " + cpi.authority, null); 8878 if (userId != tmpTargetUserId) { 8879 // When we actually went to determine the final targer user ID, this ended 8880 // up different than our initial check for the authority. This is because 8881 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8882 // SELF. So we need to re-check the grants again. 8883 checkedGrants = false; 8884 } 8885 } 8886 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8887 cpi.applicationInfo.uid, cpi.exported) 8888 == PackageManager.PERMISSION_GRANTED) { 8889 return null; 8890 } 8891 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8892 cpi.applicationInfo.uid, cpi.exported) 8893 == PackageManager.PERMISSION_GRANTED) { 8894 return null; 8895 } 8896 8897 PathPermission[] pps = cpi.pathPermissions; 8898 if (pps != null) { 8899 int i = pps.length; 8900 while (i > 0) { 8901 i--; 8902 PathPermission pp = pps[i]; 8903 String pprperm = pp.getReadPermission(); 8904 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8905 cpi.applicationInfo.uid, cpi.exported) 8906 == PackageManager.PERMISSION_GRANTED) { 8907 return null; 8908 } 8909 String ppwperm = pp.getWritePermission(); 8910 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8911 cpi.applicationInfo.uid, cpi.exported) 8912 == PackageManager.PERMISSION_GRANTED) { 8913 return null; 8914 } 8915 } 8916 } 8917 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8918 return null; 8919 } 8920 8921 String msg; 8922 if (!cpi.exported) { 8923 msg = "Permission Denial: opening provider " + cpi.name 8924 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8925 + ", uid=" + callingUid + ") that is not exported from uid " 8926 + cpi.applicationInfo.uid; 8927 } else { 8928 msg = "Permission Denial: opening provider " + cpi.name 8929 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8930 + ", uid=" + callingUid + ") requires " 8931 + cpi.readPermission + " or " + cpi.writePermission; 8932 } 8933 Slog.w(TAG, msg); 8934 return msg; 8935 } 8936 8937 /** 8938 * Returns if the ContentProvider has granted a uri to callingUid 8939 */ 8940 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8941 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8942 if (perms != null) { 8943 for (int i=perms.size()-1; i>=0; i--) { 8944 GrantUri grantUri = perms.keyAt(i); 8945 if (grantUri.sourceUserId == userId || !checkUser) { 8946 if (matchesProvider(grantUri.uri, cpi)) { 8947 return true; 8948 } 8949 } 8950 } 8951 } 8952 return false; 8953 } 8954 8955 /** 8956 * Returns true if the uri authority is one of the authorities specified in the provider. 8957 */ 8958 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8959 String uriAuth = uri.getAuthority(); 8960 String cpiAuth = cpi.authority; 8961 if (cpiAuth.indexOf(';') == -1) { 8962 return cpiAuth.equals(uriAuth); 8963 } 8964 String[] cpiAuths = cpiAuth.split(";"); 8965 int length = cpiAuths.length; 8966 for (int i = 0; i < length; i++) { 8967 if (cpiAuths[i].equals(uriAuth)) return true; 8968 } 8969 return false; 8970 } 8971 8972 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8973 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8974 if (r != null) { 8975 for (int i=0; i<r.conProviders.size(); i++) { 8976 ContentProviderConnection conn = r.conProviders.get(i); 8977 if (conn.provider == cpr) { 8978 if (DEBUG_PROVIDER) Slog.v(TAG, 8979 "Adding provider requested by " 8980 + r.processName + " from process " 8981 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8982 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8983 if (stable) { 8984 conn.stableCount++; 8985 conn.numStableIncs++; 8986 } else { 8987 conn.unstableCount++; 8988 conn.numUnstableIncs++; 8989 } 8990 return conn; 8991 } 8992 } 8993 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8994 if (stable) { 8995 conn.stableCount = 1; 8996 conn.numStableIncs = 1; 8997 } else { 8998 conn.unstableCount = 1; 8999 conn.numUnstableIncs = 1; 9000 } 9001 cpr.connections.add(conn); 9002 r.conProviders.add(conn); 9003 return conn; 9004 } 9005 cpr.addExternalProcessHandleLocked(externalProcessToken); 9006 return null; 9007 } 9008 9009 boolean decProviderCountLocked(ContentProviderConnection conn, 9010 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9011 if (conn != null) { 9012 cpr = conn.provider; 9013 if (DEBUG_PROVIDER) Slog.v(TAG, 9014 "Removing provider requested by " 9015 + conn.client.processName + " from process " 9016 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9017 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9018 if (stable) { 9019 conn.stableCount--; 9020 } else { 9021 conn.unstableCount--; 9022 } 9023 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9024 cpr.connections.remove(conn); 9025 conn.client.conProviders.remove(conn); 9026 return true; 9027 } 9028 return false; 9029 } 9030 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9031 return false; 9032 } 9033 9034 private void checkTime(long startTime, String where) { 9035 long now = SystemClock.elapsedRealtime(); 9036 if ((now-startTime) > 1000) { 9037 // If we are taking more than a second, log about it. 9038 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9039 } 9040 } 9041 9042 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9043 String name, IBinder token, boolean stable, int userId) { 9044 ContentProviderRecord cpr; 9045 ContentProviderConnection conn = null; 9046 ProviderInfo cpi = null; 9047 9048 synchronized(this) { 9049 long startTime = SystemClock.elapsedRealtime(); 9050 9051 ProcessRecord r = null; 9052 if (caller != null) { 9053 r = getRecordForAppLocked(caller); 9054 if (r == null) { 9055 throw new SecurityException( 9056 "Unable to find app for caller " + caller 9057 + " (pid=" + Binder.getCallingPid() 9058 + ") when getting content provider " + name); 9059 } 9060 } 9061 9062 boolean checkCrossUser = true; 9063 9064 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9065 9066 // First check if this content provider has been published... 9067 cpr = mProviderMap.getProviderByName(name, userId); 9068 // If that didn't work, check if it exists for user 0 and then 9069 // verify that it's a singleton provider before using it. 9070 if (cpr == null && userId != UserHandle.USER_OWNER) { 9071 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9072 if (cpr != null) { 9073 cpi = cpr.info; 9074 if (isSingleton(cpi.processName, cpi.applicationInfo, 9075 cpi.name, cpi.flags) 9076 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9077 userId = UserHandle.USER_OWNER; 9078 checkCrossUser = false; 9079 } else { 9080 cpr = null; 9081 cpi = null; 9082 } 9083 } 9084 } 9085 9086 boolean providerRunning = cpr != null; 9087 if (providerRunning) { 9088 cpi = cpr.info; 9089 String msg; 9090 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9091 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9092 != null) { 9093 throw new SecurityException(msg); 9094 } 9095 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9096 9097 if (r != null && cpr.canRunHere(r)) { 9098 // This provider has been published or is in the process 9099 // of being published... but it is also allowed to run 9100 // in the caller's process, so don't make a connection 9101 // and just let the caller instantiate its own instance. 9102 ContentProviderHolder holder = cpr.newHolder(null); 9103 // don't give caller the provider object, it needs 9104 // to make its own. 9105 holder.provider = null; 9106 return holder; 9107 } 9108 9109 final long origId = Binder.clearCallingIdentity(); 9110 9111 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9112 9113 // In this case the provider instance already exists, so we can 9114 // return it right away. 9115 conn = incProviderCountLocked(r, cpr, token, stable); 9116 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9117 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9118 // If this is a perceptible app accessing the provider, 9119 // make sure to count it as being accessed and thus 9120 // back up on the LRU list. This is good because 9121 // content providers are often expensive to start. 9122 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9123 updateLruProcessLocked(cpr.proc, false, null); 9124 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9125 } 9126 } 9127 9128 if (cpr.proc != null) { 9129 if (false) { 9130 if (cpr.name.flattenToShortString().equals( 9131 "com.android.providers.calendar/.CalendarProvider2")) { 9132 Slog.v(TAG, "****************** KILLING " 9133 + cpr.name.flattenToShortString()); 9134 Process.killProcess(cpr.proc.pid); 9135 } 9136 } 9137 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9138 boolean success = updateOomAdjLocked(cpr.proc); 9139 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9140 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9141 // NOTE: there is still a race here where a signal could be 9142 // pending on the process even though we managed to update its 9143 // adj level. Not sure what to do about this, but at least 9144 // the race is now smaller. 9145 if (!success) { 9146 // Uh oh... it looks like the provider's process 9147 // has been killed on us. We need to wait for a new 9148 // process to be started, and make sure its death 9149 // doesn't kill our process. 9150 Slog.i(TAG, 9151 "Existing provider " + cpr.name.flattenToShortString() 9152 + " is crashing; detaching " + r); 9153 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9154 checkTime(startTime, "getContentProviderImpl: before appDied"); 9155 appDiedLocked(cpr.proc); 9156 checkTime(startTime, "getContentProviderImpl: after appDied"); 9157 if (!lastRef) { 9158 // This wasn't the last ref our process had on 9159 // the provider... we have now been killed, bail. 9160 return null; 9161 } 9162 providerRunning = false; 9163 conn = null; 9164 } 9165 } 9166 9167 Binder.restoreCallingIdentity(origId); 9168 } 9169 9170 boolean singleton; 9171 if (!providerRunning) { 9172 try { 9173 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9174 cpi = AppGlobals.getPackageManager(). 9175 resolveContentProvider(name, 9176 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9177 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9178 } catch (RemoteException ex) { 9179 } 9180 if (cpi == null) { 9181 return null; 9182 } 9183 // If the provider is a singleton AND 9184 // (it's a call within the same user || the provider is a 9185 // privileged app) 9186 // Then allow connecting to the singleton provider 9187 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9188 cpi.name, cpi.flags) 9189 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9190 if (singleton) { 9191 userId = UserHandle.USER_OWNER; 9192 } 9193 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9194 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9195 9196 String msg; 9197 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9198 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9199 != null) { 9200 throw new SecurityException(msg); 9201 } 9202 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9203 9204 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9205 && !cpi.processName.equals("system")) { 9206 // If this content provider does not run in the system 9207 // process, and the system is not yet ready to run other 9208 // processes, then fail fast instead of hanging. 9209 throw new IllegalArgumentException( 9210 "Attempt to launch content provider before system ready"); 9211 } 9212 9213 // Make sure that the user who owns this provider is started. If not, 9214 // we don't want to allow it to run. 9215 if (mStartedUsers.get(userId) == null) { 9216 Slog.w(TAG, "Unable to launch app " 9217 + cpi.applicationInfo.packageName + "/" 9218 + cpi.applicationInfo.uid + " for provider " 9219 + name + ": user " + userId + " is stopped"); 9220 return null; 9221 } 9222 9223 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9224 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9225 cpr = mProviderMap.getProviderByClass(comp, userId); 9226 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9227 final boolean firstClass = cpr == null; 9228 if (firstClass) { 9229 final long ident = Binder.clearCallingIdentity(); 9230 try { 9231 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9232 ApplicationInfo ai = 9233 AppGlobals.getPackageManager(). 9234 getApplicationInfo( 9235 cpi.applicationInfo.packageName, 9236 STOCK_PM_FLAGS, userId); 9237 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9238 if (ai == null) { 9239 Slog.w(TAG, "No package info for content provider " 9240 + cpi.name); 9241 return null; 9242 } 9243 ai = getAppInfoForUser(ai, userId); 9244 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9245 } catch (RemoteException ex) { 9246 // pm is in same process, this will never happen. 9247 } finally { 9248 Binder.restoreCallingIdentity(ident); 9249 } 9250 } 9251 9252 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9253 9254 if (r != null && cpr.canRunHere(r)) { 9255 // If this is a multiprocess provider, then just return its 9256 // info and allow the caller to instantiate it. Only do 9257 // this if the provider is the same user as the caller's 9258 // process, or can run as root (so can be in any process). 9259 return cpr.newHolder(null); 9260 } 9261 9262 if (DEBUG_PROVIDER) { 9263 RuntimeException e = new RuntimeException("here"); 9264 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9265 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9266 } 9267 9268 // This is single process, and our app is now connecting to it. 9269 // See if we are already in the process of launching this 9270 // provider. 9271 final int N = mLaunchingProviders.size(); 9272 int i; 9273 for (i=0; i<N; i++) { 9274 if (mLaunchingProviders.get(i) == cpr) { 9275 break; 9276 } 9277 } 9278 9279 // If the provider is not already being launched, then get it 9280 // started. 9281 if (i >= N) { 9282 final long origId = Binder.clearCallingIdentity(); 9283 9284 try { 9285 // Content provider is now in use, its package can't be stopped. 9286 try { 9287 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9288 AppGlobals.getPackageManager().setPackageStoppedState( 9289 cpr.appInfo.packageName, false, userId); 9290 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9291 } catch (RemoteException e) { 9292 } catch (IllegalArgumentException e) { 9293 Slog.w(TAG, "Failed trying to unstop package " 9294 + cpr.appInfo.packageName + ": " + e); 9295 } 9296 9297 // Use existing process if already started 9298 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9299 ProcessRecord proc = getProcessRecordLocked( 9300 cpi.processName, cpr.appInfo.uid, false); 9301 if (proc != null && proc.thread != null) { 9302 if (DEBUG_PROVIDER) { 9303 Slog.d(TAG, "Installing in existing process " + proc); 9304 } 9305 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9306 proc.pubProviders.put(cpi.name, cpr); 9307 try { 9308 proc.thread.scheduleInstallProvider(cpi); 9309 } catch (RemoteException e) { 9310 } 9311 } else { 9312 checkTime(startTime, "getContentProviderImpl: before start process"); 9313 proc = startProcessLocked(cpi.processName, 9314 cpr.appInfo, false, 0, "content provider", 9315 new ComponentName(cpi.applicationInfo.packageName, 9316 cpi.name), false, false, false); 9317 checkTime(startTime, "getContentProviderImpl: after start process"); 9318 if (proc == null) { 9319 Slog.w(TAG, "Unable to launch app " 9320 + cpi.applicationInfo.packageName + "/" 9321 + cpi.applicationInfo.uid + " for provider " 9322 + name + ": process is bad"); 9323 return null; 9324 } 9325 } 9326 cpr.launchingApp = proc; 9327 mLaunchingProviders.add(cpr); 9328 } finally { 9329 Binder.restoreCallingIdentity(origId); 9330 } 9331 } 9332 9333 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9334 9335 // Make sure the provider is published (the same provider class 9336 // may be published under multiple names). 9337 if (firstClass) { 9338 mProviderMap.putProviderByClass(comp, cpr); 9339 } 9340 9341 mProviderMap.putProviderByName(name, cpr); 9342 conn = incProviderCountLocked(r, cpr, token, stable); 9343 if (conn != null) { 9344 conn.waiting = true; 9345 } 9346 } 9347 checkTime(startTime, "getContentProviderImpl: done!"); 9348 } 9349 9350 // Wait for the provider to be published... 9351 synchronized (cpr) { 9352 while (cpr.provider == null) { 9353 if (cpr.launchingApp == null) { 9354 Slog.w(TAG, "Unable to launch app " 9355 + cpi.applicationInfo.packageName + "/" 9356 + cpi.applicationInfo.uid + " for provider " 9357 + name + ": launching app became null"); 9358 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9359 UserHandle.getUserId(cpi.applicationInfo.uid), 9360 cpi.applicationInfo.packageName, 9361 cpi.applicationInfo.uid, name); 9362 return null; 9363 } 9364 try { 9365 if (DEBUG_MU) { 9366 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9367 + cpr.launchingApp); 9368 } 9369 if (conn != null) { 9370 conn.waiting = true; 9371 } 9372 cpr.wait(); 9373 } catch (InterruptedException ex) { 9374 } finally { 9375 if (conn != null) { 9376 conn.waiting = false; 9377 } 9378 } 9379 } 9380 } 9381 return cpr != null ? cpr.newHolder(conn) : null; 9382 } 9383 9384 @Override 9385 public final ContentProviderHolder getContentProvider( 9386 IApplicationThread caller, String name, int userId, boolean stable) { 9387 enforceNotIsolatedCaller("getContentProvider"); 9388 if (caller == null) { 9389 String msg = "null IApplicationThread when getting content provider " 9390 + name; 9391 Slog.w(TAG, msg); 9392 throw new SecurityException(msg); 9393 } 9394 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9395 // with cross-user grant. 9396 return getContentProviderImpl(caller, name, null, stable, userId); 9397 } 9398 9399 public ContentProviderHolder getContentProviderExternal( 9400 String name, int userId, IBinder token) { 9401 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9402 "Do not have permission in call getContentProviderExternal()"); 9403 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9404 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9405 return getContentProviderExternalUnchecked(name, token, userId); 9406 } 9407 9408 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9409 IBinder token, int userId) { 9410 return getContentProviderImpl(null, name, token, true, userId); 9411 } 9412 9413 /** 9414 * Drop a content provider from a ProcessRecord's bookkeeping 9415 */ 9416 public void removeContentProvider(IBinder connection, boolean stable) { 9417 enforceNotIsolatedCaller("removeContentProvider"); 9418 long ident = Binder.clearCallingIdentity(); 9419 try { 9420 synchronized (this) { 9421 ContentProviderConnection conn; 9422 try { 9423 conn = (ContentProviderConnection)connection; 9424 } catch (ClassCastException e) { 9425 String msg ="removeContentProvider: " + connection 9426 + " not a ContentProviderConnection"; 9427 Slog.w(TAG, msg); 9428 throw new IllegalArgumentException(msg); 9429 } 9430 if (conn == null) { 9431 throw new NullPointerException("connection is null"); 9432 } 9433 if (decProviderCountLocked(conn, null, null, stable)) { 9434 updateOomAdjLocked(); 9435 } 9436 } 9437 } finally { 9438 Binder.restoreCallingIdentity(ident); 9439 } 9440 } 9441 9442 public void removeContentProviderExternal(String name, IBinder token) { 9443 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9444 "Do not have permission in call removeContentProviderExternal()"); 9445 int userId = UserHandle.getCallingUserId(); 9446 long ident = Binder.clearCallingIdentity(); 9447 try { 9448 removeContentProviderExternalUnchecked(name, token, userId); 9449 } finally { 9450 Binder.restoreCallingIdentity(ident); 9451 } 9452 } 9453 9454 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9455 synchronized (this) { 9456 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9457 if(cpr == null) { 9458 //remove from mProvidersByClass 9459 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9460 return; 9461 } 9462 9463 //update content provider record entry info 9464 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9465 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9466 if (localCpr.hasExternalProcessHandles()) { 9467 if (localCpr.removeExternalProcessHandleLocked(token)) { 9468 updateOomAdjLocked(); 9469 } else { 9470 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9471 + " with no external reference for token: " 9472 + token + "."); 9473 } 9474 } else { 9475 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9476 + " with no external references."); 9477 } 9478 } 9479 } 9480 9481 public final void publishContentProviders(IApplicationThread caller, 9482 List<ContentProviderHolder> providers) { 9483 if (providers == null) { 9484 return; 9485 } 9486 9487 enforceNotIsolatedCaller("publishContentProviders"); 9488 synchronized (this) { 9489 final ProcessRecord r = getRecordForAppLocked(caller); 9490 if (DEBUG_MU) 9491 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9492 if (r == null) { 9493 throw new SecurityException( 9494 "Unable to find app for caller " + caller 9495 + " (pid=" + Binder.getCallingPid() 9496 + ") when publishing content providers"); 9497 } 9498 9499 final long origId = Binder.clearCallingIdentity(); 9500 9501 final int N = providers.size(); 9502 for (int i=0; i<N; i++) { 9503 ContentProviderHolder src = providers.get(i); 9504 if (src == null || src.info == null || src.provider == null) { 9505 continue; 9506 } 9507 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9508 if (DEBUG_MU) 9509 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9510 if (dst != null) { 9511 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9512 mProviderMap.putProviderByClass(comp, dst); 9513 String names[] = dst.info.authority.split(";"); 9514 for (int j = 0; j < names.length; j++) { 9515 mProviderMap.putProviderByName(names[j], dst); 9516 } 9517 9518 int NL = mLaunchingProviders.size(); 9519 int j; 9520 for (j=0; j<NL; j++) { 9521 if (mLaunchingProviders.get(j) == dst) { 9522 mLaunchingProviders.remove(j); 9523 j--; 9524 NL--; 9525 } 9526 } 9527 synchronized (dst) { 9528 dst.provider = src.provider; 9529 dst.proc = r; 9530 dst.notifyAll(); 9531 } 9532 updateOomAdjLocked(r); 9533 } 9534 } 9535 9536 Binder.restoreCallingIdentity(origId); 9537 } 9538 } 9539 9540 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9541 ContentProviderConnection conn; 9542 try { 9543 conn = (ContentProviderConnection)connection; 9544 } catch (ClassCastException e) { 9545 String msg ="refContentProvider: " + connection 9546 + " not a ContentProviderConnection"; 9547 Slog.w(TAG, msg); 9548 throw new IllegalArgumentException(msg); 9549 } 9550 if (conn == null) { 9551 throw new NullPointerException("connection is null"); 9552 } 9553 9554 synchronized (this) { 9555 if (stable > 0) { 9556 conn.numStableIncs += stable; 9557 } 9558 stable = conn.stableCount + stable; 9559 if (stable < 0) { 9560 throw new IllegalStateException("stableCount < 0: " + stable); 9561 } 9562 9563 if (unstable > 0) { 9564 conn.numUnstableIncs += unstable; 9565 } 9566 unstable = conn.unstableCount + unstable; 9567 if (unstable < 0) { 9568 throw new IllegalStateException("unstableCount < 0: " + unstable); 9569 } 9570 9571 if ((stable+unstable) <= 0) { 9572 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9573 + stable + " unstable=" + unstable); 9574 } 9575 conn.stableCount = stable; 9576 conn.unstableCount = unstable; 9577 return !conn.dead; 9578 } 9579 } 9580 9581 public void unstableProviderDied(IBinder connection) { 9582 ContentProviderConnection conn; 9583 try { 9584 conn = (ContentProviderConnection)connection; 9585 } catch (ClassCastException e) { 9586 String msg ="refContentProvider: " + connection 9587 + " not a ContentProviderConnection"; 9588 Slog.w(TAG, msg); 9589 throw new IllegalArgumentException(msg); 9590 } 9591 if (conn == null) { 9592 throw new NullPointerException("connection is null"); 9593 } 9594 9595 // Safely retrieve the content provider associated with the connection. 9596 IContentProvider provider; 9597 synchronized (this) { 9598 provider = conn.provider.provider; 9599 } 9600 9601 if (provider == null) { 9602 // Um, yeah, we're way ahead of you. 9603 return; 9604 } 9605 9606 // Make sure the caller is being honest with us. 9607 if (provider.asBinder().pingBinder()) { 9608 // Er, no, still looks good to us. 9609 synchronized (this) { 9610 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9611 + " says " + conn + " died, but we don't agree"); 9612 return; 9613 } 9614 } 9615 9616 // Well look at that! It's dead! 9617 synchronized (this) { 9618 if (conn.provider.provider != provider) { 9619 // But something changed... good enough. 9620 return; 9621 } 9622 9623 ProcessRecord proc = conn.provider.proc; 9624 if (proc == null || proc.thread == null) { 9625 // Seems like the process is already cleaned up. 9626 return; 9627 } 9628 9629 // As far as we're concerned, this is just like receiving a 9630 // death notification... just a bit prematurely. 9631 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9632 + ") early provider death"); 9633 final long ident = Binder.clearCallingIdentity(); 9634 try { 9635 appDiedLocked(proc); 9636 } finally { 9637 Binder.restoreCallingIdentity(ident); 9638 } 9639 } 9640 } 9641 9642 @Override 9643 public void appNotRespondingViaProvider(IBinder connection) { 9644 enforceCallingPermission( 9645 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9646 9647 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9648 if (conn == null) { 9649 Slog.w(TAG, "ContentProviderConnection is null"); 9650 return; 9651 } 9652 9653 final ProcessRecord host = conn.provider.proc; 9654 if (host == null) { 9655 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9656 return; 9657 } 9658 9659 final long token = Binder.clearCallingIdentity(); 9660 try { 9661 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9662 } finally { 9663 Binder.restoreCallingIdentity(token); 9664 } 9665 } 9666 9667 public final void installSystemProviders() { 9668 List<ProviderInfo> providers; 9669 synchronized (this) { 9670 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9671 providers = generateApplicationProvidersLocked(app); 9672 if (providers != null) { 9673 for (int i=providers.size()-1; i>=0; i--) { 9674 ProviderInfo pi = (ProviderInfo)providers.get(i); 9675 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9676 Slog.w(TAG, "Not installing system proc provider " + pi.name 9677 + ": not system .apk"); 9678 providers.remove(i); 9679 } 9680 } 9681 } 9682 } 9683 if (providers != null) { 9684 mSystemThread.installSystemProviders(providers); 9685 } 9686 9687 mCoreSettingsObserver = new CoreSettingsObserver(this); 9688 9689 //mUsageStatsService.monitorPackages(); 9690 } 9691 9692 /** 9693 * Allows apps to retrieve the MIME type of a URI. 9694 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9695 * users, then it does not need permission to access the ContentProvider. 9696 * Either, it needs cross-user uri grants. 9697 * 9698 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9699 * 9700 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9701 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9702 */ 9703 public String getProviderMimeType(Uri uri, int userId) { 9704 enforceNotIsolatedCaller("getProviderMimeType"); 9705 final String name = uri.getAuthority(); 9706 int callingUid = Binder.getCallingUid(); 9707 int callingPid = Binder.getCallingPid(); 9708 long ident = 0; 9709 boolean clearedIdentity = false; 9710 userId = unsafeConvertIncomingUser(userId); 9711 if (canClearIdentity(callingPid, callingUid, userId)) { 9712 clearedIdentity = true; 9713 ident = Binder.clearCallingIdentity(); 9714 } 9715 ContentProviderHolder holder = null; 9716 try { 9717 holder = getContentProviderExternalUnchecked(name, null, userId); 9718 if (holder != null) { 9719 return holder.provider.getType(uri); 9720 } 9721 } catch (RemoteException e) { 9722 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9723 return null; 9724 } finally { 9725 // We need to clear the identity to call removeContentProviderExternalUnchecked 9726 if (!clearedIdentity) { 9727 ident = Binder.clearCallingIdentity(); 9728 } 9729 try { 9730 if (holder != null) { 9731 removeContentProviderExternalUnchecked(name, null, userId); 9732 } 9733 } finally { 9734 Binder.restoreCallingIdentity(ident); 9735 } 9736 } 9737 9738 return null; 9739 } 9740 9741 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9742 if (UserHandle.getUserId(callingUid) == userId) { 9743 return true; 9744 } 9745 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9746 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9747 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9748 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9749 return true; 9750 } 9751 return false; 9752 } 9753 9754 // ========================================================= 9755 // GLOBAL MANAGEMENT 9756 // ========================================================= 9757 9758 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9759 boolean isolated, int isolatedUid) { 9760 String proc = customProcess != null ? customProcess : info.processName; 9761 BatteryStatsImpl.Uid.Proc ps = null; 9762 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9763 int uid = info.uid; 9764 if (isolated) { 9765 if (isolatedUid == 0) { 9766 int userId = UserHandle.getUserId(uid); 9767 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9768 while (true) { 9769 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9770 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9771 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9772 } 9773 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9774 mNextIsolatedProcessUid++; 9775 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9776 // No process for this uid, use it. 9777 break; 9778 } 9779 stepsLeft--; 9780 if (stepsLeft <= 0) { 9781 return null; 9782 } 9783 } 9784 } else { 9785 // Special case for startIsolatedProcess (internal only), where 9786 // the uid of the isolated process is specified by the caller. 9787 uid = isolatedUid; 9788 } 9789 } 9790 return new ProcessRecord(stats, info, proc, uid); 9791 } 9792 9793 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9794 String abiOverride) { 9795 ProcessRecord app; 9796 if (!isolated) { 9797 app = getProcessRecordLocked(info.processName, info.uid, true); 9798 } else { 9799 app = null; 9800 } 9801 9802 if (app == null) { 9803 app = newProcessRecordLocked(info, null, isolated, 0); 9804 mProcessNames.put(info.processName, app.uid, app); 9805 if (isolated) { 9806 mIsolatedProcesses.put(app.uid, app); 9807 } 9808 updateLruProcessLocked(app, false, null); 9809 updateOomAdjLocked(); 9810 } 9811 9812 // This package really, really can not be stopped. 9813 try { 9814 AppGlobals.getPackageManager().setPackageStoppedState( 9815 info.packageName, false, UserHandle.getUserId(app.uid)); 9816 } catch (RemoteException e) { 9817 } catch (IllegalArgumentException e) { 9818 Slog.w(TAG, "Failed trying to unstop package " 9819 + info.packageName + ": " + e); 9820 } 9821 9822 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9823 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9824 app.persistent = true; 9825 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9826 } 9827 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9828 mPersistentStartingProcesses.add(app); 9829 startProcessLocked(app, "added application", app.processName, abiOverride, 9830 null /* entryPoint */, null /* entryPointArgs */); 9831 } 9832 9833 return app; 9834 } 9835 9836 public void unhandledBack() { 9837 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9838 "unhandledBack()"); 9839 9840 synchronized(this) { 9841 final long origId = Binder.clearCallingIdentity(); 9842 try { 9843 getFocusedStack().unhandledBackLocked(); 9844 } finally { 9845 Binder.restoreCallingIdentity(origId); 9846 } 9847 } 9848 } 9849 9850 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9851 enforceNotIsolatedCaller("openContentUri"); 9852 final int userId = UserHandle.getCallingUserId(); 9853 String name = uri.getAuthority(); 9854 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9855 ParcelFileDescriptor pfd = null; 9856 if (cph != null) { 9857 // We record the binder invoker's uid in thread-local storage before 9858 // going to the content provider to open the file. Later, in the code 9859 // that handles all permissions checks, we look for this uid and use 9860 // that rather than the Activity Manager's own uid. The effect is that 9861 // we do the check against the caller's permissions even though it looks 9862 // to the content provider like the Activity Manager itself is making 9863 // the request. 9864 sCallerIdentity.set(new Identity( 9865 Binder.getCallingPid(), Binder.getCallingUid())); 9866 try { 9867 pfd = cph.provider.openFile(null, uri, "r", null); 9868 } catch (FileNotFoundException e) { 9869 // do nothing; pfd will be returned null 9870 } finally { 9871 // Ensure that whatever happens, we clean up the identity state 9872 sCallerIdentity.remove(); 9873 } 9874 9875 // We've got the fd now, so we're done with the provider. 9876 removeContentProviderExternalUnchecked(name, null, userId); 9877 } else { 9878 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9879 } 9880 return pfd; 9881 } 9882 9883 // Actually is sleeping or shutting down or whatever else in the future 9884 // is an inactive state. 9885 public boolean isSleepingOrShuttingDown() { 9886 return isSleeping() || mShuttingDown; 9887 } 9888 9889 public boolean isSleeping() { 9890 return mSleeping; 9891 } 9892 9893 void goingToSleep() { 9894 synchronized(this) { 9895 mWentToSleep = true; 9896 goToSleepIfNeededLocked(); 9897 } 9898 } 9899 9900 void finishRunningVoiceLocked() { 9901 if (mRunningVoice) { 9902 mRunningVoice = false; 9903 goToSleepIfNeededLocked(); 9904 } 9905 } 9906 9907 void goToSleepIfNeededLocked() { 9908 if (mWentToSleep && !mRunningVoice) { 9909 if (!mSleeping) { 9910 mSleeping = true; 9911 mStackSupervisor.goingToSleepLocked(); 9912 9913 // Initialize the wake times of all processes. 9914 checkExcessivePowerUsageLocked(false); 9915 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9916 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9917 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9918 } 9919 } 9920 } 9921 9922 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9923 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9924 // Never persist the home stack. 9925 return; 9926 } 9927 mTaskPersister.wakeup(task, flush); 9928 } 9929 9930 @Override 9931 public boolean shutdown(int timeout) { 9932 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9933 != PackageManager.PERMISSION_GRANTED) { 9934 throw new SecurityException("Requires permission " 9935 + android.Manifest.permission.SHUTDOWN); 9936 } 9937 9938 boolean timedout = false; 9939 9940 synchronized(this) { 9941 mShuttingDown = true; 9942 updateEventDispatchingLocked(); 9943 timedout = mStackSupervisor.shutdownLocked(timeout); 9944 } 9945 9946 mAppOpsService.shutdown(); 9947 if (mUsageStatsService != null) { 9948 mUsageStatsService.prepareShutdown(); 9949 } 9950 mBatteryStatsService.shutdown(); 9951 synchronized (this) { 9952 mProcessStats.shutdownLocked(); 9953 } 9954 notifyTaskPersisterLocked(null, true); 9955 9956 return timedout; 9957 } 9958 9959 public final void activitySlept(IBinder token) { 9960 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9961 9962 final long origId = Binder.clearCallingIdentity(); 9963 9964 synchronized (this) { 9965 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9966 if (r != null) { 9967 mStackSupervisor.activitySleptLocked(r); 9968 } 9969 } 9970 9971 Binder.restoreCallingIdentity(origId); 9972 } 9973 9974 private String lockScreenShownToString() { 9975 switch (mLockScreenShown) { 9976 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 9977 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 9978 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 9979 default: return "Unknown=" + mLockScreenShown; 9980 } 9981 } 9982 9983 void logLockScreen(String msg) { 9984 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9985 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 9986 mWentToSleep + " mSleeping=" + mSleeping); 9987 } 9988 9989 void comeOutOfSleepIfNeededLocked() { 9990 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 9991 if (mSleeping) { 9992 mSleeping = false; 9993 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9994 } 9995 } 9996 } 9997 9998 void wakingUp() { 9999 synchronized(this) { 10000 mWentToSleep = false; 10001 comeOutOfSleepIfNeededLocked(); 10002 } 10003 } 10004 10005 void startRunningVoiceLocked() { 10006 if (!mRunningVoice) { 10007 mRunningVoice = true; 10008 comeOutOfSleepIfNeededLocked(); 10009 } 10010 } 10011 10012 private void updateEventDispatchingLocked() { 10013 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10014 } 10015 10016 public void setLockScreenShown(boolean shown) { 10017 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10018 != PackageManager.PERMISSION_GRANTED) { 10019 throw new SecurityException("Requires permission " 10020 + android.Manifest.permission.DEVICE_POWER); 10021 } 10022 10023 synchronized(this) { 10024 long ident = Binder.clearCallingIdentity(); 10025 try { 10026 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10027 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10028 comeOutOfSleepIfNeededLocked(); 10029 } finally { 10030 Binder.restoreCallingIdentity(ident); 10031 } 10032 } 10033 } 10034 10035 @Override 10036 public void stopAppSwitches() { 10037 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10038 != PackageManager.PERMISSION_GRANTED) { 10039 throw new SecurityException("Requires permission " 10040 + android.Manifest.permission.STOP_APP_SWITCHES); 10041 } 10042 10043 synchronized(this) { 10044 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10045 + APP_SWITCH_DELAY_TIME; 10046 mDidAppSwitch = false; 10047 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10048 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10049 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10050 } 10051 } 10052 10053 public void resumeAppSwitches() { 10054 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10055 != PackageManager.PERMISSION_GRANTED) { 10056 throw new SecurityException("Requires permission " 10057 + android.Manifest.permission.STOP_APP_SWITCHES); 10058 } 10059 10060 synchronized(this) { 10061 // Note that we don't execute any pending app switches... we will 10062 // let those wait until either the timeout, or the next start 10063 // activity request. 10064 mAppSwitchesAllowedTime = 0; 10065 } 10066 } 10067 10068 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10069 int callingPid, int callingUid, String name) { 10070 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10071 return true; 10072 } 10073 10074 int perm = checkComponentPermission( 10075 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10076 sourceUid, -1, true); 10077 if (perm == PackageManager.PERMISSION_GRANTED) { 10078 return true; 10079 } 10080 10081 // If the actual IPC caller is different from the logical source, then 10082 // also see if they are allowed to control app switches. 10083 if (callingUid != -1 && callingUid != sourceUid) { 10084 perm = checkComponentPermission( 10085 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10086 callingUid, -1, true); 10087 if (perm == PackageManager.PERMISSION_GRANTED) { 10088 return true; 10089 } 10090 } 10091 10092 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10093 return false; 10094 } 10095 10096 public void setDebugApp(String packageName, boolean waitForDebugger, 10097 boolean persistent) { 10098 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10099 "setDebugApp()"); 10100 10101 long ident = Binder.clearCallingIdentity(); 10102 try { 10103 // Note that this is not really thread safe if there are multiple 10104 // callers into it at the same time, but that's not a situation we 10105 // care about. 10106 if (persistent) { 10107 final ContentResolver resolver = mContext.getContentResolver(); 10108 Settings.Global.putString( 10109 resolver, Settings.Global.DEBUG_APP, 10110 packageName); 10111 Settings.Global.putInt( 10112 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10113 waitForDebugger ? 1 : 0); 10114 } 10115 10116 synchronized (this) { 10117 if (!persistent) { 10118 mOrigDebugApp = mDebugApp; 10119 mOrigWaitForDebugger = mWaitForDebugger; 10120 } 10121 mDebugApp = packageName; 10122 mWaitForDebugger = waitForDebugger; 10123 mDebugTransient = !persistent; 10124 if (packageName != null) { 10125 forceStopPackageLocked(packageName, -1, false, false, true, true, 10126 false, UserHandle.USER_ALL, "set debug app"); 10127 } 10128 } 10129 } finally { 10130 Binder.restoreCallingIdentity(ident); 10131 } 10132 } 10133 10134 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10135 synchronized (this) { 10136 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10137 if (!isDebuggable) { 10138 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10139 throw new SecurityException("Process not debuggable: " + app.packageName); 10140 } 10141 } 10142 10143 mOpenGlTraceApp = processName; 10144 } 10145 } 10146 10147 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10148 synchronized (this) { 10149 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10150 if (!isDebuggable) { 10151 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10152 throw new SecurityException("Process not debuggable: " + app.packageName); 10153 } 10154 } 10155 mProfileApp = processName; 10156 mProfileFile = profilerInfo.profileFile; 10157 if (mProfileFd != null) { 10158 try { 10159 mProfileFd.close(); 10160 } catch (IOException e) { 10161 } 10162 mProfileFd = null; 10163 } 10164 mProfileFd = profilerInfo.profileFd; 10165 mSamplingInterval = profilerInfo.samplingInterval; 10166 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10167 mProfileType = 0; 10168 } 10169 } 10170 10171 @Override 10172 public void setAlwaysFinish(boolean enabled) { 10173 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10174 "setAlwaysFinish()"); 10175 10176 Settings.Global.putInt( 10177 mContext.getContentResolver(), 10178 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10179 10180 synchronized (this) { 10181 mAlwaysFinishActivities = enabled; 10182 } 10183 } 10184 10185 @Override 10186 public void setActivityController(IActivityController controller) { 10187 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10188 "setActivityController()"); 10189 synchronized (this) { 10190 mController = controller; 10191 Watchdog.getInstance().setActivityController(controller); 10192 } 10193 } 10194 10195 @Override 10196 public void setUserIsMonkey(boolean userIsMonkey) { 10197 synchronized (this) { 10198 synchronized (mPidsSelfLocked) { 10199 final int callingPid = Binder.getCallingPid(); 10200 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10201 if (precessRecord == null) { 10202 throw new SecurityException("Unknown process: " + callingPid); 10203 } 10204 if (precessRecord.instrumentationUiAutomationConnection == null) { 10205 throw new SecurityException("Only an instrumentation process " 10206 + "with a UiAutomation can call setUserIsMonkey"); 10207 } 10208 } 10209 mUserIsMonkey = userIsMonkey; 10210 } 10211 } 10212 10213 @Override 10214 public boolean isUserAMonkey() { 10215 synchronized (this) { 10216 // If there is a controller also implies the user is a monkey. 10217 return (mUserIsMonkey || mController != null); 10218 } 10219 } 10220 10221 public void requestBugReport() { 10222 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10223 SystemProperties.set("ctl.start", "bugreport"); 10224 } 10225 10226 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10227 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10228 } 10229 10230 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10231 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10232 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10233 } 10234 return KEY_DISPATCHING_TIMEOUT; 10235 } 10236 10237 @Override 10238 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10239 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10240 != PackageManager.PERMISSION_GRANTED) { 10241 throw new SecurityException("Requires permission " 10242 + android.Manifest.permission.FILTER_EVENTS); 10243 } 10244 ProcessRecord proc; 10245 long timeout; 10246 synchronized (this) { 10247 synchronized (mPidsSelfLocked) { 10248 proc = mPidsSelfLocked.get(pid); 10249 } 10250 timeout = getInputDispatchingTimeoutLocked(proc); 10251 } 10252 10253 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10254 return -1; 10255 } 10256 10257 return timeout; 10258 } 10259 10260 /** 10261 * Handle input dispatching timeouts. 10262 * Returns whether input dispatching should be aborted or not. 10263 */ 10264 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10265 final ActivityRecord activity, final ActivityRecord parent, 10266 final boolean aboveSystem, String reason) { 10267 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10268 != PackageManager.PERMISSION_GRANTED) { 10269 throw new SecurityException("Requires permission " 10270 + android.Manifest.permission.FILTER_EVENTS); 10271 } 10272 10273 final String annotation; 10274 if (reason == null) { 10275 annotation = "Input dispatching timed out"; 10276 } else { 10277 annotation = "Input dispatching timed out (" + reason + ")"; 10278 } 10279 10280 if (proc != null) { 10281 synchronized (this) { 10282 if (proc.debugging) { 10283 return false; 10284 } 10285 10286 if (mDidDexOpt) { 10287 // Give more time since we were dexopting. 10288 mDidDexOpt = false; 10289 return false; 10290 } 10291 10292 if (proc.instrumentationClass != null) { 10293 Bundle info = new Bundle(); 10294 info.putString("shortMsg", "keyDispatchingTimedOut"); 10295 info.putString("longMsg", annotation); 10296 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10297 return true; 10298 } 10299 } 10300 mHandler.post(new Runnable() { 10301 @Override 10302 public void run() { 10303 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10304 } 10305 }); 10306 } 10307 10308 return true; 10309 } 10310 10311 public Bundle getAssistContextExtras(int requestType) { 10312 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10313 UserHandle.getCallingUserId()); 10314 if (pae == null) { 10315 return null; 10316 } 10317 synchronized (pae) { 10318 while (!pae.haveResult) { 10319 try { 10320 pae.wait(); 10321 } catch (InterruptedException e) { 10322 } 10323 } 10324 if (pae.result != null) { 10325 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10326 } 10327 } 10328 synchronized (this) { 10329 mPendingAssistExtras.remove(pae); 10330 mHandler.removeCallbacks(pae); 10331 } 10332 return pae.extras; 10333 } 10334 10335 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10336 int userHandle) { 10337 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10338 "getAssistContextExtras()"); 10339 PendingAssistExtras pae; 10340 Bundle extras = new Bundle(); 10341 synchronized (this) { 10342 ActivityRecord activity = getFocusedStack().mResumedActivity; 10343 if (activity == null) { 10344 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10345 return null; 10346 } 10347 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10348 if (activity.app == null || activity.app.thread == null) { 10349 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10350 return null; 10351 } 10352 if (activity.app.pid == Binder.getCallingPid()) { 10353 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10354 return null; 10355 } 10356 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10357 try { 10358 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10359 requestType); 10360 mPendingAssistExtras.add(pae); 10361 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10362 } catch (RemoteException e) { 10363 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10364 return null; 10365 } 10366 return pae; 10367 } 10368 } 10369 10370 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10371 PendingAssistExtras pae = (PendingAssistExtras)token; 10372 synchronized (pae) { 10373 pae.result = extras; 10374 pae.haveResult = true; 10375 pae.notifyAll(); 10376 if (pae.intent == null) { 10377 // Caller is just waiting for the result. 10378 return; 10379 } 10380 } 10381 10382 // We are now ready to launch the assist activity. 10383 synchronized (this) { 10384 boolean exists = mPendingAssistExtras.remove(pae); 10385 mHandler.removeCallbacks(pae); 10386 if (!exists) { 10387 // Timed out. 10388 return; 10389 } 10390 } 10391 pae.intent.replaceExtras(extras); 10392 if (pae.hint != null) { 10393 pae.intent.putExtra(pae.hint, true); 10394 } 10395 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10396 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10397 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10398 closeSystemDialogs("assist"); 10399 try { 10400 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10401 } catch (ActivityNotFoundException e) { 10402 Slog.w(TAG, "No activity to handle assist action.", e); 10403 } 10404 } 10405 10406 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10407 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10408 } 10409 10410 public void registerProcessObserver(IProcessObserver observer) { 10411 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10412 "registerProcessObserver()"); 10413 synchronized (this) { 10414 mProcessObservers.register(observer); 10415 } 10416 } 10417 10418 @Override 10419 public void unregisterProcessObserver(IProcessObserver observer) { 10420 synchronized (this) { 10421 mProcessObservers.unregister(observer); 10422 } 10423 } 10424 10425 @Override 10426 public boolean convertFromTranslucent(IBinder token) { 10427 final long origId = Binder.clearCallingIdentity(); 10428 try { 10429 synchronized (this) { 10430 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10431 if (r == null) { 10432 return false; 10433 } 10434 final boolean translucentChanged = r.changeWindowTranslucency(true); 10435 if (translucentChanged) { 10436 r.task.stack.releaseBackgroundResources(); 10437 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10438 } 10439 mWindowManager.setAppFullscreen(token, true); 10440 return translucentChanged; 10441 } 10442 } finally { 10443 Binder.restoreCallingIdentity(origId); 10444 } 10445 } 10446 10447 @Override 10448 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10449 final long origId = Binder.clearCallingIdentity(); 10450 try { 10451 synchronized (this) { 10452 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10453 if (r == null) { 10454 return false; 10455 } 10456 int index = r.task.mActivities.lastIndexOf(r); 10457 if (index > 0) { 10458 ActivityRecord under = r.task.mActivities.get(index - 1); 10459 under.returningOptions = options; 10460 } 10461 final boolean translucentChanged = r.changeWindowTranslucency(false); 10462 if (translucentChanged) { 10463 r.task.stack.convertToTranslucent(r); 10464 } 10465 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10466 mWindowManager.setAppFullscreen(token, false); 10467 return translucentChanged; 10468 } 10469 } finally { 10470 Binder.restoreCallingIdentity(origId); 10471 } 10472 } 10473 10474 @Override 10475 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10476 final long origId = Binder.clearCallingIdentity(); 10477 try { 10478 synchronized (this) { 10479 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10480 if (r != null) { 10481 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10482 } 10483 } 10484 return false; 10485 } finally { 10486 Binder.restoreCallingIdentity(origId); 10487 } 10488 } 10489 10490 @Override 10491 public boolean isBackgroundVisibleBehind(IBinder token) { 10492 final long origId = Binder.clearCallingIdentity(); 10493 try { 10494 synchronized (this) { 10495 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10496 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10497 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10498 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10499 return visible; 10500 } 10501 } finally { 10502 Binder.restoreCallingIdentity(origId); 10503 } 10504 } 10505 10506 @Override 10507 public ActivityOptions getActivityOptions(IBinder token) { 10508 final long origId = Binder.clearCallingIdentity(); 10509 try { 10510 synchronized (this) { 10511 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10512 if (r != null) { 10513 final ActivityOptions activityOptions = r.pendingOptions; 10514 r.pendingOptions = null; 10515 return activityOptions; 10516 } 10517 return null; 10518 } 10519 } finally { 10520 Binder.restoreCallingIdentity(origId); 10521 } 10522 } 10523 10524 @Override 10525 public void setImmersive(IBinder token, boolean immersive) { 10526 synchronized(this) { 10527 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10528 if (r == null) { 10529 throw new IllegalArgumentException(); 10530 } 10531 r.immersive = immersive; 10532 10533 // update associated state if we're frontmost 10534 if (r == mFocusedActivity) { 10535 if (DEBUG_IMMERSIVE) { 10536 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10537 } 10538 applyUpdateLockStateLocked(r); 10539 } 10540 } 10541 } 10542 10543 @Override 10544 public boolean isImmersive(IBinder token) { 10545 synchronized (this) { 10546 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10547 if (r == null) { 10548 throw new IllegalArgumentException(); 10549 } 10550 return r.immersive; 10551 } 10552 } 10553 10554 public boolean isTopActivityImmersive() { 10555 enforceNotIsolatedCaller("startActivity"); 10556 synchronized (this) { 10557 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10558 return (r != null) ? r.immersive : false; 10559 } 10560 } 10561 10562 @Override 10563 public boolean isTopOfTask(IBinder token) { 10564 synchronized (this) { 10565 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10566 if (r == null) { 10567 throw new IllegalArgumentException(); 10568 } 10569 return r.task.getTopActivity() == r; 10570 } 10571 } 10572 10573 public final void enterSafeMode() { 10574 synchronized(this) { 10575 // It only makes sense to do this before the system is ready 10576 // and started launching other packages. 10577 if (!mSystemReady) { 10578 try { 10579 AppGlobals.getPackageManager().enterSafeMode(); 10580 } catch (RemoteException e) { 10581 } 10582 } 10583 10584 mSafeMode = true; 10585 } 10586 } 10587 10588 public final void showSafeModeOverlay() { 10589 View v = LayoutInflater.from(mContext).inflate( 10590 com.android.internal.R.layout.safe_mode, null); 10591 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10592 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10593 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10594 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10595 lp.gravity = Gravity.BOTTOM | Gravity.START; 10596 lp.format = v.getBackground().getOpacity(); 10597 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10598 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10599 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10600 ((WindowManager)mContext.getSystemService( 10601 Context.WINDOW_SERVICE)).addView(v, lp); 10602 } 10603 10604 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10605 if (!(sender instanceof PendingIntentRecord)) { 10606 return; 10607 } 10608 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10609 synchronized (stats) { 10610 if (mBatteryStatsService.isOnBattery()) { 10611 mBatteryStatsService.enforceCallingPermission(); 10612 PendingIntentRecord rec = (PendingIntentRecord)sender; 10613 int MY_UID = Binder.getCallingUid(); 10614 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10615 BatteryStatsImpl.Uid.Pkg pkg = 10616 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10617 sourcePkg != null ? sourcePkg : rec.key.packageName); 10618 pkg.incWakeupsLocked(); 10619 } 10620 } 10621 } 10622 10623 public boolean killPids(int[] pids, String pReason, boolean secure) { 10624 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10625 throw new SecurityException("killPids only available to the system"); 10626 } 10627 String reason = (pReason == null) ? "Unknown" : pReason; 10628 // XXX Note: don't acquire main activity lock here, because the window 10629 // manager calls in with its locks held. 10630 10631 boolean killed = false; 10632 synchronized (mPidsSelfLocked) { 10633 int[] types = new int[pids.length]; 10634 int worstType = 0; 10635 for (int i=0; i<pids.length; i++) { 10636 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10637 if (proc != null) { 10638 int type = proc.setAdj; 10639 types[i] = type; 10640 if (type > worstType) { 10641 worstType = type; 10642 } 10643 } 10644 } 10645 10646 // If the worst oom_adj is somewhere in the cached proc LRU range, 10647 // then constrain it so we will kill all cached procs. 10648 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10649 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10650 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10651 } 10652 10653 // If this is not a secure call, don't let it kill processes that 10654 // are important. 10655 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10656 worstType = ProcessList.SERVICE_ADJ; 10657 } 10658 10659 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10660 for (int i=0; i<pids.length; i++) { 10661 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10662 if (proc == null) { 10663 continue; 10664 } 10665 int adj = proc.setAdj; 10666 if (adj >= worstType && !proc.killedByAm) { 10667 proc.kill(reason, true); 10668 killed = true; 10669 } 10670 } 10671 } 10672 return killed; 10673 } 10674 10675 @Override 10676 public void killUid(int uid, String reason) { 10677 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10678 throw new SecurityException("killUid only available to the system"); 10679 } 10680 synchronized (this) { 10681 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10682 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10683 reason != null ? reason : "kill uid"); 10684 } 10685 } 10686 10687 @Override 10688 public boolean killProcessesBelowForeground(String reason) { 10689 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10690 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10691 } 10692 10693 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10694 } 10695 10696 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10697 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10698 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10699 } 10700 10701 boolean killed = false; 10702 synchronized (mPidsSelfLocked) { 10703 final int size = mPidsSelfLocked.size(); 10704 for (int i = 0; i < size; i++) { 10705 final int pid = mPidsSelfLocked.keyAt(i); 10706 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10707 if (proc == null) continue; 10708 10709 final int adj = proc.setAdj; 10710 if (adj > belowAdj && !proc.killedByAm) { 10711 proc.kill(reason, true); 10712 killed = true; 10713 } 10714 } 10715 } 10716 return killed; 10717 } 10718 10719 @Override 10720 public void hang(final IBinder who, boolean allowRestart) { 10721 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10722 != PackageManager.PERMISSION_GRANTED) { 10723 throw new SecurityException("Requires permission " 10724 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10725 } 10726 10727 final IBinder.DeathRecipient death = new DeathRecipient() { 10728 @Override 10729 public void binderDied() { 10730 synchronized (this) { 10731 notifyAll(); 10732 } 10733 } 10734 }; 10735 10736 try { 10737 who.linkToDeath(death, 0); 10738 } catch (RemoteException e) { 10739 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10740 return; 10741 } 10742 10743 synchronized (this) { 10744 Watchdog.getInstance().setAllowRestart(allowRestart); 10745 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10746 synchronized (death) { 10747 while (who.isBinderAlive()) { 10748 try { 10749 death.wait(); 10750 } catch (InterruptedException e) { 10751 } 10752 } 10753 } 10754 Watchdog.getInstance().setAllowRestart(true); 10755 } 10756 } 10757 10758 @Override 10759 public void restart() { 10760 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10761 != PackageManager.PERMISSION_GRANTED) { 10762 throw new SecurityException("Requires permission " 10763 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10764 } 10765 10766 Log.i(TAG, "Sending shutdown broadcast..."); 10767 10768 BroadcastReceiver br = new BroadcastReceiver() { 10769 @Override public void onReceive(Context context, Intent intent) { 10770 // Now the broadcast is done, finish up the low-level shutdown. 10771 Log.i(TAG, "Shutting down activity manager..."); 10772 shutdown(10000); 10773 Log.i(TAG, "Shutdown complete, restarting!"); 10774 Process.killProcess(Process.myPid()); 10775 System.exit(10); 10776 } 10777 }; 10778 10779 // First send the high-level shut down broadcast. 10780 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10781 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10782 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10783 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10784 mContext.sendOrderedBroadcastAsUser(intent, 10785 UserHandle.ALL, null, br, mHandler, 0, null, null); 10786 */ 10787 br.onReceive(mContext, intent); 10788 } 10789 10790 private long getLowRamTimeSinceIdle(long now) { 10791 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10792 } 10793 10794 @Override 10795 public void performIdleMaintenance() { 10796 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10797 != PackageManager.PERMISSION_GRANTED) { 10798 throw new SecurityException("Requires permission " 10799 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10800 } 10801 10802 synchronized (this) { 10803 final long now = SystemClock.uptimeMillis(); 10804 final long timeSinceLastIdle = now - mLastIdleTime; 10805 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10806 mLastIdleTime = now; 10807 mLowRamTimeSinceLastIdle = 0; 10808 if (mLowRamStartTime != 0) { 10809 mLowRamStartTime = now; 10810 } 10811 10812 StringBuilder sb = new StringBuilder(128); 10813 sb.append("Idle maintenance over "); 10814 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10815 sb.append(" low RAM for "); 10816 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10817 Slog.i(TAG, sb.toString()); 10818 10819 // If at least 1/3 of our time since the last idle period has been spent 10820 // with RAM low, then we want to kill processes. 10821 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10822 10823 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10824 ProcessRecord proc = mLruProcesses.get(i); 10825 if (proc.notCachedSinceIdle) { 10826 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10827 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10828 if (doKilling && proc.initialIdlePss != 0 10829 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10830 proc.kill("idle maint (pss " + proc.lastPss 10831 + " from " + proc.initialIdlePss + ")", true); 10832 } 10833 } 10834 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10835 proc.notCachedSinceIdle = true; 10836 proc.initialIdlePss = 0; 10837 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10838 isSleeping(), now); 10839 } 10840 } 10841 10842 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10843 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10844 } 10845 } 10846 10847 private void retrieveSettings() { 10848 final ContentResolver resolver = mContext.getContentResolver(); 10849 String debugApp = Settings.Global.getString( 10850 resolver, Settings.Global.DEBUG_APP); 10851 boolean waitForDebugger = Settings.Global.getInt( 10852 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10853 boolean alwaysFinishActivities = Settings.Global.getInt( 10854 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10855 boolean forceRtl = Settings.Global.getInt( 10856 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10857 // Transfer any global setting for forcing RTL layout, into a System Property 10858 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10859 10860 Configuration configuration = new Configuration(); 10861 Settings.System.getConfiguration(resolver, configuration); 10862 if (forceRtl) { 10863 // This will take care of setting the correct layout direction flags 10864 configuration.setLayoutDirection(configuration.locale); 10865 } 10866 10867 synchronized (this) { 10868 mDebugApp = mOrigDebugApp = debugApp; 10869 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10870 mAlwaysFinishActivities = alwaysFinishActivities; 10871 // This happens before any activities are started, so we can 10872 // change mConfiguration in-place. 10873 updateConfigurationLocked(configuration, null, false, true); 10874 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10875 } 10876 } 10877 10878 /** Loads resources after the current configuration has been set. */ 10879 private void loadResourcesOnSystemReady() { 10880 final Resources res = mContext.getResources(); 10881 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10882 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10883 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10884 } 10885 10886 public boolean testIsSystemReady() { 10887 // no need to synchronize(this) just to read & return the value 10888 return mSystemReady; 10889 } 10890 10891 private static File getCalledPreBootReceiversFile() { 10892 File dataDir = Environment.getDataDirectory(); 10893 File systemDir = new File(dataDir, "system"); 10894 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10895 return fname; 10896 } 10897 10898 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10899 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10900 File file = getCalledPreBootReceiversFile(); 10901 FileInputStream fis = null; 10902 try { 10903 fis = new FileInputStream(file); 10904 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10905 int fvers = dis.readInt(); 10906 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10907 String vers = dis.readUTF(); 10908 String codename = dis.readUTF(); 10909 String build = dis.readUTF(); 10910 if (android.os.Build.VERSION.RELEASE.equals(vers) 10911 && android.os.Build.VERSION.CODENAME.equals(codename) 10912 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10913 int num = dis.readInt(); 10914 while (num > 0) { 10915 num--; 10916 String pkg = dis.readUTF(); 10917 String cls = dis.readUTF(); 10918 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10919 } 10920 } 10921 } 10922 } catch (FileNotFoundException e) { 10923 } catch (IOException e) { 10924 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10925 } finally { 10926 if (fis != null) { 10927 try { 10928 fis.close(); 10929 } catch (IOException e) { 10930 } 10931 } 10932 } 10933 return lastDoneReceivers; 10934 } 10935 10936 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10937 File file = getCalledPreBootReceiversFile(); 10938 FileOutputStream fos = null; 10939 DataOutputStream dos = null; 10940 try { 10941 fos = new FileOutputStream(file); 10942 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10943 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10944 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10945 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10946 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10947 dos.writeInt(list.size()); 10948 for (int i=0; i<list.size(); i++) { 10949 dos.writeUTF(list.get(i).getPackageName()); 10950 dos.writeUTF(list.get(i).getClassName()); 10951 } 10952 } catch (IOException e) { 10953 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10954 file.delete(); 10955 } finally { 10956 FileUtils.sync(fos); 10957 if (dos != null) { 10958 try { 10959 dos.close(); 10960 } catch (IOException e) { 10961 // TODO Auto-generated catch block 10962 e.printStackTrace(); 10963 } 10964 } 10965 } 10966 } 10967 10968 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10969 ArrayList<ComponentName> doneReceivers, int userId) { 10970 boolean waitingUpdate = false; 10971 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10972 List<ResolveInfo> ris = null; 10973 try { 10974 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10975 intent, null, 0, userId); 10976 } catch (RemoteException e) { 10977 } 10978 if (ris != null) { 10979 for (int i=ris.size()-1; i>=0; i--) { 10980 if ((ris.get(i).activityInfo.applicationInfo.flags 10981 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10982 ris.remove(i); 10983 } 10984 } 10985 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10986 10987 // For User 0, load the version number. When delivering to a new user, deliver 10988 // to all receivers. 10989 if (userId == UserHandle.USER_OWNER) { 10990 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10991 for (int i=0; i<ris.size(); i++) { 10992 ActivityInfo ai = ris.get(i).activityInfo; 10993 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10994 if (lastDoneReceivers.contains(comp)) { 10995 // We already did the pre boot receiver for this app with the current 10996 // platform version, so don't do it again... 10997 ris.remove(i); 10998 i--; 10999 // ...however, do keep it as one that has been done, so we don't 11000 // forget about it when rewriting the file of last done receivers. 11001 doneReceivers.add(comp); 11002 } 11003 } 11004 } 11005 11006 // If primary user, send broadcast to all available users, else just to userId 11007 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11008 : new int[] { userId }; 11009 for (int i = 0; i < ris.size(); i++) { 11010 ActivityInfo ai = ris.get(i).activityInfo; 11011 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11012 doneReceivers.add(comp); 11013 intent.setComponent(comp); 11014 for (int j=0; j<users.length; j++) { 11015 IIntentReceiver finisher = null; 11016 // On last receiver and user, set up a completion callback 11017 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11018 finisher = new IIntentReceiver.Stub() { 11019 public void performReceive(Intent intent, int resultCode, 11020 String data, Bundle extras, boolean ordered, 11021 boolean sticky, int sendingUser) { 11022 // The raw IIntentReceiver interface is called 11023 // with the AM lock held, so redispatch to 11024 // execute our code without the lock. 11025 mHandler.post(onFinishCallback); 11026 } 11027 }; 11028 } 11029 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11030 + " for user " + users[j]); 11031 broadcastIntentLocked(null, null, intent, null, finisher, 11032 0, null, null, null, AppOpsManager.OP_NONE, 11033 true, false, MY_PID, Process.SYSTEM_UID, 11034 users[j]); 11035 if (finisher != null) { 11036 waitingUpdate = true; 11037 } 11038 } 11039 } 11040 } 11041 11042 return waitingUpdate; 11043 } 11044 11045 public void systemReady(final Runnable goingCallback) { 11046 synchronized(this) { 11047 if (mSystemReady) { 11048 // If we're done calling all the receivers, run the next "boot phase" passed in 11049 // by the SystemServer 11050 if (goingCallback != null) { 11051 goingCallback.run(); 11052 } 11053 return; 11054 } 11055 11056 // Make sure we have the current profile info, since it is needed for 11057 // security checks. 11058 updateCurrentProfileIdsLocked(); 11059 11060 if (mRecentTasks == null) { 11061 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11062 if (!mRecentTasks.isEmpty()) { 11063 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11064 } 11065 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11066 mTaskPersister.startPersisting(); 11067 } 11068 11069 // Check to see if there are any update receivers to run. 11070 if (!mDidUpdate) { 11071 if (mWaitingUpdate) { 11072 return; 11073 } 11074 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11075 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11076 public void run() { 11077 synchronized (ActivityManagerService.this) { 11078 mDidUpdate = true; 11079 } 11080 writeLastDonePreBootReceivers(doneReceivers); 11081 showBootMessage(mContext.getText( 11082 R.string.android_upgrading_complete), 11083 false); 11084 systemReady(goingCallback); 11085 } 11086 }, doneReceivers, UserHandle.USER_OWNER); 11087 11088 if (mWaitingUpdate) { 11089 return; 11090 } 11091 mDidUpdate = true; 11092 } 11093 11094 mAppOpsService.systemReady(); 11095 mSystemReady = true; 11096 } 11097 11098 ArrayList<ProcessRecord> procsToKill = null; 11099 synchronized(mPidsSelfLocked) { 11100 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11101 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11102 if (!isAllowedWhileBooting(proc.info)){ 11103 if (procsToKill == null) { 11104 procsToKill = new ArrayList<ProcessRecord>(); 11105 } 11106 procsToKill.add(proc); 11107 } 11108 } 11109 } 11110 11111 synchronized(this) { 11112 if (procsToKill != null) { 11113 for (int i=procsToKill.size()-1; i>=0; i--) { 11114 ProcessRecord proc = procsToKill.get(i); 11115 Slog.i(TAG, "Removing system update proc: " + proc); 11116 removeProcessLocked(proc, true, false, "system update done"); 11117 } 11118 } 11119 11120 // Now that we have cleaned up any update processes, we 11121 // are ready to start launching real processes and know that 11122 // we won't trample on them any more. 11123 mProcessesReady = true; 11124 } 11125 11126 Slog.i(TAG, "System now ready"); 11127 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11128 SystemClock.uptimeMillis()); 11129 11130 synchronized(this) { 11131 // Make sure we have no pre-ready processes sitting around. 11132 11133 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11134 ResolveInfo ri = mContext.getPackageManager() 11135 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11136 STOCK_PM_FLAGS); 11137 CharSequence errorMsg = null; 11138 if (ri != null) { 11139 ActivityInfo ai = ri.activityInfo; 11140 ApplicationInfo app = ai.applicationInfo; 11141 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11142 mTopAction = Intent.ACTION_FACTORY_TEST; 11143 mTopData = null; 11144 mTopComponent = new ComponentName(app.packageName, 11145 ai.name); 11146 } else { 11147 errorMsg = mContext.getResources().getText( 11148 com.android.internal.R.string.factorytest_not_system); 11149 } 11150 } else { 11151 errorMsg = mContext.getResources().getText( 11152 com.android.internal.R.string.factorytest_no_action); 11153 } 11154 if (errorMsg != null) { 11155 mTopAction = null; 11156 mTopData = null; 11157 mTopComponent = null; 11158 Message msg = Message.obtain(); 11159 msg.what = SHOW_FACTORY_ERROR_MSG; 11160 msg.getData().putCharSequence("msg", errorMsg); 11161 mHandler.sendMessage(msg); 11162 } 11163 } 11164 } 11165 11166 retrieveSettings(); 11167 loadResourcesOnSystemReady(); 11168 11169 synchronized (this) { 11170 readGrantedUriPermissionsLocked(); 11171 } 11172 11173 if (goingCallback != null) goingCallback.run(); 11174 11175 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11176 Integer.toString(mCurrentUserId), mCurrentUserId); 11177 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11178 Integer.toString(mCurrentUserId), mCurrentUserId); 11179 mSystemServiceManager.startUser(mCurrentUserId); 11180 11181 synchronized (this) { 11182 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11183 try { 11184 List apps = AppGlobals.getPackageManager(). 11185 getPersistentApplications(STOCK_PM_FLAGS); 11186 if (apps != null) { 11187 int N = apps.size(); 11188 int i; 11189 for (i=0; i<N; i++) { 11190 ApplicationInfo info 11191 = (ApplicationInfo)apps.get(i); 11192 if (info != null && 11193 !info.packageName.equals("android")) { 11194 addAppLocked(info, false, null /* ABI override */); 11195 } 11196 } 11197 } 11198 } catch (RemoteException ex) { 11199 // pm is in same process, this will never happen. 11200 } 11201 } 11202 11203 // Start up initial activity. 11204 mBooting = true; 11205 startHomeActivityLocked(mCurrentUserId); 11206 11207 try { 11208 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11209 Message msg = Message.obtain(); 11210 msg.what = SHOW_UID_ERROR_MSG; 11211 mHandler.sendMessage(msg); 11212 } 11213 } catch (RemoteException e) { 11214 } 11215 11216 long ident = Binder.clearCallingIdentity(); 11217 try { 11218 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11219 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11220 | Intent.FLAG_RECEIVER_FOREGROUND); 11221 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11222 broadcastIntentLocked(null, null, intent, 11223 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11224 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11225 intent = new Intent(Intent.ACTION_USER_STARTING); 11226 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11227 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11228 broadcastIntentLocked(null, null, intent, 11229 null, new IIntentReceiver.Stub() { 11230 @Override 11231 public void performReceive(Intent intent, int resultCode, String data, 11232 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11233 throws RemoteException { 11234 } 11235 }, 0, null, null, 11236 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11237 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11238 } catch (Throwable t) { 11239 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11240 } finally { 11241 Binder.restoreCallingIdentity(ident); 11242 } 11243 mStackSupervisor.resumeTopActivitiesLocked(); 11244 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11245 } 11246 } 11247 11248 private boolean makeAppCrashingLocked(ProcessRecord app, 11249 String shortMsg, String longMsg, String stackTrace) { 11250 app.crashing = true; 11251 app.crashingReport = generateProcessError(app, 11252 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11253 startAppProblemLocked(app); 11254 app.stopFreezingAllLocked(); 11255 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11256 } 11257 11258 private void makeAppNotRespondingLocked(ProcessRecord app, 11259 String activity, String shortMsg, String longMsg) { 11260 app.notResponding = true; 11261 app.notRespondingReport = generateProcessError(app, 11262 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11263 activity, shortMsg, longMsg, null); 11264 startAppProblemLocked(app); 11265 app.stopFreezingAllLocked(); 11266 } 11267 11268 /** 11269 * Generate a process error record, suitable for attachment to a ProcessRecord. 11270 * 11271 * @param app The ProcessRecord in which the error occurred. 11272 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11273 * ActivityManager.AppErrorStateInfo 11274 * @param activity The activity associated with the crash, if known. 11275 * @param shortMsg Short message describing the crash. 11276 * @param longMsg Long message describing the crash. 11277 * @param stackTrace Full crash stack trace, may be null. 11278 * 11279 * @return Returns a fully-formed AppErrorStateInfo record. 11280 */ 11281 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11282 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11283 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11284 11285 report.condition = condition; 11286 report.processName = app.processName; 11287 report.pid = app.pid; 11288 report.uid = app.info.uid; 11289 report.tag = activity; 11290 report.shortMsg = shortMsg; 11291 report.longMsg = longMsg; 11292 report.stackTrace = stackTrace; 11293 11294 return report; 11295 } 11296 11297 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11298 synchronized (this) { 11299 app.crashing = false; 11300 app.crashingReport = null; 11301 app.notResponding = false; 11302 app.notRespondingReport = null; 11303 if (app.anrDialog == fromDialog) { 11304 app.anrDialog = null; 11305 } 11306 if (app.waitDialog == fromDialog) { 11307 app.waitDialog = null; 11308 } 11309 if (app.pid > 0 && app.pid != MY_PID) { 11310 handleAppCrashLocked(app, null, null, null); 11311 app.kill("user request after error", true); 11312 } 11313 } 11314 } 11315 11316 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11317 String stackTrace) { 11318 long now = SystemClock.uptimeMillis(); 11319 11320 Long crashTime; 11321 if (!app.isolated) { 11322 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11323 } else { 11324 crashTime = null; 11325 } 11326 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11327 // This process loses! 11328 Slog.w(TAG, "Process " + app.info.processName 11329 + " has crashed too many times: killing!"); 11330 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11331 app.userId, app.info.processName, app.uid); 11332 mStackSupervisor.handleAppCrashLocked(app); 11333 if (!app.persistent) { 11334 // We don't want to start this process again until the user 11335 // explicitly does so... but for persistent process, we really 11336 // need to keep it running. If a persistent process is actually 11337 // repeatedly crashing, then badness for everyone. 11338 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11339 app.info.processName); 11340 if (!app.isolated) { 11341 // XXX We don't have a way to mark isolated processes 11342 // as bad, since they don't have a peristent identity. 11343 mBadProcesses.put(app.info.processName, app.uid, 11344 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11345 mProcessCrashTimes.remove(app.info.processName, app.uid); 11346 } 11347 app.bad = true; 11348 app.removed = true; 11349 // Don't let services in this process be restarted and potentially 11350 // annoy the user repeatedly. Unless it is persistent, since those 11351 // processes run critical code. 11352 removeProcessLocked(app, false, false, "crash"); 11353 mStackSupervisor.resumeTopActivitiesLocked(); 11354 return false; 11355 } 11356 mStackSupervisor.resumeTopActivitiesLocked(); 11357 } else { 11358 mStackSupervisor.finishTopRunningActivityLocked(app); 11359 } 11360 11361 // Bump up the crash count of any services currently running in the proc. 11362 for (int i=app.services.size()-1; i>=0; i--) { 11363 // Any services running in the application need to be placed 11364 // back in the pending list. 11365 ServiceRecord sr = app.services.valueAt(i); 11366 sr.crashCount++; 11367 } 11368 11369 // If the crashing process is what we consider to be the "home process" and it has been 11370 // replaced by a third-party app, clear the package preferred activities from packages 11371 // with a home activity running in the process to prevent a repeatedly crashing app 11372 // from blocking the user to manually clear the list. 11373 final ArrayList<ActivityRecord> activities = app.activities; 11374 if (app == mHomeProcess && activities.size() > 0 11375 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11376 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11377 final ActivityRecord r = activities.get(activityNdx); 11378 if (r.isHomeActivity()) { 11379 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11380 try { 11381 ActivityThread.getPackageManager() 11382 .clearPackagePreferredActivities(r.packageName); 11383 } catch (RemoteException c) { 11384 // pm is in same process, this will never happen. 11385 } 11386 } 11387 } 11388 } 11389 11390 if (!app.isolated) { 11391 // XXX Can't keep track of crash times for isolated processes, 11392 // because they don't have a perisistent identity. 11393 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11394 } 11395 11396 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11397 return true; 11398 } 11399 11400 void startAppProblemLocked(ProcessRecord app) { 11401 // If this app is not running under the current user, then we 11402 // can't give it a report button because that would require 11403 // launching the report UI under a different user. 11404 app.errorReportReceiver = null; 11405 11406 for (int userId : mCurrentProfileIds) { 11407 if (app.userId == userId) { 11408 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11409 mContext, app.info.packageName, app.info.flags); 11410 } 11411 } 11412 skipCurrentReceiverLocked(app); 11413 } 11414 11415 void skipCurrentReceiverLocked(ProcessRecord app) { 11416 for (BroadcastQueue queue : mBroadcastQueues) { 11417 queue.skipCurrentReceiverLocked(app); 11418 } 11419 } 11420 11421 /** 11422 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11423 * The application process will exit immediately after this call returns. 11424 * @param app object of the crashing app, null for the system server 11425 * @param crashInfo describing the exception 11426 */ 11427 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11428 ProcessRecord r = findAppProcess(app, "Crash"); 11429 final String processName = app == null ? "system_server" 11430 : (r == null ? "unknown" : r.processName); 11431 11432 handleApplicationCrashInner("crash", r, processName, crashInfo); 11433 } 11434 11435 /* Native crash reporting uses this inner version because it needs to be somewhat 11436 * decoupled from the AM-managed cleanup lifecycle 11437 */ 11438 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11439 ApplicationErrorReport.CrashInfo crashInfo) { 11440 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11441 UserHandle.getUserId(Binder.getCallingUid()), processName, 11442 r == null ? -1 : r.info.flags, 11443 crashInfo.exceptionClassName, 11444 crashInfo.exceptionMessage, 11445 crashInfo.throwFileName, 11446 crashInfo.throwLineNumber); 11447 11448 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11449 11450 crashApplication(r, crashInfo); 11451 } 11452 11453 public void handleApplicationStrictModeViolation( 11454 IBinder app, 11455 int violationMask, 11456 StrictMode.ViolationInfo info) { 11457 ProcessRecord r = findAppProcess(app, "StrictMode"); 11458 if (r == null) { 11459 return; 11460 } 11461 11462 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11463 Integer stackFingerprint = info.hashCode(); 11464 boolean logIt = true; 11465 synchronized (mAlreadyLoggedViolatedStacks) { 11466 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11467 logIt = false; 11468 // TODO: sub-sample into EventLog for these, with 11469 // the info.durationMillis? Then we'd get 11470 // the relative pain numbers, without logging all 11471 // the stack traces repeatedly. We'd want to do 11472 // likewise in the client code, which also does 11473 // dup suppression, before the Binder call. 11474 } else { 11475 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11476 mAlreadyLoggedViolatedStacks.clear(); 11477 } 11478 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11479 } 11480 } 11481 if (logIt) { 11482 logStrictModeViolationToDropBox(r, info); 11483 } 11484 } 11485 11486 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11487 AppErrorResult result = new AppErrorResult(); 11488 synchronized (this) { 11489 final long origId = Binder.clearCallingIdentity(); 11490 11491 Message msg = Message.obtain(); 11492 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11493 HashMap<String, Object> data = new HashMap<String, Object>(); 11494 data.put("result", result); 11495 data.put("app", r); 11496 data.put("violationMask", violationMask); 11497 data.put("info", info); 11498 msg.obj = data; 11499 mHandler.sendMessage(msg); 11500 11501 Binder.restoreCallingIdentity(origId); 11502 } 11503 int res = result.get(); 11504 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11505 } 11506 } 11507 11508 // Depending on the policy in effect, there could be a bunch of 11509 // these in quick succession so we try to batch these together to 11510 // minimize disk writes, number of dropbox entries, and maximize 11511 // compression, by having more fewer, larger records. 11512 private void logStrictModeViolationToDropBox( 11513 ProcessRecord process, 11514 StrictMode.ViolationInfo info) { 11515 if (info == null) { 11516 return; 11517 } 11518 final boolean isSystemApp = process == null || 11519 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11520 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11521 final String processName = process == null ? "unknown" : process.processName; 11522 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11523 final DropBoxManager dbox = (DropBoxManager) 11524 mContext.getSystemService(Context.DROPBOX_SERVICE); 11525 11526 // Exit early if the dropbox isn't configured to accept this report type. 11527 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11528 11529 boolean bufferWasEmpty; 11530 boolean needsFlush; 11531 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11532 synchronized (sb) { 11533 bufferWasEmpty = sb.length() == 0; 11534 appendDropBoxProcessHeaders(process, processName, sb); 11535 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11536 sb.append("System-App: ").append(isSystemApp).append("\n"); 11537 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11538 if (info.violationNumThisLoop != 0) { 11539 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11540 } 11541 if (info.numAnimationsRunning != 0) { 11542 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11543 } 11544 if (info.broadcastIntentAction != null) { 11545 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11546 } 11547 if (info.durationMillis != -1) { 11548 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11549 } 11550 if (info.numInstances != -1) { 11551 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11552 } 11553 if (info.tags != null) { 11554 for (String tag : info.tags) { 11555 sb.append("Span-Tag: ").append(tag).append("\n"); 11556 } 11557 } 11558 sb.append("\n"); 11559 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11560 sb.append(info.crashInfo.stackTrace); 11561 } 11562 sb.append("\n"); 11563 11564 // Only buffer up to ~64k. Various logging bits truncate 11565 // things at 128k. 11566 needsFlush = (sb.length() > 64 * 1024); 11567 } 11568 11569 // Flush immediately if the buffer's grown too large, or this 11570 // is a non-system app. Non-system apps are isolated with a 11571 // different tag & policy and not batched. 11572 // 11573 // Batching is useful during internal testing with 11574 // StrictMode settings turned up high. Without batching, 11575 // thousands of separate files could be created on boot. 11576 if (!isSystemApp || needsFlush) { 11577 new Thread("Error dump: " + dropboxTag) { 11578 @Override 11579 public void run() { 11580 String report; 11581 synchronized (sb) { 11582 report = sb.toString(); 11583 sb.delete(0, sb.length()); 11584 sb.trimToSize(); 11585 } 11586 if (report.length() != 0) { 11587 dbox.addText(dropboxTag, report); 11588 } 11589 } 11590 }.start(); 11591 return; 11592 } 11593 11594 // System app batching: 11595 if (!bufferWasEmpty) { 11596 // An existing dropbox-writing thread is outstanding, so 11597 // we don't need to start it up. The existing thread will 11598 // catch the buffer appends we just did. 11599 return; 11600 } 11601 11602 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11603 // (After this point, we shouldn't access AMS internal data structures.) 11604 new Thread("Error dump: " + dropboxTag) { 11605 @Override 11606 public void run() { 11607 // 5 second sleep to let stacks arrive and be batched together 11608 try { 11609 Thread.sleep(5000); // 5 seconds 11610 } catch (InterruptedException e) {} 11611 11612 String errorReport; 11613 synchronized (mStrictModeBuffer) { 11614 errorReport = mStrictModeBuffer.toString(); 11615 if (errorReport.length() == 0) { 11616 return; 11617 } 11618 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11619 mStrictModeBuffer.trimToSize(); 11620 } 11621 dbox.addText(dropboxTag, errorReport); 11622 } 11623 }.start(); 11624 } 11625 11626 /** 11627 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11628 * @param app object of the crashing app, null for the system server 11629 * @param tag reported by the caller 11630 * @param system whether this wtf is coming from the system 11631 * @param crashInfo describing the context of the error 11632 * @return true if the process should exit immediately (WTF is fatal) 11633 */ 11634 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11635 final ApplicationErrorReport.CrashInfo crashInfo) { 11636 final int callingUid = Binder.getCallingUid(); 11637 final int callingPid = Binder.getCallingPid(); 11638 11639 if (system) { 11640 // If this is coming from the system, we could very well have low-level 11641 // system locks held, so we want to do this all asynchronously. And we 11642 // never want this to become fatal, so there is that too. 11643 mHandler.post(new Runnable() { 11644 @Override public void run() { 11645 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11646 } 11647 }); 11648 return false; 11649 } 11650 11651 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11652 crashInfo); 11653 11654 if (r != null && r.pid != Process.myPid() && 11655 Settings.Global.getInt(mContext.getContentResolver(), 11656 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11657 crashApplication(r, crashInfo); 11658 return true; 11659 } else { 11660 return false; 11661 } 11662 } 11663 11664 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11665 final ApplicationErrorReport.CrashInfo crashInfo) { 11666 final ProcessRecord r = findAppProcess(app, "WTF"); 11667 final String processName = app == null ? "system_server" 11668 : (r == null ? "unknown" : r.processName); 11669 11670 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11671 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11672 11673 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11674 11675 return r; 11676 } 11677 11678 /** 11679 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11680 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11681 */ 11682 private ProcessRecord findAppProcess(IBinder app, String reason) { 11683 if (app == null) { 11684 return null; 11685 } 11686 11687 synchronized (this) { 11688 final int NP = mProcessNames.getMap().size(); 11689 for (int ip=0; ip<NP; ip++) { 11690 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11691 final int NA = apps.size(); 11692 for (int ia=0; ia<NA; ia++) { 11693 ProcessRecord p = apps.valueAt(ia); 11694 if (p.thread != null && p.thread.asBinder() == app) { 11695 return p; 11696 } 11697 } 11698 } 11699 11700 Slog.w(TAG, "Can't find mystery application for " + reason 11701 + " from pid=" + Binder.getCallingPid() 11702 + " uid=" + Binder.getCallingUid() + ": " + app); 11703 return null; 11704 } 11705 } 11706 11707 /** 11708 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11709 * to append various headers to the dropbox log text. 11710 */ 11711 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11712 StringBuilder sb) { 11713 // Watchdog thread ends up invoking this function (with 11714 // a null ProcessRecord) to add the stack file to dropbox. 11715 // Do not acquire a lock on this (am) in such cases, as it 11716 // could cause a potential deadlock, if and when watchdog 11717 // is invoked due to unavailability of lock on am and it 11718 // would prevent watchdog from killing system_server. 11719 if (process == null) { 11720 sb.append("Process: ").append(processName).append("\n"); 11721 return; 11722 } 11723 // Note: ProcessRecord 'process' is guarded by the service 11724 // instance. (notably process.pkgList, which could otherwise change 11725 // concurrently during execution of this method) 11726 synchronized (this) { 11727 sb.append("Process: ").append(processName).append("\n"); 11728 int flags = process.info.flags; 11729 IPackageManager pm = AppGlobals.getPackageManager(); 11730 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11731 for (int ip=0; ip<process.pkgList.size(); ip++) { 11732 String pkg = process.pkgList.keyAt(ip); 11733 sb.append("Package: ").append(pkg); 11734 try { 11735 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11736 if (pi != null) { 11737 sb.append(" v").append(pi.versionCode); 11738 if (pi.versionName != null) { 11739 sb.append(" (").append(pi.versionName).append(")"); 11740 } 11741 } 11742 } catch (RemoteException e) { 11743 Slog.e(TAG, "Error getting package info: " + pkg, e); 11744 } 11745 sb.append("\n"); 11746 } 11747 } 11748 } 11749 11750 private static String processClass(ProcessRecord process) { 11751 if (process == null || process.pid == MY_PID) { 11752 return "system_server"; 11753 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11754 return "system_app"; 11755 } else { 11756 return "data_app"; 11757 } 11758 } 11759 11760 /** 11761 * Write a description of an error (crash, WTF, ANR) to the drop box. 11762 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11763 * @param process which caused the error, null means the system server 11764 * @param activity which triggered the error, null if unknown 11765 * @param parent activity related to the error, null if unknown 11766 * @param subject line related to the error, null if absent 11767 * @param report in long form describing the error, null if absent 11768 * @param logFile to include in the report, null if none 11769 * @param crashInfo giving an application stack trace, null if absent 11770 */ 11771 public void addErrorToDropBox(String eventType, 11772 ProcessRecord process, String processName, ActivityRecord activity, 11773 ActivityRecord parent, String subject, 11774 final String report, final File logFile, 11775 final ApplicationErrorReport.CrashInfo crashInfo) { 11776 // NOTE -- this must never acquire the ActivityManagerService lock, 11777 // otherwise the watchdog may be prevented from resetting the system. 11778 11779 final String dropboxTag = processClass(process) + "_" + eventType; 11780 final DropBoxManager dbox = (DropBoxManager) 11781 mContext.getSystemService(Context.DROPBOX_SERVICE); 11782 11783 // Exit early if the dropbox isn't configured to accept this report type. 11784 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11785 11786 final StringBuilder sb = new StringBuilder(1024); 11787 appendDropBoxProcessHeaders(process, processName, sb); 11788 if (activity != null) { 11789 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11790 } 11791 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11792 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11793 } 11794 if (parent != null && parent != activity) { 11795 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11796 } 11797 if (subject != null) { 11798 sb.append("Subject: ").append(subject).append("\n"); 11799 } 11800 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11801 if (Debug.isDebuggerConnected()) { 11802 sb.append("Debugger: Connected\n"); 11803 } 11804 sb.append("\n"); 11805 11806 // Do the rest in a worker thread to avoid blocking the caller on I/O 11807 // (After this point, we shouldn't access AMS internal data structures.) 11808 Thread worker = new Thread("Error dump: " + dropboxTag) { 11809 @Override 11810 public void run() { 11811 if (report != null) { 11812 sb.append(report); 11813 } 11814 if (logFile != null) { 11815 try { 11816 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11817 "\n\n[[TRUNCATED]]")); 11818 } catch (IOException e) { 11819 Slog.e(TAG, "Error reading " + logFile, e); 11820 } 11821 } 11822 if (crashInfo != null && crashInfo.stackTrace != null) { 11823 sb.append(crashInfo.stackTrace); 11824 } 11825 11826 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11827 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11828 if (lines > 0) { 11829 sb.append("\n"); 11830 11831 // Merge several logcat streams, and take the last N lines 11832 InputStreamReader input = null; 11833 try { 11834 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11835 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11836 "-b", "crash", 11837 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11838 11839 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11840 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11841 input = new InputStreamReader(logcat.getInputStream()); 11842 11843 int num; 11844 char[] buf = new char[8192]; 11845 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11846 } catch (IOException e) { 11847 Slog.e(TAG, "Error running logcat", e); 11848 } finally { 11849 if (input != null) try { input.close(); } catch (IOException e) {} 11850 } 11851 } 11852 11853 dbox.addText(dropboxTag, sb.toString()); 11854 } 11855 }; 11856 11857 if (process == null) { 11858 // If process is null, we are being called from some internal code 11859 // and may be about to die -- run this synchronously. 11860 worker.run(); 11861 } else { 11862 worker.start(); 11863 } 11864 } 11865 11866 /** 11867 * Bring up the "unexpected error" dialog box for a crashing app. 11868 * Deal with edge cases (intercepts from instrumented applications, 11869 * ActivityController, error intent receivers, that sort of thing). 11870 * @param r the application crashing 11871 * @param crashInfo describing the failure 11872 */ 11873 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11874 long timeMillis = System.currentTimeMillis(); 11875 String shortMsg = crashInfo.exceptionClassName; 11876 String longMsg = crashInfo.exceptionMessage; 11877 String stackTrace = crashInfo.stackTrace; 11878 if (shortMsg != null && longMsg != null) { 11879 longMsg = shortMsg + ": " + longMsg; 11880 } else if (shortMsg != null) { 11881 longMsg = shortMsg; 11882 } 11883 11884 AppErrorResult result = new AppErrorResult(); 11885 synchronized (this) { 11886 if (mController != null) { 11887 try { 11888 String name = r != null ? r.processName : null; 11889 int pid = r != null ? r.pid : Binder.getCallingPid(); 11890 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11891 if (!mController.appCrashed(name, pid, 11892 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11893 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11894 && "Native crash".equals(crashInfo.exceptionClassName)) { 11895 Slog.w(TAG, "Skip killing native crashed app " + name 11896 + "(" + pid + ") during testing"); 11897 } else { 11898 Slog.w(TAG, "Force-killing crashed app " + name 11899 + " at watcher's request"); 11900 if (r != null) { 11901 r.kill("crash", true); 11902 } else { 11903 // Huh. 11904 Process.killProcess(pid); 11905 Process.killProcessGroup(uid, pid); 11906 } 11907 } 11908 return; 11909 } 11910 } catch (RemoteException e) { 11911 mController = null; 11912 Watchdog.getInstance().setActivityController(null); 11913 } 11914 } 11915 11916 final long origId = Binder.clearCallingIdentity(); 11917 11918 // If this process is running instrumentation, finish it. 11919 if (r != null && r.instrumentationClass != null) { 11920 Slog.w(TAG, "Error in app " + r.processName 11921 + " running instrumentation " + r.instrumentationClass + ":"); 11922 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11923 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11924 Bundle info = new Bundle(); 11925 info.putString("shortMsg", shortMsg); 11926 info.putString("longMsg", longMsg); 11927 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11928 Binder.restoreCallingIdentity(origId); 11929 return; 11930 } 11931 11932 // If we can't identify the process or it's already exceeded its crash quota, 11933 // quit right away without showing a crash dialog. 11934 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11935 Binder.restoreCallingIdentity(origId); 11936 return; 11937 } 11938 11939 Message msg = Message.obtain(); 11940 msg.what = SHOW_ERROR_MSG; 11941 HashMap data = new HashMap(); 11942 data.put("result", result); 11943 data.put("app", r); 11944 msg.obj = data; 11945 mHandler.sendMessage(msg); 11946 11947 Binder.restoreCallingIdentity(origId); 11948 } 11949 11950 int res = result.get(); 11951 11952 Intent appErrorIntent = null; 11953 synchronized (this) { 11954 if (r != null && !r.isolated) { 11955 // XXX Can't keep track of crash time for isolated processes, 11956 // since they don't have a persistent identity. 11957 mProcessCrashTimes.put(r.info.processName, r.uid, 11958 SystemClock.uptimeMillis()); 11959 } 11960 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11961 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11962 } 11963 } 11964 11965 if (appErrorIntent != null) { 11966 try { 11967 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11968 } catch (ActivityNotFoundException e) { 11969 Slog.w(TAG, "bug report receiver dissappeared", e); 11970 } 11971 } 11972 } 11973 11974 Intent createAppErrorIntentLocked(ProcessRecord r, 11975 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11976 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11977 if (report == null) { 11978 return null; 11979 } 11980 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11981 result.setComponent(r.errorReportReceiver); 11982 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11983 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11984 return result; 11985 } 11986 11987 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11988 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11989 if (r.errorReportReceiver == null) { 11990 return null; 11991 } 11992 11993 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11994 return null; 11995 } 11996 11997 ApplicationErrorReport report = new ApplicationErrorReport(); 11998 report.packageName = r.info.packageName; 11999 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12000 report.processName = r.processName; 12001 report.time = timeMillis; 12002 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12003 12004 if (r.crashing || r.forceCrashReport) { 12005 report.type = ApplicationErrorReport.TYPE_CRASH; 12006 report.crashInfo = crashInfo; 12007 } else if (r.notResponding) { 12008 report.type = ApplicationErrorReport.TYPE_ANR; 12009 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12010 12011 report.anrInfo.activity = r.notRespondingReport.tag; 12012 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12013 report.anrInfo.info = r.notRespondingReport.longMsg; 12014 } 12015 12016 return report; 12017 } 12018 12019 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12020 enforceNotIsolatedCaller("getProcessesInErrorState"); 12021 // assume our apps are happy - lazy create the list 12022 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12023 12024 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12025 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12026 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12027 12028 synchronized (this) { 12029 12030 // iterate across all processes 12031 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12032 ProcessRecord app = mLruProcesses.get(i); 12033 if (!allUsers && app.userId != userId) { 12034 continue; 12035 } 12036 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12037 // This one's in trouble, so we'll generate a report for it 12038 // crashes are higher priority (in case there's a crash *and* an anr) 12039 ActivityManager.ProcessErrorStateInfo report = null; 12040 if (app.crashing) { 12041 report = app.crashingReport; 12042 } else if (app.notResponding) { 12043 report = app.notRespondingReport; 12044 } 12045 12046 if (report != null) { 12047 if (errList == null) { 12048 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12049 } 12050 errList.add(report); 12051 } else { 12052 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12053 " crashing = " + app.crashing + 12054 " notResponding = " + app.notResponding); 12055 } 12056 } 12057 } 12058 } 12059 12060 return errList; 12061 } 12062 12063 static int procStateToImportance(int procState, int memAdj, 12064 ActivityManager.RunningAppProcessInfo currApp) { 12065 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12066 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12067 currApp.lru = memAdj; 12068 } else { 12069 currApp.lru = 0; 12070 } 12071 return imp; 12072 } 12073 12074 private void fillInProcMemInfo(ProcessRecord app, 12075 ActivityManager.RunningAppProcessInfo outInfo) { 12076 outInfo.pid = app.pid; 12077 outInfo.uid = app.info.uid; 12078 if (mHeavyWeightProcess == app) { 12079 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12080 } 12081 if (app.persistent) { 12082 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12083 } 12084 if (app.activities.size() > 0) { 12085 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12086 } 12087 outInfo.lastTrimLevel = app.trimMemoryLevel; 12088 int adj = app.curAdj; 12089 int procState = app.curProcState; 12090 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12091 outInfo.importanceReasonCode = app.adjTypeCode; 12092 outInfo.processState = app.curProcState; 12093 } 12094 12095 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12096 enforceNotIsolatedCaller("getRunningAppProcesses"); 12097 // Lazy instantiation of list 12098 List<ActivityManager.RunningAppProcessInfo> runList = null; 12099 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12100 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12101 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12102 synchronized (this) { 12103 // Iterate across all processes 12104 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12105 ProcessRecord app = mLruProcesses.get(i); 12106 if (!allUsers && app.userId != userId) { 12107 continue; 12108 } 12109 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12110 // Generate process state info for running application 12111 ActivityManager.RunningAppProcessInfo currApp = 12112 new ActivityManager.RunningAppProcessInfo(app.processName, 12113 app.pid, app.getPackageList()); 12114 fillInProcMemInfo(app, currApp); 12115 if (app.adjSource instanceof ProcessRecord) { 12116 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12117 currApp.importanceReasonImportance = 12118 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12119 app.adjSourceProcState); 12120 } else if (app.adjSource instanceof ActivityRecord) { 12121 ActivityRecord r = (ActivityRecord)app.adjSource; 12122 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12123 } 12124 if (app.adjTarget instanceof ComponentName) { 12125 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12126 } 12127 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12128 // + " lru=" + currApp.lru); 12129 if (runList == null) { 12130 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12131 } 12132 runList.add(currApp); 12133 } 12134 } 12135 } 12136 return runList; 12137 } 12138 12139 public List<ApplicationInfo> getRunningExternalApplications() { 12140 enforceNotIsolatedCaller("getRunningExternalApplications"); 12141 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12142 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12143 if (runningApps != null && runningApps.size() > 0) { 12144 Set<String> extList = new HashSet<String>(); 12145 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12146 if (app.pkgList != null) { 12147 for (String pkg : app.pkgList) { 12148 extList.add(pkg); 12149 } 12150 } 12151 } 12152 IPackageManager pm = AppGlobals.getPackageManager(); 12153 for (String pkg : extList) { 12154 try { 12155 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12156 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12157 retList.add(info); 12158 } 12159 } catch (RemoteException e) { 12160 } 12161 } 12162 } 12163 return retList; 12164 } 12165 12166 @Override 12167 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12168 enforceNotIsolatedCaller("getMyMemoryState"); 12169 synchronized (this) { 12170 ProcessRecord proc; 12171 synchronized (mPidsSelfLocked) { 12172 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12173 } 12174 fillInProcMemInfo(proc, outInfo); 12175 } 12176 } 12177 12178 @Override 12179 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12180 if (checkCallingPermission(android.Manifest.permission.DUMP) 12181 != PackageManager.PERMISSION_GRANTED) { 12182 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12183 + Binder.getCallingPid() 12184 + ", uid=" + Binder.getCallingUid() 12185 + " without permission " 12186 + android.Manifest.permission.DUMP); 12187 return; 12188 } 12189 12190 boolean dumpAll = false; 12191 boolean dumpClient = false; 12192 String dumpPackage = null; 12193 12194 int opti = 0; 12195 while (opti < args.length) { 12196 String opt = args[opti]; 12197 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12198 break; 12199 } 12200 opti++; 12201 if ("-a".equals(opt)) { 12202 dumpAll = true; 12203 } else if ("-c".equals(opt)) { 12204 dumpClient = true; 12205 } else if ("-h".equals(opt)) { 12206 pw.println("Activity manager dump options:"); 12207 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12208 pw.println(" cmd may be one of:"); 12209 pw.println(" a[ctivities]: activity stack state"); 12210 pw.println(" r[recents]: recent activities state"); 12211 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12212 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12213 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12214 pw.println(" o[om]: out of memory management"); 12215 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12216 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12217 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12218 pw.println(" service [COMP_SPEC]: service client-side state"); 12219 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12220 pw.println(" all: dump all activities"); 12221 pw.println(" top: dump the top activity"); 12222 pw.println(" write: write all pending state to storage"); 12223 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12224 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12225 pw.println(" a partial substring in a component name, a"); 12226 pw.println(" hex object identifier."); 12227 pw.println(" -a: include all available server state."); 12228 pw.println(" -c: include client state."); 12229 return; 12230 } else { 12231 pw.println("Unknown argument: " + opt + "; use -h for help"); 12232 } 12233 } 12234 12235 long origId = Binder.clearCallingIdentity(); 12236 boolean more = false; 12237 // Is the caller requesting to dump a particular piece of data? 12238 if (opti < args.length) { 12239 String cmd = args[opti]; 12240 opti++; 12241 if ("activities".equals(cmd) || "a".equals(cmd)) { 12242 synchronized (this) { 12243 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12244 } 12245 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12246 synchronized (this) { 12247 dumpRecentsLocked(fd, pw, args, opti, true, null); 12248 } 12249 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12250 String[] newArgs; 12251 String name; 12252 if (opti >= args.length) { 12253 name = null; 12254 newArgs = EMPTY_STRING_ARRAY; 12255 } else { 12256 name = args[opti]; 12257 opti++; 12258 newArgs = new String[args.length - opti]; 12259 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12260 args.length - opti); 12261 } 12262 synchronized (this) { 12263 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12264 } 12265 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12266 String[] newArgs; 12267 String name; 12268 if (opti >= args.length) { 12269 name = null; 12270 newArgs = EMPTY_STRING_ARRAY; 12271 } else { 12272 name = args[opti]; 12273 opti++; 12274 newArgs = new String[args.length - opti]; 12275 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12276 args.length - opti); 12277 } 12278 synchronized (this) { 12279 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12280 } 12281 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12282 String[] newArgs; 12283 String name; 12284 if (opti >= args.length) { 12285 name = null; 12286 newArgs = EMPTY_STRING_ARRAY; 12287 } else { 12288 name = args[opti]; 12289 opti++; 12290 newArgs = new String[args.length - opti]; 12291 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12292 args.length - opti); 12293 } 12294 synchronized (this) { 12295 dumpProcessesLocked(fd, pw, args, opti, true, name); 12296 } 12297 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12298 synchronized (this) { 12299 dumpOomLocked(fd, pw, args, opti, true); 12300 } 12301 } else if ("provider".equals(cmd)) { 12302 String[] newArgs; 12303 String name; 12304 if (opti >= args.length) { 12305 name = null; 12306 newArgs = EMPTY_STRING_ARRAY; 12307 } else { 12308 name = args[opti]; 12309 opti++; 12310 newArgs = new String[args.length - opti]; 12311 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12312 } 12313 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12314 pw.println("No providers match: " + name); 12315 pw.println("Use -h for help."); 12316 } 12317 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12318 synchronized (this) { 12319 dumpProvidersLocked(fd, pw, args, opti, true, null); 12320 } 12321 } else if ("service".equals(cmd)) { 12322 String[] newArgs; 12323 String name; 12324 if (opti >= args.length) { 12325 name = null; 12326 newArgs = EMPTY_STRING_ARRAY; 12327 } else { 12328 name = args[opti]; 12329 opti++; 12330 newArgs = new String[args.length - opti]; 12331 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12332 args.length - opti); 12333 } 12334 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12335 pw.println("No services match: " + name); 12336 pw.println("Use -h for help."); 12337 } 12338 } else if ("package".equals(cmd)) { 12339 String[] newArgs; 12340 if (opti >= args.length) { 12341 pw.println("package: no package name specified"); 12342 pw.println("Use -h for help."); 12343 } else { 12344 dumpPackage = args[opti]; 12345 opti++; 12346 newArgs = new String[args.length - opti]; 12347 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12348 args.length - opti); 12349 args = newArgs; 12350 opti = 0; 12351 more = true; 12352 } 12353 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12354 synchronized (this) { 12355 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12356 } 12357 } else if ("write".equals(cmd)) { 12358 mTaskPersister.flush(); 12359 pw.println("All tasks persisted."); 12360 return; 12361 } else { 12362 // Dumping a single activity? 12363 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12364 pw.println("Bad activity command, or no activities match: " + cmd); 12365 pw.println("Use -h for help."); 12366 } 12367 } 12368 if (!more) { 12369 Binder.restoreCallingIdentity(origId); 12370 return; 12371 } 12372 } 12373 12374 // No piece of data specified, dump everything. 12375 synchronized (this) { 12376 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12377 pw.println(); 12378 if (dumpAll) { 12379 pw.println("-------------------------------------------------------------------------------"); 12380 } 12381 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12382 pw.println(); 12383 if (dumpAll) { 12384 pw.println("-------------------------------------------------------------------------------"); 12385 } 12386 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12387 pw.println(); 12388 if (dumpAll) { 12389 pw.println("-------------------------------------------------------------------------------"); 12390 } 12391 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12392 pw.println(); 12393 if (dumpAll) { 12394 pw.println("-------------------------------------------------------------------------------"); 12395 } 12396 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12397 pw.println(); 12398 if (dumpAll) { 12399 pw.println("-------------------------------------------------------------------------------"); 12400 } 12401 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12402 pw.println(); 12403 if (dumpAll) { 12404 pw.println("-------------------------------------------------------------------------------"); 12405 } 12406 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12407 } 12408 Binder.restoreCallingIdentity(origId); 12409 } 12410 12411 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12412 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12413 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12414 12415 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12416 dumpPackage); 12417 boolean needSep = printedAnything; 12418 12419 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12420 dumpPackage, needSep, " mFocusedActivity: "); 12421 if (printed) { 12422 printedAnything = true; 12423 needSep = false; 12424 } 12425 12426 if (dumpPackage == null) { 12427 if (needSep) { 12428 pw.println(); 12429 } 12430 needSep = true; 12431 printedAnything = true; 12432 mStackSupervisor.dump(pw, " "); 12433 } 12434 12435 if (!printedAnything) { 12436 pw.println(" (nothing)"); 12437 } 12438 } 12439 12440 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12441 int opti, boolean dumpAll, String dumpPackage) { 12442 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12443 12444 boolean printedAnything = false; 12445 12446 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12447 boolean printedHeader = false; 12448 12449 final int N = mRecentTasks.size(); 12450 for (int i=0; i<N; i++) { 12451 TaskRecord tr = mRecentTasks.get(i); 12452 if (dumpPackage != null) { 12453 if (tr.realActivity == null || 12454 !dumpPackage.equals(tr.realActivity)) { 12455 continue; 12456 } 12457 } 12458 if (!printedHeader) { 12459 pw.println(" Recent tasks:"); 12460 printedHeader = true; 12461 printedAnything = true; 12462 } 12463 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12464 pw.println(tr); 12465 if (dumpAll) { 12466 mRecentTasks.get(i).dump(pw, " "); 12467 } 12468 } 12469 } 12470 12471 if (!printedAnything) { 12472 pw.println(" (nothing)"); 12473 } 12474 } 12475 12476 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12477 int opti, boolean dumpAll, String dumpPackage) { 12478 boolean needSep = false; 12479 boolean printedAnything = false; 12480 int numPers = 0; 12481 12482 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12483 12484 if (dumpAll) { 12485 final int NP = mProcessNames.getMap().size(); 12486 for (int ip=0; ip<NP; ip++) { 12487 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12488 final int NA = procs.size(); 12489 for (int ia=0; ia<NA; ia++) { 12490 ProcessRecord r = procs.valueAt(ia); 12491 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12492 continue; 12493 } 12494 if (!needSep) { 12495 pw.println(" All known processes:"); 12496 needSep = true; 12497 printedAnything = true; 12498 } 12499 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12500 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12501 pw.print(" "); pw.println(r); 12502 r.dump(pw, " "); 12503 if (r.persistent) { 12504 numPers++; 12505 } 12506 } 12507 } 12508 } 12509 12510 if (mIsolatedProcesses.size() > 0) { 12511 boolean printed = false; 12512 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12513 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12514 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12515 continue; 12516 } 12517 if (!printed) { 12518 if (needSep) { 12519 pw.println(); 12520 } 12521 pw.println(" Isolated process list (sorted by uid):"); 12522 printedAnything = true; 12523 printed = true; 12524 needSep = true; 12525 } 12526 pw.println(String.format("%sIsolated #%2d: %s", 12527 " ", i, r.toString())); 12528 } 12529 } 12530 12531 if (mLruProcesses.size() > 0) { 12532 if (needSep) { 12533 pw.println(); 12534 } 12535 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12536 pw.print(" total, non-act at "); 12537 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12538 pw.print(", non-svc at "); 12539 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12540 pw.println("):"); 12541 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12542 needSep = true; 12543 printedAnything = true; 12544 } 12545 12546 if (dumpAll || dumpPackage != null) { 12547 synchronized (mPidsSelfLocked) { 12548 boolean printed = false; 12549 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12550 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12551 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12552 continue; 12553 } 12554 if (!printed) { 12555 if (needSep) pw.println(); 12556 needSep = true; 12557 pw.println(" PID mappings:"); 12558 printed = true; 12559 printedAnything = true; 12560 } 12561 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12562 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12563 } 12564 } 12565 } 12566 12567 if (mForegroundProcesses.size() > 0) { 12568 synchronized (mPidsSelfLocked) { 12569 boolean printed = false; 12570 for (int i=0; i<mForegroundProcesses.size(); i++) { 12571 ProcessRecord r = mPidsSelfLocked.get( 12572 mForegroundProcesses.valueAt(i).pid); 12573 if (dumpPackage != null && (r == null 12574 || !r.pkgList.containsKey(dumpPackage))) { 12575 continue; 12576 } 12577 if (!printed) { 12578 if (needSep) pw.println(); 12579 needSep = true; 12580 pw.println(" Foreground Processes:"); 12581 printed = true; 12582 printedAnything = true; 12583 } 12584 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12585 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12586 } 12587 } 12588 } 12589 12590 if (mPersistentStartingProcesses.size() > 0) { 12591 if (needSep) pw.println(); 12592 needSep = true; 12593 printedAnything = true; 12594 pw.println(" Persisent processes that are starting:"); 12595 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12596 "Starting Norm", "Restarting PERS", dumpPackage); 12597 } 12598 12599 if (mRemovedProcesses.size() > 0) { 12600 if (needSep) pw.println(); 12601 needSep = true; 12602 printedAnything = true; 12603 pw.println(" Processes that are being removed:"); 12604 dumpProcessList(pw, this, mRemovedProcesses, " ", 12605 "Removed Norm", "Removed PERS", dumpPackage); 12606 } 12607 12608 if (mProcessesOnHold.size() > 0) { 12609 if (needSep) pw.println(); 12610 needSep = true; 12611 printedAnything = true; 12612 pw.println(" Processes that are on old until the system is ready:"); 12613 dumpProcessList(pw, this, mProcessesOnHold, " ", 12614 "OnHold Norm", "OnHold PERS", dumpPackage); 12615 } 12616 12617 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12618 12619 if (mProcessCrashTimes.getMap().size() > 0) { 12620 boolean printed = false; 12621 long now = SystemClock.uptimeMillis(); 12622 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12623 final int NP = pmap.size(); 12624 for (int ip=0; ip<NP; ip++) { 12625 String pname = pmap.keyAt(ip); 12626 SparseArray<Long> uids = pmap.valueAt(ip); 12627 final int N = uids.size(); 12628 for (int i=0; i<N; i++) { 12629 int puid = uids.keyAt(i); 12630 ProcessRecord r = mProcessNames.get(pname, puid); 12631 if (dumpPackage != null && (r == null 12632 || !r.pkgList.containsKey(dumpPackage))) { 12633 continue; 12634 } 12635 if (!printed) { 12636 if (needSep) pw.println(); 12637 needSep = true; 12638 pw.println(" Time since processes crashed:"); 12639 printed = true; 12640 printedAnything = true; 12641 } 12642 pw.print(" Process "); pw.print(pname); 12643 pw.print(" uid "); pw.print(puid); 12644 pw.print(": last crashed "); 12645 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12646 pw.println(" ago"); 12647 } 12648 } 12649 } 12650 12651 if (mBadProcesses.getMap().size() > 0) { 12652 boolean printed = false; 12653 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12654 final int NP = pmap.size(); 12655 for (int ip=0; ip<NP; ip++) { 12656 String pname = pmap.keyAt(ip); 12657 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12658 final int N = uids.size(); 12659 for (int i=0; i<N; i++) { 12660 int puid = uids.keyAt(i); 12661 ProcessRecord r = mProcessNames.get(pname, puid); 12662 if (dumpPackage != null && (r == null 12663 || !r.pkgList.containsKey(dumpPackage))) { 12664 continue; 12665 } 12666 if (!printed) { 12667 if (needSep) pw.println(); 12668 needSep = true; 12669 pw.println(" Bad processes:"); 12670 printedAnything = true; 12671 } 12672 BadProcessInfo info = uids.valueAt(i); 12673 pw.print(" Bad process "); pw.print(pname); 12674 pw.print(" uid "); pw.print(puid); 12675 pw.print(": crashed at time "); pw.println(info.time); 12676 if (info.shortMsg != null) { 12677 pw.print(" Short msg: "); pw.println(info.shortMsg); 12678 } 12679 if (info.longMsg != null) { 12680 pw.print(" Long msg: "); pw.println(info.longMsg); 12681 } 12682 if (info.stack != null) { 12683 pw.println(" Stack:"); 12684 int lastPos = 0; 12685 for (int pos=0; pos<info.stack.length(); pos++) { 12686 if (info.stack.charAt(pos) == '\n') { 12687 pw.print(" "); 12688 pw.write(info.stack, lastPos, pos-lastPos); 12689 pw.println(); 12690 lastPos = pos+1; 12691 } 12692 } 12693 if (lastPos < info.stack.length()) { 12694 pw.print(" "); 12695 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12696 pw.println(); 12697 } 12698 } 12699 } 12700 } 12701 } 12702 12703 if (dumpPackage == null) { 12704 pw.println(); 12705 needSep = false; 12706 pw.println(" mStartedUsers:"); 12707 for (int i=0; i<mStartedUsers.size(); i++) { 12708 UserStartedState uss = mStartedUsers.valueAt(i); 12709 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12710 pw.print(": "); uss.dump("", pw); 12711 } 12712 pw.print(" mStartedUserArray: ["); 12713 for (int i=0; i<mStartedUserArray.length; i++) { 12714 if (i > 0) pw.print(", "); 12715 pw.print(mStartedUserArray[i]); 12716 } 12717 pw.println("]"); 12718 pw.print(" mUserLru: ["); 12719 for (int i=0; i<mUserLru.size(); i++) { 12720 if (i > 0) pw.print(", "); 12721 pw.print(mUserLru.get(i)); 12722 } 12723 pw.println("]"); 12724 if (dumpAll) { 12725 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12726 } 12727 synchronized (mUserProfileGroupIdsSelfLocked) { 12728 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12729 pw.println(" mUserProfileGroupIds:"); 12730 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12731 pw.print(" User #"); 12732 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12733 pw.print(" -> profile #"); 12734 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12735 } 12736 } 12737 } 12738 } 12739 if (mHomeProcess != null && (dumpPackage == null 12740 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12741 if (needSep) { 12742 pw.println(); 12743 needSep = false; 12744 } 12745 pw.println(" mHomeProcess: " + mHomeProcess); 12746 } 12747 if (mPreviousProcess != null && (dumpPackage == null 12748 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12749 if (needSep) { 12750 pw.println(); 12751 needSep = false; 12752 } 12753 pw.println(" mPreviousProcess: " + mPreviousProcess); 12754 } 12755 if (dumpAll) { 12756 StringBuilder sb = new StringBuilder(128); 12757 sb.append(" mPreviousProcessVisibleTime: "); 12758 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12759 pw.println(sb); 12760 } 12761 if (mHeavyWeightProcess != null && (dumpPackage == null 12762 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12763 if (needSep) { 12764 pw.println(); 12765 needSep = false; 12766 } 12767 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12768 } 12769 if (dumpPackage == null) { 12770 pw.println(" mConfiguration: " + mConfiguration); 12771 } 12772 if (dumpAll) { 12773 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12774 if (mCompatModePackages.getPackages().size() > 0) { 12775 boolean printed = false; 12776 for (Map.Entry<String, Integer> entry 12777 : mCompatModePackages.getPackages().entrySet()) { 12778 String pkg = entry.getKey(); 12779 int mode = entry.getValue(); 12780 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12781 continue; 12782 } 12783 if (!printed) { 12784 pw.println(" mScreenCompatPackages:"); 12785 printed = true; 12786 } 12787 pw.print(" "); pw.print(pkg); pw.print(": "); 12788 pw.print(mode); pw.println(); 12789 } 12790 } 12791 } 12792 if (dumpPackage == null) { 12793 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12794 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12795 + " mLockScreenShown " + lockScreenShownToString()); 12796 } 12797 if (mShuttingDown || mRunningVoice) { 12798 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12799 } 12800 } 12801 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12802 || mOrigWaitForDebugger) { 12803 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12804 || dumpPackage.equals(mOrigDebugApp)) { 12805 if (needSep) { 12806 pw.println(); 12807 needSep = false; 12808 } 12809 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12810 + " mDebugTransient=" + mDebugTransient 12811 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12812 } 12813 } 12814 if (mOpenGlTraceApp != null) { 12815 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12816 if (needSep) { 12817 pw.println(); 12818 needSep = false; 12819 } 12820 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12821 } 12822 } 12823 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12824 || mProfileFd != null) { 12825 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12826 if (needSep) { 12827 pw.println(); 12828 needSep = false; 12829 } 12830 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12831 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12832 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12833 + mAutoStopProfiler); 12834 pw.println(" mProfileType=" + mProfileType); 12835 } 12836 } 12837 if (dumpPackage == null) { 12838 if (mAlwaysFinishActivities || mController != null) { 12839 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12840 + " mController=" + mController); 12841 } 12842 if (dumpAll) { 12843 pw.println(" Total persistent processes: " + numPers); 12844 pw.println(" mProcessesReady=" + mProcessesReady 12845 + " mSystemReady=" + mSystemReady 12846 + " mBooted=" + mBooted 12847 + " mFactoryTest=" + mFactoryTest); 12848 pw.println(" mBooting=" + mBooting 12849 + " mCallFinishBooting=" + mCallFinishBooting 12850 + " mBootAnimationComplete=" + mBootAnimationComplete); 12851 pw.print(" mLastPowerCheckRealtime="); 12852 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12853 pw.println(""); 12854 pw.print(" mLastPowerCheckUptime="); 12855 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12856 pw.println(""); 12857 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12858 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12859 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12860 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12861 + " (" + mLruProcesses.size() + " total)" 12862 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12863 + " mNumServiceProcs=" + mNumServiceProcs 12864 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12865 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12866 + " mLastMemoryLevel" + mLastMemoryLevel 12867 + " mLastNumProcesses" + mLastNumProcesses); 12868 long now = SystemClock.uptimeMillis(); 12869 pw.print(" mLastIdleTime="); 12870 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12871 pw.print(" mLowRamSinceLastIdle="); 12872 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12873 pw.println(); 12874 } 12875 } 12876 12877 if (!printedAnything) { 12878 pw.println(" (nothing)"); 12879 } 12880 } 12881 12882 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12883 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12884 if (mProcessesToGc.size() > 0) { 12885 boolean printed = false; 12886 long now = SystemClock.uptimeMillis(); 12887 for (int i=0; i<mProcessesToGc.size(); i++) { 12888 ProcessRecord proc = mProcessesToGc.get(i); 12889 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12890 continue; 12891 } 12892 if (!printed) { 12893 if (needSep) pw.println(); 12894 needSep = true; 12895 pw.println(" Processes that are waiting to GC:"); 12896 printed = true; 12897 } 12898 pw.print(" Process "); pw.println(proc); 12899 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12900 pw.print(", last gced="); 12901 pw.print(now-proc.lastRequestedGc); 12902 pw.print(" ms ago, last lowMem="); 12903 pw.print(now-proc.lastLowMemory); 12904 pw.println(" ms ago"); 12905 12906 } 12907 } 12908 return needSep; 12909 } 12910 12911 void printOomLevel(PrintWriter pw, String name, int adj) { 12912 pw.print(" "); 12913 if (adj >= 0) { 12914 pw.print(' '); 12915 if (adj < 10) pw.print(' '); 12916 } else { 12917 if (adj > -10) pw.print(' '); 12918 } 12919 pw.print(adj); 12920 pw.print(": "); 12921 pw.print(name); 12922 pw.print(" ("); 12923 pw.print(mProcessList.getMemLevel(adj)/1024); 12924 pw.println(" kB)"); 12925 } 12926 12927 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12928 int opti, boolean dumpAll) { 12929 boolean needSep = false; 12930 12931 if (mLruProcesses.size() > 0) { 12932 if (needSep) pw.println(); 12933 needSep = true; 12934 pw.println(" OOM levels:"); 12935 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12936 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12937 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12938 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12939 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12940 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12941 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12942 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12943 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12944 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12945 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12946 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12947 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12948 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12949 12950 if (needSep) pw.println(); 12951 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12952 pw.print(" total, non-act at "); 12953 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12954 pw.print(", non-svc at "); 12955 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12956 pw.println("):"); 12957 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12958 needSep = true; 12959 } 12960 12961 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12962 12963 pw.println(); 12964 pw.println(" mHomeProcess: " + mHomeProcess); 12965 pw.println(" mPreviousProcess: " + mPreviousProcess); 12966 if (mHeavyWeightProcess != null) { 12967 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12968 } 12969 12970 return true; 12971 } 12972 12973 /** 12974 * There are three ways to call this: 12975 * - no provider specified: dump all the providers 12976 * - a flattened component name that matched an existing provider was specified as the 12977 * first arg: dump that one provider 12978 * - the first arg isn't the flattened component name of an existing provider: 12979 * dump all providers whose component contains the first arg as a substring 12980 */ 12981 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12982 int opti, boolean dumpAll) { 12983 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12984 } 12985 12986 static class ItemMatcher { 12987 ArrayList<ComponentName> components; 12988 ArrayList<String> strings; 12989 ArrayList<Integer> objects; 12990 boolean all; 12991 12992 ItemMatcher() { 12993 all = true; 12994 } 12995 12996 void build(String name) { 12997 ComponentName componentName = ComponentName.unflattenFromString(name); 12998 if (componentName != null) { 12999 if (components == null) { 13000 components = new ArrayList<ComponentName>(); 13001 } 13002 components.add(componentName); 13003 all = false; 13004 } else { 13005 int objectId = 0; 13006 // Not a '/' separated full component name; maybe an object ID? 13007 try { 13008 objectId = Integer.parseInt(name, 16); 13009 if (objects == null) { 13010 objects = new ArrayList<Integer>(); 13011 } 13012 objects.add(objectId); 13013 all = false; 13014 } catch (RuntimeException e) { 13015 // Not an integer; just do string match. 13016 if (strings == null) { 13017 strings = new ArrayList<String>(); 13018 } 13019 strings.add(name); 13020 all = false; 13021 } 13022 } 13023 } 13024 13025 int build(String[] args, int opti) { 13026 for (; opti<args.length; opti++) { 13027 String name = args[opti]; 13028 if ("--".equals(name)) { 13029 return opti+1; 13030 } 13031 build(name); 13032 } 13033 return opti; 13034 } 13035 13036 boolean match(Object object, ComponentName comp) { 13037 if (all) { 13038 return true; 13039 } 13040 if (components != null) { 13041 for (int i=0; i<components.size(); i++) { 13042 if (components.get(i).equals(comp)) { 13043 return true; 13044 } 13045 } 13046 } 13047 if (objects != null) { 13048 for (int i=0; i<objects.size(); i++) { 13049 if (System.identityHashCode(object) == objects.get(i)) { 13050 return true; 13051 } 13052 } 13053 } 13054 if (strings != null) { 13055 String flat = comp.flattenToString(); 13056 for (int i=0; i<strings.size(); i++) { 13057 if (flat.contains(strings.get(i))) { 13058 return true; 13059 } 13060 } 13061 } 13062 return false; 13063 } 13064 } 13065 13066 /** 13067 * There are three things that cmd can be: 13068 * - a flattened component name that matches an existing activity 13069 * - the cmd arg isn't the flattened component name of an existing activity: 13070 * dump all activity whose component contains the cmd as a substring 13071 * - A hex number of the ActivityRecord object instance. 13072 */ 13073 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13074 int opti, boolean dumpAll) { 13075 ArrayList<ActivityRecord> activities; 13076 13077 synchronized (this) { 13078 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13079 } 13080 13081 if (activities.size() <= 0) { 13082 return false; 13083 } 13084 13085 String[] newArgs = new String[args.length - opti]; 13086 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13087 13088 TaskRecord lastTask = null; 13089 boolean needSep = false; 13090 for (int i=activities.size()-1; i>=0; i--) { 13091 ActivityRecord r = activities.get(i); 13092 if (needSep) { 13093 pw.println(); 13094 } 13095 needSep = true; 13096 synchronized (this) { 13097 if (lastTask != r.task) { 13098 lastTask = r.task; 13099 pw.print("TASK "); pw.print(lastTask.affinity); 13100 pw.print(" id="); pw.println(lastTask.taskId); 13101 if (dumpAll) { 13102 lastTask.dump(pw, " "); 13103 } 13104 } 13105 } 13106 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13107 } 13108 return true; 13109 } 13110 13111 /** 13112 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13113 * there is a thread associated with the activity. 13114 */ 13115 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13116 final ActivityRecord r, String[] args, boolean dumpAll) { 13117 String innerPrefix = prefix + " "; 13118 synchronized (this) { 13119 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13120 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13121 pw.print(" pid="); 13122 if (r.app != null) pw.println(r.app.pid); 13123 else pw.println("(not running)"); 13124 if (dumpAll) { 13125 r.dump(pw, innerPrefix); 13126 } 13127 } 13128 if (r.app != null && r.app.thread != null) { 13129 // flush anything that is already in the PrintWriter since the thread is going 13130 // to write to the file descriptor directly 13131 pw.flush(); 13132 try { 13133 TransferPipe tp = new TransferPipe(); 13134 try { 13135 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13136 r.appToken, innerPrefix, args); 13137 tp.go(fd); 13138 } finally { 13139 tp.kill(); 13140 } 13141 } catch (IOException e) { 13142 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13143 } catch (RemoteException e) { 13144 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13145 } 13146 } 13147 } 13148 13149 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13150 int opti, boolean dumpAll, String dumpPackage) { 13151 boolean needSep = false; 13152 boolean onlyHistory = false; 13153 boolean printedAnything = false; 13154 13155 if ("history".equals(dumpPackage)) { 13156 if (opti < args.length && "-s".equals(args[opti])) { 13157 dumpAll = false; 13158 } 13159 onlyHistory = true; 13160 dumpPackage = null; 13161 } 13162 13163 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13164 if (!onlyHistory && dumpAll) { 13165 if (mRegisteredReceivers.size() > 0) { 13166 boolean printed = false; 13167 Iterator it = mRegisteredReceivers.values().iterator(); 13168 while (it.hasNext()) { 13169 ReceiverList r = (ReceiverList)it.next(); 13170 if (dumpPackage != null && (r.app == null || 13171 !dumpPackage.equals(r.app.info.packageName))) { 13172 continue; 13173 } 13174 if (!printed) { 13175 pw.println(" Registered Receivers:"); 13176 needSep = true; 13177 printed = true; 13178 printedAnything = true; 13179 } 13180 pw.print(" * "); pw.println(r); 13181 r.dump(pw, " "); 13182 } 13183 } 13184 13185 if (mReceiverResolver.dump(pw, needSep ? 13186 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13187 " ", dumpPackage, false)) { 13188 needSep = true; 13189 printedAnything = true; 13190 } 13191 } 13192 13193 for (BroadcastQueue q : mBroadcastQueues) { 13194 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13195 printedAnything |= needSep; 13196 } 13197 13198 needSep = true; 13199 13200 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13201 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13202 if (needSep) { 13203 pw.println(); 13204 } 13205 needSep = true; 13206 printedAnything = true; 13207 pw.print(" Sticky broadcasts for user "); 13208 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13209 StringBuilder sb = new StringBuilder(128); 13210 for (Map.Entry<String, ArrayList<Intent>> ent 13211 : mStickyBroadcasts.valueAt(user).entrySet()) { 13212 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13213 if (dumpAll) { 13214 pw.println(":"); 13215 ArrayList<Intent> intents = ent.getValue(); 13216 final int N = intents.size(); 13217 for (int i=0; i<N; i++) { 13218 sb.setLength(0); 13219 sb.append(" Intent: "); 13220 intents.get(i).toShortString(sb, false, true, false, false); 13221 pw.println(sb.toString()); 13222 Bundle bundle = intents.get(i).getExtras(); 13223 if (bundle != null) { 13224 pw.print(" "); 13225 pw.println(bundle.toString()); 13226 } 13227 } 13228 } else { 13229 pw.println(""); 13230 } 13231 } 13232 } 13233 } 13234 13235 if (!onlyHistory && dumpAll) { 13236 pw.println(); 13237 for (BroadcastQueue queue : mBroadcastQueues) { 13238 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13239 + queue.mBroadcastsScheduled); 13240 } 13241 pw.println(" mHandler:"); 13242 mHandler.dump(new PrintWriterPrinter(pw), " "); 13243 needSep = true; 13244 printedAnything = true; 13245 } 13246 13247 if (!printedAnything) { 13248 pw.println(" (nothing)"); 13249 } 13250 } 13251 13252 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13253 int opti, boolean dumpAll, String dumpPackage) { 13254 boolean needSep; 13255 boolean printedAnything = false; 13256 13257 ItemMatcher matcher = new ItemMatcher(); 13258 matcher.build(args, opti); 13259 13260 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13261 13262 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13263 printedAnything |= needSep; 13264 13265 if (mLaunchingProviders.size() > 0) { 13266 boolean printed = false; 13267 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13268 ContentProviderRecord r = mLaunchingProviders.get(i); 13269 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13270 continue; 13271 } 13272 if (!printed) { 13273 if (needSep) pw.println(); 13274 needSep = true; 13275 pw.println(" Launching content providers:"); 13276 printed = true; 13277 printedAnything = true; 13278 } 13279 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13280 pw.println(r); 13281 } 13282 } 13283 13284 if (mGrantedUriPermissions.size() > 0) { 13285 boolean printed = false; 13286 int dumpUid = -2; 13287 if (dumpPackage != null) { 13288 try { 13289 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13290 } catch (NameNotFoundException e) { 13291 dumpUid = -1; 13292 } 13293 } 13294 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13295 int uid = mGrantedUriPermissions.keyAt(i); 13296 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13297 continue; 13298 } 13299 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13300 if (!printed) { 13301 if (needSep) pw.println(); 13302 needSep = true; 13303 pw.println(" Granted Uri Permissions:"); 13304 printed = true; 13305 printedAnything = true; 13306 } 13307 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13308 for (UriPermission perm : perms.values()) { 13309 pw.print(" "); pw.println(perm); 13310 if (dumpAll) { 13311 perm.dump(pw, " "); 13312 } 13313 } 13314 } 13315 } 13316 13317 if (!printedAnything) { 13318 pw.println(" (nothing)"); 13319 } 13320 } 13321 13322 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13323 int opti, boolean dumpAll, String dumpPackage) { 13324 boolean printed = false; 13325 13326 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13327 13328 if (mIntentSenderRecords.size() > 0) { 13329 Iterator<WeakReference<PendingIntentRecord>> it 13330 = mIntentSenderRecords.values().iterator(); 13331 while (it.hasNext()) { 13332 WeakReference<PendingIntentRecord> ref = it.next(); 13333 PendingIntentRecord rec = ref != null ? ref.get(): null; 13334 if (dumpPackage != null && (rec == null 13335 || !dumpPackage.equals(rec.key.packageName))) { 13336 continue; 13337 } 13338 printed = true; 13339 if (rec != null) { 13340 pw.print(" * "); pw.println(rec); 13341 if (dumpAll) { 13342 rec.dump(pw, " "); 13343 } 13344 } else { 13345 pw.print(" * "); pw.println(ref); 13346 } 13347 } 13348 } 13349 13350 if (!printed) { 13351 pw.println(" (nothing)"); 13352 } 13353 } 13354 13355 private static final int dumpProcessList(PrintWriter pw, 13356 ActivityManagerService service, List list, 13357 String prefix, String normalLabel, String persistentLabel, 13358 String dumpPackage) { 13359 int numPers = 0; 13360 final int N = list.size()-1; 13361 for (int i=N; i>=0; i--) { 13362 ProcessRecord r = (ProcessRecord)list.get(i); 13363 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13364 continue; 13365 } 13366 pw.println(String.format("%s%s #%2d: %s", 13367 prefix, (r.persistent ? persistentLabel : normalLabel), 13368 i, r.toString())); 13369 if (r.persistent) { 13370 numPers++; 13371 } 13372 } 13373 return numPers; 13374 } 13375 13376 private static final boolean dumpProcessOomList(PrintWriter pw, 13377 ActivityManagerService service, List<ProcessRecord> origList, 13378 String prefix, String normalLabel, String persistentLabel, 13379 boolean inclDetails, String dumpPackage) { 13380 13381 ArrayList<Pair<ProcessRecord, Integer>> list 13382 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13383 for (int i=0; i<origList.size(); i++) { 13384 ProcessRecord r = origList.get(i); 13385 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13386 continue; 13387 } 13388 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13389 } 13390 13391 if (list.size() <= 0) { 13392 return false; 13393 } 13394 13395 Comparator<Pair<ProcessRecord, Integer>> comparator 13396 = new Comparator<Pair<ProcessRecord, Integer>>() { 13397 @Override 13398 public int compare(Pair<ProcessRecord, Integer> object1, 13399 Pair<ProcessRecord, Integer> object2) { 13400 if (object1.first.setAdj != object2.first.setAdj) { 13401 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13402 } 13403 if (object1.second.intValue() != object2.second.intValue()) { 13404 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13405 } 13406 return 0; 13407 } 13408 }; 13409 13410 Collections.sort(list, comparator); 13411 13412 final long curRealtime = SystemClock.elapsedRealtime(); 13413 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13414 final long curUptime = SystemClock.uptimeMillis(); 13415 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13416 13417 for (int i=list.size()-1; i>=0; i--) { 13418 ProcessRecord r = list.get(i).first; 13419 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13420 char schedGroup; 13421 switch (r.setSchedGroup) { 13422 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13423 schedGroup = 'B'; 13424 break; 13425 case Process.THREAD_GROUP_DEFAULT: 13426 schedGroup = 'F'; 13427 break; 13428 default: 13429 schedGroup = '?'; 13430 break; 13431 } 13432 char foreground; 13433 if (r.foregroundActivities) { 13434 foreground = 'A'; 13435 } else if (r.foregroundServices) { 13436 foreground = 'S'; 13437 } else { 13438 foreground = ' '; 13439 } 13440 String procState = ProcessList.makeProcStateString(r.curProcState); 13441 pw.print(prefix); 13442 pw.print(r.persistent ? persistentLabel : normalLabel); 13443 pw.print(" #"); 13444 int num = (origList.size()-1)-list.get(i).second; 13445 if (num < 10) pw.print(' '); 13446 pw.print(num); 13447 pw.print(": "); 13448 pw.print(oomAdj); 13449 pw.print(' '); 13450 pw.print(schedGroup); 13451 pw.print('/'); 13452 pw.print(foreground); 13453 pw.print('/'); 13454 pw.print(procState); 13455 pw.print(" trm:"); 13456 if (r.trimMemoryLevel < 10) pw.print(' '); 13457 pw.print(r.trimMemoryLevel); 13458 pw.print(' '); 13459 pw.print(r.toShortString()); 13460 pw.print(" ("); 13461 pw.print(r.adjType); 13462 pw.println(')'); 13463 if (r.adjSource != null || r.adjTarget != null) { 13464 pw.print(prefix); 13465 pw.print(" "); 13466 if (r.adjTarget instanceof ComponentName) { 13467 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13468 } else if (r.adjTarget != null) { 13469 pw.print(r.adjTarget.toString()); 13470 } else { 13471 pw.print("{null}"); 13472 } 13473 pw.print("<="); 13474 if (r.adjSource instanceof ProcessRecord) { 13475 pw.print("Proc{"); 13476 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13477 pw.println("}"); 13478 } else if (r.adjSource != null) { 13479 pw.println(r.adjSource.toString()); 13480 } else { 13481 pw.println("{null}"); 13482 } 13483 } 13484 if (inclDetails) { 13485 pw.print(prefix); 13486 pw.print(" "); 13487 pw.print("oom: max="); pw.print(r.maxAdj); 13488 pw.print(" curRaw="); pw.print(r.curRawAdj); 13489 pw.print(" setRaw="); pw.print(r.setRawAdj); 13490 pw.print(" cur="); pw.print(r.curAdj); 13491 pw.print(" set="); pw.println(r.setAdj); 13492 pw.print(prefix); 13493 pw.print(" "); 13494 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13495 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13496 pw.print(" lastPss="); pw.print(r.lastPss); 13497 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13498 pw.print(prefix); 13499 pw.print(" "); 13500 pw.print("cached="); pw.print(r.cached); 13501 pw.print(" empty="); pw.print(r.empty); 13502 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13503 13504 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13505 if (r.lastWakeTime != 0) { 13506 long wtime; 13507 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13508 synchronized (stats) { 13509 wtime = stats.getProcessWakeTime(r.info.uid, 13510 r.pid, curRealtime); 13511 } 13512 long timeUsed = wtime - r.lastWakeTime; 13513 pw.print(prefix); 13514 pw.print(" "); 13515 pw.print("keep awake over "); 13516 TimeUtils.formatDuration(realtimeSince, pw); 13517 pw.print(" used "); 13518 TimeUtils.formatDuration(timeUsed, pw); 13519 pw.print(" ("); 13520 pw.print((timeUsed*100)/realtimeSince); 13521 pw.println("%)"); 13522 } 13523 if (r.lastCpuTime != 0) { 13524 long timeUsed = r.curCpuTime - r.lastCpuTime; 13525 pw.print(prefix); 13526 pw.print(" "); 13527 pw.print("run cpu over "); 13528 TimeUtils.formatDuration(uptimeSince, pw); 13529 pw.print(" used "); 13530 TimeUtils.formatDuration(timeUsed, pw); 13531 pw.print(" ("); 13532 pw.print((timeUsed*100)/uptimeSince); 13533 pw.println("%)"); 13534 } 13535 } 13536 } 13537 } 13538 return true; 13539 } 13540 13541 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13542 String[] args) { 13543 ArrayList<ProcessRecord> procs; 13544 synchronized (this) { 13545 if (args != null && args.length > start 13546 && args[start].charAt(0) != '-') { 13547 procs = new ArrayList<ProcessRecord>(); 13548 int pid = -1; 13549 try { 13550 pid = Integer.parseInt(args[start]); 13551 } catch (NumberFormatException e) { 13552 } 13553 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13554 ProcessRecord proc = mLruProcesses.get(i); 13555 if (proc.pid == pid) { 13556 procs.add(proc); 13557 } else if (allPkgs && proc.pkgList != null 13558 && proc.pkgList.containsKey(args[start])) { 13559 procs.add(proc); 13560 } else if (proc.processName.equals(args[start])) { 13561 procs.add(proc); 13562 } 13563 } 13564 if (procs.size() <= 0) { 13565 return null; 13566 } 13567 } else { 13568 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13569 } 13570 } 13571 return procs; 13572 } 13573 13574 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13575 PrintWriter pw, String[] args) { 13576 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13577 if (procs == null) { 13578 pw.println("No process found for: " + args[0]); 13579 return; 13580 } 13581 13582 long uptime = SystemClock.uptimeMillis(); 13583 long realtime = SystemClock.elapsedRealtime(); 13584 pw.println("Applications Graphics Acceleration Info:"); 13585 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13586 13587 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13588 ProcessRecord r = procs.get(i); 13589 if (r.thread != null) { 13590 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13591 pw.flush(); 13592 try { 13593 TransferPipe tp = new TransferPipe(); 13594 try { 13595 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13596 tp.go(fd); 13597 } finally { 13598 tp.kill(); 13599 } 13600 } catch (IOException e) { 13601 pw.println("Failure while dumping the app: " + r); 13602 pw.flush(); 13603 } catch (RemoteException e) { 13604 pw.println("Got a RemoteException while dumping the app " + r); 13605 pw.flush(); 13606 } 13607 } 13608 } 13609 } 13610 13611 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13612 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13613 if (procs == null) { 13614 pw.println("No process found for: " + args[0]); 13615 return; 13616 } 13617 13618 pw.println("Applications Database Info:"); 13619 13620 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13621 ProcessRecord r = procs.get(i); 13622 if (r.thread != null) { 13623 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13624 pw.flush(); 13625 try { 13626 TransferPipe tp = new TransferPipe(); 13627 try { 13628 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13629 tp.go(fd); 13630 } finally { 13631 tp.kill(); 13632 } 13633 } catch (IOException e) { 13634 pw.println("Failure while dumping the app: " + r); 13635 pw.flush(); 13636 } catch (RemoteException e) { 13637 pw.println("Got a RemoteException while dumping the app " + r); 13638 pw.flush(); 13639 } 13640 } 13641 } 13642 } 13643 13644 final static class MemItem { 13645 final boolean isProc; 13646 final String label; 13647 final String shortLabel; 13648 final long pss; 13649 final int id; 13650 final boolean hasActivities; 13651 ArrayList<MemItem> subitems; 13652 13653 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13654 boolean _hasActivities) { 13655 isProc = true; 13656 label = _label; 13657 shortLabel = _shortLabel; 13658 pss = _pss; 13659 id = _id; 13660 hasActivities = _hasActivities; 13661 } 13662 13663 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13664 isProc = false; 13665 label = _label; 13666 shortLabel = _shortLabel; 13667 pss = _pss; 13668 id = _id; 13669 hasActivities = false; 13670 } 13671 } 13672 13673 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13674 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13675 if (sort && !isCompact) { 13676 Collections.sort(items, new Comparator<MemItem>() { 13677 @Override 13678 public int compare(MemItem lhs, MemItem rhs) { 13679 if (lhs.pss < rhs.pss) { 13680 return 1; 13681 } else if (lhs.pss > rhs.pss) { 13682 return -1; 13683 } 13684 return 0; 13685 } 13686 }); 13687 } 13688 13689 for (int i=0; i<items.size(); i++) { 13690 MemItem mi = items.get(i); 13691 if (!isCompact) { 13692 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13693 } else if (mi.isProc) { 13694 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13695 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13696 pw.println(mi.hasActivities ? ",a" : ",e"); 13697 } else { 13698 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13699 pw.println(mi.pss); 13700 } 13701 if (mi.subitems != null) { 13702 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13703 true, isCompact); 13704 } 13705 } 13706 } 13707 13708 // These are in KB. 13709 static final long[] DUMP_MEM_BUCKETS = new long[] { 13710 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13711 120*1024, 160*1024, 200*1024, 13712 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13713 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13714 }; 13715 13716 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13717 boolean stackLike) { 13718 int start = label.lastIndexOf('.'); 13719 if (start >= 0) start++; 13720 else start = 0; 13721 int end = label.length(); 13722 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13723 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13724 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13725 out.append(bucket); 13726 out.append(stackLike ? "MB." : "MB "); 13727 out.append(label, start, end); 13728 return; 13729 } 13730 } 13731 out.append(memKB/1024); 13732 out.append(stackLike ? "MB." : "MB "); 13733 out.append(label, start, end); 13734 } 13735 13736 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13737 ProcessList.NATIVE_ADJ, 13738 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13739 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13740 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13741 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13742 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13743 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13744 }; 13745 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13746 "Native", 13747 "System", "Persistent", "Persistent Service", "Foreground", 13748 "Visible", "Perceptible", 13749 "Heavy Weight", "Backup", 13750 "A Services", "Home", 13751 "Previous", "B Services", "Cached" 13752 }; 13753 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13754 "native", 13755 "sys", "pers", "persvc", "fore", 13756 "vis", "percept", 13757 "heavy", "backup", 13758 "servicea", "home", 13759 "prev", "serviceb", "cached" 13760 }; 13761 13762 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13763 long realtime, boolean isCheckinRequest, boolean isCompact) { 13764 if (isCheckinRequest || isCompact) { 13765 // short checkin version 13766 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13767 } else { 13768 pw.println("Applications Memory Usage (kB):"); 13769 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13770 } 13771 } 13772 13773 private static final int KSM_SHARED = 0; 13774 private static final int KSM_SHARING = 1; 13775 private static final int KSM_UNSHARED = 2; 13776 private static final int KSM_VOLATILE = 3; 13777 13778 private final long[] getKsmInfo() { 13779 long[] longOut = new long[4]; 13780 final int[] SINGLE_LONG_FORMAT = new int[] { 13781 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13782 }; 13783 long[] longTmp = new long[1]; 13784 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13785 SINGLE_LONG_FORMAT, null, longTmp, null); 13786 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13787 longTmp[0] = 0; 13788 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13789 SINGLE_LONG_FORMAT, null, longTmp, null); 13790 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13791 longTmp[0] = 0; 13792 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13793 SINGLE_LONG_FORMAT, null, longTmp, null); 13794 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13795 longTmp[0] = 0; 13796 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13797 SINGLE_LONG_FORMAT, null, longTmp, null); 13798 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13799 return longOut; 13800 } 13801 13802 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13803 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13804 boolean dumpDetails = false; 13805 boolean dumpFullDetails = false; 13806 boolean dumpDalvik = false; 13807 boolean oomOnly = false; 13808 boolean isCompact = false; 13809 boolean localOnly = false; 13810 boolean packages = false; 13811 13812 int opti = 0; 13813 while (opti < args.length) { 13814 String opt = args[opti]; 13815 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13816 break; 13817 } 13818 opti++; 13819 if ("-a".equals(opt)) { 13820 dumpDetails = true; 13821 dumpFullDetails = true; 13822 dumpDalvik = true; 13823 } else if ("-d".equals(opt)) { 13824 dumpDalvik = true; 13825 } else if ("-c".equals(opt)) { 13826 isCompact = true; 13827 } else if ("--oom".equals(opt)) { 13828 oomOnly = true; 13829 } else if ("--local".equals(opt)) { 13830 localOnly = true; 13831 } else if ("--package".equals(opt)) { 13832 packages = true; 13833 } else if ("-h".equals(opt)) { 13834 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13835 pw.println(" -a: include all available information for each process."); 13836 pw.println(" -d: include dalvik details when dumping process details."); 13837 pw.println(" -c: dump in a compact machine-parseable representation."); 13838 pw.println(" --oom: only show processes organized by oom adj."); 13839 pw.println(" --local: only collect details locally, don't call process."); 13840 pw.println(" --package: interpret process arg as package, dumping all"); 13841 pw.println(" processes that have loaded that package."); 13842 pw.println("If [process] is specified it can be the name or "); 13843 pw.println("pid of a specific process to dump."); 13844 return; 13845 } else { 13846 pw.println("Unknown argument: " + opt + "; use -h for help"); 13847 } 13848 } 13849 13850 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13851 long uptime = SystemClock.uptimeMillis(); 13852 long realtime = SystemClock.elapsedRealtime(); 13853 final long[] tmpLong = new long[1]; 13854 13855 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13856 if (procs == null) { 13857 // No Java processes. Maybe they want to print a native process. 13858 if (args != null && args.length > opti 13859 && args[opti].charAt(0) != '-') { 13860 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13861 = new ArrayList<ProcessCpuTracker.Stats>(); 13862 updateCpuStatsNow(); 13863 int findPid = -1; 13864 try { 13865 findPid = Integer.parseInt(args[opti]); 13866 } catch (NumberFormatException e) { 13867 } 13868 synchronized (mProcessCpuTracker) { 13869 final int N = mProcessCpuTracker.countStats(); 13870 for (int i=0; i<N; i++) { 13871 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13872 if (st.pid == findPid || (st.baseName != null 13873 && st.baseName.equals(args[opti]))) { 13874 nativeProcs.add(st); 13875 } 13876 } 13877 } 13878 if (nativeProcs.size() > 0) { 13879 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13880 isCompact); 13881 Debug.MemoryInfo mi = null; 13882 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13883 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13884 final int pid = r.pid; 13885 if (!isCheckinRequest && dumpDetails) { 13886 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13887 } 13888 if (mi == null) { 13889 mi = new Debug.MemoryInfo(); 13890 } 13891 if (dumpDetails || (!brief && !oomOnly)) { 13892 Debug.getMemoryInfo(pid, mi); 13893 } else { 13894 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13895 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13896 } 13897 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13898 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13899 if (isCheckinRequest) { 13900 pw.println(); 13901 } 13902 } 13903 return; 13904 } 13905 } 13906 pw.println("No process found for: " + args[opti]); 13907 return; 13908 } 13909 13910 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13911 dumpDetails = true; 13912 } 13913 13914 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13915 13916 String[] innerArgs = new String[args.length-opti]; 13917 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13918 13919 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13920 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13921 long nativePss=0, dalvikPss=0, otherPss=0; 13922 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13923 13924 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13925 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13926 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13927 13928 long totalPss = 0; 13929 long cachedPss = 0; 13930 13931 Debug.MemoryInfo mi = null; 13932 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13933 final ProcessRecord r = procs.get(i); 13934 final IApplicationThread thread; 13935 final int pid; 13936 final int oomAdj; 13937 final boolean hasActivities; 13938 synchronized (this) { 13939 thread = r.thread; 13940 pid = r.pid; 13941 oomAdj = r.getSetAdjWithServices(); 13942 hasActivities = r.activities.size() > 0; 13943 } 13944 if (thread != null) { 13945 if (!isCheckinRequest && dumpDetails) { 13946 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13947 } 13948 if (mi == null) { 13949 mi = new Debug.MemoryInfo(); 13950 } 13951 if (dumpDetails || (!brief && !oomOnly)) { 13952 Debug.getMemoryInfo(pid, mi); 13953 } else { 13954 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13955 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13956 } 13957 if (dumpDetails) { 13958 if (localOnly) { 13959 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13960 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13961 if (isCheckinRequest) { 13962 pw.println(); 13963 } 13964 } else { 13965 try { 13966 pw.flush(); 13967 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13968 dumpDalvik, innerArgs); 13969 } catch (RemoteException e) { 13970 if (!isCheckinRequest) { 13971 pw.println("Got RemoteException!"); 13972 pw.flush(); 13973 } 13974 } 13975 } 13976 } 13977 13978 final long myTotalPss = mi.getTotalPss(); 13979 final long myTotalUss = mi.getTotalUss(); 13980 13981 synchronized (this) { 13982 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13983 // Record this for posterity if the process has been stable. 13984 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13985 } 13986 } 13987 13988 if (!isCheckinRequest && mi != null) { 13989 totalPss += myTotalPss; 13990 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13991 (hasActivities ? " / activities)" : ")"), 13992 r.processName, myTotalPss, pid, hasActivities); 13993 procMems.add(pssItem); 13994 procMemsMap.put(pid, pssItem); 13995 13996 nativePss += mi.nativePss; 13997 dalvikPss += mi.dalvikPss; 13998 otherPss += mi.otherPss; 13999 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14000 long mem = mi.getOtherPss(j); 14001 miscPss[j] += mem; 14002 otherPss -= mem; 14003 } 14004 14005 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14006 cachedPss += myTotalPss; 14007 } 14008 14009 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14010 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14011 || oomIndex == (oomPss.length-1)) { 14012 oomPss[oomIndex] += myTotalPss; 14013 if (oomProcs[oomIndex] == null) { 14014 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14015 } 14016 oomProcs[oomIndex].add(pssItem); 14017 break; 14018 } 14019 } 14020 } 14021 } 14022 } 14023 14024 long nativeProcTotalPss = 0; 14025 14026 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14027 // If we are showing aggregations, also look for native processes to 14028 // include so that our aggregations are more accurate. 14029 updateCpuStatsNow(); 14030 synchronized (mProcessCpuTracker) { 14031 final int N = mProcessCpuTracker.countStats(); 14032 for (int i=0; i<N; i++) { 14033 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14034 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14035 if (mi == null) { 14036 mi = new Debug.MemoryInfo(); 14037 } 14038 if (!brief && !oomOnly) { 14039 Debug.getMemoryInfo(st.pid, mi); 14040 } else { 14041 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14042 mi.nativePrivateDirty = (int)tmpLong[0]; 14043 } 14044 14045 final long myTotalPss = mi.getTotalPss(); 14046 totalPss += myTotalPss; 14047 nativeProcTotalPss += myTotalPss; 14048 14049 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14050 st.name, myTotalPss, st.pid, false); 14051 procMems.add(pssItem); 14052 14053 nativePss += mi.nativePss; 14054 dalvikPss += mi.dalvikPss; 14055 otherPss += mi.otherPss; 14056 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14057 long mem = mi.getOtherPss(j); 14058 miscPss[j] += mem; 14059 otherPss -= mem; 14060 } 14061 oomPss[0] += myTotalPss; 14062 if (oomProcs[0] == null) { 14063 oomProcs[0] = new ArrayList<MemItem>(); 14064 } 14065 oomProcs[0].add(pssItem); 14066 } 14067 } 14068 } 14069 14070 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14071 14072 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14073 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14074 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14075 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14076 String label = Debug.MemoryInfo.getOtherLabel(j); 14077 catMems.add(new MemItem(label, label, miscPss[j], j)); 14078 } 14079 14080 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14081 for (int j=0; j<oomPss.length; j++) { 14082 if (oomPss[j] != 0) { 14083 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14084 : DUMP_MEM_OOM_LABEL[j]; 14085 MemItem item = new MemItem(label, label, oomPss[j], 14086 DUMP_MEM_OOM_ADJ[j]); 14087 item.subitems = oomProcs[j]; 14088 oomMems.add(item); 14089 } 14090 } 14091 14092 if (!brief && !oomOnly && !isCompact) { 14093 pw.println(); 14094 pw.println("Total PSS by process:"); 14095 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14096 pw.println(); 14097 } 14098 if (!isCompact) { 14099 pw.println("Total PSS by OOM adjustment:"); 14100 } 14101 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14102 if (!brief && !oomOnly) { 14103 PrintWriter out = categoryPw != null ? categoryPw : pw; 14104 if (!isCompact) { 14105 out.println(); 14106 out.println("Total PSS by category:"); 14107 } 14108 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14109 } 14110 if (!isCompact) { 14111 pw.println(); 14112 } 14113 MemInfoReader memInfo = new MemInfoReader(); 14114 memInfo.readMemInfo(); 14115 if (nativeProcTotalPss > 0) { 14116 synchronized (this) { 14117 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14118 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14119 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14120 } 14121 } 14122 if (!brief) { 14123 if (!isCompact) { 14124 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14125 pw.print(" kB (status "); 14126 switch (mLastMemoryLevel) { 14127 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14128 pw.println("normal)"); 14129 break; 14130 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14131 pw.println("moderate)"); 14132 break; 14133 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14134 pw.println("low)"); 14135 break; 14136 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14137 pw.println("critical)"); 14138 break; 14139 default: 14140 pw.print(mLastMemoryLevel); 14141 pw.println(")"); 14142 break; 14143 } 14144 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14145 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14146 pw.print(cachedPss); pw.print(" cached pss + "); 14147 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14148 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14149 } else { 14150 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14151 pw.print(cachedPss + memInfo.getCachedSizeKb() 14152 + memInfo.getFreeSizeKb()); pw.print(","); 14153 pw.println(totalPss - cachedPss); 14154 } 14155 } 14156 if (!isCompact) { 14157 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14158 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14159 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14160 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14161 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14162 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14163 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14164 } 14165 if (!brief) { 14166 if (memInfo.getZramTotalSizeKb() != 0) { 14167 if (!isCompact) { 14168 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14169 pw.print(" kB physical used for "); 14170 pw.print(memInfo.getSwapTotalSizeKb() 14171 - memInfo.getSwapFreeSizeKb()); 14172 pw.print(" kB in swap ("); 14173 pw.print(memInfo.getSwapTotalSizeKb()); 14174 pw.println(" kB total swap)"); 14175 } else { 14176 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14177 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14178 pw.println(memInfo.getSwapFreeSizeKb()); 14179 } 14180 } 14181 final long[] ksm = getKsmInfo(); 14182 if (!isCompact) { 14183 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14184 || ksm[KSM_VOLATILE] != 0) { 14185 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14186 pw.print(" kB saved from shared "); 14187 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14188 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14189 pw.print(" kB unshared; "); 14190 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14191 } 14192 pw.print(" Tuning: "); 14193 pw.print(ActivityManager.staticGetMemoryClass()); 14194 pw.print(" (large "); 14195 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14196 pw.print("), oom "); 14197 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14198 pw.print(" kB"); 14199 pw.print(", restore limit "); 14200 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14201 pw.print(" kB"); 14202 if (ActivityManager.isLowRamDeviceStatic()) { 14203 pw.print(" (low-ram)"); 14204 } 14205 if (ActivityManager.isHighEndGfx()) { 14206 pw.print(" (high-end-gfx)"); 14207 } 14208 pw.println(); 14209 } else { 14210 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14211 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14212 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14213 pw.print("tuning,"); 14214 pw.print(ActivityManager.staticGetMemoryClass()); 14215 pw.print(','); 14216 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14217 pw.print(','); 14218 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14219 if (ActivityManager.isLowRamDeviceStatic()) { 14220 pw.print(",low-ram"); 14221 } 14222 if (ActivityManager.isHighEndGfx()) { 14223 pw.print(",high-end-gfx"); 14224 } 14225 pw.println(); 14226 } 14227 } 14228 } 14229 } 14230 14231 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14232 String name) { 14233 sb.append(" "); 14234 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14235 sb.append(' '); 14236 sb.append(ProcessList.makeProcStateString(procState)); 14237 sb.append(' '); 14238 ProcessList.appendRamKb(sb, pss); 14239 sb.append(" kB: "); 14240 sb.append(name); 14241 } 14242 14243 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14244 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14245 sb.append(" ("); 14246 sb.append(mi.pid); 14247 sb.append(") "); 14248 sb.append(mi.adjType); 14249 sb.append('\n'); 14250 if (mi.adjReason != null) { 14251 sb.append(" "); 14252 sb.append(mi.adjReason); 14253 sb.append('\n'); 14254 } 14255 } 14256 14257 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14258 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14259 for (int i=0, N=memInfos.size(); i<N; i++) { 14260 ProcessMemInfo mi = memInfos.get(i); 14261 infoMap.put(mi.pid, mi); 14262 } 14263 updateCpuStatsNow(); 14264 synchronized (mProcessCpuTracker) { 14265 final int N = mProcessCpuTracker.countStats(); 14266 for (int i=0; i<N; i++) { 14267 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14268 if (st.vsize > 0) { 14269 long pss = Debug.getPss(st.pid, null); 14270 if (pss > 0) { 14271 if (infoMap.indexOfKey(st.pid) < 0) { 14272 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14273 ProcessList.NATIVE_ADJ, -1, "native", null); 14274 mi.pss = pss; 14275 memInfos.add(mi); 14276 } 14277 } 14278 } 14279 } 14280 } 14281 14282 long totalPss = 0; 14283 for (int i=0, N=memInfos.size(); i<N; i++) { 14284 ProcessMemInfo mi = memInfos.get(i); 14285 if (mi.pss == 0) { 14286 mi.pss = Debug.getPss(mi.pid, null); 14287 } 14288 totalPss += mi.pss; 14289 } 14290 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14291 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14292 if (lhs.oomAdj != rhs.oomAdj) { 14293 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14294 } 14295 if (lhs.pss != rhs.pss) { 14296 return lhs.pss < rhs.pss ? 1 : -1; 14297 } 14298 return 0; 14299 } 14300 }); 14301 14302 StringBuilder tag = new StringBuilder(128); 14303 StringBuilder stack = new StringBuilder(128); 14304 tag.append("Low on memory -- "); 14305 appendMemBucket(tag, totalPss, "total", false); 14306 appendMemBucket(stack, totalPss, "total", true); 14307 14308 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14309 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14310 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14311 14312 boolean firstLine = true; 14313 int lastOomAdj = Integer.MIN_VALUE; 14314 long extraNativeRam = 0; 14315 long cachedPss = 0; 14316 for (int i=0, N=memInfos.size(); i<N; i++) { 14317 ProcessMemInfo mi = memInfos.get(i); 14318 14319 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14320 cachedPss += mi.pss; 14321 } 14322 14323 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14324 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14325 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14326 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14327 if (lastOomAdj != mi.oomAdj) { 14328 lastOomAdj = mi.oomAdj; 14329 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14330 tag.append(" / "); 14331 } 14332 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14333 if (firstLine) { 14334 stack.append(":"); 14335 firstLine = false; 14336 } 14337 stack.append("\n\t at "); 14338 } else { 14339 stack.append("$"); 14340 } 14341 } else { 14342 tag.append(" "); 14343 stack.append("$"); 14344 } 14345 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14346 appendMemBucket(tag, mi.pss, mi.name, false); 14347 } 14348 appendMemBucket(stack, mi.pss, mi.name, true); 14349 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14350 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14351 stack.append("("); 14352 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14353 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14354 stack.append(DUMP_MEM_OOM_LABEL[k]); 14355 stack.append(":"); 14356 stack.append(DUMP_MEM_OOM_ADJ[k]); 14357 } 14358 } 14359 stack.append(")"); 14360 } 14361 } 14362 14363 appendMemInfo(fullNativeBuilder, mi); 14364 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14365 // The short form only has native processes that are >= 1MB. 14366 if (mi.pss >= 1000) { 14367 appendMemInfo(shortNativeBuilder, mi); 14368 } else { 14369 extraNativeRam += mi.pss; 14370 } 14371 } else { 14372 // Short form has all other details, but if we have collected RAM 14373 // from smaller native processes let's dump a summary of that. 14374 if (extraNativeRam > 0) { 14375 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14376 -1, extraNativeRam, "(Other native)"); 14377 shortNativeBuilder.append('\n'); 14378 extraNativeRam = 0; 14379 } 14380 appendMemInfo(fullJavaBuilder, mi); 14381 } 14382 } 14383 14384 fullJavaBuilder.append(" "); 14385 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14386 fullJavaBuilder.append(" kB: TOTAL\n"); 14387 14388 MemInfoReader memInfo = new MemInfoReader(); 14389 memInfo.readMemInfo(); 14390 final long[] infos = memInfo.getRawInfo(); 14391 14392 StringBuilder memInfoBuilder = new StringBuilder(1024); 14393 Debug.getMemInfo(infos); 14394 memInfoBuilder.append(" MemInfo: "); 14395 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14396 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14397 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14398 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14399 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14400 memInfoBuilder.append(" "); 14401 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14402 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14403 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14404 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14405 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14406 memInfoBuilder.append(" ZRAM: "); 14407 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14408 memInfoBuilder.append(" kB RAM, "); 14409 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14410 memInfoBuilder.append(" kB swap total, "); 14411 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14412 memInfoBuilder.append(" kB swap free\n"); 14413 } 14414 final long[] ksm = getKsmInfo(); 14415 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14416 || ksm[KSM_VOLATILE] != 0) { 14417 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14418 memInfoBuilder.append(" kB saved from shared "); 14419 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14420 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14421 memInfoBuilder.append(" kB unshared; "); 14422 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14423 } 14424 memInfoBuilder.append(" Free RAM: "); 14425 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14426 + memInfo.getFreeSizeKb()); 14427 memInfoBuilder.append(" kB\n"); 14428 memInfoBuilder.append(" Used RAM: "); 14429 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14430 memInfoBuilder.append(" kB\n"); 14431 memInfoBuilder.append(" Lost RAM: "); 14432 memInfoBuilder.append(memInfo.getTotalSizeKb() 14433 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14434 - memInfo.getKernelUsedSizeKb()); 14435 memInfoBuilder.append(" kB\n"); 14436 Slog.i(TAG, "Low on memory:"); 14437 Slog.i(TAG, shortNativeBuilder.toString()); 14438 Slog.i(TAG, fullJavaBuilder.toString()); 14439 Slog.i(TAG, memInfoBuilder.toString()); 14440 14441 StringBuilder dropBuilder = new StringBuilder(1024); 14442 /* 14443 StringWriter oomSw = new StringWriter(); 14444 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14445 StringWriter catSw = new StringWriter(); 14446 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14447 String[] emptyArgs = new String[] { }; 14448 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14449 oomPw.flush(); 14450 String oomString = oomSw.toString(); 14451 */ 14452 dropBuilder.append("Low on memory:"); 14453 dropBuilder.append(stack); 14454 dropBuilder.append('\n'); 14455 dropBuilder.append(fullNativeBuilder); 14456 dropBuilder.append(fullJavaBuilder); 14457 dropBuilder.append('\n'); 14458 dropBuilder.append(memInfoBuilder); 14459 dropBuilder.append('\n'); 14460 /* 14461 dropBuilder.append(oomString); 14462 dropBuilder.append('\n'); 14463 */ 14464 StringWriter catSw = new StringWriter(); 14465 synchronized (ActivityManagerService.this) { 14466 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14467 String[] emptyArgs = new String[] { }; 14468 catPw.println(); 14469 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14470 catPw.println(); 14471 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14472 false, false, null); 14473 catPw.println(); 14474 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14475 catPw.flush(); 14476 } 14477 dropBuilder.append(catSw.toString()); 14478 addErrorToDropBox("lowmem", null, "system_server", null, 14479 null, tag.toString(), dropBuilder.toString(), null, null); 14480 //Slog.i(TAG, "Sent to dropbox:"); 14481 //Slog.i(TAG, dropBuilder.toString()); 14482 synchronized (ActivityManagerService.this) { 14483 long now = SystemClock.uptimeMillis(); 14484 if (mLastMemUsageReportTime < now) { 14485 mLastMemUsageReportTime = now; 14486 } 14487 } 14488 } 14489 14490 /** 14491 * Searches array of arguments for the specified string 14492 * @param args array of argument strings 14493 * @param value value to search for 14494 * @return true if the value is contained in the array 14495 */ 14496 private static boolean scanArgs(String[] args, String value) { 14497 if (args != null) { 14498 for (String arg : args) { 14499 if (value.equals(arg)) { 14500 return true; 14501 } 14502 } 14503 } 14504 return false; 14505 } 14506 14507 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14508 ContentProviderRecord cpr, boolean always) { 14509 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14510 14511 if (!inLaunching || always) { 14512 synchronized (cpr) { 14513 cpr.launchingApp = null; 14514 cpr.notifyAll(); 14515 } 14516 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14517 String names[] = cpr.info.authority.split(";"); 14518 for (int j = 0; j < names.length; j++) { 14519 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14520 } 14521 } 14522 14523 for (int i=0; i<cpr.connections.size(); i++) { 14524 ContentProviderConnection conn = cpr.connections.get(i); 14525 if (conn.waiting) { 14526 // If this connection is waiting for the provider, then we don't 14527 // need to mess with its process unless we are always removing 14528 // or for some reason the provider is not currently launching. 14529 if (inLaunching && !always) { 14530 continue; 14531 } 14532 } 14533 ProcessRecord capp = conn.client; 14534 conn.dead = true; 14535 if (conn.stableCount > 0) { 14536 if (!capp.persistent && capp.thread != null 14537 && capp.pid != 0 14538 && capp.pid != MY_PID) { 14539 capp.kill("depends on provider " 14540 + cpr.name.flattenToShortString() 14541 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14542 } 14543 } else if (capp.thread != null && conn.provider.provider != null) { 14544 try { 14545 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14546 } catch (RemoteException e) { 14547 } 14548 // In the protocol here, we don't expect the client to correctly 14549 // clean up this connection, we'll just remove it. 14550 cpr.connections.remove(i); 14551 conn.client.conProviders.remove(conn); 14552 } 14553 } 14554 14555 if (inLaunching && always) { 14556 mLaunchingProviders.remove(cpr); 14557 } 14558 return inLaunching; 14559 } 14560 14561 /** 14562 * Main code for cleaning up a process when it has gone away. This is 14563 * called both as a result of the process dying, or directly when stopping 14564 * a process when running in single process mode. 14565 * 14566 * @return Returns true if the given process has been restarted, so the 14567 * app that was passed in must remain on the process lists. 14568 */ 14569 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14570 boolean restarting, boolean allowRestart, int index) { 14571 if (index >= 0) { 14572 removeLruProcessLocked(app); 14573 ProcessList.remove(app.pid); 14574 } 14575 14576 mProcessesToGc.remove(app); 14577 mPendingPssProcesses.remove(app); 14578 14579 // Dismiss any open dialogs. 14580 if (app.crashDialog != null && !app.forceCrashReport) { 14581 app.crashDialog.dismiss(); 14582 app.crashDialog = null; 14583 } 14584 if (app.anrDialog != null) { 14585 app.anrDialog.dismiss(); 14586 app.anrDialog = null; 14587 } 14588 if (app.waitDialog != null) { 14589 app.waitDialog.dismiss(); 14590 app.waitDialog = null; 14591 } 14592 14593 app.crashing = false; 14594 app.notResponding = false; 14595 14596 app.resetPackageList(mProcessStats); 14597 app.unlinkDeathRecipient(); 14598 app.makeInactive(mProcessStats); 14599 app.waitingToKill = null; 14600 app.forcingToForeground = null; 14601 updateProcessForegroundLocked(app, false, false); 14602 app.foregroundActivities = false; 14603 app.hasShownUi = false; 14604 app.treatLikeActivity = false; 14605 app.hasAboveClient = false; 14606 app.hasClientActivities = false; 14607 14608 mServices.killServicesLocked(app, allowRestart); 14609 14610 boolean restart = false; 14611 14612 // Remove published content providers. 14613 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14614 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14615 final boolean always = app.bad || !allowRestart; 14616 if (removeDyingProviderLocked(app, cpr, always) || always) { 14617 // We left the provider in the launching list, need to 14618 // restart it. 14619 restart = true; 14620 } 14621 14622 cpr.provider = null; 14623 cpr.proc = null; 14624 } 14625 app.pubProviders.clear(); 14626 14627 // Take care of any launching providers waiting for this process. 14628 if (checkAppInLaunchingProvidersLocked(app, false)) { 14629 restart = true; 14630 } 14631 14632 // Unregister from connected content providers. 14633 if (!app.conProviders.isEmpty()) { 14634 for (int i=0; i<app.conProviders.size(); i++) { 14635 ContentProviderConnection conn = app.conProviders.get(i); 14636 conn.provider.connections.remove(conn); 14637 } 14638 app.conProviders.clear(); 14639 } 14640 14641 // At this point there may be remaining entries in mLaunchingProviders 14642 // where we were the only one waiting, so they are no longer of use. 14643 // Look for these and clean up if found. 14644 // XXX Commented out for now. Trying to figure out a way to reproduce 14645 // the actual situation to identify what is actually going on. 14646 if (false) { 14647 for (int i=0; i<mLaunchingProviders.size(); i++) { 14648 ContentProviderRecord cpr = (ContentProviderRecord) 14649 mLaunchingProviders.get(i); 14650 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14651 synchronized (cpr) { 14652 cpr.launchingApp = null; 14653 cpr.notifyAll(); 14654 } 14655 } 14656 } 14657 } 14658 14659 skipCurrentReceiverLocked(app); 14660 14661 // Unregister any receivers. 14662 for (int i=app.receivers.size()-1; i>=0; i--) { 14663 removeReceiverLocked(app.receivers.valueAt(i)); 14664 } 14665 app.receivers.clear(); 14666 14667 // If the app is undergoing backup, tell the backup manager about it 14668 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14669 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14670 + mBackupTarget.appInfo + " died during backup"); 14671 try { 14672 IBackupManager bm = IBackupManager.Stub.asInterface( 14673 ServiceManager.getService(Context.BACKUP_SERVICE)); 14674 bm.agentDisconnected(app.info.packageName); 14675 } catch (RemoteException e) { 14676 // can't happen; backup manager is local 14677 } 14678 } 14679 14680 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14681 ProcessChangeItem item = mPendingProcessChanges.get(i); 14682 if (item.pid == app.pid) { 14683 mPendingProcessChanges.remove(i); 14684 mAvailProcessChanges.add(item); 14685 } 14686 } 14687 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14688 14689 // If the caller is restarting this app, then leave it in its 14690 // current lists and let the caller take care of it. 14691 if (restarting) { 14692 return false; 14693 } 14694 14695 if (!app.persistent || app.isolated) { 14696 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14697 "Removing non-persistent process during cleanup: " + app); 14698 mProcessNames.remove(app.processName, app.uid); 14699 mIsolatedProcesses.remove(app.uid); 14700 if (mHeavyWeightProcess == app) { 14701 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14702 mHeavyWeightProcess.userId, 0)); 14703 mHeavyWeightProcess = null; 14704 } 14705 } else if (!app.removed) { 14706 // This app is persistent, so we need to keep its record around. 14707 // If it is not already on the pending app list, add it there 14708 // and start a new process for it. 14709 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14710 mPersistentStartingProcesses.add(app); 14711 restart = true; 14712 } 14713 } 14714 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14715 "Clean-up removing on hold: " + app); 14716 mProcessesOnHold.remove(app); 14717 14718 if (app == mHomeProcess) { 14719 mHomeProcess = null; 14720 } 14721 if (app == mPreviousProcess) { 14722 mPreviousProcess = null; 14723 } 14724 14725 if (restart && !app.isolated) { 14726 // We have components that still need to be running in the 14727 // process, so re-launch it. 14728 if (index < 0) { 14729 ProcessList.remove(app.pid); 14730 } 14731 mProcessNames.put(app.processName, app.uid, app); 14732 startProcessLocked(app, "restart", app.processName); 14733 return true; 14734 } else if (app.pid > 0 && app.pid != MY_PID) { 14735 // Goodbye! 14736 boolean removed; 14737 synchronized (mPidsSelfLocked) { 14738 mPidsSelfLocked.remove(app.pid); 14739 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14740 } 14741 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14742 if (app.isolated) { 14743 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14744 } 14745 app.setPid(0); 14746 } 14747 return false; 14748 } 14749 14750 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14751 // Look through the content providers we are waiting to have launched, 14752 // and if any run in this process then either schedule a restart of 14753 // the process or kill the client waiting for it if this process has 14754 // gone bad. 14755 int NL = mLaunchingProviders.size(); 14756 boolean restart = false; 14757 for (int i=0; i<NL; i++) { 14758 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14759 if (cpr.launchingApp == app) { 14760 if (!alwaysBad && !app.bad) { 14761 restart = true; 14762 } else { 14763 removeDyingProviderLocked(app, cpr, true); 14764 // cpr should have been removed from mLaunchingProviders 14765 NL = mLaunchingProviders.size(); 14766 i--; 14767 } 14768 } 14769 } 14770 return restart; 14771 } 14772 14773 // ========================================================= 14774 // SERVICES 14775 // ========================================================= 14776 14777 @Override 14778 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14779 int flags) { 14780 enforceNotIsolatedCaller("getServices"); 14781 synchronized (this) { 14782 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14783 } 14784 } 14785 14786 @Override 14787 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14788 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14789 synchronized (this) { 14790 return mServices.getRunningServiceControlPanelLocked(name); 14791 } 14792 } 14793 14794 @Override 14795 public ComponentName startService(IApplicationThread caller, Intent service, 14796 String resolvedType, int userId) { 14797 enforceNotIsolatedCaller("startService"); 14798 // Refuse possible leaked file descriptors 14799 if (service != null && service.hasFileDescriptors() == true) { 14800 throw new IllegalArgumentException("File descriptors passed in Intent"); 14801 } 14802 14803 if (DEBUG_SERVICE) 14804 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14805 synchronized(this) { 14806 final int callingPid = Binder.getCallingPid(); 14807 final int callingUid = Binder.getCallingUid(); 14808 final long origId = Binder.clearCallingIdentity(); 14809 ComponentName res = mServices.startServiceLocked(caller, service, 14810 resolvedType, callingPid, callingUid, userId); 14811 Binder.restoreCallingIdentity(origId); 14812 return res; 14813 } 14814 } 14815 14816 ComponentName startServiceInPackage(int uid, 14817 Intent service, String resolvedType, int userId) { 14818 synchronized(this) { 14819 if (DEBUG_SERVICE) 14820 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14821 final long origId = Binder.clearCallingIdentity(); 14822 ComponentName res = mServices.startServiceLocked(null, service, 14823 resolvedType, -1, uid, userId); 14824 Binder.restoreCallingIdentity(origId); 14825 return res; 14826 } 14827 } 14828 14829 @Override 14830 public int stopService(IApplicationThread caller, Intent service, 14831 String resolvedType, int userId) { 14832 enforceNotIsolatedCaller("stopService"); 14833 // Refuse possible leaked file descriptors 14834 if (service != null && service.hasFileDescriptors() == true) { 14835 throw new IllegalArgumentException("File descriptors passed in Intent"); 14836 } 14837 14838 synchronized(this) { 14839 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14840 } 14841 } 14842 14843 @Override 14844 public IBinder peekService(Intent service, String resolvedType) { 14845 enforceNotIsolatedCaller("peekService"); 14846 // Refuse possible leaked file descriptors 14847 if (service != null && service.hasFileDescriptors() == true) { 14848 throw new IllegalArgumentException("File descriptors passed in Intent"); 14849 } 14850 synchronized(this) { 14851 return mServices.peekServiceLocked(service, resolvedType); 14852 } 14853 } 14854 14855 @Override 14856 public boolean stopServiceToken(ComponentName className, IBinder token, 14857 int startId) { 14858 synchronized(this) { 14859 return mServices.stopServiceTokenLocked(className, token, startId); 14860 } 14861 } 14862 14863 @Override 14864 public void setServiceForeground(ComponentName className, IBinder token, 14865 int id, Notification notification, boolean removeNotification) { 14866 synchronized(this) { 14867 mServices.setServiceForegroundLocked(className, token, id, notification, 14868 removeNotification); 14869 } 14870 } 14871 14872 @Override 14873 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14874 boolean requireFull, String name, String callerPackage) { 14875 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14876 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14877 } 14878 14879 int unsafeConvertIncomingUser(int userId) { 14880 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14881 ? mCurrentUserId : userId; 14882 } 14883 14884 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14885 int allowMode, String name, String callerPackage) { 14886 final int callingUserId = UserHandle.getUserId(callingUid); 14887 if (callingUserId == userId) { 14888 return userId; 14889 } 14890 14891 // Note that we may be accessing mCurrentUserId outside of a lock... 14892 // shouldn't be a big deal, if this is being called outside 14893 // of a locked context there is intrinsically a race with 14894 // the value the caller will receive and someone else changing it. 14895 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14896 // we will switch to the calling user if access to the current user fails. 14897 int targetUserId = unsafeConvertIncomingUser(userId); 14898 14899 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14900 final boolean allow; 14901 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14902 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14903 // If the caller has this permission, they always pass go. And collect $200. 14904 allow = true; 14905 } else if (allowMode == ALLOW_FULL_ONLY) { 14906 // We require full access, sucks to be you. 14907 allow = false; 14908 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14909 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14910 // If the caller does not have either permission, they are always doomed. 14911 allow = false; 14912 } else if (allowMode == ALLOW_NON_FULL) { 14913 // We are blanket allowing non-full access, you lucky caller! 14914 allow = true; 14915 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14916 // We may or may not allow this depending on whether the two users are 14917 // in the same profile. 14918 synchronized (mUserProfileGroupIdsSelfLocked) { 14919 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14920 UserInfo.NO_PROFILE_GROUP_ID); 14921 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14922 UserInfo.NO_PROFILE_GROUP_ID); 14923 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14924 && callingProfile == targetProfile; 14925 } 14926 } else { 14927 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14928 } 14929 if (!allow) { 14930 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14931 // In this case, they would like to just execute as their 14932 // owner user instead of failing. 14933 targetUserId = callingUserId; 14934 } else { 14935 StringBuilder builder = new StringBuilder(128); 14936 builder.append("Permission Denial: "); 14937 builder.append(name); 14938 if (callerPackage != null) { 14939 builder.append(" from "); 14940 builder.append(callerPackage); 14941 } 14942 builder.append(" asks to run as user "); 14943 builder.append(userId); 14944 builder.append(" but is calling from user "); 14945 builder.append(UserHandle.getUserId(callingUid)); 14946 builder.append("; this requires "); 14947 builder.append(INTERACT_ACROSS_USERS_FULL); 14948 if (allowMode != ALLOW_FULL_ONLY) { 14949 builder.append(" or "); 14950 builder.append(INTERACT_ACROSS_USERS); 14951 } 14952 String msg = builder.toString(); 14953 Slog.w(TAG, msg); 14954 throw new SecurityException(msg); 14955 } 14956 } 14957 } 14958 if (!allowAll && targetUserId < 0) { 14959 throw new IllegalArgumentException( 14960 "Call does not support special user #" + targetUserId); 14961 } 14962 // Check shell permission 14963 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14964 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14965 targetUserId)) { 14966 throw new SecurityException("Shell does not have permission to access user " 14967 + targetUserId + "\n " + Debug.getCallers(3)); 14968 } 14969 } 14970 return targetUserId; 14971 } 14972 14973 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14974 String className, int flags) { 14975 boolean result = false; 14976 // For apps that don't have pre-defined UIDs, check for permission 14977 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14978 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14979 if (ActivityManager.checkUidPermission( 14980 INTERACT_ACROSS_USERS, 14981 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14982 ComponentName comp = new ComponentName(aInfo.packageName, className); 14983 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14984 + " requests FLAG_SINGLE_USER, but app does not hold " 14985 + INTERACT_ACROSS_USERS; 14986 Slog.w(TAG, msg); 14987 throw new SecurityException(msg); 14988 } 14989 // Permission passed 14990 result = true; 14991 } 14992 } else if ("system".equals(componentProcessName)) { 14993 result = true; 14994 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14995 // Phone app and persistent apps are allowed to export singleuser providers. 14996 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14997 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14998 } 14999 if (DEBUG_MU) { 15000 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15001 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15002 } 15003 return result; 15004 } 15005 15006 /** 15007 * Checks to see if the caller is in the same app as the singleton 15008 * component, or the component is in a special app. It allows special apps 15009 * to export singleton components but prevents exporting singleton 15010 * components for regular apps. 15011 */ 15012 boolean isValidSingletonCall(int callingUid, int componentUid) { 15013 int componentAppId = UserHandle.getAppId(componentUid); 15014 return UserHandle.isSameApp(callingUid, componentUid) 15015 || componentAppId == Process.SYSTEM_UID 15016 || componentAppId == Process.PHONE_UID 15017 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15018 == PackageManager.PERMISSION_GRANTED; 15019 } 15020 15021 public int bindService(IApplicationThread caller, IBinder token, 15022 Intent service, String resolvedType, 15023 IServiceConnection connection, int flags, int userId) { 15024 enforceNotIsolatedCaller("bindService"); 15025 15026 // Refuse possible leaked file descriptors 15027 if (service != null && service.hasFileDescriptors() == true) { 15028 throw new IllegalArgumentException("File descriptors passed in Intent"); 15029 } 15030 15031 synchronized(this) { 15032 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15033 connection, flags, userId); 15034 } 15035 } 15036 15037 public boolean unbindService(IServiceConnection connection) { 15038 synchronized (this) { 15039 return mServices.unbindServiceLocked(connection); 15040 } 15041 } 15042 15043 public void publishService(IBinder token, Intent intent, IBinder service) { 15044 // Refuse possible leaked file descriptors 15045 if (intent != null && intent.hasFileDescriptors() == true) { 15046 throw new IllegalArgumentException("File descriptors passed in Intent"); 15047 } 15048 15049 synchronized(this) { 15050 if (!(token instanceof ServiceRecord)) { 15051 throw new IllegalArgumentException("Invalid service token"); 15052 } 15053 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15054 } 15055 } 15056 15057 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 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 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15065 } 15066 } 15067 15068 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15069 synchronized(this) { 15070 if (!(token instanceof ServiceRecord)) { 15071 throw new IllegalArgumentException("Invalid service token"); 15072 } 15073 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15074 } 15075 } 15076 15077 // ========================================================= 15078 // BACKUP AND RESTORE 15079 // ========================================================= 15080 15081 // Cause the target app to be launched if necessary and its backup agent 15082 // instantiated. The backup agent will invoke backupAgentCreated() on the 15083 // activity manager to announce its creation. 15084 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15085 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15086 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15087 15088 synchronized(this) { 15089 // !!! TODO: currently no check here that we're already bound 15090 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15091 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15092 synchronized (stats) { 15093 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15094 } 15095 15096 // Backup agent is now in use, its package can't be stopped. 15097 try { 15098 AppGlobals.getPackageManager().setPackageStoppedState( 15099 app.packageName, false, UserHandle.getUserId(app.uid)); 15100 } catch (RemoteException e) { 15101 } catch (IllegalArgumentException e) { 15102 Slog.w(TAG, "Failed trying to unstop package " 15103 + app.packageName + ": " + e); 15104 } 15105 15106 BackupRecord r = new BackupRecord(ss, app, backupMode); 15107 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15108 ? new ComponentName(app.packageName, app.backupAgentName) 15109 : new ComponentName("android", "FullBackupAgent"); 15110 // startProcessLocked() returns existing proc's record if it's already running 15111 ProcessRecord proc = startProcessLocked(app.processName, app, 15112 false, 0, "backup", hostingName, false, false, false); 15113 if (proc == null) { 15114 Slog.e(TAG, "Unable to start backup agent process " + r); 15115 return false; 15116 } 15117 15118 r.app = proc; 15119 mBackupTarget = r; 15120 mBackupAppName = app.packageName; 15121 15122 // Try not to kill the process during backup 15123 updateOomAdjLocked(proc); 15124 15125 // If the process is already attached, schedule the creation of the backup agent now. 15126 // If it is not yet live, this will be done when it attaches to the framework. 15127 if (proc.thread != null) { 15128 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15129 try { 15130 proc.thread.scheduleCreateBackupAgent(app, 15131 compatibilityInfoForPackageLocked(app), backupMode); 15132 } catch (RemoteException e) { 15133 // Will time out on the backup manager side 15134 } 15135 } else { 15136 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15137 } 15138 // Invariants: at this point, the target app process exists and the application 15139 // is either already running or in the process of coming up. mBackupTarget and 15140 // mBackupAppName describe the app, so that when it binds back to the AM we 15141 // know that it's scheduled for a backup-agent operation. 15142 } 15143 15144 return true; 15145 } 15146 15147 @Override 15148 public void clearPendingBackup() { 15149 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15150 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15151 15152 synchronized (this) { 15153 mBackupTarget = null; 15154 mBackupAppName = null; 15155 } 15156 } 15157 15158 // A backup agent has just come up 15159 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15160 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15161 + " = " + agent); 15162 15163 synchronized(this) { 15164 if (!agentPackageName.equals(mBackupAppName)) { 15165 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15166 return; 15167 } 15168 } 15169 15170 long oldIdent = Binder.clearCallingIdentity(); 15171 try { 15172 IBackupManager bm = IBackupManager.Stub.asInterface( 15173 ServiceManager.getService(Context.BACKUP_SERVICE)); 15174 bm.agentConnected(agentPackageName, agent); 15175 } catch (RemoteException e) { 15176 // can't happen; the backup manager service is local 15177 } catch (Exception e) { 15178 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15179 e.printStackTrace(); 15180 } finally { 15181 Binder.restoreCallingIdentity(oldIdent); 15182 } 15183 } 15184 15185 // done with this agent 15186 public void unbindBackupAgent(ApplicationInfo appInfo) { 15187 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15188 if (appInfo == null) { 15189 Slog.w(TAG, "unbind backup agent for null app"); 15190 return; 15191 } 15192 15193 synchronized(this) { 15194 try { 15195 if (mBackupAppName == null) { 15196 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15197 return; 15198 } 15199 15200 if (!mBackupAppName.equals(appInfo.packageName)) { 15201 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15202 return; 15203 } 15204 15205 // Not backing this app up any more; reset its OOM adjustment 15206 final ProcessRecord proc = mBackupTarget.app; 15207 updateOomAdjLocked(proc); 15208 15209 // If the app crashed during backup, 'thread' will be null here 15210 if (proc.thread != null) { 15211 try { 15212 proc.thread.scheduleDestroyBackupAgent(appInfo, 15213 compatibilityInfoForPackageLocked(appInfo)); 15214 } catch (Exception e) { 15215 Slog.e(TAG, "Exception when unbinding backup agent:"); 15216 e.printStackTrace(); 15217 } 15218 } 15219 } finally { 15220 mBackupTarget = null; 15221 mBackupAppName = null; 15222 } 15223 } 15224 } 15225 // ========================================================= 15226 // BROADCASTS 15227 // ========================================================= 15228 15229 private final List getStickiesLocked(String action, IntentFilter filter, 15230 List cur, int userId) { 15231 final ContentResolver resolver = mContext.getContentResolver(); 15232 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15233 if (stickies == null) { 15234 return cur; 15235 } 15236 final ArrayList<Intent> list = stickies.get(action); 15237 if (list == null) { 15238 return cur; 15239 } 15240 int N = list.size(); 15241 for (int i=0; i<N; i++) { 15242 Intent intent = list.get(i); 15243 if (filter.match(resolver, intent, true, TAG) >= 0) { 15244 if (cur == null) { 15245 cur = new ArrayList<Intent>(); 15246 } 15247 cur.add(intent); 15248 } 15249 } 15250 return cur; 15251 } 15252 15253 boolean isPendingBroadcastProcessLocked(int pid) { 15254 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15255 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15256 } 15257 15258 void skipPendingBroadcastLocked(int pid) { 15259 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15260 for (BroadcastQueue queue : mBroadcastQueues) { 15261 queue.skipPendingBroadcastLocked(pid); 15262 } 15263 } 15264 15265 // The app just attached; send any pending broadcasts that it should receive 15266 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15267 boolean didSomething = false; 15268 for (BroadcastQueue queue : mBroadcastQueues) { 15269 didSomething |= queue.sendPendingBroadcastsLocked(app); 15270 } 15271 return didSomething; 15272 } 15273 15274 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15275 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15276 enforceNotIsolatedCaller("registerReceiver"); 15277 int callingUid; 15278 int callingPid; 15279 synchronized(this) { 15280 ProcessRecord callerApp = null; 15281 if (caller != null) { 15282 callerApp = getRecordForAppLocked(caller); 15283 if (callerApp == null) { 15284 throw new SecurityException( 15285 "Unable to find app for caller " + caller 15286 + " (pid=" + Binder.getCallingPid() 15287 + ") when registering receiver " + receiver); 15288 } 15289 if (callerApp.info.uid != Process.SYSTEM_UID && 15290 !callerApp.pkgList.containsKey(callerPackage) && 15291 !"android".equals(callerPackage)) { 15292 throw new SecurityException("Given caller package " + callerPackage 15293 + " is not running in process " + callerApp); 15294 } 15295 callingUid = callerApp.info.uid; 15296 callingPid = callerApp.pid; 15297 } else { 15298 callerPackage = null; 15299 callingUid = Binder.getCallingUid(); 15300 callingPid = Binder.getCallingPid(); 15301 } 15302 15303 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15304 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15305 15306 List allSticky = null; 15307 15308 // Look for any matching sticky broadcasts... 15309 Iterator actions = filter.actionsIterator(); 15310 if (actions != null) { 15311 while (actions.hasNext()) { 15312 String action = (String)actions.next(); 15313 allSticky = getStickiesLocked(action, filter, allSticky, 15314 UserHandle.USER_ALL); 15315 allSticky = getStickiesLocked(action, filter, allSticky, 15316 UserHandle.getUserId(callingUid)); 15317 } 15318 } else { 15319 allSticky = getStickiesLocked(null, filter, allSticky, 15320 UserHandle.USER_ALL); 15321 allSticky = getStickiesLocked(null, filter, allSticky, 15322 UserHandle.getUserId(callingUid)); 15323 } 15324 15325 // The first sticky in the list is returned directly back to 15326 // the client. 15327 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15328 15329 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15330 + ": " + sticky); 15331 15332 if (receiver == null) { 15333 return sticky; 15334 } 15335 15336 ReceiverList rl 15337 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15338 if (rl == null) { 15339 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15340 userId, receiver); 15341 if (rl.app != null) { 15342 rl.app.receivers.add(rl); 15343 } else { 15344 try { 15345 receiver.asBinder().linkToDeath(rl, 0); 15346 } catch (RemoteException e) { 15347 return sticky; 15348 } 15349 rl.linkedToDeath = true; 15350 } 15351 mRegisteredReceivers.put(receiver.asBinder(), rl); 15352 } else if (rl.uid != callingUid) { 15353 throw new IllegalArgumentException( 15354 "Receiver requested to register for uid " + callingUid 15355 + " was previously registered for uid " + rl.uid); 15356 } else if (rl.pid != callingPid) { 15357 throw new IllegalArgumentException( 15358 "Receiver requested to register for pid " + callingPid 15359 + " was previously registered for pid " + rl.pid); 15360 } else if (rl.userId != userId) { 15361 throw new IllegalArgumentException( 15362 "Receiver requested to register for user " + userId 15363 + " was previously registered for user " + rl.userId); 15364 } 15365 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15366 permission, callingUid, userId); 15367 rl.add(bf); 15368 if (!bf.debugCheck()) { 15369 Slog.w(TAG, "==> For Dynamic broadast"); 15370 } 15371 mReceiverResolver.addFilter(bf); 15372 15373 // Enqueue broadcasts for all existing stickies that match 15374 // this filter. 15375 if (allSticky != null) { 15376 ArrayList receivers = new ArrayList(); 15377 receivers.add(bf); 15378 15379 int N = allSticky.size(); 15380 for (int i=0; i<N; i++) { 15381 Intent intent = (Intent)allSticky.get(i); 15382 BroadcastQueue queue = broadcastQueueForIntent(intent); 15383 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15384 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15385 null, null, false, true, true, -1); 15386 queue.enqueueParallelBroadcastLocked(r); 15387 queue.scheduleBroadcastsLocked(); 15388 } 15389 } 15390 15391 return sticky; 15392 } 15393 } 15394 15395 public void unregisterReceiver(IIntentReceiver receiver) { 15396 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15397 15398 final long origId = Binder.clearCallingIdentity(); 15399 try { 15400 boolean doTrim = false; 15401 15402 synchronized(this) { 15403 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15404 if (rl != null) { 15405 if (rl.curBroadcast != null) { 15406 BroadcastRecord r = rl.curBroadcast; 15407 final boolean doNext = finishReceiverLocked( 15408 receiver.asBinder(), r.resultCode, r.resultData, 15409 r.resultExtras, r.resultAbort); 15410 if (doNext) { 15411 doTrim = true; 15412 r.queue.processNextBroadcast(false); 15413 } 15414 } 15415 15416 if (rl.app != null) { 15417 rl.app.receivers.remove(rl); 15418 } 15419 removeReceiverLocked(rl); 15420 if (rl.linkedToDeath) { 15421 rl.linkedToDeath = false; 15422 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15423 } 15424 } 15425 } 15426 15427 // If we actually concluded any broadcasts, we might now be able 15428 // to trim the recipients' apps from our working set 15429 if (doTrim) { 15430 trimApplications(); 15431 return; 15432 } 15433 15434 } finally { 15435 Binder.restoreCallingIdentity(origId); 15436 } 15437 } 15438 15439 void removeReceiverLocked(ReceiverList rl) { 15440 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15441 int N = rl.size(); 15442 for (int i=0; i<N; i++) { 15443 mReceiverResolver.removeFilter(rl.get(i)); 15444 } 15445 } 15446 15447 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15448 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15449 ProcessRecord r = mLruProcesses.get(i); 15450 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15451 try { 15452 r.thread.dispatchPackageBroadcast(cmd, packages); 15453 } catch (RemoteException ex) { 15454 } 15455 } 15456 } 15457 } 15458 15459 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15460 int callingUid, int[] users) { 15461 List<ResolveInfo> receivers = null; 15462 try { 15463 HashSet<ComponentName> singleUserReceivers = null; 15464 boolean scannedFirstReceivers = false; 15465 for (int user : users) { 15466 // Skip users that have Shell restrictions 15467 if (callingUid == Process.SHELL_UID 15468 && getUserManagerLocked().hasUserRestriction( 15469 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15470 continue; 15471 } 15472 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15473 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15474 if (user != 0 && newReceivers != null) { 15475 // If this is not the primary user, we need to check for 15476 // any receivers that should be filtered out. 15477 for (int i=0; i<newReceivers.size(); i++) { 15478 ResolveInfo ri = newReceivers.get(i); 15479 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15480 newReceivers.remove(i); 15481 i--; 15482 } 15483 } 15484 } 15485 if (newReceivers != null && newReceivers.size() == 0) { 15486 newReceivers = null; 15487 } 15488 if (receivers == null) { 15489 receivers = newReceivers; 15490 } else if (newReceivers != null) { 15491 // We need to concatenate the additional receivers 15492 // found with what we have do far. This would be easy, 15493 // but we also need to de-dup any receivers that are 15494 // singleUser. 15495 if (!scannedFirstReceivers) { 15496 // Collect any single user receivers we had already retrieved. 15497 scannedFirstReceivers = true; 15498 for (int i=0; i<receivers.size(); i++) { 15499 ResolveInfo ri = receivers.get(i); 15500 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15501 ComponentName cn = new ComponentName( 15502 ri.activityInfo.packageName, ri.activityInfo.name); 15503 if (singleUserReceivers == null) { 15504 singleUserReceivers = new HashSet<ComponentName>(); 15505 } 15506 singleUserReceivers.add(cn); 15507 } 15508 } 15509 } 15510 // Add the new results to the existing results, tracking 15511 // and de-dupping single user receivers. 15512 for (int i=0; i<newReceivers.size(); i++) { 15513 ResolveInfo ri = newReceivers.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 if (!singleUserReceivers.contains(cn)) { 15521 singleUserReceivers.add(cn); 15522 receivers.add(ri); 15523 } 15524 } else { 15525 receivers.add(ri); 15526 } 15527 } 15528 } 15529 } 15530 } catch (RemoteException ex) { 15531 // pm is in same process, this will never happen. 15532 } 15533 return receivers; 15534 } 15535 15536 private final int broadcastIntentLocked(ProcessRecord callerApp, 15537 String callerPackage, Intent intent, String resolvedType, 15538 IIntentReceiver resultTo, int resultCode, String resultData, 15539 Bundle map, String requiredPermission, int appOp, 15540 boolean ordered, boolean sticky, int callingPid, int callingUid, 15541 int userId) { 15542 intent = new Intent(intent); 15543 15544 // By default broadcasts do not go to stopped apps. 15545 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15546 15547 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15548 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15549 + " ordered=" + ordered + " userid=" + userId); 15550 if ((resultTo != null) && !ordered) { 15551 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15552 } 15553 15554 userId = handleIncomingUser(callingPid, callingUid, userId, 15555 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15556 15557 // Make sure that the user who is receiving this broadcast is started. 15558 // If not, we will just skip it. 15559 15560 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15561 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15562 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15563 Slog.w(TAG, "Skipping broadcast of " + intent 15564 + ": user " + userId + " is stopped"); 15565 return ActivityManager.BROADCAST_SUCCESS; 15566 } 15567 } 15568 15569 /* 15570 * Prevent non-system code (defined here to be non-persistent 15571 * processes) from sending protected broadcasts. 15572 */ 15573 int callingAppId = UserHandle.getAppId(callingUid); 15574 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15575 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15576 || callingAppId == Process.NFC_UID || callingUid == 0) { 15577 // Always okay. 15578 } else if (callerApp == null || !callerApp.persistent) { 15579 try { 15580 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15581 intent.getAction())) { 15582 String msg = "Permission Denial: not allowed to send broadcast " 15583 + intent.getAction() + " from pid=" 15584 + callingPid + ", uid=" + callingUid; 15585 Slog.w(TAG, msg); 15586 throw new SecurityException(msg); 15587 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15588 // Special case for compatibility: we don't want apps to send this, 15589 // but historically it has not been protected and apps may be using it 15590 // to poke their own app widget. So, instead of making it protected, 15591 // just limit it to the caller. 15592 if (callerApp == null) { 15593 String msg = "Permission Denial: not allowed to send broadcast " 15594 + intent.getAction() + " from unknown caller."; 15595 Slog.w(TAG, msg); 15596 throw new SecurityException(msg); 15597 } else if (intent.getComponent() != null) { 15598 // They are good enough to send to an explicit component... verify 15599 // it is being sent to the calling app. 15600 if (!intent.getComponent().getPackageName().equals( 15601 callerApp.info.packageName)) { 15602 String msg = "Permission Denial: not allowed to send broadcast " 15603 + intent.getAction() + " to " 15604 + intent.getComponent().getPackageName() + " from " 15605 + callerApp.info.packageName; 15606 Slog.w(TAG, msg); 15607 throw new SecurityException(msg); 15608 } 15609 } else { 15610 // Limit broadcast to their own package. 15611 intent.setPackage(callerApp.info.packageName); 15612 } 15613 } 15614 } catch (RemoteException e) { 15615 Slog.w(TAG, "Remote exception", e); 15616 return ActivityManager.BROADCAST_SUCCESS; 15617 } 15618 } 15619 15620 // Handle special intents: if this broadcast is from the package 15621 // manager about a package being removed, we need to remove all of 15622 // its activities from the history stack. 15623 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15624 intent.getAction()); 15625 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15626 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15627 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15628 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15629 || uidRemoved) { 15630 if (checkComponentPermission( 15631 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15632 callingPid, callingUid, -1, true) 15633 == PackageManager.PERMISSION_GRANTED) { 15634 if (uidRemoved) { 15635 final Bundle intentExtras = intent.getExtras(); 15636 final int uid = intentExtras != null 15637 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15638 if (uid >= 0) { 15639 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15640 synchronized (bs) { 15641 bs.removeUidStatsLocked(uid); 15642 } 15643 mAppOpsService.uidRemoved(uid); 15644 } 15645 } else { 15646 // If resources are unavailable just force stop all 15647 // those packages and flush the attribute cache as well. 15648 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15649 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15650 if (list != null && (list.length > 0)) { 15651 for (String pkg : list) { 15652 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15653 "storage unmount"); 15654 } 15655 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15656 sendPackageBroadcastLocked( 15657 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15658 } 15659 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15660 intent.getAction())) { 15661 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15662 } else { 15663 Uri data = intent.getData(); 15664 String ssp; 15665 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15666 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15667 intent.getAction()); 15668 boolean fullUninstall = removed && 15669 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15670 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15671 forceStopPackageLocked(ssp, UserHandle.getAppId( 15672 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15673 false, fullUninstall, userId, 15674 removed ? "pkg removed" : "pkg changed"); 15675 } 15676 if (removed) { 15677 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15678 new String[] {ssp}, userId); 15679 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15680 mAppOpsService.packageRemoved( 15681 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15682 15683 // Remove all permissions granted from/to this package 15684 removeUriPermissionsForPackageLocked(ssp, userId, true); 15685 } 15686 } 15687 } 15688 } 15689 } 15690 } else { 15691 String msg = "Permission Denial: " + intent.getAction() 15692 + " broadcast from " + callerPackage + " (pid=" + callingPid 15693 + ", uid=" + callingUid + ")" 15694 + " requires " 15695 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15696 Slog.w(TAG, msg); 15697 throw new SecurityException(msg); 15698 } 15699 15700 // Special case for adding a package: by default turn on compatibility 15701 // mode. 15702 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15703 Uri data = intent.getData(); 15704 String ssp; 15705 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15706 mCompatModePackages.handlePackageAddedLocked(ssp, 15707 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15708 } 15709 } 15710 15711 /* 15712 * If this is the time zone changed action, queue up a message that will reset the timezone 15713 * of all currently running processes. This message will get queued up before the broadcast 15714 * happens. 15715 */ 15716 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15717 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15718 } 15719 15720 /* 15721 * If the user set the time, let all running processes know. 15722 */ 15723 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15724 final int is24Hour = intent.getBooleanExtra( 15725 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15726 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15727 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15728 synchronized (stats) { 15729 stats.noteCurrentTimeChangedLocked(); 15730 } 15731 } 15732 15733 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15734 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15735 } 15736 15737 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15738 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15739 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15740 } 15741 15742 // Add to the sticky list if requested. 15743 if (sticky) { 15744 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15745 callingPid, callingUid) 15746 != PackageManager.PERMISSION_GRANTED) { 15747 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15748 + callingPid + ", uid=" + callingUid 15749 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15750 Slog.w(TAG, msg); 15751 throw new SecurityException(msg); 15752 } 15753 if (requiredPermission != null) { 15754 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15755 + " and enforce permission " + requiredPermission); 15756 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15757 } 15758 if (intent.getComponent() != null) { 15759 throw new SecurityException( 15760 "Sticky broadcasts can't target a specific component"); 15761 } 15762 // We use userId directly here, since the "all" target is maintained 15763 // as a separate set of sticky broadcasts. 15764 if (userId != UserHandle.USER_ALL) { 15765 // But first, if this is not a broadcast to all users, then 15766 // make sure it doesn't conflict with an existing broadcast to 15767 // all users. 15768 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15769 UserHandle.USER_ALL); 15770 if (stickies != null) { 15771 ArrayList<Intent> list = stickies.get(intent.getAction()); 15772 if (list != null) { 15773 int N = list.size(); 15774 int i; 15775 for (i=0; i<N; i++) { 15776 if (intent.filterEquals(list.get(i))) { 15777 throw new IllegalArgumentException( 15778 "Sticky broadcast " + intent + " for user " 15779 + userId + " conflicts with existing global broadcast"); 15780 } 15781 } 15782 } 15783 } 15784 } 15785 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15786 if (stickies == null) { 15787 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15788 mStickyBroadcasts.put(userId, stickies); 15789 } 15790 ArrayList<Intent> list = stickies.get(intent.getAction()); 15791 if (list == null) { 15792 list = new ArrayList<Intent>(); 15793 stickies.put(intent.getAction(), list); 15794 } 15795 int N = list.size(); 15796 int i; 15797 for (i=0; i<N; i++) { 15798 if (intent.filterEquals(list.get(i))) { 15799 // This sticky already exists, replace it. 15800 list.set(i, new Intent(intent)); 15801 break; 15802 } 15803 } 15804 if (i >= N) { 15805 list.add(new Intent(intent)); 15806 } 15807 } 15808 15809 int[] users; 15810 if (userId == UserHandle.USER_ALL) { 15811 // Caller wants broadcast to go to all started users. 15812 users = mStartedUserArray; 15813 } else { 15814 // Caller wants broadcast to go to one specific user. 15815 users = new int[] {userId}; 15816 } 15817 15818 // Figure out who all will receive this broadcast. 15819 List receivers = null; 15820 List<BroadcastFilter> registeredReceivers = null; 15821 // Need to resolve the intent to interested receivers... 15822 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15823 == 0) { 15824 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15825 } 15826 if (intent.getComponent() == null) { 15827 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15828 // Query one target user at a time, excluding shell-restricted users 15829 UserManagerService ums = getUserManagerLocked(); 15830 for (int i = 0; i < users.length; i++) { 15831 if (ums.hasUserRestriction( 15832 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15833 continue; 15834 } 15835 List<BroadcastFilter> registeredReceiversForUser = 15836 mReceiverResolver.queryIntent(intent, 15837 resolvedType, false, users[i]); 15838 if (registeredReceivers == null) { 15839 registeredReceivers = registeredReceiversForUser; 15840 } else if (registeredReceiversForUser != null) { 15841 registeredReceivers.addAll(registeredReceiversForUser); 15842 } 15843 } 15844 } else { 15845 registeredReceivers = mReceiverResolver.queryIntent(intent, 15846 resolvedType, false, userId); 15847 } 15848 } 15849 15850 final boolean replacePending = 15851 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15852 15853 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15854 + " replacePending=" + replacePending); 15855 15856 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15857 if (!ordered && NR > 0) { 15858 // If we are not serializing this broadcast, then send the 15859 // registered receivers separately so they don't wait for the 15860 // components to be launched. 15861 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15862 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15863 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15864 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15865 ordered, sticky, false, userId); 15866 if (DEBUG_BROADCAST) Slog.v( 15867 TAG, "Enqueueing parallel broadcast " + r); 15868 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15869 if (!replaced) { 15870 queue.enqueueParallelBroadcastLocked(r); 15871 queue.scheduleBroadcastsLocked(); 15872 } 15873 registeredReceivers = null; 15874 NR = 0; 15875 } 15876 15877 // Merge into one list. 15878 int ir = 0; 15879 if (receivers != null) { 15880 // A special case for PACKAGE_ADDED: do not allow the package 15881 // being added to see this broadcast. This prevents them from 15882 // using this as a back door to get run as soon as they are 15883 // installed. Maybe in the future we want to have a special install 15884 // broadcast or such for apps, but we'd like to deliberately make 15885 // this decision. 15886 String skipPackages[] = null; 15887 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15888 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15889 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15890 Uri data = intent.getData(); 15891 if (data != null) { 15892 String pkgName = data.getSchemeSpecificPart(); 15893 if (pkgName != null) { 15894 skipPackages = new String[] { pkgName }; 15895 } 15896 } 15897 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15898 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15899 } 15900 if (skipPackages != null && (skipPackages.length > 0)) { 15901 for (String skipPackage : skipPackages) { 15902 if (skipPackage != null) { 15903 int NT = receivers.size(); 15904 for (int it=0; it<NT; it++) { 15905 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15906 if (curt.activityInfo.packageName.equals(skipPackage)) { 15907 receivers.remove(it); 15908 it--; 15909 NT--; 15910 } 15911 } 15912 } 15913 } 15914 } 15915 15916 int NT = receivers != null ? receivers.size() : 0; 15917 int it = 0; 15918 ResolveInfo curt = null; 15919 BroadcastFilter curr = null; 15920 while (it < NT && ir < NR) { 15921 if (curt == null) { 15922 curt = (ResolveInfo)receivers.get(it); 15923 } 15924 if (curr == null) { 15925 curr = registeredReceivers.get(ir); 15926 } 15927 if (curr.getPriority() >= curt.priority) { 15928 // Insert this broadcast record into the final list. 15929 receivers.add(it, curr); 15930 ir++; 15931 curr = null; 15932 it++; 15933 NT++; 15934 } else { 15935 // Skip to the next ResolveInfo in the final list. 15936 it++; 15937 curt = null; 15938 } 15939 } 15940 } 15941 while (ir < NR) { 15942 if (receivers == null) { 15943 receivers = new ArrayList(); 15944 } 15945 receivers.add(registeredReceivers.get(ir)); 15946 ir++; 15947 } 15948 15949 if ((receivers != null && receivers.size() > 0) 15950 || resultTo != null) { 15951 BroadcastQueue queue = broadcastQueueForIntent(intent); 15952 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15953 callerPackage, callingPid, callingUid, resolvedType, 15954 requiredPermission, appOp, receivers, resultTo, resultCode, 15955 resultData, map, ordered, sticky, false, userId); 15956 if (DEBUG_BROADCAST) Slog.v( 15957 TAG, "Enqueueing ordered broadcast " + r 15958 + ": prev had " + queue.mOrderedBroadcasts.size()); 15959 if (DEBUG_BROADCAST) { 15960 int seq = r.intent.getIntExtra("seq", -1); 15961 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15962 } 15963 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15964 if (!replaced) { 15965 queue.enqueueOrderedBroadcastLocked(r); 15966 queue.scheduleBroadcastsLocked(); 15967 } 15968 } 15969 15970 return ActivityManager.BROADCAST_SUCCESS; 15971 } 15972 15973 final Intent verifyBroadcastLocked(Intent intent) { 15974 // Refuse possible leaked file descriptors 15975 if (intent != null && intent.hasFileDescriptors() == true) { 15976 throw new IllegalArgumentException("File descriptors passed in Intent"); 15977 } 15978 15979 int flags = intent.getFlags(); 15980 15981 if (!mProcessesReady) { 15982 // if the caller really truly claims to know what they're doing, go 15983 // ahead and allow the broadcast without launching any receivers 15984 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15985 intent = new Intent(intent); 15986 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15987 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15988 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15989 + " before boot completion"); 15990 throw new IllegalStateException("Cannot broadcast before boot completed"); 15991 } 15992 } 15993 15994 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15995 throw new IllegalArgumentException( 15996 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15997 } 15998 15999 return intent; 16000 } 16001 16002 public final int broadcastIntent(IApplicationThread caller, 16003 Intent intent, String resolvedType, IIntentReceiver resultTo, 16004 int resultCode, String resultData, Bundle map, 16005 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16006 enforceNotIsolatedCaller("broadcastIntent"); 16007 synchronized(this) { 16008 intent = verifyBroadcastLocked(intent); 16009 16010 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16011 final int callingPid = Binder.getCallingPid(); 16012 final int callingUid = Binder.getCallingUid(); 16013 final long origId = Binder.clearCallingIdentity(); 16014 int res = broadcastIntentLocked(callerApp, 16015 callerApp != null ? callerApp.info.packageName : null, 16016 intent, resolvedType, resultTo, 16017 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16018 callingPid, callingUid, userId); 16019 Binder.restoreCallingIdentity(origId); 16020 return res; 16021 } 16022 } 16023 16024 int broadcastIntentInPackage(String packageName, int uid, 16025 Intent intent, String resolvedType, IIntentReceiver resultTo, 16026 int resultCode, String resultData, Bundle map, 16027 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16028 synchronized(this) { 16029 intent = verifyBroadcastLocked(intent); 16030 16031 final long origId = Binder.clearCallingIdentity(); 16032 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16033 resultTo, resultCode, resultData, map, requiredPermission, 16034 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16035 Binder.restoreCallingIdentity(origId); 16036 return res; 16037 } 16038 } 16039 16040 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16041 // Refuse possible leaked file descriptors 16042 if (intent != null && intent.hasFileDescriptors() == true) { 16043 throw new IllegalArgumentException("File descriptors passed in Intent"); 16044 } 16045 16046 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16047 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16048 16049 synchronized(this) { 16050 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16051 != PackageManager.PERMISSION_GRANTED) { 16052 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16053 + Binder.getCallingPid() 16054 + ", uid=" + Binder.getCallingUid() 16055 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16056 Slog.w(TAG, msg); 16057 throw new SecurityException(msg); 16058 } 16059 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16060 if (stickies != null) { 16061 ArrayList<Intent> list = stickies.get(intent.getAction()); 16062 if (list != null) { 16063 int N = list.size(); 16064 int i; 16065 for (i=0; i<N; i++) { 16066 if (intent.filterEquals(list.get(i))) { 16067 list.remove(i); 16068 break; 16069 } 16070 } 16071 if (list.size() <= 0) { 16072 stickies.remove(intent.getAction()); 16073 } 16074 } 16075 if (stickies.size() <= 0) { 16076 mStickyBroadcasts.remove(userId); 16077 } 16078 } 16079 } 16080 } 16081 16082 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16083 String resultData, Bundle resultExtras, boolean resultAbort) { 16084 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16085 if (r == null) { 16086 Slog.w(TAG, "finishReceiver called but not found on queue"); 16087 return false; 16088 } 16089 16090 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16091 } 16092 16093 void backgroundServicesFinishedLocked(int userId) { 16094 for (BroadcastQueue queue : mBroadcastQueues) { 16095 queue.backgroundServicesFinishedLocked(userId); 16096 } 16097 } 16098 16099 public void finishReceiver(IBinder who, int resultCode, String resultData, 16100 Bundle resultExtras, boolean resultAbort) { 16101 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16102 16103 // Refuse possible leaked file descriptors 16104 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16105 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16106 } 16107 16108 final long origId = Binder.clearCallingIdentity(); 16109 try { 16110 boolean doNext = false; 16111 BroadcastRecord r; 16112 16113 synchronized(this) { 16114 r = broadcastRecordForReceiverLocked(who); 16115 if (r != null) { 16116 doNext = r.queue.finishReceiverLocked(r, resultCode, 16117 resultData, resultExtras, resultAbort, true); 16118 } 16119 } 16120 16121 if (doNext) { 16122 r.queue.processNextBroadcast(false); 16123 } 16124 trimApplications(); 16125 } finally { 16126 Binder.restoreCallingIdentity(origId); 16127 } 16128 } 16129 16130 // ========================================================= 16131 // INSTRUMENTATION 16132 // ========================================================= 16133 16134 public boolean startInstrumentation(ComponentName className, 16135 String profileFile, int flags, Bundle arguments, 16136 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16137 int userId, String abiOverride) { 16138 enforceNotIsolatedCaller("startInstrumentation"); 16139 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16140 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16141 // Refuse possible leaked file descriptors 16142 if (arguments != null && arguments.hasFileDescriptors()) { 16143 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16144 } 16145 16146 synchronized(this) { 16147 InstrumentationInfo ii = null; 16148 ApplicationInfo ai = null; 16149 try { 16150 ii = mContext.getPackageManager().getInstrumentationInfo( 16151 className, STOCK_PM_FLAGS); 16152 ai = AppGlobals.getPackageManager().getApplicationInfo( 16153 ii.targetPackage, STOCK_PM_FLAGS, userId); 16154 } catch (PackageManager.NameNotFoundException e) { 16155 } catch (RemoteException e) { 16156 } 16157 if (ii == null) { 16158 reportStartInstrumentationFailure(watcher, className, 16159 "Unable to find instrumentation info for: " + className); 16160 return false; 16161 } 16162 if (ai == null) { 16163 reportStartInstrumentationFailure(watcher, className, 16164 "Unable to find instrumentation target package: " + ii.targetPackage); 16165 return false; 16166 } 16167 16168 int match = mContext.getPackageManager().checkSignatures( 16169 ii.targetPackage, ii.packageName); 16170 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16171 String msg = "Permission Denial: starting instrumentation " 16172 + className + " from pid=" 16173 + Binder.getCallingPid() 16174 + ", uid=" + Binder.getCallingPid() 16175 + " not allowed because package " + ii.packageName 16176 + " does not have a signature matching the target " 16177 + ii.targetPackage; 16178 reportStartInstrumentationFailure(watcher, className, msg); 16179 throw new SecurityException(msg); 16180 } 16181 16182 final long origId = Binder.clearCallingIdentity(); 16183 // Instrumentation can kill and relaunch even persistent processes 16184 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16185 "start instr"); 16186 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16187 app.instrumentationClass = className; 16188 app.instrumentationInfo = ai; 16189 app.instrumentationProfileFile = profileFile; 16190 app.instrumentationArguments = arguments; 16191 app.instrumentationWatcher = watcher; 16192 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16193 app.instrumentationResultClass = className; 16194 Binder.restoreCallingIdentity(origId); 16195 } 16196 16197 return true; 16198 } 16199 16200 /** 16201 * Report errors that occur while attempting to start Instrumentation. Always writes the 16202 * error to the logs, but if somebody is watching, send the report there too. This enables 16203 * the "am" command to report errors with more information. 16204 * 16205 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16206 * @param cn The component name of the instrumentation. 16207 * @param report The error report. 16208 */ 16209 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16210 ComponentName cn, String report) { 16211 Slog.w(TAG, report); 16212 try { 16213 if (watcher != null) { 16214 Bundle results = new Bundle(); 16215 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16216 results.putString("Error", report); 16217 watcher.instrumentationStatus(cn, -1, results); 16218 } 16219 } catch (RemoteException e) { 16220 Slog.w(TAG, e); 16221 } 16222 } 16223 16224 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16225 if (app.instrumentationWatcher != null) { 16226 try { 16227 // NOTE: IInstrumentationWatcher *must* be oneway here 16228 app.instrumentationWatcher.instrumentationFinished( 16229 app.instrumentationClass, 16230 resultCode, 16231 results); 16232 } catch (RemoteException e) { 16233 } 16234 } 16235 if (app.instrumentationUiAutomationConnection != null) { 16236 try { 16237 app.instrumentationUiAutomationConnection.shutdown(); 16238 } catch (RemoteException re) { 16239 /* ignore */ 16240 } 16241 // Only a UiAutomation can set this flag and now that 16242 // it is finished we make sure it is reset to its default. 16243 mUserIsMonkey = false; 16244 } 16245 app.instrumentationWatcher = null; 16246 app.instrumentationUiAutomationConnection = null; 16247 app.instrumentationClass = null; 16248 app.instrumentationInfo = null; 16249 app.instrumentationProfileFile = null; 16250 app.instrumentationArguments = null; 16251 16252 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16253 "finished inst"); 16254 } 16255 16256 public void finishInstrumentation(IApplicationThread target, 16257 int resultCode, Bundle results) { 16258 int userId = UserHandle.getCallingUserId(); 16259 // Refuse possible leaked file descriptors 16260 if (results != null && results.hasFileDescriptors()) { 16261 throw new IllegalArgumentException("File descriptors passed in Intent"); 16262 } 16263 16264 synchronized(this) { 16265 ProcessRecord app = getRecordForAppLocked(target); 16266 if (app == null) { 16267 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16268 return; 16269 } 16270 final long origId = Binder.clearCallingIdentity(); 16271 finishInstrumentationLocked(app, resultCode, results); 16272 Binder.restoreCallingIdentity(origId); 16273 } 16274 } 16275 16276 // ========================================================= 16277 // CONFIGURATION 16278 // ========================================================= 16279 16280 public ConfigurationInfo getDeviceConfigurationInfo() { 16281 ConfigurationInfo config = new ConfigurationInfo(); 16282 synchronized (this) { 16283 config.reqTouchScreen = mConfiguration.touchscreen; 16284 config.reqKeyboardType = mConfiguration.keyboard; 16285 config.reqNavigation = mConfiguration.navigation; 16286 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16287 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16288 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16289 } 16290 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16291 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16292 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16293 } 16294 config.reqGlEsVersion = GL_ES_VERSION; 16295 } 16296 return config; 16297 } 16298 16299 ActivityStack getFocusedStack() { 16300 return mStackSupervisor.getFocusedStack(); 16301 } 16302 16303 public Configuration getConfiguration() { 16304 Configuration ci; 16305 synchronized(this) { 16306 ci = new Configuration(mConfiguration); 16307 } 16308 return ci; 16309 } 16310 16311 public void updatePersistentConfiguration(Configuration values) { 16312 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16313 "updateConfiguration()"); 16314 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16315 "updateConfiguration()"); 16316 if (values == null) { 16317 throw new NullPointerException("Configuration must not be null"); 16318 } 16319 16320 synchronized(this) { 16321 final long origId = Binder.clearCallingIdentity(); 16322 updateConfigurationLocked(values, null, true, false); 16323 Binder.restoreCallingIdentity(origId); 16324 } 16325 } 16326 16327 public void updateConfiguration(Configuration values) { 16328 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16329 "updateConfiguration()"); 16330 16331 synchronized(this) { 16332 if (values == null && mWindowManager != null) { 16333 // sentinel: fetch the current configuration from the window manager 16334 values = mWindowManager.computeNewConfiguration(); 16335 } 16336 16337 if (mWindowManager != null) { 16338 mProcessList.applyDisplaySize(mWindowManager); 16339 } 16340 16341 final long origId = Binder.clearCallingIdentity(); 16342 if (values != null) { 16343 Settings.System.clearConfiguration(values); 16344 } 16345 updateConfigurationLocked(values, null, false, false); 16346 Binder.restoreCallingIdentity(origId); 16347 } 16348 } 16349 16350 /** 16351 * Do either or both things: (1) change the current configuration, and (2) 16352 * make sure the given activity is running with the (now) current 16353 * configuration. Returns true if the activity has been left running, or 16354 * false if <var>starting</var> is being destroyed to match the new 16355 * configuration. 16356 * @param persistent TODO 16357 */ 16358 boolean updateConfigurationLocked(Configuration values, 16359 ActivityRecord starting, boolean persistent, boolean initLocale) { 16360 int changes = 0; 16361 16362 if (values != null) { 16363 Configuration newConfig = new Configuration(mConfiguration); 16364 changes = newConfig.updateFrom(values); 16365 if (changes != 0) { 16366 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16367 Slog.i(TAG, "Updating configuration to: " + values); 16368 } 16369 16370 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16371 16372 if (values.locale != null && !initLocale) { 16373 saveLocaleLocked(values.locale, 16374 !values.locale.equals(mConfiguration.locale), 16375 values.userSetLocale); 16376 } 16377 16378 mConfigurationSeq++; 16379 if (mConfigurationSeq <= 0) { 16380 mConfigurationSeq = 1; 16381 } 16382 newConfig.seq = mConfigurationSeq; 16383 mConfiguration = newConfig; 16384 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16385 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16386 //mUsageStatsService.noteStartConfig(newConfig); 16387 16388 final Configuration configCopy = new Configuration(mConfiguration); 16389 16390 // TODO: If our config changes, should we auto dismiss any currently 16391 // showing dialogs? 16392 mShowDialogs = shouldShowDialogs(newConfig); 16393 16394 AttributeCache ac = AttributeCache.instance(); 16395 if (ac != null) { 16396 ac.updateConfiguration(configCopy); 16397 } 16398 16399 // Make sure all resources in our process are updated 16400 // right now, so that anyone who is going to retrieve 16401 // resource values after we return will be sure to get 16402 // the new ones. This is especially important during 16403 // boot, where the first config change needs to guarantee 16404 // all resources have that config before following boot 16405 // code is executed. 16406 mSystemThread.applyConfigurationToResources(configCopy); 16407 16408 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16409 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16410 msg.obj = new Configuration(configCopy); 16411 mHandler.sendMessage(msg); 16412 } 16413 16414 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16415 ProcessRecord app = mLruProcesses.get(i); 16416 try { 16417 if (app.thread != null) { 16418 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16419 + app.processName + " new config " + mConfiguration); 16420 app.thread.scheduleConfigurationChanged(configCopy); 16421 } 16422 } catch (Exception e) { 16423 } 16424 } 16425 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16426 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16427 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16428 | Intent.FLAG_RECEIVER_FOREGROUND); 16429 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16430 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16431 Process.SYSTEM_UID, UserHandle.USER_ALL); 16432 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16433 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16434 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16435 broadcastIntentLocked(null, null, intent, 16436 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16437 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16438 } 16439 } 16440 } 16441 16442 boolean kept = true; 16443 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16444 // mainStack is null during startup. 16445 if (mainStack != null) { 16446 if (changes != 0 && starting == null) { 16447 // If the configuration changed, and the caller is not already 16448 // in the process of starting an activity, then find the top 16449 // activity to check if its configuration needs to change. 16450 starting = mainStack.topRunningActivityLocked(null); 16451 } 16452 16453 if (starting != null) { 16454 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16455 // And we need to make sure at this point that all other activities 16456 // are made visible with the correct configuration. 16457 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16458 } 16459 } 16460 16461 if (values != null && mWindowManager != null) { 16462 mWindowManager.setNewConfiguration(mConfiguration); 16463 } 16464 16465 return kept; 16466 } 16467 16468 /** 16469 * Decide based on the configuration whether we should shouw the ANR, 16470 * crash, etc dialogs. The idea is that if there is no affordnace to 16471 * press the on-screen buttons, we shouldn't show the dialog. 16472 * 16473 * A thought: SystemUI might also want to get told about this, the Power 16474 * dialog / global actions also might want different behaviors. 16475 */ 16476 private static final boolean shouldShowDialogs(Configuration config) { 16477 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16478 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16479 } 16480 16481 /** 16482 * Save the locale. You must be inside a synchronized (this) block. 16483 */ 16484 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16485 if(isDiff) { 16486 SystemProperties.set("user.language", l.getLanguage()); 16487 SystemProperties.set("user.region", l.getCountry()); 16488 } 16489 16490 if(isPersist) { 16491 SystemProperties.set("persist.sys.language", l.getLanguage()); 16492 SystemProperties.set("persist.sys.country", l.getCountry()); 16493 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16494 16495 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16496 } 16497 } 16498 16499 @Override 16500 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16501 synchronized (this) { 16502 ActivityRecord srec = ActivityRecord.forToken(token); 16503 if (srec.task != null && srec.task.stack != null) { 16504 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16505 } 16506 } 16507 return false; 16508 } 16509 16510 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16511 Intent resultData) { 16512 16513 synchronized (this) { 16514 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16515 if (stack != null) { 16516 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16517 } 16518 return false; 16519 } 16520 } 16521 16522 public int getLaunchedFromUid(IBinder activityToken) { 16523 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16524 if (srec == null) { 16525 return -1; 16526 } 16527 return srec.launchedFromUid; 16528 } 16529 16530 public String getLaunchedFromPackage(IBinder activityToken) { 16531 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16532 if (srec == null) { 16533 return null; 16534 } 16535 return srec.launchedFromPackage; 16536 } 16537 16538 // ========================================================= 16539 // LIFETIME MANAGEMENT 16540 // ========================================================= 16541 16542 // Returns which broadcast queue the app is the current [or imminent] receiver 16543 // on, or 'null' if the app is not an active broadcast recipient. 16544 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16545 BroadcastRecord r = app.curReceiver; 16546 if (r != null) { 16547 return r.queue; 16548 } 16549 16550 // It's not the current receiver, but it might be starting up to become one 16551 synchronized (this) { 16552 for (BroadcastQueue queue : mBroadcastQueues) { 16553 r = queue.mPendingBroadcast; 16554 if (r != null && r.curApp == app) { 16555 // found it; report which queue it's in 16556 return queue; 16557 } 16558 } 16559 } 16560 16561 return null; 16562 } 16563 16564 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16565 boolean doingAll, long now) { 16566 if (mAdjSeq == app.adjSeq) { 16567 // This adjustment has already been computed. 16568 return app.curRawAdj; 16569 } 16570 16571 if (app.thread == null) { 16572 app.adjSeq = mAdjSeq; 16573 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16574 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16575 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16576 } 16577 16578 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16579 app.adjSource = null; 16580 app.adjTarget = null; 16581 app.empty = false; 16582 app.cached = false; 16583 16584 final int activitiesSize = app.activities.size(); 16585 16586 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16587 // The max adjustment doesn't allow this app to be anything 16588 // below foreground, so it is not worth doing work for it. 16589 app.adjType = "fixed"; 16590 app.adjSeq = mAdjSeq; 16591 app.curRawAdj = app.maxAdj; 16592 app.foregroundActivities = false; 16593 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16594 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16595 // System processes can do UI, and when they do we want to have 16596 // them trim their memory after the user leaves the UI. To 16597 // facilitate this, here we need to determine whether or not it 16598 // is currently showing UI. 16599 app.systemNoUi = true; 16600 if (app == TOP_APP) { 16601 app.systemNoUi = false; 16602 } else if (activitiesSize > 0) { 16603 for (int j = 0; j < activitiesSize; j++) { 16604 final ActivityRecord r = app.activities.get(j); 16605 if (r.visible) { 16606 app.systemNoUi = false; 16607 } 16608 } 16609 } 16610 if (!app.systemNoUi) { 16611 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16612 } 16613 return (app.curAdj=app.maxAdj); 16614 } 16615 16616 app.systemNoUi = false; 16617 16618 // Determine the importance of the process, starting with most 16619 // important to least, and assign an appropriate OOM adjustment. 16620 int adj; 16621 int schedGroup; 16622 int procState; 16623 boolean foregroundActivities = false; 16624 BroadcastQueue queue; 16625 if (app == TOP_APP) { 16626 // The last app on the list is the foreground app. 16627 adj = ProcessList.FOREGROUND_APP_ADJ; 16628 schedGroup = Process.THREAD_GROUP_DEFAULT; 16629 app.adjType = "top-activity"; 16630 foregroundActivities = true; 16631 procState = ActivityManager.PROCESS_STATE_TOP; 16632 } else if (app.instrumentationClass != null) { 16633 // Don't want to kill running instrumentation. 16634 adj = ProcessList.FOREGROUND_APP_ADJ; 16635 schedGroup = Process.THREAD_GROUP_DEFAULT; 16636 app.adjType = "instrumentation"; 16637 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16638 } else if ((queue = isReceivingBroadcast(app)) != null) { 16639 // An app that is currently receiving a broadcast also 16640 // counts as being in the foreground for OOM killer purposes. 16641 // It's placed in a sched group based on the nature of the 16642 // broadcast as reflected by which queue it's active in. 16643 adj = ProcessList.FOREGROUND_APP_ADJ; 16644 schedGroup = (queue == mFgBroadcastQueue) 16645 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16646 app.adjType = "broadcast"; 16647 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16648 } else if (app.executingServices.size() > 0) { 16649 // An app that is currently executing a service callback also 16650 // counts as being in the foreground. 16651 adj = ProcessList.FOREGROUND_APP_ADJ; 16652 schedGroup = app.execServicesFg ? 16653 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16654 app.adjType = "exec-service"; 16655 procState = ActivityManager.PROCESS_STATE_SERVICE; 16656 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16657 } else { 16658 // As far as we know the process is empty. We may change our mind later. 16659 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16660 // At this point we don't actually know the adjustment. Use the cached adj 16661 // value that the caller wants us to. 16662 adj = cachedAdj; 16663 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16664 app.cached = true; 16665 app.empty = true; 16666 app.adjType = "cch-empty"; 16667 } 16668 16669 // Examine all activities if not already foreground. 16670 if (!foregroundActivities && activitiesSize > 0) { 16671 for (int j = 0; j < activitiesSize; j++) { 16672 final ActivityRecord r = app.activities.get(j); 16673 if (r.app != app) { 16674 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16675 + app + "?!?"); 16676 continue; 16677 } 16678 if (r.visible) { 16679 // App has a visible activity; only upgrade adjustment. 16680 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16681 adj = ProcessList.VISIBLE_APP_ADJ; 16682 app.adjType = "visible"; 16683 } 16684 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16685 procState = ActivityManager.PROCESS_STATE_TOP; 16686 } 16687 schedGroup = Process.THREAD_GROUP_DEFAULT; 16688 app.cached = false; 16689 app.empty = false; 16690 foregroundActivities = true; 16691 break; 16692 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16693 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16694 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16695 app.adjType = "pausing"; 16696 } 16697 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16698 procState = ActivityManager.PROCESS_STATE_TOP; 16699 } 16700 schedGroup = Process.THREAD_GROUP_DEFAULT; 16701 app.cached = false; 16702 app.empty = false; 16703 foregroundActivities = true; 16704 } else if (r.state == ActivityState.STOPPING) { 16705 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16706 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16707 app.adjType = "stopping"; 16708 } 16709 // For the process state, we will at this point consider the 16710 // process to be cached. It will be cached either as an activity 16711 // or empty depending on whether the activity is finishing. We do 16712 // this so that we can treat the process as cached for purposes of 16713 // memory trimming (determing current memory level, trim command to 16714 // send to process) since there can be an arbitrary number of stopping 16715 // processes and they should soon all go into the cached state. 16716 if (!r.finishing) { 16717 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16718 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16719 } 16720 } 16721 app.cached = false; 16722 app.empty = false; 16723 foregroundActivities = true; 16724 } else { 16725 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16726 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16727 app.adjType = "cch-act"; 16728 } 16729 } 16730 } 16731 } 16732 16733 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16734 if (app.foregroundServices) { 16735 // The user is aware of this app, so make it visible. 16736 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16737 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16738 app.cached = false; 16739 app.adjType = "fg-service"; 16740 schedGroup = Process.THREAD_GROUP_DEFAULT; 16741 } else if (app.forcingToForeground != null) { 16742 // The user is aware of this app, so make it visible. 16743 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16744 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16745 app.cached = false; 16746 app.adjType = "force-fg"; 16747 app.adjSource = app.forcingToForeground; 16748 schedGroup = Process.THREAD_GROUP_DEFAULT; 16749 } 16750 } 16751 16752 if (app == mHeavyWeightProcess) { 16753 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16754 // We don't want to kill the current heavy-weight process. 16755 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16756 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16757 app.cached = false; 16758 app.adjType = "heavy"; 16759 } 16760 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16761 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16762 } 16763 } 16764 16765 if (app == mHomeProcess) { 16766 if (adj > ProcessList.HOME_APP_ADJ) { 16767 // This process is hosting what we currently consider to be the 16768 // home app, so we don't want to let it go into the background. 16769 adj = ProcessList.HOME_APP_ADJ; 16770 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16771 app.cached = false; 16772 app.adjType = "home"; 16773 } 16774 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16775 procState = ActivityManager.PROCESS_STATE_HOME; 16776 } 16777 } 16778 16779 if (app == mPreviousProcess && app.activities.size() > 0) { 16780 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16781 // This was the previous process that showed UI to the user. 16782 // We want to try to keep it around more aggressively, to give 16783 // a good experience around switching between two apps. 16784 adj = ProcessList.PREVIOUS_APP_ADJ; 16785 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16786 app.cached = false; 16787 app.adjType = "previous"; 16788 } 16789 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16790 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16791 } 16792 } 16793 16794 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16795 + " reason=" + app.adjType); 16796 16797 // By default, we use the computed adjustment. It may be changed if 16798 // there are applications dependent on our services or providers, but 16799 // this gives us a baseline and makes sure we don't get into an 16800 // infinite recursion. 16801 app.adjSeq = mAdjSeq; 16802 app.curRawAdj = adj; 16803 app.hasStartedServices = false; 16804 16805 if (mBackupTarget != null && app == mBackupTarget.app) { 16806 // If possible we want to avoid killing apps while they're being backed up 16807 if (adj > ProcessList.BACKUP_APP_ADJ) { 16808 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16809 adj = ProcessList.BACKUP_APP_ADJ; 16810 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16811 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16812 } 16813 app.adjType = "backup"; 16814 app.cached = false; 16815 } 16816 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16817 procState = ActivityManager.PROCESS_STATE_BACKUP; 16818 } 16819 } 16820 16821 boolean mayBeTop = false; 16822 16823 for (int is = app.services.size()-1; 16824 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16825 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16826 || procState > ActivityManager.PROCESS_STATE_TOP); 16827 is--) { 16828 ServiceRecord s = app.services.valueAt(is); 16829 if (s.startRequested) { 16830 app.hasStartedServices = true; 16831 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16832 procState = ActivityManager.PROCESS_STATE_SERVICE; 16833 } 16834 if (app.hasShownUi && app != mHomeProcess) { 16835 // If this process has shown some UI, let it immediately 16836 // go to the LRU list because it may be pretty heavy with 16837 // UI stuff. We'll tag it with a label just to help 16838 // debug and understand what is going on. 16839 if (adj > ProcessList.SERVICE_ADJ) { 16840 app.adjType = "cch-started-ui-services"; 16841 } 16842 } else { 16843 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16844 // This service has seen some activity within 16845 // recent memory, so we will keep its process ahead 16846 // of the background processes. 16847 if (adj > ProcessList.SERVICE_ADJ) { 16848 adj = ProcessList.SERVICE_ADJ; 16849 app.adjType = "started-services"; 16850 app.cached = false; 16851 } 16852 } 16853 // If we have let the service slide into the background 16854 // state, still have some text describing what it is doing 16855 // even though the service no longer has an impact. 16856 if (adj > ProcessList.SERVICE_ADJ) { 16857 app.adjType = "cch-started-services"; 16858 } 16859 } 16860 } 16861 for (int conni = s.connections.size()-1; 16862 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16863 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16864 || procState > ActivityManager.PROCESS_STATE_TOP); 16865 conni--) { 16866 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16867 for (int i = 0; 16868 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16869 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16870 || procState > ActivityManager.PROCESS_STATE_TOP); 16871 i++) { 16872 // XXX should compute this based on the max of 16873 // all connected clients. 16874 ConnectionRecord cr = clist.get(i); 16875 if (cr.binding.client == app) { 16876 // Binding to ourself is not interesting. 16877 continue; 16878 } 16879 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16880 ProcessRecord client = cr.binding.client; 16881 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16882 TOP_APP, doingAll, now); 16883 int clientProcState = client.curProcState; 16884 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16885 // If the other app is cached for any reason, for purposes here 16886 // we are going to consider it empty. The specific cached state 16887 // doesn't propagate except under certain conditions. 16888 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16889 } 16890 String adjType = null; 16891 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16892 // Not doing bind OOM management, so treat 16893 // this guy more like a started service. 16894 if (app.hasShownUi && app != mHomeProcess) { 16895 // If this process has shown some UI, let it immediately 16896 // go to the LRU list because it may be pretty heavy with 16897 // UI stuff. We'll tag it with a label just to help 16898 // debug and understand what is going on. 16899 if (adj > clientAdj) { 16900 adjType = "cch-bound-ui-services"; 16901 } 16902 app.cached = false; 16903 clientAdj = adj; 16904 clientProcState = procState; 16905 } else { 16906 if (now >= (s.lastActivity 16907 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16908 // This service has not seen activity within 16909 // recent memory, so allow it to drop to the 16910 // LRU list if there is no other reason to keep 16911 // it around. We'll also tag it with a label just 16912 // to help debug and undertand what is going on. 16913 if (adj > clientAdj) { 16914 adjType = "cch-bound-services"; 16915 } 16916 clientAdj = adj; 16917 } 16918 } 16919 } 16920 if (adj > clientAdj) { 16921 // If this process has recently shown UI, and 16922 // the process that is binding to it is less 16923 // important than being visible, then we don't 16924 // care about the binding as much as we care 16925 // about letting this process get into the LRU 16926 // list to be killed and restarted if needed for 16927 // memory. 16928 if (app.hasShownUi && app != mHomeProcess 16929 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16930 adjType = "cch-bound-ui-services"; 16931 } else { 16932 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16933 |Context.BIND_IMPORTANT)) != 0) { 16934 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16935 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16936 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16937 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16938 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16939 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16940 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16941 adj = clientAdj; 16942 } else { 16943 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16944 adj = ProcessList.VISIBLE_APP_ADJ; 16945 } 16946 } 16947 if (!client.cached) { 16948 app.cached = false; 16949 } 16950 adjType = "service"; 16951 } 16952 } 16953 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16954 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16955 schedGroup = Process.THREAD_GROUP_DEFAULT; 16956 } 16957 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16958 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16959 // Special handling of clients who are in the top state. 16960 // We *may* want to consider this process to be in the 16961 // top state as well, but only if there is not another 16962 // reason for it to be running. Being on the top is a 16963 // special state, meaning you are specifically running 16964 // for the current top app. If the process is already 16965 // running in the background for some other reason, it 16966 // is more important to continue considering it to be 16967 // in the background state. 16968 mayBeTop = true; 16969 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16970 } else { 16971 // Special handling for above-top states (persistent 16972 // processes). These should not bring the current process 16973 // into the top state, since they are not on top. Instead 16974 // give them the best state after that. 16975 clientProcState = 16976 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16977 } 16978 } 16979 } else { 16980 if (clientProcState < 16981 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16982 clientProcState = 16983 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16984 } 16985 } 16986 if (procState > clientProcState) { 16987 procState = clientProcState; 16988 } 16989 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16990 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16991 app.pendingUiClean = true; 16992 } 16993 if (adjType != null) { 16994 app.adjType = adjType; 16995 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16996 .REASON_SERVICE_IN_USE; 16997 app.adjSource = cr.binding.client; 16998 app.adjSourceProcState = clientProcState; 16999 app.adjTarget = s.name; 17000 } 17001 } 17002 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17003 app.treatLikeActivity = true; 17004 } 17005 final ActivityRecord a = cr.activity; 17006 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17007 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17008 (a.visible || a.state == ActivityState.RESUMED 17009 || a.state == ActivityState.PAUSING)) { 17010 adj = ProcessList.FOREGROUND_APP_ADJ; 17011 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17012 schedGroup = Process.THREAD_GROUP_DEFAULT; 17013 } 17014 app.cached = false; 17015 app.adjType = "service"; 17016 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17017 .REASON_SERVICE_IN_USE; 17018 app.adjSource = a; 17019 app.adjSourceProcState = procState; 17020 app.adjTarget = s.name; 17021 } 17022 } 17023 } 17024 } 17025 } 17026 17027 for (int provi = app.pubProviders.size()-1; 17028 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17029 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17030 || procState > ActivityManager.PROCESS_STATE_TOP); 17031 provi--) { 17032 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17033 for (int i = cpr.connections.size()-1; 17034 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17035 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17036 || procState > ActivityManager.PROCESS_STATE_TOP); 17037 i--) { 17038 ContentProviderConnection conn = cpr.connections.get(i); 17039 ProcessRecord client = conn.client; 17040 if (client == app) { 17041 // Being our own client is not interesting. 17042 continue; 17043 } 17044 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17045 int clientProcState = client.curProcState; 17046 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17047 // If the other app is cached for any reason, for purposes here 17048 // we are going to consider it empty. 17049 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17050 } 17051 if (adj > clientAdj) { 17052 if (app.hasShownUi && app != mHomeProcess 17053 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17054 app.adjType = "cch-ui-provider"; 17055 } else { 17056 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17057 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17058 app.adjType = "provider"; 17059 } 17060 app.cached &= client.cached; 17061 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17062 .REASON_PROVIDER_IN_USE; 17063 app.adjSource = client; 17064 app.adjSourceProcState = clientProcState; 17065 app.adjTarget = cpr.name; 17066 } 17067 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17068 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17069 // Special handling of clients who are in the top state. 17070 // We *may* want to consider this process to be in the 17071 // top state as well, but only if there is not another 17072 // reason for it to be running. Being on the top is a 17073 // special state, meaning you are specifically running 17074 // for the current top app. If the process is already 17075 // running in the background for some other reason, it 17076 // is more important to continue considering it to be 17077 // in the background state. 17078 mayBeTop = true; 17079 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17080 } else { 17081 // Special handling for above-top states (persistent 17082 // processes). These should not bring the current process 17083 // into the top state, since they are not on top. Instead 17084 // give them the best state after that. 17085 clientProcState = 17086 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17087 } 17088 } 17089 if (procState > clientProcState) { 17090 procState = clientProcState; 17091 } 17092 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17093 schedGroup = Process.THREAD_GROUP_DEFAULT; 17094 } 17095 } 17096 // If the provider has external (non-framework) process 17097 // dependencies, ensure that its adjustment is at least 17098 // FOREGROUND_APP_ADJ. 17099 if (cpr.hasExternalProcessHandles()) { 17100 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17101 adj = ProcessList.FOREGROUND_APP_ADJ; 17102 schedGroup = Process.THREAD_GROUP_DEFAULT; 17103 app.cached = false; 17104 app.adjType = "provider"; 17105 app.adjTarget = cpr.name; 17106 } 17107 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17108 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17109 } 17110 } 17111 } 17112 17113 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17114 // A client of one of our services or providers is in the top state. We 17115 // *may* want to be in the top state, but not if we are already running in 17116 // the background for some other reason. For the decision here, we are going 17117 // to pick out a few specific states that we want to remain in when a client 17118 // is top (states that tend to be longer-term) and otherwise allow it to go 17119 // to the top state. 17120 switch (procState) { 17121 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17122 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17123 case ActivityManager.PROCESS_STATE_SERVICE: 17124 // These all are longer-term states, so pull them up to the top 17125 // of the background states, but not all the way to the top state. 17126 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17127 break; 17128 default: 17129 // Otherwise, top is a better choice, so take it. 17130 procState = ActivityManager.PROCESS_STATE_TOP; 17131 break; 17132 } 17133 } 17134 17135 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17136 if (app.hasClientActivities) { 17137 // This is a cached process, but with client activities. Mark it so. 17138 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17139 app.adjType = "cch-client-act"; 17140 } else if (app.treatLikeActivity) { 17141 // This is a cached process, but somebody wants us to treat it like it has 17142 // an activity, okay! 17143 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17144 app.adjType = "cch-as-act"; 17145 } 17146 } 17147 17148 if (adj == ProcessList.SERVICE_ADJ) { 17149 if (doingAll) { 17150 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17151 mNewNumServiceProcs++; 17152 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17153 if (!app.serviceb) { 17154 // This service isn't far enough down on the LRU list to 17155 // normally be a B service, but if we are low on RAM and it 17156 // is large we want to force it down since we would prefer to 17157 // keep launcher over it. 17158 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17159 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17160 app.serviceHighRam = true; 17161 app.serviceb = true; 17162 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17163 } else { 17164 mNewNumAServiceProcs++; 17165 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17166 } 17167 } else { 17168 app.serviceHighRam = false; 17169 } 17170 } 17171 if (app.serviceb) { 17172 adj = ProcessList.SERVICE_B_ADJ; 17173 } 17174 } 17175 17176 app.curRawAdj = adj; 17177 17178 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17179 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17180 if (adj > app.maxAdj) { 17181 adj = app.maxAdj; 17182 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17183 schedGroup = Process.THREAD_GROUP_DEFAULT; 17184 } 17185 } 17186 17187 // Do final modification to adj. Everything we do between here and applying 17188 // the final setAdj must be done in this function, because we will also use 17189 // it when computing the final cached adj later. Note that we don't need to 17190 // worry about this for max adj above, since max adj will always be used to 17191 // keep it out of the cached vaues. 17192 app.curAdj = app.modifyRawOomAdj(adj); 17193 app.curSchedGroup = schedGroup; 17194 app.curProcState = procState; 17195 app.foregroundActivities = foregroundActivities; 17196 17197 return app.curRawAdj; 17198 } 17199 17200 /** 17201 * Schedule PSS collection of a process. 17202 */ 17203 void requestPssLocked(ProcessRecord proc, int procState) { 17204 if (mPendingPssProcesses.contains(proc)) { 17205 return; 17206 } 17207 if (mPendingPssProcesses.size() == 0) { 17208 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17209 } 17210 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17211 proc.pssProcState = procState; 17212 mPendingPssProcesses.add(proc); 17213 } 17214 17215 /** 17216 * Schedule PSS collection of all processes. 17217 */ 17218 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17219 if (!always) { 17220 if (now < (mLastFullPssTime + 17221 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17222 return; 17223 } 17224 } 17225 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17226 mLastFullPssTime = now; 17227 mFullPssPending = true; 17228 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17229 mPendingPssProcesses.clear(); 17230 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17231 ProcessRecord app = mLruProcesses.get(i); 17232 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17233 app.pssProcState = app.setProcState; 17234 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17235 isSleeping(), now); 17236 mPendingPssProcesses.add(app); 17237 } 17238 } 17239 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17240 } 17241 17242 /** 17243 * Ask a given process to GC right now. 17244 */ 17245 final void performAppGcLocked(ProcessRecord app) { 17246 try { 17247 app.lastRequestedGc = SystemClock.uptimeMillis(); 17248 if (app.thread != null) { 17249 if (app.reportLowMemory) { 17250 app.reportLowMemory = false; 17251 app.thread.scheduleLowMemory(); 17252 } else { 17253 app.thread.processInBackground(); 17254 } 17255 } 17256 } catch (Exception e) { 17257 // whatever. 17258 } 17259 } 17260 17261 /** 17262 * Returns true if things are idle enough to perform GCs. 17263 */ 17264 private final boolean canGcNowLocked() { 17265 boolean processingBroadcasts = false; 17266 for (BroadcastQueue q : mBroadcastQueues) { 17267 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17268 processingBroadcasts = true; 17269 } 17270 } 17271 return !processingBroadcasts 17272 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17273 } 17274 17275 /** 17276 * Perform GCs on all processes that are waiting for it, but only 17277 * if things are idle. 17278 */ 17279 final void performAppGcsLocked() { 17280 final int N = mProcessesToGc.size(); 17281 if (N <= 0) { 17282 return; 17283 } 17284 if (canGcNowLocked()) { 17285 while (mProcessesToGc.size() > 0) { 17286 ProcessRecord proc = mProcessesToGc.remove(0); 17287 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17288 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17289 <= SystemClock.uptimeMillis()) { 17290 // To avoid spamming the system, we will GC processes one 17291 // at a time, waiting a few seconds between each. 17292 performAppGcLocked(proc); 17293 scheduleAppGcsLocked(); 17294 return; 17295 } else { 17296 // It hasn't been long enough since we last GCed this 17297 // process... put it in the list to wait for its time. 17298 addProcessToGcListLocked(proc); 17299 break; 17300 } 17301 } 17302 } 17303 17304 scheduleAppGcsLocked(); 17305 } 17306 } 17307 17308 /** 17309 * If all looks good, perform GCs on all processes waiting for them. 17310 */ 17311 final void performAppGcsIfAppropriateLocked() { 17312 if (canGcNowLocked()) { 17313 performAppGcsLocked(); 17314 return; 17315 } 17316 // Still not idle, wait some more. 17317 scheduleAppGcsLocked(); 17318 } 17319 17320 /** 17321 * Schedule the execution of all pending app GCs. 17322 */ 17323 final void scheduleAppGcsLocked() { 17324 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17325 17326 if (mProcessesToGc.size() > 0) { 17327 // Schedule a GC for the time to the next process. 17328 ProcessRecord proc = mProcessesToGc.get(0); 17329 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17330 17331 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17332 long now = SystemClock.uptimeMillis(); 17333 if (when < (now+GC_TIMEOUT)) { 17334 when = now + GC_TIMEOUT; 17335 } 17336 mHandler.sendMessageAtTime(msg, when); 17337 } 17338 } 17339 17340 /** 17341 * Add a process to the array of processes waiting to be GCed. Keeps the 17342 * list in sorted order by the last GC time. The process can't already be 17343 * on the list. 17344 */ 17345 final void addProcessToGcListLocked(ProcessRecord proc) { 17346 boolean added = false; 17347 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17348 if (mProcessesToGc.get(i).lastRequestedGc < 17349 proc.lastRequestedGc) { 17350 added = true; 17351 mProcessesToGc.add(i+1, proc); 17352 break; 17353 } 17354 } 17355 if (!added) { 17356 mProcessesToGc.add(0, proc); 17357 } 17358 } 17359 17360 /** 17361 * Set up to ask a process to GC itself. This will either do it 17362 * immediately, or put it on the list of processes to gc the next 17363 * time things are idle. 17364 */ 17365 final void scheduleAppGcLocked(ProcessRecord app) { 17366 long now = SystemClock.uptimeMillis(); 17367 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17368 return; 17369 } 17370 if (!mProcessesToGc.contains(app)) { 17371 addProcessToGcListLocked(app); 17372 scheduleAppGcsLocked(); 17373 } 17374 } 17375 17376 final void checkExcessivePowerUsageLocked(boolean doKills) { 17377 updateCpuStatsNow(); 17378 17379 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17380 boolean doWakeKills = doKills; 17381 boolean doCpuKills = doKills; 17382 if (mLastPowerCheckRealtime == 0) { 17383 doWakeKills = false; 17384 } 17385 if (mLastPowerCheckUptime == 0) { 17386 doCpuKills = false; 17387 } 17388 if (stats.isScreenOn()) { 17389 doWakeKills = false; 17390 } 17391 final long curRealtime = SystemClock.elapsedRealtime(); 17392 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17393 final long curUptime = SystemClock.uptimeMillis(); 17394 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17395 mLastPowerCheckRealtime = curRealtime; 17396 mLastPowerCheckUptime = curUptime; 17397 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17398 doWakeKills = false; 17399 } 17400 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17401 doCpuKills = false; 17402 } 17403 int i = mLruProcesses.size(); 17404 while (i > 0) { 17405 i--; 17406 ProcessRecord app = mLruProcesses.get(i); 17407 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17408 long wtime; 17409 synchronized (stats) { 17410 wtime = stats.getProcessWakeTime(app.info.uid, 17411 app.pid, curRealtime); 17412 } 17413 long wtimeUsed = wtime - app.lastWakeTime; 17414 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17415 if (DEBUG_POWER) { 17416 StringBuilder sb = new StringBuilder(128); 17417 sb.append("Wake for "); 17418 app.toShortString(sb); 17419 sb.append(": over "); 17420 TimeUtils.formatDuration(realtimeSince, sb); 17421 sb.append(" used "); 17422 TimeUtils.formatDuration(wtimeUsed, sb); 17423 sb.append(" ("); 17424 sb.append((wtimeUsed*100)/realtimeSince); 17425 sb.append("%)"); 17426 Slog.i(TAG, sb.toString()); 17427 sb.setLength(0); 17428 sb.append("CPU for "); 17429 app.toShortString(sb); 17430 sb.append(": over "); 17431 TimeUtils.formatDuration(uptimeSince, sb); 17432 sb.append(" used "); 17433 TimeUtils.formatDuration(cputimeUsed, sb); 17434 sb.append(" ("); 17435 sb.append((cputimeUsed*100)/uptimeSince); 17436 sb.append("%)"); 17437 Slog.i(TAG, sb.toString()); 17438 } 17439 // If a process has held a wake lock for more 17440 // than 50% of the time during this period, 17441 // that sounds bad. Kill! 17442 if (doWakeKills && realtimeSince > 0 17443 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17444 synchronized (stats) { 17445 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17446 realtimeSince, wtimeUsed); 17447 } 17448 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17449 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17450 } else if (doCpuKills && uptimeSince > 0 17451 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17452 synchronized (stats) { 17453 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17454 uptimeSince, cputimeUsed); 17455 } 17456 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17457 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17458 } else { 17459 app.lastWakeTime = wtime; 17460 app.lastCpuTime = app.curCpuTime; 17461 } 17462 } 17463 } 17464 } 17465 17466 private final boolean applyOomAdjLocked(ProcessRecord app, 17467 ProcessRecord TOP_APP, boolean doingAll, long now) { 17468 boolean success = true; 17469 17470 if (app.curRawAdj != app.setRawAdj) { 17471 app.setRawAdj = app.curRawAdj; 17472 } 17473 17474 int changes = 0; 17475 17476 if (app.curAdj != app.setAdj) { 17477 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17478 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17479 TAG, "Set " + app.pid + " " + app.processName + 17480 " adj " + app.curAdj + ": " + app.adjType); 17481 app.setAdj = app.curAdj; 17482 } 17483 17484 if (app.setSchedGroup != app.curSchedGroup) { 17485 app.setSchedGroup = app.curSchedGroup; 17486 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17487 "Setting process group of " + app.processName 17488 + " to " + app.curSchedGroup); 17489 if (app.waitingToKill != null && 17490 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17491 app.kill(app.waitingToKill, true); 17492 success = false; 17493 } else { 17494 if (true) { 17495 long oldId = Binder.clearCallingIdentity(); 17496 try { 17497 Process.setProcessGroup(app.pid, app.curSchedGroup); 17498 } catch (Exception e) { 17499 Slog.w(TAG, "Failed setting process group of " + app.pid 17500 + " to " + app.curSchedGroup); 17501 e.printStackTrace(); 17502 } finally { 17503 Binder.restoreCallingIdentity(oldId); 17504 } 17505 } else { 17506 if (app.thread != null) { 17507 try { 17508 app.thread.setSchedulingGroup(app.curSchedGroup); 17509 } catch (RemoteException e) { 17510 } 17511 } 17512 } 17513 Process.setSwappiness(app.pid, 17514 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17515 } 17516 } 17517 if (app.repForegroundActivities != app.foregroundActivities) { 17518 app.repForegroundActivities = app.foregroundActivities; 17519 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17520 } 17521 if (app.repProcState != app.curProcState) { 17522 app.repProcState = app.curProcState; 17523 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17524 if (app.thread != null) { 17525 try { 17526 if (false) { 17527 //RuntimeException h = new RuntimeException("here"); 17528 Slog.i(TAG, "Sending new process state " + app.repProcState 17529 + " to " + app /*, h*/); 17530 } 17531 app.thread.setProcessState(app.repProcState); 17532 } catch (RemoteException e) { 17533 } 17534 } 17535 } 17536 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17537 app.setProcState)) { 17538 app.lastStateTime = now; 17539 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17540 isSleeping(), now); 17541 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17542 + ProcessList.makeProcStateString(app.setProcState) + " to " 17543 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17544 + (app.nextPssTime-now) + ": " + app); 17545 } else { 17546 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17547 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17548 requestPssLocked(app, app.setProcState); 17549 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17550 isSleeping(), now); 17551 } else if (false && DEBUG_PSS) { 17552 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17553 } 17554 } 17555 if (app.setProcState != app.curProcState) { 17556 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17557 "Proc state change of " + app.processName 17558 + " to " + app.curProcState); 17559 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17560 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17561 if (setImportant && !curImportant) { 17562 // This app is no longer something we consider important enough to allow to 17563 // use arbitrary amounts of battery power. Note 17564 // its current wake lock time to later know to kill it if 17565 // it is not behaving well. 17566 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17567 synchronized (stats) { 17568 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17569 app.pid, SystemClock.elapsedRealtime()); 17570 } 17571 app.lastCpuTime = app.curCpuTime; 17572 17573 } 17574 app.setProcState = app.curProcState; 17575 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17576 app.notCachedSinceIdle = false; 17577 } 17578 if (!doingAll) { 17579 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17580 } else { 17581 app.procStateChanged = true; 17582 } 17583 } 17584 17585 if (changes != 0) { 17586 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17587 int i = mPendingProcessChanges.size()-1; 17588 ProcessChangeItem item = null; 17589 while (i >= 0) { 17590 item = mPendingProcessChanges.get(i); 17591 if (item.pid == app.pid) { 17592 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17593 break; 17594 } 17595 i--; 17596 } 17597 if (i < 0) { 17598 // No existing item in pending changes; need a new one. 17599 final int NA = mAvailProcessChanges.size(); 17600 if (NA > 0) { 17601 item = mAvailProcessChanges.remove(NA-1); 17602 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17603 } else { 17604 item = new ProcessChangeItem(); 17605 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17606 } 17607 item.changes = 0; 17608 item.pid = app.pid; 17609 item.uid = app.info.uid; 17610 if (mPendingProcessChanges.size() == 0) { 17611 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17612 "*** Enqueueing dispatch processes changed!"); 17613 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17614 } 17615 mPendingProcessChanges.add(item); 17616 } 17617 item.changes |= changes; 17618 item.processState = app.repProcState; 17619 item.foregroundActivities = app.repForegroundActivities; 17620 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17621 + Integer.toHexString(System.identityHashCode(item)) 17622 + " " + app.toShortString() + ": changes=" + item.changes 17623 + " procState=" + item.processState 17624 + " foreground=" + item.foregroundActivities 17625 + " type=" + app.adjType + " source=" + app.adjSource 17626 + " target=" + app.adjTarget); 17627 } 17628 17629 return success; 17630 } 17631 17632 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17633 if (proc.thread != null) { 17634 if (proc.baseProcessTracker != null) { 17635 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17636 } 17637 if (proc.repProcState >= 0) { 17638 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17639 proc.repProcState); 17640 } 17641 } 17642 } 17643 17644 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17645 ProcessRecord TOP_APP, boolean doingAll, long now) { 17646 if (app.thread == null) { 17647 return false; 17648 } 17649 17650 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17651 17652 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17653 } 17654 17655 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17656 boolean oomAdj) { 17657 if (isForeground != proc.foregroundServices) { 17658 proc.foregroundServices = isForeground; 17659 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17660 proc.info.uid); 17661 if (isForeground) { 17662 if (curProcs == null) { 17663 curProcs = new ArrayList<ProcessRecord>(); 17664 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17665 } 17666 if (!curProcs.contains(proc)) { 17667 curProcs.add(proc); 17668 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17669 proc.info.packageName, proc.info.uid); 17670 } 17671 } else { 17672 if (curProcs != null) { 17673 if (curProcs.remove(proc)) { 17674 mBatteryStatsService.noteEvent( 17675 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17676 proc.info.packageName, proc.info.uid); 17677 if (curProcs.size() <= 0) { 17678 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17679 } 17680 } 17681 } 17682 } 17683 if (oomAdj) { 17684 updateOomAdjLocked(); 17685 } 17686 } 17687 } 17688 17689 private final ActivityRecord resumedAppLocked() { 17690 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17691 String pkg; 17692 int uid; 17693 if (act != null) { 17694 pkg = act.packageName; 17695 uid = act.info.applicationInfo.uid; 17696 } else { 17697 pkg = null; 17698 uid = -1; 17699 } 17700 // Has the UID or resumed package name changed? 17701 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17702 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17703 if (mCurResumedPackage != null) { 17704 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17705 mCurResumedPackage, mCurResumedUid); 17706 } 17707 mCurResumedPackage = pkg; 17708 mCurResumedUid = uid; 17709 if (mCurResumedPackage != null) { 17710 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17711 mCurResumedPackage, mCurResumedUid); 17712 } 17713 } 17714 return act; 17715 } 17716 17717 final boolean updateOomAdjLocked(ProcessRecord app) { 17718 final ActivityRecord TOP_ACT = resumedAppLocked(); 17719 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17720 final boolean wasCached = app.cached; 17721 17722 mAdjSeq++; 17723 17724 // This is the desired cached adjusment we want to tell it to use. 17725 // If our app is currently cached, we know it, and that is it. Otherwise, 17726 // we don't know it yet, and it needs to now be cached we will then 17727 // need to do a complete oom adj. 17728 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17729 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17730 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17731 SystemClock.uptimeMillis()); 17732 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17733 // Changed to/from cached state, so apps after it in the LRU 17734 // list may also be changed. 17735 updateOomAdjLocked(); 17736 } 17737 return success; 17738 } 17739 17740 final void updateOomAdjLocked() { 17741 final ActivityRecord TOP_ACT = resumedAppLocked(); 17742 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17743 final long now = SystemClock.uptimeMillis(); 17744 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17745 final int N = mLruProcesses.size(); 17746 17747 if (false) { 17748 RuntimeException e = new RuntimeException(); 17749 e.fillInStackTrace(); 17750 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17751 } 17752 17753 mAdjSeq++; 17754 mNewNumServiceProcs = 0; 17755 mNewNumAServiceProcs = 0; 17756 17757 final int emptyProcessLimit; 17758 final int cachedProcessLimit; 17759 if (mProcessLimit <= 0) { 17760 emptyProcessLimit = cachedProcessLimit = 0; 17761 } else if (mProcessLimit == 1) { 17762 emptyProcessLimit = 1; 17763 cachedProcessLimit = 0; 17764 } else { 17765 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17766 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17767 } 17768 17769 // Let's determine how many processes we have running vs. 17770 // how many slots we have for background processes; we may want 17771 // to put multiple processes in a slot of there are enough of 17772 // them. 17773 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17774 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17775 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17776 if (numEmptyProcs > cachedProcessLimit) { 17777 // If there are more empty processes than our limit on cached 17778 // processes, then use the cached process limit for the factor. 17779 // This ensures that the really old empty processes get pushed 17780 // down to the bottom, so if we are running low on memory we will 17781 // have a better chance at keeping around more cached processes 17782 // instead of a gazillion empty processes. 17783 numEmptyProcs = cachedProcessLimit; 17784 } 17785 int emptyFactor = numEmptyProcs/numSlots; 17786 if (emptyFactor < 1) emptyFactor = 1; 17787 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17788 if (cachedFactor < 1) cachedFactor = 1; 17789 int stepCached = 0; 17790 int stepEmpty = 0; 17791 int numCached = 0; 17792 int numEmpty = 0; 17793 int numTrimming = 0; 17794 17795 mNumNonCachedProcs = 0; 17796 mNumCachedHiddenProcs = 0; 17797 17798 // First update the OOM adjustment for each of the 17799 // application processes based on their current state. 17800 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17801 int nextCachedAdj = curCachedAdj+1; 17802 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17803 int nextEmptyAdj = curEmptyAdj+2; 17804 for (int i=N-1; i>=0; i--) { 17805 ProcessRecord app = mLruProcesses.get(i); 17806 if (!app.killedByAm && app.thread != null) { 17807 app.procStateChanged = false; 17808 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17809 17810 // If we haven't yet assigned the final cached adj 17811 // to the process, do that now. 17812 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17813 switch (app.curProcState) { 17814 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17815 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17816 // This process is a cached process holding activities... 17817 // assign it the next cached value for that type, and then 17818 // step that cached level. 17819 app.curRawAdj = curCachedAdj; 17820 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17821 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17822 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17823 + ")"); 17824 if (curCachedAdj != nextCachedAdj) { 17825 stepCached++; 17826 if (stepCached >= cachedFactor) { 17827 stepCached = 0; 17828 curCachedAdj = nextCachedAdj; 17829 nextCachedAdj += 2; 17830 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17831 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17832 } 17833 } 17834 } 17835 break; 17836 default: 17837 // For everything else, assign next empty cached process 17838 // level and bump that up. Note that this means that 17839 // long-running services that have dropped down to the 17840 // cached level will be treated as empty (since their process 17841 // state is still as a service), which is what we want. 17842 app.curRawAdj = curEmptyAdj; 17843 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17844 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17845 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17846 + ")"); 17847 if (curEmptyAdj != nextEmptyAdj) { 17848 stepEmpty++; 17849 if (stepEmpty >= emptyFactor) { 17850 stepEmpty = 0; 17851 curEmptyAdj = nextEmptyAdj; 17852 nextEmptyAdj += 2; 17853 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17854 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17855 } 17856 } 17857 } 17858 break; 17859 } 17860 } 17861 17862 applyOomAdjLocked(app, TOP_APP, true, now); 17863 17864 // Count the number of process types. 17865 switch (app.curProcState) { 17866 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17867 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17868 mNumCachedHiddenProcs++; 17869 numCached++; 17870 if (numCached > cachedProcessLimit) { 17871 app.kill("cached #" + numCached, true); 17872 } 17873 break; 17874 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17875 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17876 && app.lastActivityTime < oldTime) { 17877 app.kill("empty for " 17878 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17879 / 1000) + "s", true); 17880 } else { 17881 numEmpty++; 17882 if (numEmpty > emptyProcessLimit) { 17883 app.kill("empty #" + numEmpty, true); 17884 } 17885 } 17886 break; 17887 default: 17888 mNumNonCachedProcs++; 17889 break; 17890 } 17891 17892 if (app.isolated && app.services.size() <= 0) { 17893 // If this is an isolated process, and there are no 17894 // services running in it, then the process is no longer 17895 // needed. We agressively kill these because we can by 17896 // definition not re-use the same process again, and it is 17897 // good to avoid having whatever code was running in them 17898 // left sitting around after no longer needed. 17899 app.kill("isolated not needed", true); 17900 } 17901 17902 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17903 && !app.killedByAm) { 17904 numTrimming++; 17905 } 17906 } 17907 } 17908 17909 mNumServiceProcs = mNewNumServiceProcs; 17910 17911 // Now determine the memory trimming level of background processes. 17912 // Unfortunately we need to start at the back of the list to do this 17913 // properly. We only do this if the number of background apps we 17914 // are managing to keep around is less than half the maximum we desire; 17915 // if we are keeping a good number around, we'll let them use whatever 17916 // memory they want. 17917 final int numCachedAndEmpty = numCached + numEmpty; 17918 int memFactor; 17919 if (numCached <= ProcessList.TRIM_CACHED_APPS 17920 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17921 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17922 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17923 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17924 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17925 } else { 17926 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17927 } 17928 } else { 17929 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17930 } 17931 // We always allow the memory level to go up (better). We only allow it to go 17932 // down if we are in a state where that is allowed, *and* the total number of processes 17933 // has gone down since last time. 17934 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17935 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17936 + " last=" + mLastNumProcesses); 17937 if (memFactor > mLastMemoryLevel) { 17938 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17939 memFactor = mLastMemoryLevel; 17940 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17941 } 17942 } 17943 mLastMemoryLevel = memFactor; 17944 mLastNumProcesses = mLruProcesses.size(); 17945 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17946 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17947 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17948 if (mLowRamStartTime == 0) { 17949 mLowRamStartTime = now; 17950 } 17951 int step = 0; 17952 int fgTrimLevel; 17953 switch (memFactor) { 17954 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17955 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17956 break; 17957 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17958 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17959 break; 17960 default: 17961 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17962 break; 17963 } 17964 int factor = numTrimming/3; 17965 int minFactor = 2; 17966 if (mHomeProcess != null) minFactor++; 17967 if (mPreviousProcess != null) minFactor++; 17968 if (factor < minFactor) factor = minFactor; 17969 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17970 for (int i=N-1; i>=0; i--) { 17971 ProcessRecord app = mLruProcesses.get(i); 17972 if (allChanged || app.procStateChanged) { 17973 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17974 app.procStateChanged = false; 17975 } 17976 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17977 && !app.killedByAm) { 17978 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17979 try { 17980 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17981 "Trimming memory of " + app.processName 17982 + " to " + curLevel); 17983 app.thread.scheduleTrimMemory(curLevel); 17984 } catch (RemoteException e) { 17985 } 17986 if (false) { 17987 // For now we won't do this; our memory trimming seems 17988 // to be good enough at this point that destroying 17989 // activities causes more harm than good. 17990 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17991 && app != mHomeProcess && app != mPreviousProcess) { 17992 // Need to do this on its own message because the stack may not 17993 // be in a consistent state at this point. 17994 // For these apps we will also finish their activities 17995 // to help them free memory. 17996 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17997 } 17998 } 17999 } 18000 app.trimMemoryLevel = curLevel; 18001 step++; 18002 if (step >= factor) { 18003 step = 0; 18004 switch (curLevel) { 18005 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18006 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18007 break; 18008 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18009 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18010 break; 18011 } 18012 } 18013 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18014 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18015 && app.thread != null) { 18016 try { 18017 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18018 "Trimming memory of heavy-weight " + app.processName 18019 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18020 app.thread.scheduleTrimMemory( 18021 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18022 } catch (RemoteException e) { 18023 } 18024 } 18025 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18026 } else { 18027 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18028 || app.systemNoUi) && app.pendingUiClean) { 18029 // If this application is now in the background and it 18030 // had done UI, then give it the special trim level to 18031 // have it free UI resources. 18032 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18033 if (app.trimMemoryLevel < level && app.thread != null) { 18034 try { 18035 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18036 "Trimming memory of bg-ui " + app.processName 18037 + " to " + level); 18038 app.thread.scheduleTrimMemory(level); 18039 } catch (RemoteException e) { 18040 } 18041 } 18042 app.pendingUiClean = false; 18043 } 18044 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18045 try { 18046 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18047 "Trimming memory of fg " + app.processName 18048 + " to " + fgTrimLevel); 18049 app.thread.scheduleTrimMemory(fgTrimLevel); 18050 } catch (RemoteException e) { 18051 } 18052 } 18053 app.trimMemoryLevel = fgTrimLevel; 18054 } 18055 } 18056 } else { 18057 if (mLowRamStartTime != 0) { 18058 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18059 mLowRamStartTime = 0; 18060 } 18061 for (int i=N-1; i>=0; i--) { 18062 ProcessRecord app = mLruProcesses.get(i); 18063 if (allChanged || app.procStateChanged) { 18064 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18065 app.procStateChanged = false; 18066 } 18067 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18068 || app.systemNoUi) && app.pendingUiClean) { 18069 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18070 && app.thread != null) { 18071 try { 18072 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18073 "Trimming memory of ui hidden " + app.processName 18074 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18075 app.thread.scheduleTrimMemory( 18076 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18077 } catch (RemoteException e) { 18078 } 18079 } 18080 app.pendingUiClean = false; 18081 } 18082 app.trimMemoryLevel = 0; 18083 } 18084 } 18085 18086 if (mAlwaysFinishActivities) { 18087 // Need to do this on its own message because the stack may not 18088 // be in a consistent state at this point. 18089 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18090 } 18091 18092 if (allChanged) { 18093 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18094 } 18095 18096 if (mProcessStats.shouldWriteNowLocked(now)) { 18097 mHandler.post(new Runnable() { 18098 @Override public void run() { 18099 synchronized (ActivityManagerService.this) { 18100 mProcessStats.writeStateAsyncLocked(); 18101 } 18102 } 18103 }); 18104 } 18105 18106 if (DEBUG_OOM_ADJ) { 18107 if (false) { 18108 RuntimeException here = new RuntimeException("here"); 18109 here.fillInStackTrace(); 18110 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18111 } else { 18112 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18113 } 18114 } 18115 } 18116 18117 final void trimApplications() { 18118 synchronized (this) { 18119 int i; 18120 18121 // First remove any unused application processes whose package 18122 // has been removed. 18123 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18124 final ProcessRecord app = mRemovedProcesses.get(i); 18125 if (app.activities.size() == 0 18126 && app.curReceiver == null && app.services.size() == 0) { 18127 Slog.i( 18128 TAG, "Exiting empty application process " 18129 + app.processName + " (" 18130 + (app.thread != null ? app.thread.asBinder() : null) 18131 + ")\n"); 18132 if (app.pid > 0 && app.pid != MY_PID) { 18133 app.kill("empty", false); 18134 } else { 18135 try { 18136 app.thread.scheduleExit(); 18137 } catch (Exception e) { 18138 // Ignore exceptions. 18139 } 18140 } 18141 cleanUpApplicationRecordLocked(app, false, true, -1); 18142 mRemovedProcesses.remove(i); 18143 18144 if (app.persistent) { 18145 addAppLocked(app.info, false, null /* ABI override */); 18146 } 18147 } 18148 } 18149 18150 // Now update the oom adj for all processes. 18151 updateOomAdjLocked(); 18152 } 18153 } 18154 18155 /** This method sends the specified signal to each of the persistent apps */ 18156 public void signalPersistentProcesses(int sig) throws RemoteException { 18157 if (sig != Process.SIGNAL_USR1) { 18158 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18159 } 18160 18161 synchronized (this) { 18162 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18163 != PackageManager.PERMISSION_GRANTED) { 18164 throw new SecurityException("Requires permission " 18165 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18166 } 18167 18168 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18169 ProcessRecord r = mLruProcesses.get(i); 18170 if (r.thread != null && r.persistent) { 18171 Process.sendSignal(r.pid, sig); 18172 } 18173 } 18174 } 18175 } 18176 18177 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18178 if (proc == null || proc == mProfileProc) { 18179 proc = mProfileProc; 18180 profileType = mProfileType; 18181 clearProfilerLocked(); 18182 } 18183 if (proc == null) { 18184 return; 18185 } 18186 try { 18187 proc.thread.profilerControl(false, null, profileType); 18188 } catch (RemoteException e) { 18189 throw new IllegalStateException("Process disappeared"); 18190 } 18191 } 18192 18193 private void clearProfilerLocked() { 18194 if (mProfileFd != null) { 18195 try { 18196 mProfileFd.close(); 18197 } catch (IOException e) { 18198 } 18199 } 18200 mProfileApp = null; 18201 mProfileProc = null; 18202 mProfileFile = null; 18203 mProfileType = 0; 18204 mAutoStopProfiler = false; 18205 mSamplingInterval = 0; 18206 } 18207 18208 public boolean profileControl(String process, int userId, boolean start, 18209 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18210 18211 try { 18212 synchronized (this) { 18213 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18214 // its own permission. 18215 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18216 != PackageManager.PERMISSION_GRANTED) { 18217 throw new SecurityException("Requires permission " 18218 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18219 } 18220 18221 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18222 throw new IllegalArgumentException("null profile info or fd"); 18223 } 18224 18225 ProcessRecord proc = null; 18226 if (process != null) { 18227 proc = findProcessLocked(process, userId, "profileControl"); 18228 } 18229 18230 if (start && (proc == null || proc.thread == null)) { 18231 throw new IllegalArgumentException("Unknown process: " + process); 18232 } 18233 18234 if (start) { 18235 stopProfilerLocked(null, 0); 18236 setProfileApp(proc.info, proc.processName, profilerInfo); 18237 mProfileProc = proc; 18238 mProfileType = profileType; 18239 ParcelFileDescriptor fd = profilerInfo.profileFd; 18240 try { 18241 fd = fd.dup(); 18242 } catch (IOException e) { 18243 fd = null; 18244 } 18245 profilerInfo.profileFd = fd; 18246 proc.thread.profilerControl(start, profilerInfo, profileType); 18247 fd = null; 18248 mProfileFd = null; 18249 } else { 18250 stopProfilerLocked(proc, profileType); 18251 if (profilerInfo != null && profilerInfo.profileFd != null) { 18252 try { 18253 profilerInfo.profileFd.close(); 18254 } catch (IOException e) { 18255 } 18256 } 18257 } 18258 18259 return true; 18260 } 18261 } catch (RemoteException e) { 18262 throw new IllegalStateException("Process disappeared"); 18263 } finally { 18264 if (profilerInfo != null && profilerInfo.profileFd != null) { 18265 try { 18266 profilerInfo.profileFd.close(); 18267 } catch (IOException e) { 18268 } 18269 } 18270 } 18271 } 18272 18273 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18274 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18275 userId, true, ALLOW_FULL_ONLY, callName, null); 18276 ProcessRecord proc = null; 18277 try { 18278 int pid = Integer.parseInt(process); 18279 synchronized (mPidsSelfLocked) { 18280 proc = mPidsSelfLocked.get(pid); 18281 } 18282 } catch (NumberFormatException e) { 18283 } 18284 18285 if (proc == null) { 18286 ArrayMap<String, SparseArray<ProcessRecord>> all 18287 = mProcessNames.getMap(); 18288 SparseArray<ProcessRecord> procs = all.get(process); 18289 if (procs != null && procs.size() > 0) { 18290 proc = procs.valueAt(0); 18291 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18292 for (int i=1; i<procs.size(); i++) { 18293 ProcessRecord thisProc = procs.valueAt(i); 18294 if (thisProc.userId == userId) { 18295 proc = thisProc; 18296 break; 18297 } 18298 } 18299 } 18300 } 18301 } 18302 18303 return proc; 18304 } 18305 18306 public boolean dumpHeap(String process, int userId, boolean managed, 18307 String path, ParcelFileDescriptor fd) throws RemoteException { 18308 18309 try { 18310 synchronized (this) { 18311 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18312 // its own permission (same as profileControl). 18313 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18314 != PackageManager.PERMISSION_GRANTED) { 18315 throw new SecurityException("Requires permission " 18316 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18317 } 18318 18319 if (fd == null) { 18320 throw new IllegalArgumentException("null fd"); 18321 } 18322 18323 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18324 if (proc == null || proc.thread == null) { 18325 throw new IllegalArgumentException("Unknown process: " + process); 18326 } 18327 18328 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18329 if (!isDebuggable) { 18330 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18331 throw new SecurityException("Process not debuggable: " + proc); 18332 } 18333 } 18334 18335 proc.thread.dumpHeap(managed, path, fd); 18336 fd = null; 18337 return true; 18338 } 18339 } catch (RemoteException e) { 18340 throw new IllegalStateException("Process disappeared"); 18341 } finally { 18342 if (fd != null) { 18343 try { 18344 fd.close(); 18345 } catch (IOException e) { 18346 } 18347 } 18348 } 18349 } 18350 18351 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18352 public void monitor() { 18353 synchronized (this) { } 18354 } 18355 18356 void onCoreSettingsChange(Bundle settings) { 18357 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18358 ProcessRecord processRecord = mLruProcesses.get(i); 18359 try { 18360 if (processRecord.thread != null) { 18361 processRecord.thread.setCoreSettings(settings); 18362 } 18363 } catch (RemoteException re) { 18364 /* ignore */ 18365 } 18366 } 18367 } 18368 18369 // Multi-user methods 18370 18371 /** 18372 * Start user, if its not already running, but don't bring it to foreground. 18373 */ 18374 @Override 18375 public boolean startUserInBackground(final int userId) { 18376 return startUser(userId, /* foreground */ false); 18377 } 18378 18379 /** 18380 * Start user, if its not already running, and bring it to foreground. 18381 */ 18382 boolean startUserInForeground(final int userId, Dialog dlg) { 18383 boolean result = startUser(userId, /* foreground */ true); 18384 dlg.dismiss(); 18385 return result; 18386 } 18387 18388 /** 18389 * Refreshes the list of users related to the current user when either a 18390 * user switch happens or when a new related user is started in the 18391 * background. 18392 */ 18393 private void updateCurrentProfileIdsLocked() { 18394 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18395 mCurrentUserId, false /* enabledOnly */); 18396 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18397 for (int i = 0; i < currentProfileIds.length; i++) { 18398 currentProfileIds[i] = profiles.get(i).id; 18399 } 18400 mCurrentProfileIds = currentProfileIds; 18401 18402 synchronized (mUserProfileGroupIdsSelfLocked) { 18403 mUserProfileGroupIdsSelfLocked.clear(); 18404 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18405 for (int i = 0; i < users.size(); i++) { 18406 UserInfo user = users.get(i); 18407 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18408 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18409 } 18410 } 18411 } 18412 } 18413 18414 private Set getProfileIdsLocked(int userId) { 18415 Set userIds = new HashSet<Integer>(); 18416 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18417 userId, false /* enabledOnly */); 18418 for (UserInfo user : profiles) { 18419 userIds.add(Integer.valueOf(user.id)); 18420 } 18421 return userIds; 18422 } 18423 18424 @Override 18425 public boolean switchUser(final int userId) { 18426 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18427 String userName; 18428 synchronized (this) { 18429 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18430 if (userInfo == null) { 18431 Slog.w(TAG, "No user info for user #" + userId); 18432 return false; 18433 } 18434 if (userInfo.isManagedProfile()) { 18435 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18436 return false; 18437 } 18438 userName = userInfo.name; 18439 mTargetUserId = userId; 18440 } 18441 mHandler.removeMessages(START_USER_SWITCH_MSG); 18442 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18443 return true; 18444 } 18445 18446 private void showUserSwitchDialog(int userId, String userName) { 18447 // The dialog will show and then initiate the user switch by calling startUserInForeground 18448 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18449 true /* above system */); 18450 d.show(); 18451 } 18452 18453 private boolean startUser(final int userId, final boolean foreground) { 18454 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18455 != PackageManager.PERMISSION_GRANTED) { 18456 String msg = "Permission Denial: switchUser() from pid=" 18457 + Binder.getCallingPid() 18458 + ", uid=" + Binder.getCallingUid() 18459 + " requires " + INTERACT_ACROSS_USERS_FULL; 18460 Slog.w(TAG, msg); 18461 throw new SecurityException(msg); 18462 } 18463 18464 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18465 18466 final long ident = Binder.clearCallingIdentity(); 18467 try { 18468 synchronized (this) { 18469 final int oldUserId = mCurrentUserId; 18470 if (oldUserId == userId) { 18471 return true; 18472 } 18473 18474 mStackSupervisor.setLockTaskModeLocked(null, false); 18475 18476 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18477 if (userInfo == null) { 18478 Slog.w(TAG, "No user info for user #" + userId); 18479 return false; 18480 } 18481 if (foreground && userInfo.isManagedProfile()) { 18482 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18483 return false; 18484 } 18485 18486 if (foreground) { 18487 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18488 R.anim.screen_user_enter); 18489 } 18490 18491 boolean needStart = false; 18492 18493 // If the user we are switching to is not currently started, then 18494 // we need to start it now. 18495 if (mStartedUsers.get(userId) == null) { 18496 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18497 updateStartedUserArrayLocked(); 18498 needStart = true; 18499 } 18500 18501 final Integer userIdInt = Integer.valueOf(userId); 18502 mUserLru.remove(userIdInt); 18503 mUserLru.add(userIdInt); 18504 18505 if (foreground) { 18506 mCurrentUserId = userId; 18507 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18508 updateCurrentProfileIdsLocked(); 18509 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18510 // Once the internal notion of the active user has switched, we lock the device 18511 // with the option to show the user switcher on the keyguard. 18512 mWindowManager.lockNow(null); 18513 } else { 18514 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18515 updateCurrentProfileIdsLocked(); 18516 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18517 mUserLru.remove(currentUserIdInt); 18518 mUserLru.add(currentUserIdInt); 18519 } 18520 18521 final UserStartedState uss = mStartedUsers.get(userId); 18522 18523 // Make sure user is in the started state. If it is currently 18524 // stopping, we need to knock that off. 18525 if (uss.mState == UserStartedState.STATE_STOPPING) { 18526 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18527 // so we can just fairly silently bring the user back from 18528 // the almost-dead. 18529 uss.mState = UserStartedState.STATE_RUNNING; 18530 updateStartedUserArrayLocked(); 18531 needStart = true; 18532 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18533 // This means ACTION_SHUTDOWN has been sent, so we will 18534 // need to treat this as a new boot of the user. 18535 uss.mState = UserStartedState.STATE_BOOTING; 18536 updateStartedUserArrayLocked(); 18537 needStart = true; 18538 } 18539 18540 if (uss.mState == UserStartedState.STATE_BOOTING) { 18541 // Booting up a new user, need to tell system services about it. 18542 // Note that this is on the same handler as scheduling of broadcasts, 18543 // which is important because it needs to go first. 18544 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18545 } 18546 18547 if (foreground) { 18548 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18549 oldUserId)); 18550 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18551 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18552 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18553 oldUserId, userId, uss)); 18554 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18555 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18556 } 18557 18558 if (needStart) { 18559 // Send USER_STARTED broadcast 18560 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18561 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18562 | Intent.FLAG_RECEIVER_FOREGROUND); 18563 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18564 broadcastIntentLocked(null, null, intent, 18565 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18566 false, false, MY_PID, Process.SYSTEM_UID, userId); 18567 } 18568 18569 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18570 if (userId != UserHandle.USER_OWNER) { 18571 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18572 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18573 broadcastIntentLocked(null, null, intent, null, 18574 new IIntentReceiver.Stub() { 18575 public void performReceive(Intent intent, int resultCode, 18576 String data, Bundle extras, boolean ordered, 18577 boolean sticky, int sendingUser) { 18578 onUserInitialized(uss, foreground, oldUserId, userId); 18579 } 18580 }, 0, null, null, null, AppOpsManager.OP_NONE, 18581 true, false, MY_PID, Process.SYSTEM_UID, 18582 userId); 18583 uss.initializing = true; 18584 } else { 18585 getUserManagerLocked().makeInitialized(userInfo.id); 18586 } 18587 } 18588 18589 if (foreground) { 18590 if (!uss.initializing) { 18591 moveUserToForeground(uss, oldUserId, userId); 18592 } 18593 } else { 18594 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18595 } 18596 18597 if (needStart) { 18598 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18599 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18600 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18601 broadcastIntentLocked(null, null, intent, 18602 null, new IIntentReceiver.Stub() { 18603 @Override 18604 public void performReceive(Intent intent, int resultCode, String data, 18605 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18606 throws RemoteException { 18607 } 18608 }, 0, null, null, 18609 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18610 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18611 } 18612 } 18613 } finally { 18614 Binder.restoreCallingIdentity(ident); 18615 } 18616 18617 return true; 18618 } 18619 18620 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18621 long ident = Binder.clearCallingIdentity(); 18622 try { 18623 Intent intent; 18624 if (oldUserId >= 0) { 18625 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18626 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18627 int count = profiles.size(); 18628 for (int i = 0; i < count; i++) { 18629 int profileUserId = profiles.get(i).id; 18630 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18631 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18632 | Intent.FLAG_RECEIVER_FOREGROUND); 18633 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18634 broadcastIntentLocked(null, null, intent, 18635 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18636 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18637 } 18638 } 18639 if (newUserId >= 0) { 18640 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18641 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18642 int count = profiles.size(); 18643 for (int i = 0; i < count; i++) { 18644 int profileUserId = profiles.get(i).id; 18645 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18646 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18647 | Intent.FLAG_RECEIVER_FOREGROUND); 18648 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18649 broadcastIntentLocked(null, null, intent, 18650 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18651 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18652 } 18653 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18654 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18655 | Intent.FLAG_RECEIVER_FOREGROUND); 18656 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18657 broadcastIntentLocked(null, null, intent, 18658 null, null, 0, null, null, 18659 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18660 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18661 } 18662 } finally { 18663 Binder.restoreCallingIdentity(ident); 18664 } 18665 } 18666 18667 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18668 final int newUserId) { 18669 final int N = mUserSwitchObservers.beginBroadcast(); 18670 if (N > 0) { 18671 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18672 int mCount = 0; 18673 @Override 18674 public void sendResult(Bundle data) throws RemoteException { 18675 synchronized (ActivityManagerService.this) { 18676 if (mCurUserSwitchCallback == this) { 18677 mCount++; 18678 if (mCount == N) { 18679 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18680 } 18681 } 18682 } 18683 } 18684 }; 18685 synchronized (this) { 18686 uss.switching = true; 18687 mCurUserSwitchCallback = callback; 18688 } 18689 for (int i=0; i<N; i++) { 18690 try { 18691 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18692 newUserId, callback); 18693 } catch (RemoteException e) { 18694 } 18695 } 18696 } else { 18697 synchronized (this) { 18698 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18699 } 18700 } 18701 mUserSwitchObservers.finishBroadcast(); 18702 } 18703 18704 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18705 synchronized (this) { 18706 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18707 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18708 } 18709 } 18710 18711 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18712 mCurUserSwitchCallback = null; 18713 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18714 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18715 oldUserId, newUserId, uss)); 18716 } 18717 18718 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18719 synchronized (this) { 18720 if (foreground) { 18721 moveUserToForeground(uss, oldUserId, newUserId); 18722 } 18723 } 18724 18725 completeSwitchAndInitalize(uss, newUserId, true, false); 18726 } 18727 18728 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18729 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18730 if (homeInFront) { 18731 startHomeActivityLocked(newUserId); 18732 } else { 18733 mStackSupervisor.resumeTopActivitiesLocked(); 18734 } 18735 EventLogTags.writeAmSwitchUser(newUserId); 18736 getUserManagerLocked().userForeground(newUserId); 18737 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18738 } 18739 18740 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18741 completeSwitchAndInitalize(uss, newUserId, false, true); 18742 } 18743 18744 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18745 boolean clearInitializing, boolean clearSwitching) { 18746 boolean unfrozen = false; 18747 synchronized (this) { 18748 if (clearInitializing) { 18749 uss.initializing = false; 18750 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18751 } 18752 if (clearSwitching) { 18753 uss.switching = false; 18754 } 18755 if (!uss.switching && !uss.initializing) { 18756 mWindowManager.stopFreezingScreen(); 18757 unfrozen = true; 18758 } 18759 } 18760 if (unfrozen) { 18761 final int N = mUserSwitchObservers.beginBroadcast(); 18762 for (int i=0; i<N; i++) { 18763 try { 18764 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18765 } catch (RemoteException e) { 18766 } 18767 } 18768 mUserSwitchObservers.finishBroadcast(); 18769 } 18770 } 18771 18772 void scheduleStartProfilesLocked() { 18773 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18774 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18775 DateUtils.SECOND_IN_MILLIS); 18776 } 18777 } 18778 18779 void startProfilesLocked() { 18780 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18781 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18782 mCurrentUserId, false /* enabledOnly */); 18783 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18784 for (UserInfo user : profiles) { 18785 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18786 && user.id != mCurrentUserId) { 18787 toStart.add(user); 18788 } 18789 } 18790 final int n = toStart.size(); 18791 int i = 0; 18792 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18793 startUserInBackground(toStart.get(i).id); 18794 } 18795 if (i < n) { 18796 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18797 } 18798 } 18799 18800 void finishUserBoot(UserStartedState uss) { 18801 synchronized (this) { 18802 if (uss.mState == UserStartedState.STATE_BOOTING 18803 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18804 uss.mState = UserStartedState.STATE_RUNNING; 18805 final int userId = uss.mHandle.getIdentifier(); 18806 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18807 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18808 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18809 broadcastIntentLocked(null, null, intent, 18810 null, null, 0, null, null, 18811 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18812 true, false, MY_PID, Process.SYSTEM_UID, userId); 18813 } 18814 } 18815 } 18816 18817 void finishUserSwitch(UserStartedState uss) { 18818 synchronized (this) { 18819 finishUserBoot(uss); 18820 18821 startProfilesLocked(); 18822 18823 int num = mUserLru.size(); 18824 int i = 0; 18825 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18826 Integer oldUserId = mUserLru.get(i); 18827 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18828 if (oldUss == null) { 18829 // Shouldn't happen, but be sane if it does. 18830 mUserLru.remove(i); 18831 num--; 18832 continue; 18833 } 18834 if (oldUss.mState == UserStartedState.STATE_STOPPING 18835 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18836 // This user is already stopping, doesn't count. 18837 num--; 18838 i++; 18839 continue; 18840 } 18841 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18842 // Owner and current can't be stopped, but count as running. 18843 i++; 18844 continue; 18845 } 18846 // This is a user to be stopped. 18847 stopUserLocked(oldUserId, null); 18848 num--; 18849 i++; 18850 } 18851 } 18852 } 18853 18854 @Override 18855 public int stopUser(final int userId, final IStopUserCallback callback) { 18856 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18857 != PackageManager.PERMISSION_GRANTED) { 18858 String msg = "Permission Denial: switchUser() from pid=" 18859 + Binder.getCallingPid() 18860 + ", uid=" + Binder.getCallingUid() 18861 + " requires " + INTERACT_ACROSS_USERS_FULL; 18862 Slog.w(TAG, msg); 18863 throw new SecurityException(msg); 18864 } 18865 if (userId <= 0) { 18866 throw new IllegalArgumentException("Can't stop primary user " + userId); 18867 } 18868 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18869 synchronized (this) { 18870 return stopUserLocked(userId, callback); 18871 } 18872 } 18873 18874 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18875 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18876 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18877 return ActivityManager.USER_OP_IS_CURRENT; 18878 } 18879 18880 final UserStartedState uss = mStartedUsers.get(userId); 18881 if (uss == null) { 18882 // User is not started, nothing to do... but we do need to 18883 // callback if requested. 18884 if (callback != null) { 18885 mHandler.post(new Runnable() { 18886 @Override 18887 public void run() { 18888 try { 18889 callback.userStopped(userId); 18890 } catch (RemoteException e) { 18891 } 18892 } 18893 }); 18894 } 18895 return ActivityManager.USER_OP_SUCCESS; 18896 } 18897 18898 if (callback != null) { 18899 uss.mStopCallbacks.add(callback); 18900 } 18901 18902 if (uss.mState != UserStartedState.STATE_STOPPING 18903 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18904 uss.mState = UserStartedState.STATE_STOPPING; 18905 updateStartedUserArrayLocked(); 18906 18907 long ident = Binder.clearCallingIdentity(); 18908 try { 18909 // We are going to broadcast ACTION_USER_STOPPING and then 18910 // once that is done send a final ACTION_SHUTDOWN and then 18911 // stop the user. 18912 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18913 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18914 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18915 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18916 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18917 // This is the result receiver for the final shutdown broadcast. 18918 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18919 @Override 18920 public void performReceive(Intent intent, int resultCode, String data, 18921 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18922 finishUserStop(uss); 18923 } 18924 }; 18925 // This is the result receiver for the initial stopping broadcast. 18926 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18927 @Override 18928 public void performReceive(Intent intent, int resultCode, String data, 18929 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18930 // On to the next. 18931 synchronized (ActivityManagerService.this) { 18932 if (uss.mState != UserStartedState.STATE_STOPPING) { 18933 // Whoops, we are being started back up. Abort, abort! 18934 return; 18935 } 18936 uss.mState = UserStartedState.STATE_SHUTDOWN; 18937 } 18938 mBatteryStatsService.noteEvent( 18939 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18940 Integer.toString(userId), userId); 18941 mSystemServiceManager.stopUser(userId); 18942 broadcastIntentLocked(null, null, shutdownIntent, 18943 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18944 true, false, MY_PID, Process.SYSTEM_UID, userId); 18945 } 18946 }; 18947 // Kick things off. 18948 broadcastIntentLocked(null, null, stoppingIntent, 18949 null, stoppingReceiver, 0, null, null, 18950 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18951 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18952 } finally { 18953 Binder.restoreCallingIdentity(ident); 18954 } 18955 } 18956 18957 return ActivityManager.USER_OP_SUCCESS; 18958 } 18959 18960 void finishUserStop(UserStartedState uss) { 18961 final int userId = uss.mHandle.getIdentifier(); 18962 boolean stopped; 18963 ArrayList<IStopUserCallback> callbacks; 18964 synchronized (this) { 18965 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18966 if (mStartedUsers.get(userId) != uss) { 18967 stopped = false; 18968 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18969 stopped = false; 18970 } else { 18971 stopped = true; 18972 // User can no longer run. 18973 mStartedUsers.remove(userId); 18974 mUserLru.remove(Integer.valueOf(userId)); 18975 updateStartedUserArrayLocked(); 18976 18977 // Clean up all state and processes associated with the user. 18978 // Kill all the processes for the user. 18979 forceStopUserLocked(userId, "finish user"); 18980 } 18981 18982 // Explicitly remove the old information in mRecentTasks. 18983 removeRecentTasksForUserLocked(userId); 18984 } 18985 18986 for (int i=0; i<callbacks.size(); i++) { 18987 try { 18988 if (stopped) callbacks.get(i).userStopped(userId); 18989 else callbacks.get(i).userStopAborted(userId); 18990 } catch (RemoteException e) { 18991 } 18992 } 18993 18994 if (stopped) { 18995 mSystemServiceManager.cleanupUser(userId); 18996 synchronized (this) { 18997 mStackSupervisor.removeUserLocked(userId); 18998 } 18999 } 19000 } 19001 19002 @Override 19003 public UserInfo getCurrentUser() { 19004 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19005 != PackageManager.PERMISSION_GRANTED) && ( 19006 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19007 != PackageManager.PERMISSION_GRANTED)) { 19008 String msg = "Permission Denial: getCurrentUser() from pid=" 19009 + Binder.getCallingPid() 19010 + ", uid=" + Binder.getCallingUid() 19011 + " requires " + INTERACT_ACROSS_USERS; 19012 Slog.w(TAG, msg); 19013 throw new SecurityException(msg); 19014 } 19015 synchronized (this) { 19016 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19017 return getUserManagerLocked().getUserInfo(userId); 19018 } 19019 } 19020 19021 int getCurrentUserIdLocked() { 19022 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19023 } 19024 19025 @Override 19026 public boolean isUserRunning(int userId, boolean orStopped) { 19027 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19028 != PackageManager.PERMISSION_GRANTED) { 19029 String msg = "Permission Denial: isUserRunning() from pid=" 19030 + Binder.getCallingPid() 19031 + ", uid=" + Binder.getCallingUid() 19032 + " requires " + INTERACT_ACROSS_USERS; 19033 Slog.w(TAG, msg); 19034 throw new SecurityException(msg); 19035 } 19036 synchronized (this) { 19037 return isUserRunningLocked(userId, orStopped); 19038 } 19039 } 19040 19041 boolean isUserRunningLocked(int userId, boolean orStopped) { 19042 UserStartedState state = mStartedUsers.get(userId); 19043 if (state == null) { 19044 return false; 19045 } 19046 if (orStopped) { 19047 return true; 19048 } 19049 return state.mState != UserStartedState.STATE_STOPPING 19050 && state.mState != UserStartedState.STATE_SHUTDOWN; 19051 } 19052 19053 @Override 19054 public int[] getRunningUserIds() { 19055 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19056 != PackageManager.PERMISSION_GRANTED) { 19057 String msg = "Permission Denial: isUserRunning() from pid=" 19058 + Binder.getCallingPid() 19059 + ", uid=" + Binder.getCallingUid() 19060 + " requires " + INTERACT_ACROSS_USERS; 19061 Slog.w(TAG, msg); 19062 throw new SecurityException(msg); 19063 } 19064 synchronized (this) { 19065 return mStartedUserArray; 19066 } 19067 } 19068 19069 private void updateStartedUserArrayLocked() { 19070 int num = 0; 19071 for (int i=0; i<mStartedUsers.size(); i++) { 19072 UserStartedState uss = mStartedUsers.valueAt(i); 19073 // This list does not include stopping users. 19074 if (uss.mState != UserStartedState.STATE_STOPPING 19075 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19076 num++; 19077 } 19078 } 19079 mStartedUserArray = new int[num]; 19080 num = 0; 19081 for (int i=0; i<mStartedUsers.size(); i++) { 19082 UserStartedState uss = mStartedUsers.valueAt(i); 19083 if (uss.mState != UserStartedState.STATE_STOPPING 19084 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19085 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19086 num++; 19087 } 19088 } 19089 } 19090 19091 @Override 19092 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19093 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19094 != PackageManager.PERMISSION_GRANTED) { 19095 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19096 + Binder.getCallingPid() 19097 + ", uid=" + Binder.getCallingUid() 19098 + " requires " + INTERACT_ACROSS_USERS_FULL; 19099 Slog.w(TAG, msg); 19100 throw new SecurityException(msg); 19101 } 19102 19103 mUserSwitchObservers.register(observer); 19104 } 19105 19106 @Override 19107 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19108 mUserSwitchObservers.unregister(observer); 19109 } 19110 19111 private boolean userExists(int userId) { 19112 if (userId == 0) { 19113 return true; 19114 } 19115 UserManagerService ums = getUserManagerLocked(); 19116 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19117 } 19118 19119 int[] getUsersLocked() { 19120 UserManagerService ums = getUserManagerLocked(); 19121 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19122 } 19123 19124 UserManagerService getUserManagerLocked() { 19125 if (mUserManager == null) { 19126 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19127 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19128 } 19129 return mUserManager; 19130 } 19131 19132 private int applyUserId(int uid, int userId) { 19133 return UserHandle.getUid(userId, uid); 19134 } 19135 19136 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19137 if (info == null) return null; 19138 ApplicationInfo newInfo = new ApplicationInfo(info); 19139 newInfo.uid = applyUserId(info.uid, userId); 19140 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19141 + info.packageName; 19142 return newInfo; 19143 } 19144 19145 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19146 if (aInfo == null 19147 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19148 return aInfo; 19149 } 19150 19151 ActivityInfo info = new ActivityInfo(aInfo); 19152 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19153 return info; 19154 } 19155 19156 private final class LocalService extends ActivityManagerInternal { 19157 @Override 19158 public void goingToSleep() { 19159 ActivityManagerService.this.goingToSleep(); 19160 } 19161 19162 @Override 19163 public void wakingUp() { 19164 ActivityManagerService.this.wakingUp(); 19165 } 19166 19167 @Override 19168 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19169 String processName, String abiOverride, int uid, Runnable crashHandler) { 19170 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19171 processName, abiOverride, uid, crashHandler); 19172 } 19173 } 19174 19175 /** 19176 * An implementation of IAppTask, that allows an app to manage its own tasks via 19177 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19178 * only the process that calls getAppTasks() can call the AppTask methods. 19179 */ 19180 class AppTaskImpl extends IAppTask.Stub { 19181 private int mTaskId; 19182 private int mCallingUid; 19183 19184 public AppTaskImpl(int taskId, int callingUid) { 19185 mTaskId = taskId; 19186 mCallingUid = callingUid; 19187 } 19188 19189 private void checkCaller() { 19190 if (mCallingUid != Binder.getCallingUid()) { 19191 throw new SecurityException("Caller " + mCallingUid 19192 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19193 } 19194 } 19195 19196 @Override 19197 public void finishAndRemoveTask() { 19198 checkCaller(); 19199 19200 synchronized (ActivityManagerService.this) { 19201 long origId = Binder.clearCallingIdentity(); 19202 try { 19203 if (!removeTaskByIdLocked(mTaskId, false)) { 19204 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19205 } 19206 } finally { 19207 Binder.restoreCallingIdentity(origId); 19208 } 19209 } 19210 } 19211 19212 @Override 19213 public ActivityManager.RecentTaskInfo getTaskInfo() { 19214 checkCaller(); 19215 19216 synchronized (ActivityManagerService.this) { 19217 long origId = Binder.clearCallingIdentity(); 19218 try { 19219 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19220 if (tr == null) { 19221 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19222 } 19223 return createRecentTaskInfoFromTaskRecord(tr); 19224 } finally { 19225 Binder.restoreCallingIdentity(origId); 19226 } 19227 } 19228 } 19229 19230 @Override 19231 public void moveToFront() { 19232 checkCaller(); 19233 19234 final TaskRecord tr; 19235 synchronized (ActivityManagerService.this) { 19236 tr = recentTaskForIdLocked(mTaskId); 19237 if (tr == null) { 19238 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19239 } 19240 if (tr.getRootActivity() != null) { 19241 moveTaskToFrontLocked(tr.taskId, 0, null); 19242 return; 19243 } 19244 } 19245 19246 startActivityFromRecentsInner(tr.taskId, null); 19247 } 19248 19249 @Override 19250 public int startActivity(IBinder whoThread, String callingPackage, 19251 Intent intent, String resolvedType, Bundle options) { 19252 checkCaller(); 19253 19254 int callingUser = UserHandle.getCallingUserId(); 19255 TaskRecord tr; 19256 IApplicationThread appThread; 19257 synchronized (ActivityManagerService.this) { 19258 tr = recentTaskForIdLocked(mTaskId); 19259 if (tr == null) { 19260 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19261 } 19262 appThread = ApplicationThreadNative.asInterface(whoThread); 19263 if (appThread == null) { 19264 throw new IllegalArgumentException("Bad app thread " + appThread); 19265 } 19266 } 19267 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19268 resolvedType, null, null, null, null, 0, 0, null, null, 19269 null, options, callingUser, null, tr); 19270 } 19271 19272 @Override 19273 public void setExcludeFromRecents(boolean exclude) { 19274 checkCaller(); 19275 19276 synchronized (ActivityManagerService.this) { 19277 long origId = Binder.clearCallingIdentity(); 19278 try { 19279 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19280 if (tr == null) { 19281 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19282 } 19283 Intent intent = tr.getBaseIntent(); 19284 if (exclude) { 19285 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19286 } else { 19287 intent.setFlags(intent.getFlags() 19288 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19289 } 19290 } finally { 19291 Binder.restoreCallingIdentity(origId); 19292 } 19293 } 19294 } 19295 } 19296} 19297